Merge pull request #671 from gsd-build/fix/665-auto-resume-recovery
fix: auto-mode resume preserves context from paused session
This commit is contained in:
commit
0a43e6de4e
2 changed files with 36 additions and 5 deletions
|
|
@ -244,6 +244,9 @@ function escapeStaleWorktree(base: string): string {
|
|||
/** Crash recovery prompt — set by startAuto, consumed by first dispatchNextUnit */
|
||||
let pendingCrashRecovery: string | null = null;
|
||||
|
||||
/** Session file path captured at pause — used to synthesize recovery briefing on resume */
|
||||
let pausedSessionFile: string | null = null;
|
||||
|
||||
/** Dashboard tracking */
|
||||
let autoStartTime: number = 0;
|
||||
let completedUnits: { type: string; id: string; startedAt: number; finishedAt: number }[] = [];
|
||||
|
|
@ -588,6 +591,7 @@ export async function stopAuto(ctx?: ExtensionContext, pi?: ExtensionAPI): Promi
|
|||
clearActivityLogState();
|
||||
resetProactiveHealing();
|
||||
pendingCrashRecovery = null;
|
||||
pausedSessionFile = null;
|
||||
_handlingAgentEnd = false;
|
||||
ctx?.ui.setStatus("gsd-auto", undefined);
|
||||
ctx?.ui.setWidget("gsd-progress", undefined);
|
||||
|
|
@ -612,6 +616,11 @@ export async function stopAuto(ctx?: ExtensionContext, pi?: ExtensionAPI): Promi
|
|||
export async function pauseAuto(ctx?: ExtensionContext, _pi?: ExtensionAPI): Promise<void> {
|
||||
if (!active) return;
|
||||
clearUnitTimeout();
|
||||
|
||||
// Capture the current session file before clearing state — used for
|
||||
// recovery briefing on resume so the next agent knows what already happened.
|
||||
pausedSessionFile = ctx?.sessionManager?.getSessionFile() ?? null;
|
||||
|
||||
if (lockBase()) clearLock(lockBase());
|
||||
|
||||
// Remove SIGTERM handler registered at auto-mode start
|
||||
|
|
@ -709,6 +718,28 @@ export async function startAuto(
|
|||
// Self-heal: clear stale runtime records where artifacts already exist
|
||||
await selfHealRuntimeRecords(basePath, ctx, completedKeySet);
|
||||
invalidateAllCaches();
|
||||
|
||||
// Synthesize recovery briefing from the paused session so the next agent
|
||||
// knows what already happened (reuses crash recovery infrastructure).
|
||||
if (pausedSessionFile) {
|
||||
const activityDir = join(gsdRoot(basePath), "activity");
|
||||
const recovery = synthesizeCrashRecovery(
|
||||
basePath,
|
||||
currentUnit?.type ?? "unknown",
|
||||
currentUnit?.id ?? "unknown",
|
||||
pausedSessionFile,
|
||||
activityDir,
|
||||
);
|
||||
if (recovery && recovery.trace.toolCallCount > 0) {
|
||||
pendingCrashRecovery = recovery.prompt;
|
||||
ctx.ui.notify(
|
||||
`Recovered ${recovery.trace.toolCallCount} tool calls from paused session. Resuming with context.`,
|
||||
"info",
|
||||
);
|
||||
}
|
||||
pausedSessionFile = null;
|
||||
}
|
||||
|
||||
await dispatchNextUnit(ctx, pi);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -313,10 +313,10 @@ function formatRecoveryPrompt(
|
|||
const sections: string[] = [];
|
||||
|
||||
sections.push(
|
||||
"## Crash Recovery Briefing",
|
||||
"## Recovery Briefing",
|
||||
"",
|
||||
`You are resuming \`${unitType}\` for \`${unitId}\` after a crash.`,
|
||||
`The previous session completed **${trace.toolCallCount} tool calls** before dying.`,
|
||||
`You are resuming \`${unitType}\` for \`${unitId}\` after an interruption.`,
|
||||
`The previous session completed **${trace.toolCallCount} tool calls** before stopping.`,
|
||||
"Use this briefing to pick up exactly where it left off. Do NOT redo completed work.",
|
||||
);
|
||||
|
||||
|
|
@ -352,7 +352,7 @@ function formatRecoveryPrompt(
|
|||
// Errors
|
||||
if (trace.errors.length > 0) {
|
||||
sections.push(
|
||||
"", "### Errors Before Crash",
|
||||
"", "### Errors Before Interruption",
|
||||
...trace.errors.slice(-3).map(e => `- ${truncate(e, 200)}`),
|
||||
);
|
||||
}
|
||||
|
|
@ -368,7 +368,7 @@ function formatRecoveryPrompt(
|
|||
// Last reasoning
|
||||
if (trace.lastReasoning) {
|
||||
sections.push(
|
||||
"", "### Last Agent Reasoning Before Crash",
|
||||
"", "### Last Agent Reasoning Before Interruption",
|
||||
`> ${trace.lastReasoning.replace(/\n/g, "\n> ")}`,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue