fix: show Anthropic Opus 4.7+ thinking (#26026)

## Summary

- Updates Coder's pinned `github.com/coder/fantasy` fork to include
coder/fantasy#39.
- Exposes Anthropic `thinking_display` as a typed chat model provider
option with `summarized` and `omitted` values.
- Validates configured `thinking_display` values and maps them to
`fantasyanthropic.ProviderOptions.ThinkingDisplay`.
- Regenerates the API/UI option schemas so the admin model config form
gets a generated select field.

## Tests

- `go mod tidy`
- `make gen`
- `go test ./codersdk ./coderd/x/chatd/chatprovider ./coderd -run
'TestChatModelProviderOptions|TestAnthropicThinkingDisplayFromChat|TestProviderOptionsFromChatModelConfig_AnthropicThinkingDisplay|TestMergeMissingProviderOptions_AnthropicThinkingDisplay|TestValidateChatModelProviderOptions_AnthropicThinkingDisplay'`
- `go test ./coderd/x/chatd/... ./codersdk`
- `go test ./coderd -run
'TestValidateChatModelProviderOptions_AnthropicThinkingDisplay'`
- `pnpm --dir site exec -- biome lint --error-on-warnings
src/api/chatModelOptionsGenerated.json src/api/typesGenerated.ts`
- pre-commit hook, including fmt, lint, and slim build

> Mux working on behalf of Mike.
This commit is contained in:
Michael Suchacz
2026-06-05 08:37:54 +02:00
committed by GitHub
parent 5578ac5f3d
commit c4792cf104
10 changed files with 174 additions and 8 deletions
+1
View File
@@ -1229,6 +1229,7 @@ type ChatModelAnthropicProviderOptions struct {
SendReasoning *bool `json:"send_reasoning,omitempty" description:"Whether to include reasoning content in the response"`
Thinking *ChatModelAnthropicThinkingOptions `json:"thinking,omitempty" description:"Configuration for extended thinking"`
Effort *string `json:"effort,omitempty" label:"Reasoning Effort" description:"Controls the level of reasoning effort" enum:"low,medium,high,xhigh,max"`
ThinkingDisplay *string `json:"thinking_display,omitempty" label:"Thinking Display" description:"Controls how Anthropic returns thinking content" enum:"summarized,omitted"`
DisableParallelToolUse *bool `json:"disable_parallel_tool_use,omitempty" description:"Whether to disable parallel tool execution"`
WebSearchEnabled *bool `json:"web_search_enabled,omitempty" description:"Enable Anthropic web search tool for grounding responses with real-time information"`
AllowedDomains []string `json:"allowed_domains,omitempty" label:"Web Search: Allowed Domains" description:"Restrict web search to these domains (cannot be used with blocked_domains)"`
+9 -3
View File
@@ -24,11 +24,13 @@ func TestChatModelProviderOptions_MarshalJSON_UsesPlainProviderPayload(t *testin
sendReasoning := true
effort := "high"
thinkingDisplay := "summarized"
raw, err := json.Marshal(codersdk.ChatModelProviderOptions{
Anthropic: &codersdk.ChatModelAnthropicProviderOptions{
SendReasoning: &sendReasoning,
Effort: &effort,
SendReasoning: &sendReasoning,
Effort: &effort,
ThinkingDisplay: &thinkingDisplay,
},
})
require.NoError(t, err)
@@ -36,6 +38,7 @@ func TestChatModelProviderOptions_MarshalJSON_UsesPlainProviderPayload(t *testin
require.NotContains(t, string(raw), `"data":`)
require.Contains(t, string(raw), `"send_reasoning":true`)
require.Contains(t, string(raw), `"effort":"high"`)
require.Contains(t, string(raw), `"thinking_display":"summarized"`)
}
func TestChatModelProviderOptions_UnmarshalJSON_ParsesPlainProviderPayloads(t *testing.T) {
@@ -44,7 +47,8 @@ func TestChatModelProviderOptions_UnmarshalJSON_ParsesPlainProviderPayloads(t *t
raw := []byte(`{
"anthropic": {
"send_reasoning": true,
"effort": "high"
"effort": "high",
"thinking_display": "summarized"
}
}`)
@@ -60,6 +64,8 @@ func TestChatModelProviderOptions_UnmarshalJSON_ParsesPlainProviderPayloads(t *t
"high",
*decoded.Anthropic.Effort,
)
require.NotNil(t, decoded.Anthropic.ThinkingDisplay)
require.Equal(t, "summarized", *decoded.Anthropic.ThinkingDisplay)
}
func TestChatUsageLimitExceededFrom(t *testing.T) {