Skip to content

Commit 147b9a9

Browse files
Han KimHan Kim
authored andcommitted
fix(codex): prefer native tokens for resume budget
1 parent 800a0d3 commit 147b9a9

2 files changed

Lines changed: 60 additions & 1 deletion

File tree

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

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6204,6 +6204,65 @@ describe("runCodexAppServerAttempt", () => {
62046204
expect(savedBinding?.threadId).toBe("thread-1");
62056205
});
62066206

6207+
it("resumes a bound Codex thread when stale mirrored token totals remain over budget", async () => {
6208+
const sessionFile = path.join(tempDir, "session.jsonl");
6209+
const workspaceDir = path.join(tempDir, "workspace");
6210+
const agentDir = path.join(tempDir, "agent");
6211+
await writeExistingBinding(sessionFile, workspaceDir, { dynamicToolsFingerprint: "[]" });
6212+
await fs.writeFile(
6213+
path.join(path.dirname(sessionFile), "sessions.json"),
6214+
JSON.stringify({
6215+
"agent:main:session-1": {
6216+
sessionFile,
6217+
totalTokens: 96_000,
6218+
},
6219+
}),
6220+
);
6221+
const rolloutDir = path.join(agentDir, "codex-home", "sessions");
6222+
await fs.mkdir(rolloutDir, { recursive: true });
6223+
await fs.writeFile(
6224+
path.join(rolloutDir, "rollout-thread-existing.jsonl"),
6225+
`${JSON.stringify({
6226+
payload: {
6227+
type: "token_count",
6228+
info: {
6229+
total_token_usage: {
6230+
total_tokens: 97_000,
6231+
},
6232+
last_token_usage: {
6233+
total_tokens: 12_000,
6234+
},
6235+
},
6236+
},
6237+
})}\n`,
6238+
);
6239+
const { requests, waitForMethod, completeTurn } = createResumeHarness();
6240+
const params = createParams(sessionFile, workspaceDir);
6241+
params.agentDir = agentDir;
6242+
params.config = {
6243+
agents: {
6244+
defaults: {
6245+
compaction: {
6246+
truncateAfterCompaction: true,
6247+
maxActiveTranscriptBytes: "1mb",
6248+
},
6249+
},
6250+
},
6251+
} as never;
6252+
6253+
const run = runCodexAppServerAttempt(params, {
6254+
pluginConfig: { appServer: { mode: "yolo" } },
6255+
});
6256+
await waitForMethod("turn/start");
6257+
await completeTurn({ threadId: "thread-existing", turnId: "turn-1" });
6258+
await run;
6259+
6260+
expect(requests.map((entry) => entry.method)).toContain("thread/resume");
6261+
expect(requests.map((entry) => entry.method)).not.toContain("thread/start");
6262+
const savedBinding = await readCodexAppServerBinding(sessionFile);
6263+
expect(savedBinding?.threadId).toBe("thread-existing");
6264+
});
6265+
62076266
it("preserves bound auth when rotating an over-budget native rollout", async () => {
62086267
const sessionFile = path.join(tempDir, "session.jsonl");
62096268
const workspaceDir = path.join(tempDir, "workspace");

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,7 @@ async function rotateOversizedCodexAppServerStartupBinding(params: {
705705
Number.isFinite(sessionRecord.totalTokens)
706706
? sessionRecord.totalTokens
707707
: undefined;
708-
const tokenCount = maxFiniteNumber([sessionTokens, nativeTokens]);
708+
const tokenCount = nativeTokens ?? sessionTokens;
709709
if (tokenCount !== undefined && tokenCount >= CODEX_APP_SERVER_NATIVE_THREAD_MAX_TOKENS) {
710710
embeddedAgentLog.warn(
711711
"codex app-server native transcript exceeded active token limit; starting a fresh thread",

0 commit comments

Comments
 (0)