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