| import { useEffect, useRef, useSyncExternalStore } from 'react' |
| import { useAppState, useSetAppState } from '../state/AppState.js' |
| import { |
| buildContinuationPrompt, |
| getGoalContinuationGoalId, |
| isGoalContinuationPrompt, |
| } from '../utils/goal.js' |
| import { |
| enqueue, |
| getCommandQueue, |
| removeByFilter, |
| } from '../utils/messageQueueManager.js' |
| import type { QueryGuard } from '../utils/QueryGuard.js' |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| export function useGoalAutoContinue(queryGuard: QueryGuard): void { |
| const isActive = useSyncExternalStore( |
| queryGuard.subscribe, |
| queryGuard.getSnapshot, |
| ) |
| const goal = useAppState(s => s.goal) |
| const mode = useAppState(s => s.toolPermissionContext.mode) |
| const setAppState = useSetAppState() |
|
|
| const wasActiveRef = useRef(isActive) |
|
|
| useEffect(() => { |
| const wasActive = wasActiveRef.current |
| wasActiveRef.current = isActive |
|
|
| |
| if (!(wasActive && !isActive)) return |
|
|
| if (!goal) return |
| if (goal.status !== 'pursuing') return |
| if (mode === 'plan') return |
|
|
| const now = Date.now() |
|
|
| |
| const queue = getCommandQueue() |
| const hasBlockingQueuedWork = queue.some( |
| cmd => !isGoalContinuationPrompt(cmd.value), |
| ) |
| if (hasBlockingQueuedWork) return |
|
|
| const alreadyQueuedForThisGoal = queue.some( |
| cmd => getGoalContinuationGoalId(cmd.value) === goal.id, |
| ) |
| if (alreadyQueuedForThisGoal) return |
|
|
| removeByFilter(cmd => { |
| if (!isGoalContinuationPrompt(cmd.value)) return false |
| return getGoalContinuationGoalId(cmd.value) !== goal.id |
| }) |
|
|
| const prompt = buildContinuationPrompt(goal, now) |
| enqueue({ |
| mode: 'prompt', |
| value: prompt, |
| priority: 'later', |
| isMeta: true, |
| }) |
|
|
| setAppState(prev => ({ |
| ...prev, |
| goal: prev.goal && prev.goal.id === goal.id |
| ? { |
| ...prev.goal, |
| continuationCount: prev.goal.continuationCount + 1, |
| lastUpdatedAt: now, |
| } |
| : prev.goal, |
| })) |
| }, [isActive, goal, mode, setAppState]) |
| } |