Skip to content

Normalize context compaction before API requests - #27289

Closed
daniel-oai wants to merge 1 commit into
mainfrom
codex/fix-context-compaction-schema
Closed

daniel-oai wants to merge 1 commit into
mainfrom
codex/fix-context-compaction-schema

Conversation

@daniel-oai

Copy link
Copy Markdown
Contributor

Summary

Fixes #27269.

Remote compaction can yield ResponseItem::ContextCompaction, but the Responses API rejects context_compaction in request input. This change centralizes model/API-bound normalization so encrypted ContextCompaction payloads are sent as the API-supported compaction item, and empty context-compaction markers are omitted from model history.

The app-server/UI lifecycle path remains unchanged: UI compaction markers still flow through TurnItem::ContextCompaction and v2 ThreadItem::ContextCompaction.

Root Cause

Remote compaction post-processing preserved ResponseItem::ContextCompaction in replacement history. A later model request could replay that history into /responses, producing the API wire enum error:

Invalid value: context_compaction

What Changed

  • Added one helper, model_api_safe_response_item, for API-safe ResponseItem normalization.
  • Reused that helper from Prompt::get_formatted_input() and remote compaction replacement-history processing.
  • Converted encrypted context_compaction items to compaction before model/API use.
  • Dropped empty context_compaction items from model/API-bound history because they are UI lifecycle markers; the UI path uses TurnItem::ContextCompaction.
  • Added regression coverage for Rust enum normalization and serialized wire shape.

Validation

  • just fmt
  • just test -p codex-core formatted_input_normalizes_context_compaction_for_responses_api process_compacted_history_normalizes_context_compaction_items
    • 2 tests passed
    • recipe bench-smoke tail completed
  • Broad just test -p codex-core was attempted. The new compaction tests passed, but the full run failed in unrelated sandbox/environment categories:
    • PATH alias creation denied in sandbox
    • missing target/debug/test_stdio_server for MCP stdio tests
    • sandbox-exec: sandbox_apply: Operation not permitted
    • timing/interrupt/unified exec tests sensitive to this managed sandbox
  • just fix -p codex-core

Adversarial Review

  • Responses API wire enum: Prompt::get_formatted_input() now normalizes API-bound input, and the regression test asserts serialized JSON contains "type":"compaction" and not context_compaction.
  • UI behavior: TurnItem::ContextCompaction remains unchanged, so app-server v2 clients still receive the canonical UI compaction item.
  • Empty marker rationale: ContextCompaction { encrypted_content: None } carries no model-visible encrypted compaction payload. It is a UI lifecycle marker, so omitting it from model/API history avoids sending an unsupported enum without losing model history.
  • Resume/replay/version skew: persisted or replayed context_compaction response items are normalized at the model request boundary, and new remote replacement histories are cleaned before persistence.
  • Future item kinds: the normalization helper enumerates all current passthrough ResponseItem variants instead of using a wildcard arm, so new variants require an explicit review decision.

@daniel-oai
daniel-oai marked this pull request as ready for review June 10, 2026 03:19
@daniel-oai
daniel-oai requested a review from a team as a code owner June 10, 2026 03:19
@daniel-oai

Copy link
Copy Markdown
Contributor Author

Closing per principal review. This is not currently a slam-dunk change: it conflicted with current main in the request formatting path and needs a fresh design/review pass against the new inter-agent message normalization before reopening.

@daniel-oai daniel-oai closed this Jun 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remote connection context_compaction error in main session

1 participant