( state: SpeculationState, setAppState: (f: (prev: AppState) => AppState) => void, cleanMessageCount: number, )
| 716 | } |
| 717 | |
| 718 | export async function acceptSpeculation( |
| 719 | state: SpeculationState, |
| 720 | setAppState: (f: (prev: AppState) => AppState) => void, |
| 721 | cleanMessageCount: number, |
| 722 | ): Promise<SpeculationResult | null> { |
| 723 | if (state.status !== 'active') return null |
| 724 | |
| 725 | const { |
| 726 | id, |
| 727 | messagesRef, |
| 728 | writtenPathsRef, |
| 729 | abort, |
| 730 | startTime, |
| 731 | suggestionLength, |
| 732 | isPipelined, |
| 733 | } = state |
| 734 | const messages = messagesRef.current |
| 735 | const overlayPath = getOverlayPath(id) |
| 736 | const acceptedAt = Date.now() |
| 737 | |
| 738 | abort() |
| 739 | |
| 740 | if (cleanMessageCount > 0) { |
| 741 | await copyOverlayToMain(overlayPath, writtenPathsRef.current, getCwdState()) |
| 742 | } |
| 743 | safeRemoveOverlay(overlayPath) |
| 744 | |
| 745 | // Use snapshot boundary as default (available since state.status === 'active' was checked above) |
| 746 | let boundary: CompletionBoundary | null = state.boundary |
| 747 | let timeSavedMs = |
| 748 | Math.min(acceptedAt, boundary?.completedAt ?? Infinity) - startTime |
| 749 | |
| 750 | setAppState(prev => { |
| 751 | // Refine with latest React state if speculation is still active |
| 752 | if (prev.speculation.status === 'active' && prev.speculation.boundary) { |
| 753 | boundary = prev.speculation.boundary |
| 754 | const endTime = Math.min(acceptedAt, boundary.completedAt ?? Infinity) |
| 755 | timeSavedMs = endTime - startTime |
| 756 | } |
| 757 | return { |
| 758 | ...prev, |
| 759 | speculation: IDLE_SPECULATION_STATE, |
| 760 | speculationSessionTimeSavedMs: |
| 761 | prev.speculationSessionTimeSavedMs + timeSavedMs, |
| 762 | } |
| 763 | }) |
| 764 | |
| 765 | logForDebugging( |
| 766 | boundary === null |
| 767 | ? `[Speculation] Accept ${id}: still running, using ${messages.length} messages` |
| 768 | : `[Speculation] Accept ${id}: already complete`, |
| 769 | ) |
| 770 | |
| 771 | logSpeculation( |
| 772 | id, |
| 773 | 'accepted', |
| 774 | startTime, |
| 775 | suggestionLength, |
no test coverage detected