Skip to content

fix: preserve reasoning_details with Bedrock/Meta and unknown formats - #593

Open
LukasParke wants to merge 2 commits into
mainfrom
claude/reasoning-formats
Open

LukasParke wants to merge 2 commits into
mainfrom
claude/reasoning-formats

Conversation

@LukasParke

@LukasParke LukasParke commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Description

Bug: ReasoningFormat (src/schemas/format.ts) was missing three formats that OpenRouter emits and documents (projects/docs/guides/best-practices/reasoning-tokens.mdx, and packages/llm-interfaces/schemas/response/reasoning-schemas/format.ts in the backend):

  • bedrock-openai-responses-v1 (OpenAI-authored models on Bedrock Mantle)
  • bedrock-xai-responses-v1 (xAI-authored models on Bedrock Mantle)
  • meta-responses-v1 (Meta Responses adapter)

Because format was validated with z.enum(ReasoningFormat), any detail with one of these formats failed the union and was turned into null by the unknown-entry fallback in ReasoningDetailArraySchema / OutputUnionToReasoningDetailsSchema. The detail was silently dropped from the response metadata, so it was never replayed on the next turn, and reasoning continuity broke for those providers.

Repro: parse { type: 'reasoning.encrypted', data: '...', format: 'bedrock-openai-responses-v1' } with ReasoningDetailArraySchema and you get [].

Fix:

  • Add the three formats to the enum so it matches the backend.
  • Accept any string for format (z.union([z.enum(ReasoningFormat), z.string()])). A format the backend adds after an SDK release is now passed through verbatim instead of dropped. The server minted the format, so it can validate it when it comes back. Unknown detail types are still dropped individually, as before.

Test: new src/schemas/reasoning-details.test.ts. For each new format plus an unrecognised some-future-provider-v1, it checks that summary, encrypted and text details survive ReasoningDetailArraySchema, the response message and delta schemas, and OpenRouterProviderOptionsSchema, and that they round-trip through convertToOpenRouterChatMessages. I also tightened the existing unknown-format resilience test in signature-roundtrip.test.ts to assert that the entry is preserved. I ran the new test file against origin/main source: all 16 cases fail there and pass with this fix.

Related: a follow-up opt-in reasoningReplay option (#542) builds a format-to-family map. It will use these enum members once this PR is merged.

Checklist

  • I have run pnpm stylecheck and pnpm typecheck
  • I have run pnpm test and all tests pass
  • I have added tests for my changes (if applicable)
  • I have updated documentation (if applicable)

Changeset

  • I have run pnpm changeset to create a changeset file

🤖 Generated with Claude Code


Devin Review

The ReasoningFormat enum was missing bedrock-openai-responses-v1,
bedrock-xai-responses-v1 and meta-responses-v1, so details carrying those
formats failed schema validation and were silently dropped. Add them, and
accept any string for `format` so formats added server-side in the future
are passed through verbatim instead of dropped.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

Distinct signed reasoning blocks have distinct signatures. The fixture
reused one signature for both, which collapses them once the duplicate
tracker keys signed text by signature (#610).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant