@@ -684,9 +684,10 @@ import {
684684import {
685685 computeIncludeStable,
686686 hashStableInstructions,
687- isAgentResumeFailure,
688687 persistCapturedAgentSession,
689688 resolveAgentResumeContext,
689+ resolveAgentResumeFailurePolicy,
690+ resolveAgentResumePromptPolicy,
690691} from './agent-session-resume.js';
691692import {
692693 initialNativeSessionRecoveryMetadata,
@@ -10505,14 +10506,15 @@ export async function startServer({
1050510506 invalidationReason: agentResumeCtx.invalidationReason,
1050610507 });
1050710508 publishNativeSessionRecoveryMetadata();
10509+ const agentResumePromptPolicy = resolveAgentResumePromptPolicy(agentResumeCtx);
1050810510 const userRequestPrompt = composeChatUserRequestForAgent(
1050910511 message,
1051010512 currentPrompt,
1051110513 // Only trim to the latest turn when we are actually resuming an
1051210514 // existing session. A create turn still sends the full transcript so
1051310515 // a brand-new session (incl. first turn after another agent)
1051410516 // is seeded with prior context.
10515- { skipTranscript: agentResumeCtx.isResuming },
10517+ { skipTranscript: agentResumePromptPolicy.skipTranscript },
1051610518 );
1051710519 // The stable instruction slice (daemon prompt + tool contract + system
1051810520 // prompt = design system / skills / memory) is identical across turns of
@@ -10538,12 +10540,12 @@ export async function startServer({
1053810540 // tool-token grant's presence flips between turns (rare cwd/projectId edge
1053910541 // cases); any such change correctly forces a full re-send that turn.
1054010542 const includeStableInstructions = computeIncludeStable(
10541- agentResumeCtx.isResuming ,
10543+ agentResumePromptPolicy.skipTranscript ,
1054210544 agentResumeCtx.storedStablePromptHash,
1054310545 currentStableHash,
1054410546 );
1054510547 run.promptCache = describeStablePromptCache({
10546- isResuming: agentResumeCtx.isResuming ,
10548+ isResuming: agentResumePromptPolicy.skipTranscript ,
1054710549 storedStablePromptHash: agentResumeCtx.storedStablePromptHash,
1054810550 currentStableHash,
1054910551 storedStableSections: agentResumeCtx.storedStableSections,
@@ -11694,7 +11696,7 @@ export async function startServer({
1169411696 hasPriorAssistantTurn,
1169511697 agentLogFilePath,
1169611698 promptFilePath: promptFile?.path,
11697- resumeSessionId: agentResumeCtx .resumeSessionId,
11699+ resumeSessionId: agentResumePromptPolicy .resumeSessionId,
1169811700 newSessionId: agentResumeCtx.newSessionId,
1169911701 disablePlugins:
1170011702 def.id === 'codex'
@@ -13049,15 +13051,20 @@ export async function startServer({
1304913051 // authority on how a resume failure ends.
1305013052 if (
1305113053 (runtimeResumesSessionById(def) || def.resumesSessionViaAcpLoad === true) &&
13052- agentResumeCtx.isResuming &&
1305313054 !run.resumeAutoReseeded &&
13054- isAgentResumeFailure(def.id, agentStderrTail, agentStdoutTail)
13055+ resolveAgentResumeFailurePolicy({
13056+ agentId: def.id,
13057+ stderr: agentStderrTail,
13058+ stdout: agentStdoutTail,
13059+ isResuming: agentResumePromptPolicy.skipTranscript,
13060+ resumeSessionId: agentResumePromptPolicy.resumeSessionId,
13061+ }).resumeFailed
1305513062 ) {
1305613063 design.runs.emit(run, 'diagnostic', {
1305713064 type: 'agent_resume_failed_suppressed',
1305813065 agent_id: def.id,
1305913066 reason: 'resume_failed',
13060- previous_session_id: agentResumeCtx .resumeSessionId ?? null,
13067+ previous_session_id: agentResumePromptPolicy .resumeSessionId ?? null,
1306113068 });
1306213069 return;
1306313070 }
@@ -13199,8 +13206,8 @@ export async function startServer({
1319913206 prompt: composed,
1320013207 cwd: effectiveCwd,
1320113208 model: safeModel,
13202- parentSession: agentResumeCtx.isResuming && agentResumeCtx .resumeSessionId
13203- ? agentResumeCtx .resumeSessionId
13209+ parentSession: agentResumePromptPolicy .resumeSessionId
13210+ ? agentResumePromptPolicy .resumeSessionId
1320413211 : undefined,
1320513212 send: (channel, payload) => {
1320613213 if (channel === 'agent') {
@@ -13249,8 +13256,8 @@ export async function startServer({
1324913256 ...(def.id === 'amr' ? { modelUnavailableErrorCode: 'AMR_MODEL_UNAVAILABLE' } : {}),
1325013257 // Resume the prior upstream session (drives `session/load`) when the
1325113258 // resume-identity guard says it is safe; otherwise a fresh session/new.
13252- ...(def.resumesSessionViaAcpLoad === true && agentResumeCtx.isResuming && agentResumeCtx .resumeSessionId
13253- ? { resumeSessionId: agentResumeCtx .resumeSessionId }
13259+ ...(def.resumesSessionViaAcpLoad === true && agentResumePromptPolicy .resumeSessionId
13260+ ? { resumeSessionId: agentResumePromptPolicy .resumeSessionId }
1325413261 : {}),
1325513262 onCliReady: () => noteCliReadyAt(),
1325613263 onSessionInit: () => noteSessionInitDoneAt(),
@@ -13308,16 +13315,20 @@ export async function startServer({
1330813315 if (
1330913316 event === 'error' &&
1331013317 def.resumesSessionViaAcpLoad === true &&
13311- agentResumeCtx.isResuming &&
13312- agentResumeCtx.resumeSessionId &&
1331313318 !run.resumeAutoReseeded &&
13314- isAgentResumeFailure(def.id, agentStderrTail, agentStdoutTail)
13319+ resolveAgentResumeFailurePolicy({
13320+ agentId: def.id,
13321+ stderr: agentStderrTail,
13322+ stdout: agentStdoutTail,
13323+ isResuming: agentResumePromptPolicy.skipTranscript,
13324+ resumeSessionId: agentResumePromptPolicy.resumeSessionId,
13325+ }).resumeFailed
1331513326 ) {
1331613327 design.runs.emit(run, 'diagnostic', {
1331713328 type: 'agent_resume_failed_suppressed',
1331813329 agent_id: def.id,
1331913330 reason: 'resume_failed',
13320- previous_session_id: agentResumeCtx .resumeSessionId ?? null,
13331+ previous_session_id: agentResumePromptPolicy .resumeSessionId ?? null,
1332113332 });
1332213333 return;
1332313334 }
@@ -13523,9 +13534,14 @@ export async function startServer({
1352313534 if (
1352413535 !run.cancelRequested &&
1352513536 (runtimeResumesSessionById(def) || def.resumesSessionViaAcpLoad === true) &&
13526- agentResumeCtx.isResuming &&
1352713537 run.conversationId &&
13528- isAgentResumeFailure(def.id, agentStderrTail, agentStdoutTail)
13538+ resolveAgentResumeFailurePolicy({
13539+ agentId: def.id,
13540+ stderr: agentStderrTail,
13541+ stdout: agentStdoutTail,
13542+ isResuming: agentResumePromptPolicy.skipTranscript,
13543+ resumeSessionId: agentResumePromptPolicy.resumeSessionId,
13544+ }).autoReseedFullTranscript
1352913545 ) {
1353013546 // The resumed upstream session is gone (expired / pruned). Clear the dead
1353113547 // handle and TRANSPARENTLY re-run this same turn with a fresh session +
@@ -13538,11 +13554,11 @@ export async function startServer({
1353813554 clearAgentSession(db, run.conversationId, def.id);
1353913555 if (!run.resumeAutoReseeded) {
1354013556 run.resumeAutoReseeded = true;
13541- run.resumeAutoReseededFrom = agentResumeCtx .resumeSessionId ?? null;
13557+ run.resumeAutoReseededFrom = agentResumePromptPolicy .resumeSessionId ?? null;
1354213558 run.nativeSessionRecovery = markNativeSessionAutoReseeded({
1354313559 previous: run.nativeSessionRecovery,
1354413560 agentId: def.id,
13545- previousSessionId: agentResumeCtx .resumeSessionId,
13561+ previousSessionId: agentResumePromptPolicy .resumeSessionId,
1354613562 });
1354713563 publishNativeSessionRecoveryMetadata();
1354813564 // Persisted to the per-run events.jsonl that the help → diagnostics
@@ -13552,7 +13568,7 @@ export async function startServer({
1355213568 type: 'agent_resume_auto_reseed',
1355313569 agent_id: def.id,
1355413570 reason: 'resume_failed',
13555- previous_session_id: agentResumeCtx .resumeSessionId ?? null,
13571+ previous_session_id: agentResumePromptPolicy .resumeSessionId ?? null,
1355613572 stale_session_cleared: true,
1355713573 nativeSessionRecovery: run.nativeSessionRecovery,
1355813574 });
0 commit comments