fix(reasoning): suppress reasoning.summary for gpt-5.3-codex-spark - #65
Open
S-kkipie wants to merge 1 commit into
Open
fix(reasoning): suppress reasoning.summary for gpt-5.3-codex-spark#65S-kkipie wants to merge 1 commit into
S-kkipie wants to merge 1 commit into
Conversation
gpt-5.3-codex-spark rejects `reasoning.summary` with a 400: Unsupported parameter: 'reasoning.summary' is not supported with the 'gpt-5.3-codex-spark' model. (code: unsupported_parameter) The AI SDK derives `summary: 'detailed'` from any reasoning effort other than 'none' unless `reasoningSummary` is set explicitly, so every effort level that maps to a wire value made the request fail. The WebSocket transport surfaces that upstream error as an empty 200 response, which reaches Claude Code as "No assistant messages found" — spark was unusable for anyone with `effortLevel` set in settings.json. Pass `reasoningSummary: null` for codex-spark so the field is omitted while effort control is preserved. Verified against the real openai-oauth route: spark now returns content at low/medium/high/xhigh, with output scaling by effort. gpt-5.6-sol and gpt-5.4 are unchanged.
Owner
|
thanks for the submission. Will review shortly. Since you have a repro for the error handling bug, I'd definitely appreciate a PR if you've got time. |
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 #64.
The bug
gpt-5.3-codex-sparkreturns an empty response — HTTP 200, no content blocks,output_tokens: 0— for any request carrying a reasoning effort. In Claude Code this surfaces asNo assistant messages found, and because Claude Code sendsoutput_config.efforton every request wheneffortLevelis set in~/.claude/settings.json, spark is unusable for those users rather than degraded.Root cause
Not the effort value itself. The upstream 400 is:
@ai-sdk/openaiderives the summary from the effort (dist/index.js):So
effortProviderOptionsreturning{ openai: { reasoningEffort } }impliesreasoning.summary: 'detailed'on the wire, and spark rejects the whole request. That explains the otherwise odd effort matrix —low/medium/high/xhighfail whilenone/maxwork. The passing values are exactly the onesmapCodexEffortToOpenAImaps toundefined, which drops thereasoningobject entirely and takessummarywith it. Nothing about effort itself is unsupported.The fix
Pin
reasoningSummary: nullfor codex-spark. The AI SDK only omits the field when it is explicitly set (undefinedtriggers the derivation), sonullsuppressessummarywhile leavingeffortintact.Scoped to
/codex-spark(?:-|$)/i. Other Codex models —gpt-5.1-codex-max,gpt-5-codex— accept summaries and are untouched.I considered wiring this through the existing
supportsSummariescapability flag instead, but that field is currently descriptive metadata only — nothing reads it on the request path — so routing a wire-format fix through it would have meant changing what the flag means. This follows the established per-model quirk-helper pattern next toisGpt56Modelinstead.Verification
Against the real
openai-oauthroute (endpoint mode, ChatGPT/Codex plan):Output scales with effort as expected after the fix (
medium→ 6 output tokens,xhigh→ 76 on the same one-line prompt), so effort is genuinely reaching the model rather than being silently dropped.Tests: 4 parametrized cases pinning the suppression across effort levels, plus one asserting other Codex models keep their summary. Both directions fail if the fix is reverted — verified by reverting it (4 failures) and restoring.
pnpm typecheck && pnpm test && pnpm buildall pass locally (1183 tests).Note on the empty-200 behavior
Separate from this fix, and left alone here: when the OAuth WebSocket receives
type: "error"withinvalid_request_error,handleResponseEventrecords a diagnostic and closes the context, but the request still completes as a 200 with an empty message. That turned a preciseunsupported_parameterinto a silent empty response, and diagnosing it required--ws-diagnosticsplus a patched build to recover the message text — the diagnostic path hasheserrorMessagerather than logging it. Surfacing upstreaminvalid_request_erroras an error response would make this class of failure much cheaper to debug, but it touches the WebSocket transport and belongs in its own PR. Happy to open one if you'd like it.