Skip to content

Commit 66dcc4e

Browse files
fix(codex): beta blocker - keep context engine on canonical session key (#84954)
Merged via squash. Prepared head SHA: 6cdccaa Co-authored-by: neeravmakwana <261249544+neeravmakwana@users.noreply.github.com> Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com> Reviewed-by: @jalehman
1 parent 1b1580c commit 66dcc4e

3 files changed

Lines changed: 48 additions & 13 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Docs: https://docs.openclaw.ai
3636
- CLI/perf: keep `agents --help` out of agents action/runtime imports so help, completion, and command discovery paths avoid loading the full agents runtime. (#84483) Thanks @frankekn.
3737
- CLI/perf: keep `secrets --help` and `nodes --help` on the precomputed help path so parent help avoids loading action-heavy command runtime modules. (#84818) Thanks @frankekn.
3838
- CLI/perf: serve `doctor`, `gateway`, `models`, and `plugins` parent help from startup metadata so common subcommand help avoids full CLI program construction. (#84786) Thanks @frankekn.
39+
- Codex/Lossless: keep context-engine history on the canonical run session when Telegram DMs use per-peer runtime policy keys. Fixes #84936. (#84954) Thanks @neeravmakwana.
3940

4041
## 2026.5.20
4142

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,39 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
348348
expect(openSpy).not.toHaveBeenCalled();
349349
});
350350

351+
it("keeps context-engine history bound to the run session when sandbox key differs", async () => {
352+
const sessionFile = path.join(tempDir, "session.jsonl");
353+
const workspaceDir = path.join(tempDir, "workspace");
354+
SessionManager.open(sessionFile).appendMessage(
355+
assistantMessage("canonical main context", Date.now()) as never,
356+
);
357+
const contextEngine = createContextEngine();
358+
const harness = createStartedThreadHarness();
359+
const params = createParams(sessionFile, workspaceDir);
360+
params.sessionKey = "agent:main:main";
361+
params.sandboxSessionKey = "agent:main:telegram:default:direct:12345";
362+
params.contextEngine = contextEngine;
363+
364+
const run = runCodexAppServerAttempt(params);
365+
await harness.waitForMethod("turn/start");
366+
367+
if (!contextEngine.bootstrap) {
368+
throw new Error("expected bootstrap hook");
369+
}
370+
const bootstrapParams = requireFirstCallArg(contextEngine.bootstrap, "bootstrap") as Parameters<
371+
NonNullable<ContextEngine["bootstrap"]>
372+
>[0];
373+
expect(bootstrapParams.sessionKey).toBe("agent:main:main");
374+
375+
const assembleParams = requireFirstCallArg(contextEngine.assemble, "assemble") as Parameters<
376+
ContextEngine["assemble"]
377+
>[0];
378+
expect(assembleParams.sessionKey).toBe("agent:main:main");
379+
380+
await harness.completeTurn();
381+
await run;
382+
});
383+
351384
it("uses the runtime token budget for large Codex context-engine projections", async () => {
352385
const sessionFile = path.join(tempDir, "session.jsonl");
353386
const workspaceDir = path.join(tempDir, "workspace");

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

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,7 @@ export async function runCodexAppServerAttempt(
808808
await fs.mkdir(resolvedWorkspace, { recursive: true });
809809
const sandboxSessionKey =
810810
params.sandboxSessionKey?.trim() || params.sessionKey?.trim() || params.sessionId;
811+
const contextSessionKey = params.sessionKey?.trim() || sandboxSessionKey;
811812
const sandbox = await resolveSandboxContext({
812813
config: params.config,
813814
sessionKey: sandboxSessionKey,
@@ -882,7 +883,7 @@ export async function runCodexAppServerAttempt(
882883
});
883884
const runtimeParams = {
884885
...params,
885-
sessionKey: sandboxSessionKey,
886+
sessionKey: contextSessionKey,
886887
...(startupAuthProfileId ? { authProfileId: startupAuthProfileId } : {}),
887888
};
888889
let activeSessionId = params.sessionId;
@@ -1000,7 +1001,7 @@ export async function runCodexAppServerAttempt(
10001001
hadSessionFile,
10011002
contextEngine: activeContextEngine,
10021003
sessionId: activeSessionId,
1003-
sessionKey: sandboxSessionKey,
1004+
sessionKey: contextSessionKey,
10041005
sessionFile: activeSessionFile,
10051006
runtimeContext: buildActiveContextEngineRuntimeContext(),
10061007
runMaintenance: runHarnessContextEngineMaintenance,
@@ -1014,7 +1015,7 @@ export async function runCodexAppServerAttempt(
10141015
params,
10151016
resolvedWorkspace,
10161017
effectiveWorkspace,
1017-
sessionKey: sandboxSessionKey,
1018+
sessionKey: contextSessionKey,
10181019
sessionAgentId,
10191020
});
10201021
const baseDeveloperInstructions = joinPresentSections(
@@ -1047,7 +1048,7 @@ export async function runCodexAppServerAttempt(
10471048
const assembled = await assembleHarnessContextEngine({
10481049
contextEngine: activeContextEngine,
10491050
sessionId: activeSessionId,
1050-
sessionKey: sandboxSessionKey,
1051+
sessionKey: contextSessionKey,
10511052
messages: historyMessages,
10521053
tokenBudget: params.contextTokenBudget,
10531054
availableTools: new Set(toolBridge.specs.map((tool) => tool.name).filter(isNonEmptyString)),
@@ -1087,7 +1088,7 @@ export async function runCodexAppServerAttempt(
10871088
: { project: true, reason: "per-turn-projection" };
10881089
embeddedAgentLog.info("codex app-server context-engine projection decision", {
10891090
sessionId: params.sessionId,
1090-
sessionKey: sandboxSessionKey,
1091+
sessionKey: contextSessionKey,
10911092
engineId: activeContextEngine.info.id,
10921093
mode: contextEngineProjection?.mode ?? assembled.contextProjection?.mode ?? "per_turn",
10931094
epoch: contextEngineProjection?.epoch,
@@ -1148,7 +1149,7 @@ export async function runCodexAppServerAttempt(
11481149
};
11491150
const systemPromptReport = buildCodexSystemPromptReport({
11501151
attempt: params,
1151-
sessionKey: sandboxSessionKey,
1152+
sessionKey: contextSessionKey,
11521153
workspaceDir: effectiveWorkspace,
11531154
developerInstructions: promptBuild.developerInstructions,
11541155
workspaceBootstrapContext,
@@ -2254,7 +2255,7 @@ export async function runCodexAppServerAttempt(
22542255
"codex app-server context-engine turn overflowed; forcing context-engine compaction",
22552256
{
22562257
sessionId: activeSessionId,
2257-
sessionKey: sandboxSessionKey,
2258+
sessionKey: contextSessionKey,
22582259
threadId: thread.threadId,
22592260
engineId: activeContextEngine.info.id,
22602261
tokenBudget: params.contextTokenBudget,
@@ -2273,7 +2274,7 @@ export async function runCodexAppServerAttempt(
22732274
activeContextEngine,
22742275
{
22752276
sessionId: activeSessionId,
2276-
sessionKey: sandboxSessionKey,
2277+
sessionKey: contextSessionKey,
22772278
sessionFile: activeSessionFile,
22782279
tokenBudget: params.contextTokenBudget,
22792280
force: true,
@@ -2291,7 +2292,7 @@ export async function runCodexAppServerAttempt(
22912292
);
22922293
embeddedAgentLog.info("codex app-server context-engine forced compaction result", {
22932294
sessionId: activeSessionId,
2294-
sessionKey: sandboxSessionKey,
2295+
sessionKey: contextSessionKey,
22952296
engineId: activeContextEngine.info.id,
22962297
ok: compactResult.ok,
22972298
compacted: compactResult.compacted,
@@ -2307,7 +2308,7 @@ export async function runCodexAppServerAttempt(
23072308
await runHarnessContextEngineMaintenance({
23082309
contextEngine: activeContextEngine,
23092310
sessionId: activeSessionId,
2310-
sessionKey: sandboxSessionKey,
2311+
sessionKey: contextSessionKey,
23112312
sessionFile: activeSessionFile,
23122313
reason: "compaction",
23132314
runtimeContext: maintenanceRuntimeContext,
@@ -2317,7 +2318,7 @@ export async function runCodexAppServerAttempt(
23172318
} catch (compactErr) {
23182319
embeddedAgentLog.warn("codex app-server context-engine forced compaction failed", {
23192320
sessionId: params.sessionId,
2320-
sessionKey: sandboxSessionKey,
2321+
sessionKey: contextSessionKey,
23212322
engineId: activeContextEngine.info.id,
23222323
error: formatErrorMessage(compactErr),
23232324
});
@@ -2682,7 +2683,7 @@ export async function runCodexAppServerAttempt(
26822683
params,
26832684
agentId: sessionAgentId,
26842685
result,
2685-
sessionKey: sandboxSessionKey,
2686+
sessionKey: contextSessionKey,
26862687
threadId: thread.threadId,
26872688
turnId: activeTurnId,
26882689
});
@@ -2715,7 +2716,7 @@ export async function runCodexAppServerAttempt(
27152716
aborted: finalAborted,
27162717
yieldAborted: Boolean(result.yieldDetected),
27172718
sessionIdUsed: activeSessionId,
2718-
sessionKey: sandboxSessionKey,
2719+
sessionKey: contextSessionKey,
27192720
sessionFile: activeSessionFile,
27202721
messagesSnapshot: finalMessages,
27212722
prePromptMessageCount,

0 commit comments

Comments
 (0)