diff --git a/.changeset/add-claude-sonnet-4-6.md b/.changeset/add-claude-sonnet-4-6.md new file mode 100644 index 000000000..644039025 --- /dev/null +++ b/.changeset/add-claude-sonnet-4-6.md @@ -0,0 +1,5 @@ +--- +'@tanstack/ai-anthropic': minor +--- + +Add `claude-sonnet-4-6` model metadata to the Anthropic adapter, including 1M native context window and adaptive thinking support. diff --git a/examples/ts-react-chat/src/lib/model-selection.ts b/examples/ts-react-chat/src/lib/model-selection.ts index 0d0b04c57..95c122cd4 100644 --- a/examples/ts-react-chat/src/lib/model-selection.ts +++ b/examples/ts-react-chat/src/lib/model-selection.ts @@ -20,6 +20,11 @@ export const MODEL_OPTIONS: Array = [ { provider: 'openai', model: 'gpt-5', label: 'OpenAI - GPT-5' }, // Anthropic + { + provider: 'anthropic', + model: 'claude-sonnet-4-6', + label: 'Anthropic - Claude Sonnet 4.6', + }, { provider: 'anthropic', model: 'claude-sonnet-4-5-20250929', diff --git a/packages/typescript/ai-anthropic/src/model-meta.ts b/packages/typescript/ai-anthropic/src/model-meta.ts index ec7ca7807..82302ac02 100644 --- a/packages/typescript/ai-anthropic/src/model-meta.ts +++ b/packages/typescript/ai-anthropic/src/model-meta.ts @@ -108,6 +108,37 @@ const CLAUDE_OPUS_4_5 = { AnthropicSamplingOptions > +const CLAUDE_SONNET_4_6 = { + name: 'claude-sonnet-4-6', + id: 'claude-sonnet-4-6', + context_window: 1_000_000, + max_output_tokens: 64_000, + knowledge_cutoff: '2025-08-01', + pricing: { + input: { + normal: 3, + }, + output: { + normal: 15, + }, + }, + supports: { + input: ['text', 'image', 'document'], + extended_thinking: true, + adaptive_thinking: true, + priority_tier: true, + }, +} as const satisfies ModelMeta< + AnthropicContainerOptions & + AnthropicContextManagementOptions & + AnthropicMCPOptions & + AnthropicServiceTierOptions & + AnthropicStopSequencesOptions & + AnthropicThinkingOptions & + AnthropicToolChoiceOptions & + AnthropicSamplingOptions +> + const CLAUDE_SONNET_4_5 = { name: 'claude-sonnet-4-5', id: 'claude-sonnet-4-5', @@ -395,6 +426,7 @@ const CLAUDE_HAIKU_3 = { export const ANTHROPIC_MODELS = [ CLAUDE_OPUS_4_6.id, CLAUDE_OPUS_4_5.id, + CLAUDE_SONNET_4_6.id, CLAUDE_SONNET_4_5.id, CLAUDE_HAIKU_4_5.id, CLAUDE_OPUS_4_1.id, @@ -432,6 +464,14 @@ export type AnthropicChatModelProviderOptionsByName = { AnthropicThinkingOptions & AnthropicToolChoiceOptions & AnthropicSamplingOptions + [CLAUDE_SONNET_4_6.id]: AnthropicContainerOptions & + AnthropicContextManagementOptions & + AnthropicMCPOptions & + AnthropicServiceTierOptions & + AnthropicStopSequencesOptions & + AnthropicThinkingOptions & + AnthropicToolChoiceOptions & + AnthropicSamplingOptions [CLAUDE_SONNET_4_5.id]: AnthropicContainerOptions & AnthropicContextManagementOptions & AnthropicMCPOptions & @@ -513,6 +553,7 @@ export type AnthropicChatModelProviderOptionsByName = { export type AnthropicModelInputModalitiesByName = { [CLAUDE_OPUS_4_6.id]: typeof CLAUDE_OPUS_4_6.supports.input [CLAUDE_OPUS_4_5.id]: typeof CLAUDE_OPUS_4_5.supports.input + [CLAUDE_SONNET_4_6.id]: typeof CLAUDE_SONNET_4_6.supports.input [CLAUDE_SONNET_4_5.id]: typeof CLAUDE_SONNET_4_5.supports.input [CLAUDE_HAIKU_4_5.id]: typeof CLAUDE_HAIKU_4_5.supports.input [CLAUDE_OPUS_4_1.id]: typeof CLAUDE_OPUS_4_1.supports.input diff --git a/packages/typescript/ai-anthropic/tests/model-meta.test.ts b/packages/typescript/ai-anthropic/tests/model-meta.test.ts index 842e8c049..0caddc281 100644 --- a/packages/typescript/ai-anthropic/tests/model-meta.test.ts +++ b/packages/typescript/ai-anthropic/tests/model-meta.test.ts @@ -43,6 +43,30 @@ type BaseOptions = AnthropicContainerOptions & describe('Anthropic Model Provider Options Type Assertions', () => { describe('Models WITH extended_thinking support', () => { + it('claude-sonnet-4-6 should support thinking options', () => { + type Options = + AnthropicChatModelProviderOptionsByName['claude-sonnet-4-6'] + + // Should have thinking options + expectTypeOf().toExtend() + + // Should have service tier options (priority_tier support) + expectTypeOf().toExtend() + + // Should have base options + expectTypeOf().toExtend() + + // Verify specific properties exist + expectTypeOf().toHaveProperty('thinking') + expectTypeOf().toHaveProperty('service_tier') + expectTypeOf().toHaveProperty('container') + expectTypeOf().toHaveProperty('context_management') + expectTypeOf().toHaveProperty('mcp_servers') + expectTypeOf().toHaveProperty('stop_sequences') + expectTypeOf().toHaveProperty('tool_choice') + expectTypeOf().toHaveProperty('top_k') + }) + it('claude-sonnet-4-5 should support thinking options', () => { type Options = AnthropicChatModelProviderOptionsByName['claude-sonnet-4-5'] @@ -177,6 +201,7 @@ describe('Anthropic Model Provider Options Type Assertions', () => { type Keys = keyof AnthropicChatModelProviderOptionsByName expectTypeOf<'claude-opus-4-5'>().toExtend() + expectTypeOf<'claude-sonnet-4-6'>().toExtend() expectTypeOf<'claude-sonnet-4-5'>().toExtend() expectTypeOf<'claude-haiku-4-5'>().toExtend() expectTypeOf<'claude-opus-4-1'>().toExtend() @@ -193,6 +218,9 @@ describe('Anthropic Model Provider Options Type Assertions', () => { expectTypeOf< AnthropicChatModelProviderOptionsByName['claude-opus-4-5'] >().toHaveProperty('container') + expectTypeOf< + AnthropicChatModelProviderOptionsByName['claude-sonnet-4-6'] + >().toHaveProperty('container') expectTypeOf< AnthropicChatModelProviderOptionsByName['claude-sonnet-4-5'] >().toHaveProperty('container') @@ -223,6 +251,9 @@ describe('Anthropic Model Provider Options Type Assertions', () => { expectTypeOf< AnthropicChatModelProviderOptionsByName['claude-opus-4-5'] >().toHaveProperty('context_management') + expectTypeOf< + AnthropicChatModelProviderOptionsByName['claude-sonnet-4-6'] + >().toHaveProperty('context_management') expectTypeOf< AnthropicChatModelProviderOptionsByName['claude-sonnet-4-5'] >().toHaveProperty('context_management') @@ -253,6 +284,9 @@ describe('Anthropic Model Provider Options Type Assertions', () => { expectTypeOf< AnthropicChatModelProviderOptionsByName['claude-opus-4-5'] >().toHaveProperty('mcp_servers') + expectTypeOf< + AnthropicChatModelProviderOptionsByName['claude-sonnet-4-6'] + >().toHaveProperty('mcp_servers') expectTypeOf< AnthropicChatModelProviderOptionsByName['claude-sonnet-4-5'] >().toHaveProperty('mcp_servers') @@ -283,6 +317,9 @@ describe('Anthropic Model Provider Options Type Assertions', () => { expectTypeOf< AnthropicChatModelProviderOptionsByName['claude-opus-4-5'] >().toHaveProperty('stop_sequences') + expectTypeOf< + AnthropicChatModelProviderOptionsByName['claude-sonnet-4-6'] + >().toHaveProperty('stop_sequences') expectTypeOf< AnthropicChatModelProviderOptionsByName['claude-sonnet-4-5'] >().toHaveProperty('stop_sequences') @@ -313,6 +350,9 @@ describe('Anthropic Model Provider Options Type Assertions', () => { expectTypeOf< AnthropicChatModelProviderOptionsByName['claude-opus-4-5'] >().toHaveProperty('tool_choice') + expectTypeOf< + AnthropicChatModelProviderOptionsByName['claude-sonnet-4-6'] + >().toHaveProperty('tool_choice') expectTypeOf< AnthropicChatModelProviderOptionsByName['claude-sonnet-4-5'] >().toHaveProperty('tool_choice') @@ -343,6 +383,9 @@ describe('Anthropic Model Provider Options Type Assertions', () => { expectTypeOf< AnthropicChatModelProviderOptionsByName['claude-opus-4-5'] >().toHaveProperty('top_k') + expectTypeOf< + AnthropicChatModelProviderOptionsByName['claude-sonnet-4-6'] + >().toHaveProperty('top_k') expectTypeOf< AnthropicChatModelProviderOptionsByName['claude-sonnet-4-5'] >().toHaveProperty('top_k') @@ -375,6 +418,9 @@ describe('Anthropic Model Provider Options Type Assertions', () => { expectTypeOf< AnthropicChatModelProviderOptionsByName['claude-opus-4-5'] >().toExtend() + expectTypeOf< + AnthropicChatModelProviderOptionsByName['claude-sonnet-4-6'] + >().toExtend() expectTypeOf< AnthropicChatModelProviderOptionsByName['claude-sonnet-4-5'] >().toExtend() @@ -408,6 +454,9 @@ describe('Anthropic Model Provider Options Type Assertions', () => { expectTypeOf< AnthropicChatModelProviderOptionsByName['claude-opus-4-5'] >().toExtend() + expectTypeOf< + AnthropicChatModelProviderOptionsByName['claude-sonnet-4-6'] + >().toExtend() expectTypeOf< AnthropicChatModelProviderOptionsByName['claude-sonnet-4-5'] >().toExtend() @@ -441,6 +490,9 @@ describe('Anthropic Model Provider Options Type Assertions', () => { expectTypeOf< AnthropicChatModelProviderOptionsByName['claude-opus-4-5'] >().toExtend() + expectTypeOf< + AnthropicChatModelProviderOptionsByName['claude-sonnet-4-6'] + >().toExtend() expectTypeOf< AnthropicChatModelProviderOptionsByName['claude-sonnet-4-5'] >().toExtend() @@ -498,6 +550,22 @@ describe('Anthropic Model Input Modality Type Assertions', () => { }) }) + describe('Claude Sonnet 4.6 (text + image + document)', () => { + type Modalities = AnthropicModelInputModalitiesByName['claude-sonnet-4-6'] + type Message = ConstrainedModelMessage + + it('should allow TextPart, ImagePart, and DocumentPart', () => { + expectTypeOf>().toExtend() + expectTypeOf>().toExtend() + expectTypeOf>().toExtend() + }) + + it('should NOT allow AudioPart or VideoPart', () => { + expectTypeOf>().not.toExtend() + expectTypeOf>().not.toExtend() + }) + }) + describe('Claude Sonnet 4.5 (text + image + document)', () => { type Modalities = AnthropicModelInputModalitiesByName['claude-sonnet-4-5'] type Message = ConstrainedModelMessage