fix: keep native structured output for Claude Opus 5.5 - #78
Merged
Merged
Conversation
Contributor
Author
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
This was referenced Sep 25, 2026
anandpant
marked this pull request as ready for review
September 25, 2026 05:21
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
anandpant
force-pushed
the
fix/opus-55-structured-output
branch
from
September 25, 2026 05:44
d427b53 to
f8db945
Compare
anandpant
force-pushed
the
feat/model-refresh-0924
branch
from
September 25, 2026 05:44
f475b56 to
d69e0b6
Compare
graphite-app
Bot
changed the base branch from
feat/model-refresh-0924
to
graphite-base/78
September 25, 2026 05:48
graphite-app
Bot
force-pushed
the
graphite-base/78
branch
from
September 25, 2026 05:50
d69e0b6 to
afaca1b
Compare
graphite-app
Bot
force-pushed
the
fix/opus-55-structured-output
branch
from
September 25, 2026 05:50
f8db945 to
e62cce5
Compare
graphite-app
Bot
force-pushed
the
fix/opus-55-structured-output
branch
from
September 25, 2026 05:51
e62cce5 to
c8d09e3
Compare
Merge activity
|
## Summary Claude Opus 5.5 rejects forced tool use, so the `structuredOutputMode: 'jsonTool'` that the Anthropic adapter otherwise requests fails with HTTP 400 through the Foundry proxy. Request the provider's native output format for that model instead. - Add `requiresAnthropicNativeStructuredOutput` next to the catalog entries and thread it through `createFoundryAnthropic`, matching on both the alias and the RID. Every other Claude model keeps the existing JSON-tool mode. - Set `structuredOutputMode: 'outputFormat'` explicitly rather than omitting the option. The SDK resolves its default `'auto'` from the model ID, and this adapter addresses models by Foundry RID, so `'auto'` takes the unknown-model path. On `@ai-sdk/anthropic` 3.0.64, 3.0.95 and 4.0.5 — all inside the declared peer range — that path reports `supportsStructuredOutput: false` and still sends the forced JSON tool. `'outputFormat'` short-circuits that check on every version from 3.0.64 through 4.0.63. - The adapter's value is spread after the caller's `anthropic` options, so a caller passing `jsonTool` cannot downgrade Opus 5.5 back into the failing path. - `@ai-sdk/anthropic` 4.0.60 added an equivalent fallback upstream, but it keys on the `claude-opus-5-5` model ID, which a RID never matches. The fix has to live here. Without this, Opus 5.5 ships GA with standalone JSON and combined JSON + tools both broken by an option this package sets on the caller's behalf. ## Validation New `anthropic.test.ts` drives `createFoundryAnthropic` through the real `@ai-sdk/anthropic` peer with a stubbed fetch and asserts the outgoing Anthropic body: `output_config.format` present and no `tools`/`tool_choice` for the Opus 5.5 alias and raw RID, the forced `json` tool for Claude Opus 5, and no caller downgrade. Reverting to the earlier omit-based approach makes the downgrade case fail, so the coverage is load-bearing. Note that the pinned dev version 4.0.52 has a generic `claude-` fallback that masks the peer-floor behaviour, so the 3.0.64/4.0.5 path was verified by reading those releases' compiled `getModelCapabilities` directly. Affected unit tests, lint, and typecheck passed, and `pnpm run verify` passed at the top of the stack. A focused live rerun of Opus 5.5's JSON and JSON + tools probes on 4.0.52 passed with output identical to the previous run, so no results table changed.
graphite-app
Bot
force-pushed
the
fix/opus-55-structured-output
branch
from
September 25, 2026 05:53
c8d09e3 to
ffa3811
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.

Summary
Claude Opus 5.5 rejects forced tool use, so the
structuredOutputMode: 'jsonTool'that the Anthropic adapter otherwise requests fails with HTTP 400 through the Foundry proxy. Request the provider's native output format for that model instead.requiresAnthropicNativeStructuredOutputnext to the catalog entries and thread it throughcreateFoundryAnthropic, matching on both the alias and the RID. Every other Claude model keeps the existing JSON-tool mode.structuredOutputMode: 'outputFormat'explicitly rather than omitting the option. The SDK resolves its default'auto'from the model ID, and this adapter addresses models by Foundry RID, so'auto'takes the unknown-model path. On@ai-sdk/anthropic3.0.64, 3.0.95 and 4.0.5 — all inside the declared peer range — that path reportssupportsStructuredOutput: falseand still sends the forced JSON tool.'outputFormat'short-circuits that check on every version from 3.0.64 through 4.0.63.anthropicoptions, so a caller passingjsonToolcannot downgrade Opus 5.5 back into the failing path.@ai-sdk/anthropic4.0.60 added an equivalent fallback upstream, but it keys on theclaude-opus-5-5model ID, which a RID never matches. The fix has to live here.Without this, Opus 5.5 ships GA with standalone JSON and combined JSON + tools both broken by an option this package sets on the caller's behalf.
Validation
New
anthropic.test.tsdrivescreateFoundryAnthropicthrough the real@ai-sdk/anthropicpeer with a stubbed fetch and asserts the outgoing Anthropic body:output_config.formatpresent and notools/tool_choicefor the Opus 5.5 alias and raw RID, the forcedjsontool for Claude Opus 5, and no caller downgrade. Reverting to the earlier omit-based approach makes the downgrade case fail, so the coverage is load-bearing. Note that the pinned dev version 4.0.52 has a genericclaude-fallback that masks the peer-floor behaviour, so the 3.0.64/4.0.5 path was verified by reading those releases' compiledgetModelCapabilitiesdirectly.Affected unit tests, lint, and typecheck passed, and
pnpm run verifypassed at the top of the stack. A focused live rerun of Opus 5.5's JSON and JSON + tools probes on 4.0.52 passed with output identical to the previous run, so no results table changed.