Skip to content

Commit e7aac17

Browse files
authored
fix(codex): clear stale context-engine projection after overflow retry
Fixes #88355. When a resumed Codex context-engine thread overflows and OpenClaw retries on a fresh native thread, clear the stale thread-bootstrap projection metadata from the fresh binding. This prevents later turns from treating that fresh thread as already projected when it only received the bare retry prompt. Verification: - Autoreview clean: no accepted/actionable findings reported. - CI run 26717883204 green on head 5438f8a.
1 parent 4b7f39e commit e7aac17

2 files changed

Lines changed: 33 additions & 1 deletion

File tree

extensions/codex/src/app-server/run-attempt.context-engine.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1281,7 +1281,7 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
12811281
const savedBinding = await readCodexAppServerBinding(sessionFile);
12821282
expect(savedBinding?.threadId).toBe("thread-fresh");
12831283
expect(savedBinding?.contextEngine?.engineId).toBe("lossless-claw");
1284-
expect(savedBinding?.contextEngine?.projection?.epoch).toBe("epoch-before");
1284+
expect(savedBinding?.contextEngine?.projection).toBeUndefined();
12851285
});
12861286

12871287
it("preserves a newer context-engine binding when a stale resumed thread overflows", async () => {

extensions/codex/src/app-server/run-attempt.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1924,6 +1924,38 @@ export async function runCodexAppServerAttempt(
19241924
);
19251925
} else {
19261926
thread = await restartContextEngineCodexThread();
1927+
// The fresh retry thread was not bootstrapped with the
1928+
// context-engine projection. Clear the stale projection from
1929+
// the saved binding so the next run will re-project instead
1930+
// of assuming the old epoch is still in the thread.
1931+
{
1932+
const retryBinding = await readCodexAppServerBinding(activeSessionFile);
1933+
if (
1934+
retryBinding &&
1935+
retryBinding.threadId === thread.threadId &&
1936+
retryBinding.contextEngine?.projection
1937+
) {
1938+
const {
1939+
schemaVersion: _schemaVersion,
1940+
sessionFile: _boundSessionFile,
1941+
updatedAt: _updatedAt,
1942+
...bindingForWrite
1943+
} = retryBinding;
1944+
await writeCodexAppServerBinding(activeSessionFile, {
1945+
...bindingForWrite,
1946+
contextEngine: bindingForWrite.contextEngine
1947+
? { ...bindingForWrite.contextEngine, projection: undefined }
1948+
: undefined,
1949+
});
1950+
embeddedAgentLog.info(
1951+
"codex app-server cleared stale context-engine projection after overflow retry",
1952+
{
1953+
threadId: thread.threadId,
1954+
previousEpoch: retryBinding.contextEngine.projection.epoch,
1955+
},
1956+
);
1957+
}
1958+
}
19271959
emitCodexAppServerEvent(params, {
19281960
stream: "codex_app_server.lifecycle",
19291961
data: { phase: "thread_ready_retry", threadId: thread.threadId },

0 commit comments

Comments
 (0)