🫧 feat: Claude Opus 4.7 Reasoning Visibility - #12701
Conversation
Claude Opus 4.7 omits `thinking` content from Messages API responses by
default — empty thinking blocks still stream, but the `thinking` field is
blank unless the caller passes `display: "summarized"` in the adaptive
thinking config. This silenced the LibreChat "Thoughts" UI for Anthropic
(and Anthropic-on-Bedrock) adaptive models.
- Extend `ThinkingConfigAdaptive` in `packages/api/src/types/anthropic.ts`
with an optional `display: 'summarized' | 'omitted'` field
- Emit `{ type: 'adaptive', display: 'summarized' }` from
`configureReasoning` in `packages/api/src/endpoints/anthropic/helpers.ts`
- Emit `{ type: 'adaptive', display: 'summarized' }` from
`bedrockInputParser` in `packages/data-provider/src/bedrock.ts` and
update the local `ThinkingConfig` union
- Update existing adaptive-thinking assertions to include the new field
- Add dedicated tests asserting `display: 'summarized'` flows through
both the Anthropic endpoint and the Bedrock parser
See https://platform.claude.com/docs/en/about-claude/models/whats-new-claude-4-7#thinking-content-omitted-by-default
There was a problem hiding this comment.
Pull request overview
Restores visibility of summarized “Thoughts” (reasoning) for Anthropic adaptive-thinking models after Claude Opus 4.7 changed the default to omit reasoning unless thinking.display is explicitly set.
Changes:
- Threaded an optional
display: 'summarized' | 'omitted'field through Anthropic thinking types and configuration. - Updated Anthropic + Bedrock request builders to emit
{ type: 'adaptive', display: 'summarized' }for adaptive-thinking models. - Updated/added Jest coverage to lock in the new opt-in behavior for Opus 4.7 and related adaptive models.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/data-provider/src/bedrock.ts | Adds default thinking.display for adaptive Bedrock Anthropic models. |
| packages/data-provider/specs/bedrock.spec.ts | Updates expectations and adds regression coverage for Opus 4.7 thinking display. |
| packages/api/src/types/anthropic.ts | Extends adaptive thinking type to include optional display. |
| packages/api/src/endpoints/bedrock/initialize.spec.ts | Updates Bedrock initialize expectations to include display: 'summarized'. |
| packages/api/src/endpoints/anthropic/llm.spec.ts | Adds coverage ensuring adaptive models request display: 'summarized'. |
| packages/api/src/endpoints/anthropic/helpers.ts | Sets thinking.display='summarized' when configuring adaptive thinking. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (additionalFields.thinking === false) { | ||
| delete additionalFields.thinking; | ||
| delete additionalFields.thinkingBudget; | ||
| } else { | ||
| additionalFields.thinking = { type: 'adaptive' }; | ||
| additionalFields.thinking = { | ||
| type: 'adaptive', | ||
| display: DEFAULT_THINKING_DISPLAY, | ||
| }; | ||
| delete additionalFields.thinkingBudget; | ||
| } |
There was a problem hiding this comment.
When thinking is explicitly set to false, this branch deletes additionalFields.thinking but does not clear any pre-existing typedData.additionalModelRequestFields.thinking. If a conversation has persisted additionalModelRequestFields.thinking from earlier runs, toggling thinking: false will still send adaptive thinking on subsequent requests. Consider explicitly deleting typedData.additionalModelRequestFields.thinking (and thinkingBudget) when additionalFields.thinking === false so the user's setting reliably disables thinking even with stale AMRF data.
Narrow the reasoning-visibility opt-in to the models that actually omit thinking content by default, instead of applying it to every adaptive model. Pre-Opus-4.7 adaptive models (Opus 4.6, Sonnet 4.6) already return summaries, so sending the field is unnecessary noise. - Add `omitsThinkingByDefault(model)` in `packages/data-provider/src/bedrock.ts` that returns true only for Opus 4.7+ (including future majors like Opus 5+) - Bedrock parser now only attaches `display: 'summarized'` when the helper matches, keeping the adaptive object unchanged for older models - Anthropic endpoint `configureReasoning` uses the same helper so its emit path matches the Bedrock one - Tests: replace the blanket `display: 'summarized'` assertions with model-specific ones (Opus 4.7 gets it, Opus 4.6 / Sonnet 4.6 do not), add a dedicated `omitsThinkingByDefault` suite covering naming variants and future versions
GitNexus: 🚀 deployedThe |
GitNexus: 🚀 deployedThe |
Expose the Anthropic `thinking.display` API field as a user-facing parameter so users can override the `auto` default (which stays as the Opus-4.7+ opt-in added earlier in this PR). Also fixes the CI type error by widening the adaptive thinking type assignment via a resolver helper that returns a properly-typed object. - Add `ThinkingDisplay` enum (`auto` | `summarized` | `omitted`) and matching zod schema in `packages/data-provider/src/schemas.ts` - Add `thinkingDisplay` to `tConversationSchema`, `anthropicSettings`, and the pick lists for Bedrock input/parser + Anthropic agent params - Add `resolveThinkingDisplay(model, explicit)` helper in `packages/data-provider/src/bedrock.ts` that returns the wire value or undefined (auto → model default, explicit → always honored) - `bedrockInputParser` now reads `thinkingDisplay` from input and emits `display` only when the resolver returns a value; strips the field on non-adaptive-model branches so it does not leak - `configureReasoning` in the Anthropic endpoint threads `thinkingDisplay` through, uses the resolver, and casts the adaptive config to `AnthropicClientOptions['thinking']` so the widened shape compiles against the stale installed SDK types - Add UI slider for `thinkingDisplay` in `parameterSettings.ts` next to `effort`, with three-position `com_ui_auto` / `com_ui_summarized` / `com_ui_omitted` labels - Add translation keys `com_endpoint_anthropic_thinking_display`, `com_endpoint_anthropic_thinking_display_desc`, `com_ui_summarized`, `com_ui_omitted` - Add tests: `resolveThinkingDisplay` suite (5 cases covering auto / explicit / unknown input), parser round-trip tests for all three modes on Opus 4.6 and Opus 4.7, Anthropic endpoint tests for explicit summarized/omitted overrides
GitNexus: 🚀 deployedThe |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 999a313444
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
If a user turns adaptive thinking off but had previously selected a `thinkingDisplay` value, the stale field was left in `additionalFields` and ended up merged into the Bedrock request's `additionalModelRequestFields`. That leaks a non-Bedrock key into the payload and can round-trip back into `llmConfig`. - Delete `additionalFields.thinkingDisplay` alongside `thinking` and `thinkingBudget` in the `thinking === false` branch of `bedrockInputParser` - Add a regression test asserting `thinking`, `thinkingBudget`, and `thinkingDisplay` are all absent when adaptive thinking is disabled on an Opus 4.7 request Reported by chatgpt-codex-connector on PR #12701.
|
@codex review |
GitNexus: 🚀 deployedThe |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e28fde387d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…Display Address review findings on PR #12701: - [Codex P2] `bedrockInputSchema.transform` now extracts `thinking.display` from persisted `additionalModelRequestFields` back into the top-level `thinkingDisplay` field so explicit `'omitted'` round-trips through storage instead of being silently reverted to `'summarized'` on the next parse. - [Codex P2] `getLLMConfig` in the Anthropic endpoint now reads `.display` from a persisted `thinking` object (agents store the full Anthropic shape) and uses it as the fallback for `thinkingDisplay` when no top-level override is present. - [Audit #2] Collapse the three parallel wire-value types into a single `ThinkingDisplayWireValue = Exclude<ThinkingDisplay, 'auto'>` exported from `schemas.ts`; remove the duplicate `ThinkingDisplay` alias in `packages/api/src/types/anthropic.ts` (which collided with the enum name) and the `ThinkingDisplayValue` alias in `bedrock.ts`. - [Audit #3] Add `thinkingDisplay` to the `TEndpointOption` pick list next to `effort`. - [Audit #4] Add a TODO comment next to the `as AnthropicClientOptions['thinking']` cast explaining the stale `@librechat/agents` SDK types that require it. - Add tests: four round-trip cases asserting `bedrockInputSchema` recovers `display` from persisted AMRF (Opus 4.7 omitted, pre-4.7 summarized, unknown-value ignore, explicit top-level wins), and two `getLLMConfig` cases asserting the Anthropic endpoint preserves and overrides persisted `thinking.display`.
GitNexus: 🚀 deployedThe |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 13dc87f591
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The parser constructed a fresh adaptive thinking config without looking at any `display` already embedded in the incoming `additionalModelRequestFields.thinking`. On round-trip through `initializeBedrock`, a persisted user choice of `'omitted'` on Opus 4.7+ was silently reverted to `'summarized'` by the auto fallback. - Extract `extractPersistedDisplay` helper and reuse it in both the schema transform (form-state round-trip) and the parser (wire-request round-trip) - `bedrockInputParser` now feeds the persisted display as the resolver's explicit value when no top-level `thinkingDisplay` override is set - Add regression tests: parser preserves `display: 'omitted'` for persisted Opus 4.7 AMRF, and top-level `thinkingDisplay` still wins over persisted AMRF display Reported by chatgpt-codex-connector (P1) on PR #12701.
GitNexus: ❌ deploy failedThe deploy failed — the previous index (if any) continues to be served. |
* 🫧 fix: Restore Claude Opus 4.7 Reasoning Visibility
Claude Opus 4.7 omits `thinking` content from Messages API responses by
default — empty thinking blocks still stream, but the `thinking` field is
blank unless the caller passes `display: "summarized"` in the adaptive
thinking config. This silenced the LibreChat "Thoughts" UI for Anthropic
(and Anthropic-on-Bedrock) adaptive models.
- Extend `ThinkingConfigAdaptive` in `packages/api/src/types/anthropic.ts`
with an optional `display: 'summarized' | 'omitted'` field
- Emit `{ type: 'adaptive', display: 'summarized' }` from
`configureReasoning` in `packages/api/src/endpoints/anthropic/helpers.ts`
- Emit `{ type: 'adaptive', display: 'summarized' }` from
`bedrockInputParser` in `packages/data-provider/src/bedrock.ts` and
update the local `ThinkingConfig` union
- Update existing adaptive-thinking assertions to include the new field
- Add dedicated tests asserting `display: 'summarized'` flows through
both the Anthropic endpoint and the Bedrock parser
See https://platform.claude.com/docs/en/about-claude/models/whats-new-claude-4-7#thinking-content-omitted-by-default
* refactor: Gate `display: summarized` on Opus 4.7+
Narrow the reasoning-visibility opt-in to the models that actually omit
thinking content by default, instead of applying it to every adaptive
model. Pre-Opus-4.7 adaptive models (Opus 4.6, Sonnet 4.6) already return
summaries, so sending the field is unnecessary noise.
- Add `omitsThinkingByDefault(model)` in `packages/data-provider/src/bedrock.ts`
that returns true only for Opus 4.7+ (including future majors like Opus 5+)
- Bedrock parser now only attaches `display: 'summarized'` when the helper
matches, keeping the adaptive object unchanged for older models
- Anthropic endpoint `configureReasoning` uses the same helper so its emit
path matches the Bedrock one
- Tests: replace the blanket `display: 'summarized'` assertions with
model-specific ones (Opus 4.7 gets it, Opus 4.6 / Sonnet 4.6 do not),
add a dedicated `omitsThinkingByDefault` suite covering naming variants
and future versions
* feat: Configurable Thought Visibility for Anthropic Adaptive Models
Expose the Anthropic `thinking.display` API field as a user-facing
parameter so users can override the `auto` default (which stays as the
Opus-4.7+ opt-in added earlier in this PR). Also fixes the CI type error
by widening the adaptive thinking type assignment via a resolver helper
that returns a properly-typed object.
- Add `ThinkingDisplay` enum (`auto` | `summarized` | `omitted`) and
matching zod schema in `packages/data-provider/src/schemas.ts`
- Add `thinkingDisplay` to `tConversationSchema`, `anthropicSettings`, and
the pick lists for Bedrock input/parser + Anthropic agent params
- Add `resolveThinkingDisplay(model, explicit)` helper in
`packages/data-provider/src/bedrock.ts` that returns the wire value or
undefined (auto → model default, explicit → always honored)
- `bedrockInputParser` now reads `thinkingDisplay` from input and emits
`display` only when the resolver returns a value; strips the field
on non-adaptive-model branches so it does not leak
- `configureReasoning` in the Anthropic endpoint threads
`thinkingDisplay` through, uses the resolver, and casts the adaptive
config to `AnthropicClientOptions['thinking']` so the widened shape
compiles against the stale installed SDK types
- Add UI slider for `thinkingDisplay` in `parameterSettings.ts` next to
`effort`, with three-position `com_ui_auto` / `com_ui_summarized` /
`com_ui_omitted` labels
- Add translation keys `com_endpoint_anthropic_thinking_display`,
`com_endpoint_anthropic_thinking_display_desc`, `com_ui_summarized`,
`com_ui_omitted`
- Add tests: `resolveThinkingDisplay` suite (5 cases covering auto /
explicit / unknown input), parser round-trip tests for all three
modes on Opus 4.6 and Opus 4.7, Anthropic endpoint tests for explicit
summarized/omitted overrides
* fix: Drop `thinkingDisplay` When Adaptive Thinking Is Disabled
If a user turns adaptive thinking off but had previously selected a
`thinkingDisplay` value, the stale field was left in `additionalFields`
and ended up merged into the Bedrock request's
`additionalModelRequestFields`. That leaks a non-Bedrock key into the
payload and can round-trip back into `llmConfig`.
- Delete `additionalFields.thinkingDisplay` alongside `thinking` and
`thinkingBudget` in the `thinking === false` branch of
`bedrockInputParser`
- Add a regression test asserting `thinking`, `thinkingBudget`, and
`thinkingDisplay` are all absent when adaptive thinking is disabled on
an Opus 4.7 request
Reported by chatgpt-codex-connector on PR LibreChat-AI#12701.
* refactor: Consolidate `ThinkingDisplay` Types and Preserve Persisted Display
Address review findings on PR LibreChat-AI#12701:
- [Codex P2] `bedrockInputSchema.transform` now extracts
`thinking.display` from persisted `additionalModelRequestFields` back
into the top-level `thinkingDisplay` field so explicit `'omitted'`
round-trips through storage instead of being silently reverted to
`'summarized'` on the next parse.
- [Codex P2] `getLLMConfig` in the Anthropic endpoint now reads
`.display` from a persisted `thinking` object (agents store the full
Anthropic shape) and uses it as the fallback for `thinkingDisplay`
when no top-level override is present.
- [Audit #2] Collapse the three parallel wire-value types into a single
`ThinkingDisplayWireValue = Exclude<ThinkingDisplay, 'auto'>` exported
from `schemas.ts`; remove the duplicate `ThinkingDisplay` alias in
`packages/api/src/types/anthropic.ts` (which collided with the enum
name) and the `ThinkingDisplayValue` alias in `bedrock.ts`.
- [Audit #3] Add `thinkingDisplay` to the `TEndpointOption` pick list
next to `effort`.
- [Audit #4] Add a TODO comment next to the `as
AnthropicClientOptions['thinking']` cast explaining the stale
`@librechat/agents` SDK types that require it.
- Add tests: four round-trip cases asserting `bedrockInputSchema`
recovers `display` from persisted AMRF (Opus 4.7 omitted, pre-4.7
summarized, unknown-value ignore, explicit top-level wins), and two
`getLLMConfig` cases asserting the Anthropic endpoint preserves and
overrides persisted `thinking.display`.
* fix: Preserve Persisted `thinking.display` in bedrockInputParser
The parser constructed a fresh adaptive thinking config without looking at
any `display` already embedded in the incoming
`additionalModelRequestFields.thinking`. On round-trip through
`initializeBedrock`, a persisted user choice of `'omitted'` on Opus 4.7+
was silently reverted to `'summarized'` by the auto fallback.
- Extract `extractPersistedDisplay` helper and reuse it in both the
schema transform (form-state round-trip) and the parser (wire-request
round-trip)
- `bedrockInputParser` now feeds the persisted display as the resolver's
explicit value when no top-level `thinkingDisplay` override is set
- Add regression tests: parser preserves `display: 'omitted'` for
persisted Opus 4.7 AMRF, and top-level `thinkingDisplay` still wins
over persisted AMRF display
Reported by chatgpt-codex-connector (P1) on PR LibreChat-AI#12701.
* 🫧 fix: Restore Claude Opus 4.7 Reasoning Visibility
Claude Opus 4.7 omits `thinking` content from Messages API responses by
default — empty thinking blocks still stream, but the `thinking` field is
blank unless the caller passes `display: "summarized"` in the adaptive
thinking config. This silenced the LibreChat "Thoughts" UI for Anthropic
(and Anthropic-on-Bedrock) adaptive models.
- Extend `ThinkingConfigAdaptive` in `packages/api/src/types/anthropic.ts`
with an optional `display: 'summarized' | 'omitted'` field
- Emit `{ type: 'adaptive', display: 'summarized' }` from
`configureReasoning` in `packages/api/src/endpoints/anthropic/helpers.ts`
- Emit `{ type: 'adaptive', display: 'summarized' }` from
`bedrockInputParser` in `packages/data-provider/src/bedrock.ts` and
update the local `ThinkingConfig` union
- Update existing adaptive-thinking assertions to include the new field
- Add dedicated tests asserting `display: 'summarized'` flows through
both the Anthropic endpoint and the Bedrock parser
See https://platform.claude.com/docs/en/about-claude/models/whats-new-claude-4-7#thinking-content-omitted-by-default
* refactor: Gate `display: summarized` on Opus 4.7+
Narrow the reasoning-visibility opt-in to the models that actually omit
thinking content by default, instead of applying it to every adaptive
model. Pre-Opus-4.7 adaptive models (Opus 4.6, Sonnet 4.6) already return
summaries, so sending the field is unnecessary noise.
- Add `omitsThinkingByDefault(model)` in `packages/data-provider/src/bedrock.ts`
that returns true only for Opus 4.7+ (including future majors like Opus 5+)
- Bedrock parser now only attaches `display: 'summarized'` when the helper
matches, keeping the adaptive object unchanged for older models
- Anthropic endpoint `configureReasoning` uses the same helper so its emit
path matches the Bedrock one
- Tests: replace the blanket `display: 'summarized'` assertions with
model-specific ones (Opus 4.7 gets it, Opus 4.6 / Sonnet 4.6 do not),
add a dedicated `omitsThinkingByDefault` suite covering naming variants
and future versions
* feat: Configurable Thought Visibility for Anthropic Adaptive Models
Expose the Anthropic `thinking.display` API field as a user-facing
parameter so users can override the `auto` default (which stays as the
Opus-4.7+ opt-in added earlier in this PR). Also fixes the CI type error
by widening the adaptive thinking type assignment via a resolver helper
that returns a properly-typed object.
- Add `ThinkingDisplay` enum (`auto` | `summarized` | `omitted`) and
matching zod schema in `packages/data-provider/src/schemas.ts`
- Add `thinkingDisplay` to `tConversationSchema`, `anthropicSettings`, and
the pick lists for Bedrock input/parser + Anthropic agent params
- Add `resolveThinkingDisplay(model, explicit)` helper in
`packages/data-provider/src/bedrock.ts` that returns the wire value or
undefined (auto → model default, explicit → always honored)
- `bedrockInputParser` now reads `thinkingDisplay` from input and emits
`display` only when the resolver returns a value; strips the field
on non-adaptive-model branches so it does not leak
- `configureReasoning` in the Anthropic endpoint threads
`thinkingDisplay` through, uses the resolver, and casts the adaptive
config to `AnthropicClientOptions['thinking']` so the widened shape
compiles against the stale installed SDK types
- Add UI slider for `thinkingDisplay` in `parameterSettings.ts` next to
`effort`, with three-position `com_ui_auto` / `com_ui_summarized` /
`com_ui_omitted` labels
- Add translation keys `com_endpoint_anthropic_thinking_display`,
`com_endpoint_anthropic_thinking_display_desc`, `com_ui_summarized`,
`com_ui_omitted`
- Add tests: `resolveThinkingDisplay` suite (5 cases covering auto /
explicit / unknown input), parser round-trip tests for all three
modes on Opus 4.6 and Opus 4.7, Anthropic endpoint tests for explicit
summarized/omitted overrides
* fix: Drop `thinkingDisplay` When Adaptive Thinking Is Disabled
If a user turns adaptive thinking off but had previously selected a
`thinkingDisplay` value, the stale field was left in `additionalFields`
and ended up merged into the Bedrock request's
`additionalModelRequestFields`. That leaks a non-Bedrock key into the
payload and can round-trip back into `llmConfig`.
- Delete `additionalFields.thinkingDisplay` alongside `thinking` and
`thinkingBudget` in the `thinking === false` branch of
`bedrockInputParser`
- Add a regression test asserting `thinking`, `thinkingBudget`, and
`thinkingDisplay` are all absent when adaptive thinking is disabled on
an Opus 4.7 request
Reported by chatgpt-codex-connector on PR LibreChat-AI#12701.
* refactor: Consolidate `ThinkingDisplay` Types and Preserve Persisted Display
Address review findings on PR LibreChat-AI#12701:
- [Codex P2] `bedrockInputSchema.transform` now extracts
`thinking.display` from persisted `additionalModelRequestFields` back
into the top-level `thinkingDisplay` field so explicit `'omitted'`
round-trips through storage instead of being silently reverted to
`'summarized'` on the next parse.
- [Codex P2] `getLLMConfig` in the Anthropic endpoint now reads
`.display` from a persisted `thinking` object (agents store the full
Anthropic shape) and uses it as the fallback for `thinkingDisplay`
when no top-level override is present.
- [Audit #2] Collapse the three parallel wire-value types into a single
`ThinkingDisplayWireValue = Exclude<ThinkingDisplay, 'auto'>` exported
from `schemas.ts`; remove the duplicate `ThinkingDisplay` alias in
`packages/api/src/types/anthropic.ts` (which collided with the enum
name) and the `ThinkingDisplayValue` alias in `bedrock.ts`.
- [Audit #3] Add `thinkingDisplay` to the `TEndpointOption` pick list
next to `effort`.
- [Audit #4] Add a TODO comment next to the `as
AnthropicClientOptions['thinking']` cast explaining the stale
`@librechat/agents` SDK types that require it.
- Add tests: four round-trip cases asserting `bedrockInputSchema`
recovers `display` from persisted AMRF (Opus 4.7 omitted, pre-4.7
summarized, unknown-value ignore, explicit top-level wins), and two
`getLLMConfig` cases asserting the Anthropic endpoint preserves and
overrides persisted `thinking.display`.
* fix: Preserve Persisted `thinking.display` in bedrockInputParser
The parser constructed a fresh adaptive thinking config without looking at
any `display` already embedded in the incoming
`additionalModelRequestFields.thinking`. On round-trip through
`initializeBedrock`, a persisted user choice of `'omitted'` on Opus 4.7+
was silently reverted to `'summarized'` by the auto fallback.
- Extract `extractPersistedDisplay` helper and reuse it in both the
schema transform (form-state round-trip) and the parser (wire-request
round-trip)
- `bedrockInputParser` now feeds the persisted display as the resolver's
explicit value when no top-level `thinkingDisplay` override is set
- Add regression tests: parser preserves `display: 'omitted'` for
persisted Opus 4.7 AMRF, and top-level `thinkingDisplay` still wins
over persisted AMRF display
Reported by chatgpt-codex-connector (P1) on PR LibreChat-AI#12701.
* 🫧 fix: Restore Claude Opus 4.7 Reasoning Visibility
Claude Opus 4.7 omits `thinking` content from Messages API responses by
default — empty thinking blocks still stream, but the `thinking` field is
blank unless the caller passes `display: "summarized"` in the adaptive
thinking config. This silenced the LibreChat "Thoughts" UI for Anthropic
(and Anthropic-on-Bedrock) adaptive models.
- Extend `ThinkingConfigAdaptive` in `packages/api/src/types/anthropic.ts`
with an optional `display: 'summarized' | 'omitted'` field
- Emit `{ type: 'adaptive', display: 'summarized' }` from
`configureReasoning` in `packages/api/src/endpoints/anthropic/helpers.ts`
- Emit `{ type: 'adaptive', display: 'summarized' }` from
`bedrockInputParser` in `packages/data-provider/src/bedrock.ts` and
update the local `ThinkingConfig` union
- Update existing adaptive-thinking assertions to include the new field
- Add dedicated tests asserting `display: 'summarized'` flows through
both the Anthropic endpoint and the Bedrock parser
See https://platform.claude.com/docs/en/about-claude/models/whats-new-claude-4-7#thinking-content-omitted-by-default
* refactor: Gate `display: summarized` on Opus 4.7+
Narrow the reasoning-visibility opt-in to the models that actually omit
thinking content by default, instead of applying it to every adaptive
model. Pre-Opus-4.7 adaptive models (Opus 4.6, Sonnet 4.6) already return
summaries, so sending the field is unnecessary noise.
- Add `omitsThinkingByDefault(model)` in `packages/data-provider/src/bedrock.ts`
that returns true only for Opus 4.7+ (including future majors like Opus 5+)
- Bedrock parser now only attaches `display: 'summarized'` when the helper
matches, keeping the adaptive object unchanged for older models
- Anthropic endpoint `configureReasoning` uses the same helper so its emit
path matches the Bedrock one
- Tests: replace the blanket `display: 'summarized'` assertions with
model-specific ones (Opus 4.7 gets it, Opus 4.6 / Sonnet 4.6 do not),
add a dedicated `omitsThinkingByDefault` suite covering naming variants
and future versions
* feat: Configurable Thought Visibility for Anthropic Adaptive Models
Expose the Anthropic `thinking.display` API field as a user-facing
parameter so users can override the `auto` default (which stays as the
Opus-4.7+ opt-in added earlier in this PR). Also fixes the CI type error
by widening the adaptive thinking type assignment via a resolver helper
that returns a properly-typed object.
- Add `ThinkingDisplay` enum (`auto` | `summarized` | `omitted`) and
matching zod schema in `packages/data-provider/src/schemas.ts`
- Add `thinkingDisplay` to `tConversationSchema`, `anthropicSettings`, and
the pick lists for Bedrock input/parser + Anthropic agent params
- Add `resolveThinkingDisplay(model, explicit)` helper in
`packages/data-provider/src/bedrock.ts` that returns the wire value or
undefined (auto → model default, explicit → always honored)
- `bedrockInputParser` now reads `thinkingDisplay` from input and emits
`display` only when the resolver returns a value; strips the field
on non-adaptive-model branches so it does not leak
- `configureReasoning` in the Anthropic endpoint threads
`thinkingDisplay` through, uses the resolver, and casts the adaptive
config to `AnthropicClientOptions['thinking']` so the widened shape
compiles against the stale installed SDK types
- Add UI slider for `thinkingDisplay` in `parameterSettings.ts` next to
`effort`, with three-position `com_ui_auto` / `com_ui_summarized` /
`com_ui_omitted` labels
- Add translation keys `com_endpoint_anthropic_thinking_display`,
`com_endpoint_anthropic_thinking_display_desc`, `com_ui_summarized`,
`com_ui_omitted`
- Add tests: `resolveThinkingDisplay` suite (5 cases covering auto /
explicit / unknown input), parser round-trip tests for all three
modes on Opus 4.6 and Opus 4.7, Anthropic endpoint tests for explicit
summarized/omitted overrides
* fix: Drop `thinkingDisplay` When Adaptive Thinking Is Disabled
If a user turns adaptive thinking off but had previously selected a
`thinkingDisplay` value, the stale field was left in `additionalFields`
and ended up merged into the Bedrock request's
`additionalModelRequestFields`. That leaks a non-Bedrock key into the
payload and can round-trip back into `llmConfig`.
- Delete `additionalFields.thinkingDisplay` alongside `thinking` and
`thinkingBudget` in the `thinking === false` branch of
`bedrockInputParser`
- Add a regression test asserting `thinking`, `thinkingBudget`, and
`thinkingDisplay` are all absent when adaptive thinking is disabled on
an Opus 4.7 request
Reported by chatgpt-codex-connector on PR LibreChat-AI#12701.
* refactor: Consolidate `ThinkingDisplay` Types and Preserve Persisted Display
Address review findings on PR LibreChat-AI#12701:
- [Codex P2] `bedrockInputSchema.transform` now extracts
`thinking.display` from persisted `additionalModelRequestFields` back
into the top-level `thinkingDisplay` field so explicit `'omitted'`
round-trips through storage instead of being silently reverted to
`'summarized'` on the next parse.
- [Codex P2] `getLLMConfig` in the Anthropic endpoint now reads
`.display` from a persisted `thinking` object (agents store the full
Anthropic shape) and uses it as the fallback for `thinkingDisplay`
when no top-level override is present.
- [Audit #2] Collapse the three parallel wire-value types into a single
`ThinkingDisplayWireValue = Exclude<ThinkingDisplay, 'auto'>` exported
from `schemas.ts`; remove the duplicate `ThinkingDisplay` alias in
`packages/api/src/types/anthropic.ts` (which collided with the enum
name) and the `ThinkingDisplayValue` alias in `bedrock.ts`.
- [Audit #3] Add `thinkingDisplay` to the `TEndpointOption` pick list
next to `effort`.
- [Audit #4] Add a TODO comment next to the `as
AnthropicClientOptions['thinking']` cast explaining the stale
`@librechat/agents` SDK types that require it.
- Add tests: four round-trip cases asserting `bedrockInputSchema`
recovers `display` from persisted AMRF (Opus 4.7 omitted, pre-4.7
summarized, unknown-value ignore, explicit top-level wins), and two
`getLLMConfig` cases asserting the Anthropic endpoint preserves and
overrides persisted `thinking.display`.
* fix: Preserve Persisted `thinking.display` in bedrockInputParser
The parser constructed a fresh adaptive thinking config without looking at
any `display` already embedded in the incoming
`additionalModelRequestFields.thinking`. On round-trip through
`initializeBedrock`, a persisted user choice of `'omitted'` on Opus 4.7+
was silently reverted to `'summarized'` by the auto fallback.
- Extract `extractPersistedDisplay` helper and reuse it in both the
schema transform (form-state round-trip) and the parser (wire-request
round-trip)
- `bedrockInputParser` now feeds the persisted display as the resolver's
explicit value when no top-level `thinkingDisplay` override is set
- Add regression tests: parser preserves `display: 'omitted'` for
persisted Opus 4.7 AMRF, and top-level `thinkingDisplay` still wins
over persisted AMRF display
Reported by chatgpt-codex-connector (P1) on PR LibreChat-AI#12701.
* 🫧 fix: Restore Claude Opus 4.7 Reasoning Visibility
Claude Opus 4.7 omits `thinking` content from Messages API responses by
default — empty thinking blocks still stream, but the `thinking` field is
blank unless the caller passes `display: "summarized"` in the adaptive
thinking config. This silenced the LibreChat "Thoughts" UI for Anthropic
(and Anthropic-on-Bedrock) adaptive models.
- Extend `ThinkingConfigAdaptive` in `packages/api/src/types/anthropic.ts`
with an optional `display: 'summarized' | 'omitted'` field
- Emit `{ type: 'adaptive', display: 'summarized' }` from
`configureReasoning` in `packages/api/src/endpoints/anthropic/helpers.ts`
- Emit `{ type: 'adaptive', display: 'summarized' }` from
`bedrockInputParser` in `packages/data-provider/src/bedrock.ts` and
update the local `ThinkingConfig` union
- Update existing adaptive-thinking assertions to include the new field
- Add dedicated tests asserting `display: 'summarized'` flows through
both the Anthropic endpoint and the Bedrock parser
See https://platform.claude.com/docs/en/about-claude/models/whats-new-claude-4-7#thinking-content-omitted-by-default
* refactor: Gate `display: summarized` on Opus 4.7+
Narrow the reasoning-visibility opt-in to the models that actually omit
thinking content by default, instead of applying it to every adaptive
model. Pre-Opus-4.7 adaptive models (Opus 4.6, Sonnet 4.6) already return
summaries, so sending the field is unnecessary noise.
- Add `omitsThinkingByDefault(model)` in `packages/data-provider/src/bedrock.ts`
that returns true only for Opus 4.7+ (including future majors like Opus 5+)
- Bedrock parser now only attaches `display: 'summarized'` when the helper
matches, keeping the adaptive object unchanged for older models
- Anthropic endpoint `configureReasoning` uses the same helper so its emit
path matches the Bedrock one
- Tests: replace the blanket `display: 'summarized'` assertions with
model-specific ones (Opus 4.7 gets it, Opus 4.6 / Sonnet 4.6 do not),
add a dedicated `omitsThinkingByDefault` suite covering naming variants
and future versions
* feat: Configurable Thought Visibility for Anthropic Adaptive Models
Expose the Anthropic `thinking.display` API field as a user-facing
parameter so users can override the `auto` default (which stays as the
Opus-4.7+ opt-in added earlier in this PR). Also fixes the CI type error
by widening the adaptive thinking type assignment via a resolver helper
that returns a properly-typed object.
- Add `ThinkingDisplay` enum (`auto` | `summarized` | `omitted`) and
matching zod schema in `packages/data-provider/src/schemas.ts`
- Add `thinkingDisplay` to `tConversationSchema`, `anthropicSettings`, and
the pick lists for Bedrock input/parser + Anthropic agent params
- Add `resolveThinkingDisplay(model, explicit)` helper in
`packages/data-provider/src/bedrock.ts` that returns the wire value or
undefined (auto → model default, explicit → always honored)
- `bedrockInputParser` now reads `thinkingDisplay` from input and emits
`display` only when the resolver returns a value; strips the field
on non-adaptive-model branches so it does not leak
- `configureReasoning` in the Anthropic endpoint threads
`thinkingDisplay` through, uses the resolver, and casts the adaptive
config to `AnthropicClientOptions['thinking']` so the widened shape
compiles against the stale installed SDK types
- Add UI slider for `thinkingDisplay` in `parameterSettings.ts` next to
`effort`, with three-position `com_ui_auto` / `com_ui_summarized` /
`com_ui_omitted` labels
- Add translation keys `com_endpoint_anthropic_thinking_display`,
`com_endpoint_anthropic_thinking_display_desc`, `com_ui_summarized`,
`com_ui_omitted`
- Add tests: `resolveThinkingDisplay` suite (5 cases covering auto /
explicit / unknown input), parser round-trip tests for all three
modes on Opus 4.6 and Opus 4.7, Anthropic endpoint tests for explicit
summarized/omitted overrides
* fix: Drop `thinkingDisplay` When Adaptive Thinking Is Disabled
If a user turns adaptive thinking off but had previously selected a
`thinkingDisplay` value, the stale field was left in `additionalFields`
and ended up merged into the Bedrock request's
`additionalModelRequestFields`. That leaks a non-Bedrock key into the
payload and can round-trip back into `llmConfig`.
- Delete `additionalFields.thinkingDisplay` alongside `thinking` and
`thinkingBudget` in the `thinking === false` branch of
`bedrockInputParser`
- Add a regression test asserting `thinking`, `thinkingBudget`, and
`thinkingDisplay` are all absent when adaptive thinking is disabled on
an Opus 4.7 request
Reported by chatgpt-codex-connector on PR LibreChat-AI#12701.
* refactor: Consolidate `ThinkingDisplay` Types and Preserve Persisted Display
Address review findings on PR LibreChat-AI#12701:
- [Codex P2] `bedrockInputSchema.transform` now extracts
`thinking.display` from persisted `additionalModelRequestFields` back
into the top-level `thinkingDisplay` field so explicit `'omitted'`
round-trips through storage instead of being silently reverted to
`'summarized'` on the next parse.
- [Codex P2] `getLLMConfig` in the Anthropic endpoint now reads
`.display` from a persisted `thinking` object (agents store the full
Anthropic shape) and uses it as the fallback for `thinkingDisplay`
when no top-level override is present.
- [Audit LibreChat-AI#2] Collapse the three parallel wire-value types into a single
`ThinkingDisplayWireValue = Exclude<ThinkingDisplay, 'auto'>` exported
from `schemas.ts`; remove the duplicate `ThinkingDisplay` alias in
`packages/api/src/types/anthropic.ts` (which collided with the enum
name) and the `ThinkingDisplayValue` alias in `bedrock.ts`.
- [Audit LibreChat-AI#3] Add `thinkingDisplay` to the `TEndpointOption` pick list
next to `effort`.
- [Audit LibreChat-AI#4] Add a TODO comment next to the `as
AnthropicClientOptions['thinking']` cast explaining the stale
`@librechat/agents` SDK types that require it.
- Add tests: four round-trip cases asserting `bedrockInputSchema`
recovers `display` from persisted AMRF (Opus 4.7 omitted, pre-4.7
summarized, unknown-value ignore, explicit top-level wins), and two
`getLLMConfig` cases asserting the Anthropic endpoint preserves and
overrides persisted `thinking.display`.
* fix: Preserve Persisted `thinking.display` in bedrockInputParser
The parser constructed a fresh adaptive thinking config without looking at
any `display` already embedded in the incoming
`additionalModelRequestFields.thinking`. On round-trip through
`initializeBedrock`, a persisted user choice of `'omitted'` on Opus 4.7+
was silently reverted to `'summarized'` by the auto fallback.
- Extract `extractPersistedDisplay` helper and reuse it in both the
schema transform (form-state round-trip) and the parser (wire-request
round-trip)
- `bedrockInputParser` now feeds the persisted display as the resolver's
explicit value when no top-level `thinkingDisplay` override is set
- Add regression tests: parser preserves `display: 'omitted'` for
persisted Opus 4.7 AMRF, and top-level `thinkingDisplay` still wins
over persisted AMRF display
Reported by chatgpt-codex-connector (P1) on PR LibreChat-AI#12701.
* 🫧 fix: Restore Claude Opus 4.7 Reasoning Visibility
Claude Opus 4.7 omits `thinking` content from Messages API responses by
default — empty thinking blocks still stream, but the `thinking` field is
blank unless the caller passes `display: "summarized"` in the adaptive
thinking config. This silenced the LibreChat "Thoughts" UI for Anthropic
(and Anthropic-on-Bedrock) adaptive models.
- Extend `ThinkingConfigAdaptive` in `packages/api/src/types/anthropic.ts`
with an optional `display: 'summarized' | 'omitted'` field
- Emit `{ type: 'adaptive', display: 'summarized' }` from
`configureReasoning` in `packages/api/src/endpoints/anthropic/helpers.ts`
- Emit `{ type: 'adaptive', display: 'summarized' }` from
`bedrockInputParser` in `packages/data-provider/src/bedrock.ts` and
update the local `ThinkingConfig` union
- Update existing adaptive-thinking assertions to include the new field
- Add dedicated tests asserting `display: 'summarized'` flows through
both the Anthropic endpoint and the Bedrock parser
See https://platform.claude.com/docs/en/about-claude/models/whats-new-claude-4-7#thinking-content-omitted-by-default
* refactor: Gate `display: summarized` on Opus 4.7+
Narrow the reasoning-visibility opt-in to the models that actually omit
thinking content by default, instead of applying it to every adaptive
model. Pre-Opus-4.7 adaptive models (Opus 4.6, Sonnet 4.6) already return
summaries, so sending the field is unnecessary noise.
- Add `omitsThinkingByDefault(model)` in `packages/data-provider/src/bedrock.ts`
that returns true only for Opus 4.7+ (including future majors like Opus 5+)
- Bedrock parser now only attaches `display: 'summarized'` when the helper
matches, keeping the adaptive object unchanged for older models
- Anthropic endpoint `configureReasoning` uses the same helper so its emit
path matches the Bedrock one
- Tests: replace the blanket `display: 'summarized'` assertions with
model-specific ones (Opus 4.7 gets it, Opus 4.6 / Sonnet 4.6 do not),
add a dedicated `omitsThinkingByDefault` suite covering naming variants
and future versions
* feat: Configurable Thought Visibility for Anthropic Adaptive Models
Expose the Anthropic `thinking.display` API field as a user-facing
parameter so users can override the `auto` default (which stays as the
Opus-4.7+ opt-in added earlier in this PR). Also fixes the CI type error
by widening the adaptive thinking type assignment via a resolver helper
that returns a properly-typed object.
- Add `ThinkingDisplay` enum (`auto` | `summarized` | `omitted`) and
matching zod schema in `packages/data-provider/src/schemas.ts`
- Add `thinkingDisplay` to `tConversationSchema`, `anthropicSettings`, and
the pick lists for Bedrock input/parser + Anthropic agent params
- Add `resolveThinkingDisplay(model, explicit)` helper in
`packages/data-provider/src/bedrock.ts` that returns the wire value or
undefined (auto → model default, explicit → always honored)
- `bedrockInputParser` now reads `thinkingDisplay` from input and emits
`display` only when the resolver returns a value; strips the field
on non-adaptive-model branches so it does not leak
- `configureReasoning` in the Anthropic endpoint threads
`thinkingDisplay` through, uses the resolver, and casts the adaptive
config to `AnthropicClientOptions['thinking']` so the widened shape
compiles against the stale installed SDK types
- Add UI slider for `thinkingDisplay` in `parameterSettings.ts` next to
`effort`, with three-position `com_ui_auto` / `com_ui_summarized` /
`com_ui_omitted` labels
- Add translation keys `com_endpoint_anthropic_thinking_display`,
`com_endpoint_anthropic_thinking_display_desc`, `com_ui_summarized`,
`com_ui_omitted`
- Add tests: `resolveThinkingDisplay` suite (5 cases covering auto /
explicit / unknown input), parser round-trip tests for all three
modes on Opus 4.6 and Opus 4.7, Anthropic endpoint tests for explicit
summarized/omitted overrides
* fix: Drop `thinkingDisplay` When Adaptive Thinking Is Disabled
If a user turns adaptive thinking off but had previously selected a
`thinkingDisplay` value, the stale field was left in `additionalFields`
and ended up merged into the Bedrock request's
`additionalModelRequestFields`. That leaks a non-Bedrock key into the
payload and can round-trip back into `llmConfig`.
- Delete `additionalFields.thinkingDisplay` alongside `thinking` and
`thinkingBudget` in the `thinking === false` branch of
`bedrockInputParser`
- Add a regression test asserting `thinking`, `thinkingBudget`, and
`thinkingDisplay` are all absent when adaptive thinking is disabled on
an Opus 4.7 request
Reported by chatgpt-codex-connector on PR LibreChat-AI#12701.
* refactor: Consolidate `ThinkingDisplay` Types and Preserve Persisted Display
Address review findings on PR LibreChat-AI#12701:
- [Codex P2] `bedrockInputSchema.transform` now extracts
`thinking.display` from persisted `additionalModelRequestFields` back
into the top-level `thinkingDisplay` field so explicit `'omitted'`
round-trips through storage instead of being silently reverted to
`'summarized'` on the next parse.
- [Codex P2] `getLLMConfig` in the Anthropic endpoint now reads
`.display` from a persisted `thinking` object (agents store the full
Anthropic shape) and uses it as the fallback for `thinkingDisplay`
when no top-level override is present.
- [Audit #2] Collapse the three parallel wire-value types into a single
`ThinkingDisplayWireValue = Exclude<ThinkingDisplay, 'auto'>` exported
from `schemas.ts`; remove the duplicate `ThinkingDisplay` alias in
`packages/api/src/types/anthropic.ts` (which collided with the enum
name) and the `ThinkingDisplayValue` alias in `bedrock.ts`.
- [Audit LibreChat-AI#3] Add `thinkingDisplay` to the `TEndpointOption` pick list
next to `effort`.
- [Audit LibreChat-AI#4] Add a TODO comment next to the `as
AnthropicClientOptions['thinking']` cast explaining the stale
`@librechat/agents` SDK types that require it.
- Add tests: four round-trip cases asserting `bedrockInputSchema`
recovers `display` from persisted AMRF (Opus 4.7 omitted, pre-4.7
summarized, unknown-value ignore, explicit top-level wins), and two
`getLLMConfig` cases asserting the Anthropic endpoint preserves and
overrides persisted `thinking.display`.
* fix: Preserve Persisted `thinking.display` in bedrockInputParser
The parser constructed a fresh adaptive thinking config without looking at
any `display` already embedded in the incoming
`additionalModelRequestFields.thinking`. On round-trip through
`initializeBedrock`, a persisted user choice of `'omitted'` on Opus 4.7+
was silently reverted to `'summarized'` by the auto fallback.
- Extract `extractPersistedDisplay` helper and reuse it in both the
schema transform (form-state round-trip) and the parser (wire-request
round-trip)
- `bedrockInputParser` now feeds the persisted display as the resolver's
explicit value when no top-level `thinkingDisplay` override is set
- Add regression tests: parser preserves `display: 'omitted'` for
persisted Opus 4.7 AMRF, and top-level `thinkingDisplay` still wins
over persisted AMRF display
Reported by chatgpt-codex-connector (P1) on PR LibreChat-AI#12701.
Summary
I restored the "Thoughts" UI for Anthropic adaptive-thinking models after Claude Opus 4.7 silently changed the Messages API default so that reasoning content is omitted unless the caller explicitly opts in with
thinking.display = "summarized". The fix threads the new field through the Anthropic type, the Anthropic endpoint helper, and the Bedrock input parser so both transport paths regain visible summarized reasoning blocks.ThinkingConfigAdaptiveinpackages/api/src/types/anthropic.tswith an optionaldisplay: 'summarized' | 'omitted'field and JSDoc linking to the Anthropic 4.7 release notes.{ type: 'adaptive', display: 'summarized' }fromconfigureReasoninginpackages/api/src/endpoints/anthropic/helpers.tswhenever a model supports adaptive thinking.{ type: 'adaptive', display: 'summarized' }frombedrockInputParserinpackages/data-provider/src/bedrock.tsand widened the localThinkingConfigunion, using aDEFAULT_THINKING_DISPLAYconstant with a linking comment.bedrock.spec.tsnow asserts the parser setsthinking.display === 'summarized'foranthropic.claude-opus-4-7, andllm.spec.tsasserts the Anthropic endpoint emits the same field for Opus 4.7, Opus 4.6, and Sonnet 4.6.Fixes the empty-thoughts screenshot reported on the issue by flipping the API default back to visible summaries.
Reference: https://platform.claude.com/docs/en/about-claude/models/whats-new-claude-4-7#thinking-content-omitted-by-default
Change Type
Testing
Verified both transport paths rebuild the adaptive thinking object with the new field and that none of the pre-existing adaptive-thinking tests regressed.
cd packages/data-provider && npx jest→ 17 suites, 935 passedcd packages/api && npx jest src/endpoints/anthropic src/endpoints/bedrock→ 124/124 passTo reproduce the UI regression before the fix: use
claude-opus-4-7(Anthropic endpoint) oranthropic.claude-opus-4-7(Bedrock) with thinking enabled and observe that the "Thoughts" card never appears. With this change, the summarized thoughts render as they did for Opus 4.6 and Sonnet 4.6.Test Configuration:
claude-opus-4-7,claude-opus-4-6,claude-sonnet-4-6,anthropic.claude-opus-4-6-v1,us.anthropic.claude-opus-4-6-v1,global.anthropic.claude-opus-4-6-v1,anthropic.claude-opus-4-7Checklist