mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-03 02:56:23 +00:00
fix(codex): beta blocker - keep context engine on canonical session key (#84954)
Merged via squash.
Prepared head SHA: 6cdccaa007
Co-authored-by: neeravmakwana <261249544+neeravmakwana@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
This commit is contained in:
@@ -36,6 +36,7 @@ Docs: https://docs.openclaw.ai
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
||||
|
||||
## 2026.5.20
|
||||
|
||||
|
||||
@@ -348,6 +348,39 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
|
||||
expect(openSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("keeps context-engine history bound to the run session when sandbox key differs", async () => {
|
||||
const sessionFile = path.join(tempDir, "session.jsonl");
|
||||
const workspaceDir = path.join(tempDir, "workspace");
|
||||
SessionManager.open(sessionFile).appendMessage(
|
||||
assistantMessage("canonical main context", Date.now()) as never,
|
||||
);
|
||||
const contextEngine = createContextEngine();
|
||||
const harness = createStartedThreadHarness();
|
||||
const params = createParams(sessionFile, workspaceDir);
|
||||
params.sessionKey = "agent:main:main";
|
||||
params.sandboxSessionKey = "agent:main:telegram:default:direct:12345";
|
||||
params.contextEngine = contextEngine;
|
||||
|
||||
const run = runCodexAppServerAttempt(params);
|
||||
await harness.waitForMethod("turn/start");
|
||||
|
||||
if (!contextEngine.bootstrap) {
|
||||
throw new Error("expected bootstrap hook");
|
||||
}
|
||||
const bootstrapParams = requireFirstCallArg(contextEngine.bootstrap, "bootstrap") as Parameters<
|
||||
NonNullable<ContextEngine["bootstrap"]>
|
||||
>[0];
|
||||
expect(bootstrapParams.sessionKey).toBe("agent:main:main");
|
||||
|
||||
const assembleParams = requireFirstCallArg(contextEngine.assemble, "assemble") as Parameters<
|
||||
ContextEngine["assemble"]
|
||||
>[0];
|
||||
expect(assembleParams.sessionKey).toBe("agent:main:main");
|
||||
|
||||
await harness.completeTurn();
|
||||
await run;
|
||||
});
|
||||
|
||||
it("uses the runtime token budget for large Codex context-engine projections", async () => {
|
||||
const sessionFile = path.join(tempDir, "session.jsonl");
|
||||
const workspaceDir = path.join(tempDir, "workspace");
|
||||
|
||||
@@ -808,6 +808,7 @@ export async function runCodexAppServerAttempt(
|
||||
await fs.mkdir(resolvedWorkspace, { recursive: true });
|
||||
const sandboxSessionKey =
|
||||
params.sandboxSessionKey?.trim() || params.sessionKey?.trim() || params.sessionId;
|
||||
const contextSessionKey = params.sessionKey?.trim() || sandboxSessionKey;
|
||||
const sandbox = await resolveSandboxContext({
|
||||
config: params.config,
|
||||
sessionKey: sandboxSessionKey,
|
||||
@@ -882,7 +883,7 @@ export async function runCodexAppServerAttempt(
|
||||
});
|
||||
const runtimeParams = {
|
||||
...params,
|
||||
sessionKey: sandboxSessionKey,
|
||||
sessionKey: contextSessionKey,
|
||||
...(startupAuthProfileId ? { authProfileId: startupAuthProfileId } : {}),
|
||||
};
|
||||
let activeSessionId = params.sessionId;
|
||||
@@ -1000,7 +1001,7 @@ export async function runCodexAppServerAttempt(
|
||||
hadSessionFile,
|
||||
contextEngine: activeContextEngine,
|
||||
sessionId: activeSessionId,
|
||||
sessionKey: sandboxSessionKey,
|
||||
sessionKey: contextSessionKey,
|
||||
sessionFile: activeSessionFile,
|
||||
runtimeContext: buildActiveContextEngineRuntimeContext(),
|
||||
runMaintenance: runHarnessContextEngineMaintenance,
|
||||
@@ -1014,7 +1015,7 @@ export async function runCodexAppServerAttempt(
|
||||
params,
|
||||
resolvedWorkspace,
|
||||
effectiveWorkspace,
|
||||
sessionKey: sandboxSessionKey,
|
||||
sessionKey: contextSessionKey,
|
||||
sessionAgentId,
|
||||
});
|
||||
const baseDeveloperInstructions = joinPresentSections(
|
||||
@@ -1047,7 +1048,7 @@ export async function runCodexAppServerAttempt(
|
||||
const assembled = await assembleHarnessContextEngine({
|
||||
contextEngine: activeContextEngine,
|
||||
sessionId: activeSessionId,
|
||||
sessionKey: sandboxSessionKey,
|
||||
sessionKey: contextSessionKey,
|
||||
messages: historyMessages,
|
||||
tokenBudget: params.contextTokenBudget,
|
||||
availableTools: new Set(toolBridge.specs.map((tool) => tool.name).filter(isNonEmptyString)),
|
||||
@@ -1087,7 +1088,7 @@ export async function runCodexAppServerAttempt(
|
||||
: { project: true, reason: "per-turn-projection" };
|
||||
embeddedAgentLog.info("codex app-server context-engine projection decision", {
|
||||
sessionId: params.sessionId,
|
||||
sessionKey: sandboxSessionKey,
|
||||
sessionKey: contextSessionKey,
|
||||
engineId: activeContextEngine.info.id,
|
||||
mode: contextEngineProjection?.mode ?? assembled.contextProjection?.mode ?? "per_turn",
|
||||
epoch: contextEngineProjection?.epoch,
|
||||
@@ -1148,7 +1149,7 @@ export async function runCodexAppServerAttempt(
|
||||
};
|
||||
const systemPromptReport = buildCodexSystemPromptReport({
|
||||
attempt: params,
|
||||
sessionKey: sandboxSessionKey,
|
||||
sessionKey: contextSessionKey,
|
||||
workspaceDir: effectiveWorkspace,
|
||||
developerInstructions: promptBuild.developerInstructions,
|
||||
workspaceBootstrapContext,
|
||||
@@ -2254,7 +2255,7 @@ export async function runCodexAppServerAttempt(
|
||||
"codex app-server context-engine turn overflowed; forcing context-engine compaction",
|
||||
{
|
||||
sessionId: activeSessionId,
|
||||
sessionKey: sandboxSessionKey,
|
||||
sessionKey: contextSessionKey,
|
||||
threadId: thread.threadId,
|
||||
engineId: activeContextEngine.info.id,
|
||||
tokenBudget: params.contextTokenBudget,
|
||||
@@ -2273,7 +2274,7 @@ export async function runCodexAppServerAttempt(
|
||||
activeContextEngine,
|
||||
{
|
||||
sessionId: activeSessionId,
|
||||
sessionKey: sandboxSessionKey,
|
||||
sessionKey: contextSessionKey,
|
||||
sessionFile: activeSessionFile,
|
||||
tokenBudget: params.contextTokenBudget,
|
||||
force: true,
|
||||
@@ -2291,7 +2292,7 @@ export async function runCodexAppServerAttempt(
|
||||
);
|
||||
embeddedAgentLog.info("codex app-server context-engine forced compaction result", {
|
||||
sessionId: activeSessionId,
|
||||
sessionKey: sandboxSessionKey,
|
||||
sessionKey: contextSessionKey,
|
||||
engineId: activeContextEngine.info.id,
|
||||
ok: compactResult.ok,
|
||||
compacted: compactResult.compacted,
|
||||
@@ -2307,7 +2308,7 @@ export async function runCodexAppServerAttempt(
|
||||
await runHarnessContextEngineMaintenance({
|
||||
contextEngine: activeContextEngine,
|
||||
sessionId: activeSessionId,
|
||||
sessionKey: sandboxSessionKey,
|
||||
sessionKey: contextSessionKey,
|
||||
sessionFile: activeSessionFile,
|
||||
reason: "compaction",
|
||||
runtimeContext: maintenanceRuntimeContext,
|
||||
@@ -2317,7 +2318,7 @@ export async function runCodexAppServerAttempt(
|
||||
} catch (compactErr) {
|
||||
embeddedAgentLog.warn("codex app-server context-engine forced compaction failed", {
|
||||
sessionId: params.sessionId,
|
||||
sessionKey: sandboxSessionKey,
|
||||
sessionKey: contextSessionKey,
|
||||
engineId: activeContextEngine.info.id,
|
||||
error: formatErrorMessage(compactErr),
|
||||
});
|
||||
@@ -2682,7 +2683,7 @@ export async function runCodexAppServerAttempt(
|
||||
params,
|
||||
agentId: sessionAgentId,
|
||||
result,
|
||||
sessionKey: sandboxSessionKey,
|
||||
sessionKey: contextSessionKey,
|
||||
threadId: thread.threadId,
|
||||
turnId: activeTurnId,
|
||||
});
|
||||
@@ -2715,7 +2716,7 @@ export async function runCodexAppServerAttempt(
|
||||
aborted: finalAborted,
|
||||
yieldAborted: Boolean(result.yieldDetected),
|
||||
sessionIdUsed: activeSessionId,
|
||||
sessionKey: sandboxSessionKey,
|
||||
sessionKey: contextSessionKey,
|
||||
sessionFile: activeSessionFile,
|
||||
messagesSnapshot: finalMessages,
|
||||
prePromptMessageCount,
|
||||
|
||||
Reference in New Issue
Block a user