Skip to content

fix(codex): skip pass-through for unsupported response limits - #2217

Merged
looplj merged 2 commits into
looplj:unstablefrom
llc1123:fix/codex-response-limit-passthrough
Aug 13, 2026
Merged

fix(codex): skip pass-through for unsupported response limits#2217
looplj merged 2 commits into
looplj:unstablefrom
llc1123:fix/codex-response-limit-passthrough

Conversation

@llc1123

@llc1123 llc1123 commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add an optional outbound pass-through body policy so provider-specific veto rules do not live in the generic orchestrator pass-through middleware
  • make Codex veto OpenAI Responses raw body pass-through when the client body contains token limit fields Codex rejects
  • keep non-Codex channels on the existing generic pass-through rules

Root cause

Codex outbound removes token limit fields before sending upstream, but the generic pass-through middleware could later restore the original OpenAI Responses body. Requests with fields like max_output_tokens then reached Codex unchanged and failed with HTTP 400, while fallback OpenAI Responses-compatible channels such as ZenMux succeeded.

Current pass-through enablement

Body pass-through is enabled only when all generic orchestrator checks pass: current channel exists, provider request has an API format, inbound LLM API format equals outbound provider API format, original/effective stream semantics match, and channel/global pass-through setting is enabled. After that, an optional outbound policy can veto pass-through for provider-specific incompatibilities.

Tests

  • go test ./internal/server/orchestrator -run 'TestApplyPassThroughBody(SkipsWhenOutboundPolicyRejects|PreservesMappedModel|PreservesAlignedStreamWithoutPatchingIt)' -count=1\n- cd llm && go test ./transformer/openai/codex -run 'TestCodexOutbound_(RejectsPassThroughBodyWithTokenLimitFields|AllowsPassThroughBodyWithoutTokenLimitFields|StreamAcceptHeader)' -count=1

Summary by CodeRabbit

  • Bug Fixes
    • Improved Codex Responses request handling when unsupported token-limit fields are provided.
    • Requests containing unsupported token-limit fields are now processed through supported transformations instead of being passed through unchanged.
    • Preserved model mappings and supported token-limit settings for OpenAI Responses.
    • Requests without conflicting token-limit fields continue to use the original request body when appropriate.
    • Added safeguards to prevent unsupported request fields from reaching providers unchanged.

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 108a5f88-867f-4669-8ef3-12b64f9cbf1f

📥 Commits

Reviewing files that changed from the base of the PR and between 90b377c and ac93238.

📒 Files selected for processing (1)
  • internal/server/orchestrator/pass_through_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/server/orchestrator/pass_through_test.go

📝 Walkthrough

Walkthrough

The pass-through flow now consults an optional transformer policy before reusing inbound request bodies. Codex Responses requests with token-limit fields reject pass-through. Tests cover rejection and allowed bodies.

Changes

Pass-through policy

Layer / File(s) Summary
Policy contract and orchestration
llm/transformer/interfaces.go, internal/server/orchestrator/pass_through.go
The transformer interface defines pass-through approval. The orchestrator preserves the outbound body when approval is denied and allows pass-through by default when no policy exists.
Codex token-limit filtering
llm/transformer/openai/codex/outbound.go
The Codex transformer rejects pass-through for Responses bodies containing max_output_tokens, max_completion_tokens, or max_tokens. Nil, non-Responses, and bodyless requests remain allowed.
Policy validation
internal/server/orchestrator/pass_through_test.go, llm/transformer/openai/codex/outbound_executor_test.go
Tests verify policy rejection, unchanged requests, absent unsupported fields, blocked token-limit fields, and allowed bodies without those fields.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Mergeability Score: ⚪ Minimal · up to ac932

The PR limits Codex pass-through for unsupported token-limit request bodies while preserving existing behavior for other channels; no actionable merge-blocking risk remains after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant Orchestrator
  participant CodexTransformer
  participant RequestBody
  Orchestrator->>CodexTransformer: Check AllowPassThroughBody
  CodexTransformer->>RequestBody: Inspect token-limit fields
  RequestBody-->>CodexTransformer: Field presence
  CodexTransformer-->>Orchestrator: Allow or reject pass-through
  Orchestrator->>RequestBody: Reuse inbound body only when allowed
Loading

Possibly related PRs

  • looplj/axonhub#2178: Both PRs modify Codex Responses pass-through handling in internal/server/orchestrator/pass_through.go; this PR adds body-policy filtering, while the related PR forwards metadata headers.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main Codex change: skipping pass-through for unsupported response limit fields.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

llc1123 and others added 2 commits August 13, 2026 14:42
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@llc1123
llc1123 force-pushed the fix/codex-response-limit-passthrough branch from 90b377c to ac93238 Compare August 13, 2026 06:42
@looplj
looplj merged commit fc1d27d into looplj:unstable Aug 13, 2026
5 checks passed
caolib added a commit to caolib/axonhub that referenced this pull request Aug 13, 2026
* upstream/unstable: (48 commits)
  fix(codex): skip pass-through for unsupported response limits (looplj#2217)
  fix(responses): preserve image tool_choice without pass-through (looplj#2218)
  chore(actions): upgrade workflows to node24 actions (looplj#2219)
  fix(prompts): Parse project GUIDs in prompt schema (looplj#2200)
  feat: add xai_responses channel type (looplj#2212)
  fix(responses): harden stream terminal, retry, and resource boundaries (looplj#2196)
  fix(trace): only persist explicitly identified traces (looplj#2208)
  feat: hide unroutable configured models from public lists (looplj#2215)
  feat(quota): track OpenCode Go quota via official usage API (looplj#2204)
  fix: align codex quota bar colors (looplj#2166)
  feat(quota): add Charm Hyper credit balance checker (looplj#2199)
  fix(i18n): change currency code example from RMB to CNY (looplj#2202)
  feat: unify auto-refresh controls and stabilize list animations (looplj#2198)
  opt: anthropic signature recognization (looplj#2197)
  fix: model associate condition caused model not found, close looplj#2183 (looplj#2194)
  fix(responses): retry incomplete streams before done (looplj#2192)
  feat: show request cache rate, close looplj#2170 (looplj#2193)
  chore: add log for chat heartbeat (looplj#2191)
  fix(sqlite-time-format-compat): 兼容 SQLite TEXT 时间戳格式并修复 backup 注册时区退化 (looplj#2189)
  feat(models): add thinkingmachines as model developer (looplj#2190)
  ...

# Conflicts:
#	.github/workflows/docker-publish.yml
@llc1123
llc1123 deleted the fix/codex-response-limit-passthrough branch September 4, 2026 08:11
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