fix(responses,google): deliver structured output to routed chat models and honor effort ladders - #1137
Open
lidge-jun wants to merge 9 commits into
Conversation
Keep json_schema routing active when the schema member is omitted. Source: PR #985. Co-authored-by: Pranav Yerramaneni <pranavy2008@gmail.com>
Document provider-wide and per-model capability assertions and cover the provider-wide non-image path. Source: PR #978. Co-authored-by: Pranav Yerramaneni <pranavy2008@gmail.com>
|
✅ Deterministic PR hygiene checks passed. |
This was referenced Aug 6, 2026
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.
Summary
Routed
openai-chatmodels now receive structured-output requests instead of silently returning prose, and any Google model with a declared effort ladder gets itsthinkingLevelsent.Structured output.
parseRequestreduced the Responsestext.formatobject to a boolean (_structuredOutput), so the schema, name, and strict flag were discarded at the parser and no adapter could forward them —src/adapters/openai-chat.tshad noresponse_formathandling at all. The format now ridesoptions.textFormatand is re-nested underjson_schemaon the Chat wire, the inverse ofresponseFormatToText. A caller that asks for a schema and gets prose back will try toJSON.parseit, which is the failure this removes.Gemini effort.
thinkingLevelwas sent for a narrow model set only; it now follows any declared effort ladder, with the docs stating that bothreasoningEffortsandmodelReasoningEffortsassert capability and that CCA uses its envelope-specific path.Attribution
Both fixes are @DevMello's (Pranav Yerramaneni) work, from #985 and #978. Seven of the nine commits here are cherry-picked with their authorship intact; the two I authored carry
Co-authored-by: Pranav Yerramaneni.One correction on top of #985: its
json_schemabranch was guarded bytextFormat.schema !== undefined, so a schema-lessjson_schemafell through and noresponse_formatwas sent — silently reproducing the original defect on a narrower input. The guard now sits on theschemamember instead of the branch, with a regression test assertingresponse_format.type === "json_schema"is still sent when no schema is supplied.#985 and #978 are left open for the author. Planning unit:
devlog/_plan/260806_stacked_bug_campaign/(phases 090, 100).Stack 5 of the 260806 attribution campaign, stacked on #1136.
Verification
bun test tests/openai-chat-hardening.test.ts tests/responses-parser.test.ts tests/chat-completions-endpoint.test.ts tests/google-hardening.test.ts— 129 pass, 0 failbun run typecheck— exit 0bun run privacy:scan— passedbun run test(full) — exit 0Checklist