Skip to content

Commit 68f3c80

Browse files
committed
fix: preserve recent Codex context projections
1 parent 7554dee commit 68f3c80

3 files changed

Lines changed: 48 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Docs: https://docs.openclaw.ai
2525

2626
### Fixes
2727

28+
- Codex app-server: keep recent context-engine messages when oversized projected history is truncated, so short follow-ups in long channel sessions do not fall back to stale earlier turns.
2829
- Feishu: refresh inbound session delivery context for DM, group, and broadcast turns so later replies do not inherit stale WebChat routing. Fixes #78274.
2930
- QA-Lab/qa-channel: attach redacted agent tool-start traces to outbound `QaBusMessage` records so scenarios can assert actual tool use instead of relying only on reply text. Fixes #67637. Thanks @100yenadmin.
3031
- QA-Lab: fail live runtime parity reports when assistant-message usage is missing, preventing `0 vs 0` live token rows from being reported as passing proof. Fixes #80411. Thanks @100yenadmin.

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,32 @@ describe("projectContextEngineAssemblyForCodex", () => {
154154
expect(result.promptText.length).toBeLessThan(25_000);
155155
});
156156

157+
it("keeps recent context when the rendered conversation overflows", () => {
158+
const result = projectContextEngineAssemblyForCodex({
159+
assembledMessages: [
160+
textMessage("assistant", `old discrawl setup from previous day ${"x".repeat(5_850)}`),
161+
...Array.from({ length: 5 }, (_, index) =>
162+
textMessage("assistant", `stale filler ${index}:${"x".repeat(5_850)}`),
163+
),
164+
textMessage(
165+
"user",
166+
"have Codex CLI do it via /goal. tell it in a SEPARATE repo; create recrawl",
167+
),
168+
textMessage("assistant", "codex exec -C /tmp/recrawl started"),
169+
],
170+
originalHistoryMessages: [],
171+
prompt: "?",
172+
});
173+
174+
expect(result.promptText).toContain("[truncated ");
175+
expect(result.promptText).toContain("from older context");
176+
expect(result.promptText).not.toContain("old discrawl setup from previous day");
177+
expect(result.promptText).toContain("create recrawl");
178+
expect(result.promptText).toContain("codex exec -C /tmp/recrawl started");
179+
expect(result.promptText).toContain("Current user request:\n?");
180+
expect(result.promptText.length).toBeLessThan(25_000);
181+
});
182+
157183
it("can scale the rendered context cap for larger Codex context windows", () => {
158184
const result = projectContextEngineAssemblyForCodex({
159185
assembledMessages: Array.from({ length: 12 }, (_, index) =>

extensions/codex/src/app-server/context-engine-projection.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export function projectContextEngineAssemblyForCodex(params: {
4747
CONTEXT_SAFETY_NOTE,
4848
"",
4949
CONTEXT_OPEN,
50-
truncateText(renderedContext, maxRenderedContextChars),
50+
truncateOlderContext(renderedContext, maxRenderedContextChars),
5151
CONTEXT_CLOSE,
5252
"",
5353
REQUEST_HEADER,
@@ -381,3 +381,23 @@ function truncateText(text: string, maxChars: number): string {
381381
? `${text.slice(0, maxChars)}\n[truncated ${text.length - maxChars} chars]`
382382
: text;
383383
}
384+
385+
function truncateOlderContext(text: string, maxChars: number): string {
386+
if (text.length <= maxChars) {
387+
return text;
388+
}
389+
if (maxChars <= 0) {
390+
return "";
391+
}
392+
393+
const buildMarker = (omittedChars: number): string =>
394+
`[truncated ${omittedChars} chars from older context]\n`;
395+
let marker = buildMarker(text.length - maxChars);
396+
let tailChars = Math.max(0, maxChars - marker.length);
397+
marker = buildMarker(text.length - tailChars);
398+
if (marker.length >= maxChars) {
399+
return marker.slice(0, maxChars);
400+
}
401+
tailChars = maxChars - marker.length;
402+
return `${marker}${text.slice(text.length - tailChars).trimStart()}`;
403+
}

0 commit comments

Comments
 (0)