fix: Codex preflight summary compatibility (max_output_tokens + responses-lite header) - #665
Open
ranxianglei wants to merge 2 commits into
Open
fix: Codex preflight summary compatibility (max_output_tokens + responses-lite header)#665ranxianglei wants to merge 2 commits into
ranxianglei wants to merge 2 commits into
Conversation
📦 Built Package ArtifactBranch: Option A — Install from npm PR tag (recommended)npm install -g billion-context@pr-665Each push to this PR publishes a new version under the Option B — Download artifact
tar xzf billion-context-pr665.tgz
npm install -g packageThis comment is automatically updated on each push. |
Owner
Author
added 2 commits
September 10, 2026 02:57
…ects it
Responses-API preflight summaries unconditionally sent
max_output_tokens: 8192. The Codex backend
(chatgpt.com/backend-api/codex/responses) rejects that parameter with
400 {"detail":"Unsupported parameter: max_output_tokens"}, so every
over-window request died with a 502 that no client retry could recover.
Follows the existing #626 stream-required capability-learning pattern:
only an explicit HTTP 400 naming max_output_tokens causes Responses
summaries to omit it. Learning is scoped to session + upstream URL +
model, so standard Responses providers keep the 8192 output limit.
Both rejection orders (stream-first / param-first) are covered and
compatibility retries are bounded (each capability learned at most
once, <=3 attempts per range).
Adds tests/preflight-max-output-tokens.test.ts: both rejection orders
against a mock Codex-like backend (summary generation + recovery +
forwarding + second-request first-shot compatibility), a standard
provider that retains the cap, and model-scoped learning.
The independently built Responses summary body has no reasoning field, but requestSummary copied ALL main-request headers into it — including x-openai-internal-codex-responses-lite, which the backend only accepts when the body carries reasoning.context: all_turns. The summary call was rejected with 400 "…requires `reasoning.context` to be `all_turns`", killing preflight right after the max_output_tokens fix. Strip that one request-shape-specific header from the summary call only; the original model request keeps the header and its reasoning fields. Auth and routing headers are preserved. The strip is keyed on the Codex header name, so it is a no-op for Anthropic/OpenAI. Fixes #663
ranxianglei
force-pushed
the
2026-09-09_preflight-max-output-tokens
branch
from
September 10, 2026 00:51
3c35be1 to
128f9d3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #663
Two related fixes so Codex (ChatGPT-login) preflight summaries work end-to-end. Both live in
requestSummary(src/preflight.ts) and only affect the independently-built summary call — the original model request is untouched.1. Learn to drop
max_output_tokenswhen the upstream rejects itThe ChatGPT codex backend rejects the Responses
max_output_tokensparameter outright (400{"detail":"Unsupported parameter: max_output_tokens"}), which killed preflight summaries with a 502 after the #626 stream fix. The proxy now detects that rejection, retries the summarization without the optional parameter, and remembers it per session+upstream+model — so a model/provider that accepts the limit keeps the existing 8192 output cap. Both rejection orders (stream-first, param-first) recover, and the retries are bounded (each capability is learned at most once).2. Drop the Codex Lite header from the summary call only
requestSummarycopied ALL main-request headers into its independently-built summary body. The main Codex request carriesx-openai-internal-codex-responses-lite(its body hasreasoning.context: all_turns), but the summary body has no reasoning field — so the backend rejected the summary with 400 "…requiresreasoning.contextto beall_turns". The fix strips that one request-shape-specific header from the summary call only; the original model request keeps the header and its reasoning fields. Auth and routing headers are preserved. The strip is keyed on the Codex header name, so it is a no-op for Anthropic/OpenAI.Tests
tests/preflight-max-output-tokens.test.ts— 6 e2e tests:Pre-flight
npm run typecheck✓npm test✓ (1252/1252)npm run build✓Validated against the real backend by the reporter: an over-window Lite-mode request now completes after preflight folds the ranges, preserving the canary.