fix: allow opting out of response_format strict mode (#483) - #486
Merged
robert-j-y merged 1 commit intoApr 28, 2026
Merged
Conversation
Co-Authored-By: Robert Yeakel <robert.yeakel@openrouter.ai>
robert-j-y
deleted the
devin/1777126021-issue-483-structured-outputs-strict
branch
April 28, 2026 19:09
Merged
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.
Description
Fixes #483 by adding a new
structuredOutputs.strictsetting that lets users opt out ofresponse_format.json_schema.strictper chat model.Problem
src/chat/index.tshardcodedstrict: truewhenever a JSON schema response format was used:There was no provider-setting, no call-site option, and no way for a user to opt out. For models whose downstream providers don't implement strict json_schema (e.g.
moonshotai/kimi-k2.6routed through Parasail/Venice/Io Net), OpenRouter returned HTTP 404"No endpoints available matching your guardrail restrictions and data policy"because the strict flag eliminated every eligible endpoint.Fix
Added a new optional
structuredOutputs?: { strict?: boolean }field toOpenRouterChatSettings. When present, itsstrictvalue is forwarded toresponse_format.json_schema.strict. When omitted, the SDK continues to default totrue(backward compatible).Before
After
Implementation notes
src/chat/index.ts:145— replaced the hardcodedstrict: truewiththis.settings.structuredOutputs?.strict ?? true.src/types/openrouter-chat-settings.ts— added thestructuredOutputs?: { strict?: boolean }setting alongside other top-level chat settings.src/completion/index.ts— verified there is noresponse_format.json_schemabranch (the legacy completion path forwardsresponseFormatdirectly without settingstrict), so no mirror change was needed.should pass responseFormat for JSON schema structured outputsandshould use default name when name is not provided in responseFormattests insrc/chat/index.test.tscontinue to assertstrict: trueand pass without modification — the default is preserved.Tests
Added
e2e/issues/issue-483-response-format-strict-option.test.tswith 8 cases covering:strict: true(backward compat)structuredOutputs: { strict: false }→strict: falsestructuredOutputs: { strict: true }→strict: truestructuredOutputs: { strict: undefined }→ defaulttruestructuredOutputs: {}(empty object) → defaulttruenameanddescriptionresponse_formatemitted when call has noresponseFormat, regardless ofstructuredOutputsresponseFormat: { type: 'json' }(no schema) still emitsjson_object, nostrict, nojson_schemaVerified the failing-on-main subset of these tests reproduce the bug before applying the fix (2/8 fail on main, all 8 pass on this branch).
Human review checklist
Verified against the diff at HEAD:
chat(model)with nostructuredOutputssetting still emitsstrict: true(existing tests insrc/chat/index.test.tsare unmodified and continue to pass; default-case test in the new file confirms it explicitly).ascasts in the new test file (per repo no-casting rule).OpenRouterChatSettings.structuredOutputs) is the right shape — option lives on the chat settings, mirrorsreasoning/pluginsplacement, and is documented with TSDoc.src/chat/index.test.tswas modified —git diff --merge-base origin/main -- src/chat/index.test.tsis empty.minor(new public setting = small feature).Checklist
pnpm stylecheckandpnpm typecheckpnpm testand all tests pass (421 passed)e2e/issues/issue-483-response-format-strict-option.test.ts, 8 cases — all pass; the twostrict: falsecases failed on main as expected before the fix)structuredOutputssetting)Changeset
pnpm changesetto create a changeset file (minor)