fix(compaction): count nested tool result content - #99391
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 3, 2026, 4:53 AM ET / 08:53 UTC. Summary PR surface: Source +18, Tests +80. Total +98 across 4 files. Reproducibility: yes. Current main creates nested Codex Review metrics: none identified. Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land one focused compaction fix that counts and summarizes nested Codex tool-result payloads exactly once, while keeping broader safeguard and Slack recovery work separate. Do we have a high-confidence way to reproduce the issue? Yes. Current main creates nested Codex Is this the best way to solve the issue? Yes. The shared agent-core compaction estimator and summary serializer are the narrow owner boundary; changing only Codex projection would leave the generic accounting and summary asymmetry in place. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 1fef99962edf. Label changesLabel justifications:
Evidence reviewedPR surface: Source +18, Tests +80. Total +98 across 4 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
506e5b0 to
3c8d6f8
Compare
3c8d6f8 to
d6016f0
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
d6016f0 to
5904327
Compare
|
Land-ready verification for exact head
Proof gap: the production compactor used an injected deterministic summary stream rather than a paid external model call, allowing exact prompt inspection. No screenshot is useful for transcript accounting. Thanks @LZY3538 for the fix. |
|
Merged via squash.
|
* fix(compaction): count nested tool result content * fix(agent-core): unify compaction block extraction --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
What Problem This Solves
Fixes #99375.
Fixes an issue where users in tool-heavy Codex sessions could see compaction repeatedly retain the full transcript when recent context was dominated by Codex tool-result blocks. Those blocks were preserved in transcript content as nested
toolResultpayloads, but the compaction estimator did not count their text, so the cut point could collapse back to the start of the transcript.Why This Change Was Made
The shared compaction estimator now counts nested
toolResult/tool_resulttext payloads in the same content-block pass that already accounts for text and image blocks. The compaction summary serializer now preserves the same nested tool-result payloads exactly once before summarized history is dropped, usingtextfirst and falling back to stringcontentonly whentextis absent.Dependency contract checked against OpenAI Codex protocol sources in sibling
../codex:codex-rs/protocol/src/items.rsfor tool-call/result item shapes andcodex-rs/protocol/src/dynamic_tools.rsfor dynamic tool output content items.User Impact
Tool-heavy Codex conversations can choose a real compaction cut point instead of no-oping when the newest retained transcript contains nested tool-result output. When older Codex tool-result output is compacted into the replacement summary, that payload remains available to the summarizer instead of being silently omitted.
Evidence
node scripts/run-vitest.mjs packages/agent-core/src/harness/compaction/compaction-trailing-toolresult.test.tsfailed before the estimator implementation because the new nestedtoolResultcase estimated0tokens and retained entry index0.node scripts/run-vitest.mjs packages/agent-core/src/harness/compaction/utils.test.tsfailed before the serializer implementation becauseserializeConversationreturned an empty string for Codex nestedtoolResultcontent.prepareCompaction+compactfake stream captured the actual summarization prompt:{ "firstKeptEntryId": "entry-3", "summarizedRoles": ["user", "assistant", "toolResult"], "summarizedToolPayloadChars": 120039, "promptContainsMarker": true, "markerOccurrencesInPrompt": 1, "compactOk": true, "summary": "summary from captured prompt" }node scripts/run-vitest.mjs packages/agent-core/src/harness/compaction/utils.test.ts packages/agent-core/src/harness/compaction/compaction.test.ts packages/agent-core/src/harness/compaction/compaction-trailing-toolresult.test.ts packages/agent-core/src/harness/compaction/compaction-image-tokens.test.ts src/agents/embedded-agent-runner/transcript-file-state.test.ts(5 files, 35 tests passed)pnpm tsgo:corepnpm tsgo:core:testpnpm exec oxfmt --check packages/agent-core/src/harness/compaction/utils.ts packages/agent-core/src/harness/compaction/utils.test.ts packages/agent-core/src/harness/compaction/compaction.ts packages/agent-core/src/harness/compaction/compaction-trailing-toolresult.test.tsgit diff --checkKnown local proof gap:
node scripts/run-vitest.mjs extensions/codex/src/app-server/run-attempt.context-engine.test.tswas attempted earlier, but this local Windows worktree does not have thecodex-context-test-sandboxbackend registered. The run failed before exercising this compaction change, withturn/startnot observed and an unhandled sandbox backend registration error.