Skip to content

feat: opt-in Responses Lite request shape for GPT-5.6 models#45

Closed
chrisolszewski wants to merge 1 commit into
cortexkit:mainfrom
chrisolszewski:feat/responses-lite
Closed

feat: opt-in Responses Lite request shape for GPT-5.6 models#45
chrisolszewski wants to merge 1 commit into
cortexkit:mainfrom
chrisolszewski:feat/responses-lite

Conversation

@chrisolszewski

@chrisolszewski chrisolszewski commented Jul 15, 2026

Copy link
Copy Markdown

Problem

Codex sends gpt-5.6-sol, gpt-5.6-terra, and gpt-5.6-luna requests in its Responses Lite wire shape (use_responses_lite in its model catalog): a different body layout plus a per-transport marker. This plugin always sends the normal Responses shape for those models, so its traffic diverges from what the official CLI emits for exactly the models it spoofs a Codex client for.

Fix

Add an opt-in responsesLite setting (env CORTEXKIT_OPENAI_AUTH_RESPONSES_LITE, default false, resolved env → config → default like every other setting). When enabled, requests for the three Lite models are rewritten to Codex's Lite contract; everything else is byte-identical to today.

I verified the behavior directly against openai/codex at rust-v0.144.0 (7678224, the version this plugin spoofs) and current main (38b064c3); the contract is identical in both:

  • Eligibility is an exact set, not a prefix match: upstream resolves use_responses_lite by catalog lookup and unknown models default to the normal shape. Base gpt-5.6 and hypothetical future gpt-5.6-* names stay non-Lite. No model-visibility changes.
  • Body: reasoning.context: "all_turns", parallel_tool_calls: false; tools/instructions move into input as an additional_tools developer item plus a developer message for non-empty instructions (empty instructions is omitted from the wire), per the Lite branch of request assembly. Hosted Responses tools like web_search are excluded from Lite tool specs; only client-executed tools are carried.
  • Images: detail is stripped from every input_image, including ones nested in function/custom-tool outputs.
  • Transport marking: HTTP carries x-openai-internal-codex-responses-lite: true; WebSocket carries the request-scoped client_metadata key (the upgrade itself is unmarked). The existing WS→HTTP fallback converts the metadata marker into the header. WS prewarm is unchanged; Codex prewarms Lite sessions normally.
  • Keepwarm integration: replay captures keep the HTTP marker, and WS-captured bodies are converted through the existing WS→HTTP fallback sanitizer before tracking, so idle warms go out as correctly-marked HTTP Lite requests. That conversion also stops pre-existing leakage of the WS-only client_metadata keys (x-codex-turn-metadata, x-codex-ws-stream-request-start-ms) into warm replays for all WS sessions.

Scope / limits

  • Default-off and all-or-nothing per request: disabled means no Lite header, no WS metadata marker, no body reshaping. The existing wire shape is untouched, and integration tests pin this.
  • Because Lite carries tools inline, eligible requests bypass the web_search prompt-cache stabilizer, matching what Codex itself sends for these models. Documented in the settings tables.

Testing

  • bun run build · bun run typecheck · bunx biome check src: all clean
  • bun test: 576 pass / 0 fail (new: config default/file/env precedence; exact-model + disabled gating; the full eligible-body rewrite including hosted-tool exclusion and nested image-detail stripping; non-Lite preservation; WS metadata marking + prewarm; WS→HTTP fallback marker conversion; keepwarm replay of a WS-captured Lite body arriving as a marked, sanitized HTTP request)

View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Summary by cubic

Adds an opt-in Responses Lite request shape for gpt-5.6-sol, gpt-5.6-terra, and gpt-5.6-luna, matching the Codex CLI. Default is off; enabling it rewrites bodies and marks transport correctly, with improved keepwarm behavior.

  • New Features

    • New responsesLite setting (env CORTEXKIT_OPENAI_AUTH_RESPONSES_LITE, default false). When on, only the exact models above use Lite; all others are unchanged.
    • Lite body changes: reasoning.context: "all_turns", parallel_tool_calls: false, tools/instructions moved into input (hosted web_search excluded), and detail stripped from all input_images.
    • Transport markers: HTTP adds x-openai-internal-codex-responses-lite: true; WebSocket sets a client_metadata flag. WS→HTTP fallback converts the flag into the header. Keepwarm captures/replays preserve the Lite marker.
  • Bug Fixes

    • Stop leakage of WS-only client_metadata keys (x-codex-turn-metadata, x-codex-ws-stream-request-start-ms) into keepwarm HTTP replays.

Written for commit adf4564. Summary will update on new commits.

Review in cubic

Add a `responsesLite` setting (env CORTEXKIT_OPENAI_AUTH_RESPONSES_LITE,
default false) that sends gpt-5.6-sol/-terra/-luna requests in Codex's
Responses Lite wire shape, matching the Codex CLI.

Verified against openai/codex at rust-v0.144.0 (7678224, the version this
plugin spoofs) and current main (38b064c3); the Lite contract is identical
in both:

- use_responses_lite is set via catalog lookup on exactly gpt-5.6-sol,
  gpt-5.6-terra, gpt-5.6-luna; unknown models default to the normal shape,
  so eligibility here is an exact set, not a prefix match.
- Lite bodies use reasoning.context=all_turns, parallel_tool_calls=false,
  and move tools/instructions into the input: an additional_tools developer
  item (client-executed tools only — hosted tools like web_search are
  excluded, core/src/tools/spec_plan.rs) plus a developer message for
  non-empty instructions (empty instructions are omitted from the wire).
- detail is stripped from every input_image, including images nested in
  function/custom-tool outputs (core/src/client_common.rs).
- Transport marking: HTTP header x-openai-internal-codex-responses-lite;
  WebSocket uses request-scoped client_metadata (the upgrade is unmarked).
  The WS→HTTP fallback converts the metadata marker to the header.
- Codex prewarms Lite WS sessions normally; prewarm is unchanged.

Because Lite carries tools inline, eligible requests bypass the web_search
prompt-cache stabilizer, as Codex itself does for these models.

Keepwarm replays are Lite-aware: captures keep the HTTP marker header, and
WS-captured bodies are converted through the existing WS→HTTP fallback
sanitizer before tracking. That conversion also stops pre-existing leakage
of the WS-only client_metadata keys (x-codex-turn-metadata,
x-codex-ws-stream-request-start-ms) into warm replays for all WS sessions.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 11 files

Re-trigger cubic

@ualtinok

Copy link
Copy Markdown
Contributor

Superseded by the integrated implementation prepared for main. Responses Lite remains default-off, is limited to exact GPT-5.6 Sol/Luna/Terra wire models, preserves the standard request path when disabled, and now handles HTTP, WebSocket, cachekeep, and HTTP fallback marker conversion consistently. Thank you for reporting the repeatable behavior difference and contributing the initial implementation.

@ualtinok ualtinok closed this Jul 17, 2026
@chrisolszewski
chrisolszewski deleted the feat/responses-lite branch July 17, 2026 15:21
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.

2 participants