@@ -30,6 +30,23 @@ export type {
3030 CrashRestoreResult ,
3131} from './types.js' ;
3232
33+ /**
34+ * Options for sending recovery prompt
35+ */
36+ export interface SendRecoveryPromptOptions {
37+ /** Prompt to send */
38+ resumePrompt : string ;
39+ /** Monitoring ID for the session */
40+ resumeMonitoringId ?: number ;
41+ /** Source of the prompt */
42+ source : 'controller' ;
43+ }
44+
45+ /**
46+ * Callback to send recovery prompt to agent
47+ */
48+ export type SendRecoveryPromptFn = ( options : SendRecoveryPromptOptions ) => Promise < void > ;
49+
3350/**
3451 * Options for handleCrashRecovery
3552 */
@@ -54,6 +71,8 @@ export interface HandleCrashRecoveryOptions {
5471 indexManager : StepIndexManager ;
5572 /** Current session (optional) */
5673 session ?: StepSession | null ;
74+ /** Callback to send recovery prompt (required for auto mode recovery) */
75+ sendRecoveryPrompt ?: SendRecoveryPromptFn ;
5776}
5877
5978/**
@@ -119,13 +138,46 @@ export async function handleCrashRecovery(
119138
120139 const restoration = await restoreFromCrash ( restoreCtx ) ;
121140
122- // 3. Transition state machine to awaiting
123- machine . send ( {
124- type : 'STEP_COMPLETE' ,
125- output : { output : '' , monitoringId : stepData ?. monitoringId } ,
126- } ) ;
141+ // 3. Handle recovery based on mode
142+ const isAutoMode = machine . context . autoMode ;
143+ const recoveryPrompt = 'Continue where you left off. Review what was accomplished and proceed with the next logical step.' ;
144+
145+ if ( isAutoMode ) {
146+ // Auto mode: Send recovery prompt directly before transitioning
147+ // This centralizes all recovery logic here instead of scattering to wait.ts/delegated.ts
148+ if ( ! options . sendRecoveryPrompt ) {
149+ throw new Error ( '[recovery] Auto mode crash recovery requires sendRecoveryPrompt callback' ) ;
150+ }
127151
128- debug ( '[recovery] Crash recovery complete, transitioning to awaiting state' ) ;
152+ debug ( '[recovery] Auto mode: sending recovery prompt to agent' ) ;
153+ emitter . updateAgentStatus ( uniqueAgentId , 'running' ) ;
154+
155+ // Transition to running state before sending prompt
156+ machine . send ( { type : 'RESUME' } ) ;
157+
158+ // Send recovery prompt and wait for agent response
159+ await options . sendRecoveryPrompt ( {
160+ resumePrompt : recoveryPrompt ,
161+ resumeMonitoringId : stepData ?. monitoringId ,
162+ source : 'controller' ,
163+ } ) ;
164+
165+ debug ( '[recovery] Recovery prompt sent, agent responded' ) ;
166+
167+ // After agent responds, the state machine will have transitioned to awaiting/delegated
168+ // The normal flow will continue from there (chained prompts, etc.)
169+ debug ( '[recovery] Crash recovery complete (auto mode)' ) ;
170+ } else {
171+ // Manual mode: Pause and wait for user input
172+ machine . context . paused = true ;
173+
174+ machine . send ( {
175+ type : 'STEP_COMPLETE' ,
176+ output : { output : '' , monitoringId : stepData ?. monitoringId } ,
177+ } ) ;
178+
179+ debug ( '[recovery] Crash recovery complete, transitioning to awaiting state (manual mode, paused)' ) ;
180+ }
129181
130182 return { handled : true , detection, restoration } ;
131183}
0 commit comments