diff --git a/packages/types/src/providers/anthropic.ts b/packages/types/src/providers/anthropic.ts index 1c0977bd06..759ebdea55 100644 --- a/packages/types/src/providers/anthropic.ts +++ b/packages/types/src/providers/anthropic.ts @@ -6,7 +6,7 @@ export type AnthropicModelId = keyof typeof anthropicModels export const anthropicDefaultModelId: AnthropicModelId = "claude-sonnet-4-20250514" export const anthropicModels = { - "claude-4.5-sonnet": { + "claude-sonnet-4-5": { maxTokens: 64_000, // Overridden to 8k if `enableReasoningEffort` is false. contextWindow: 200_000, // Default 200K, extendable to 1M with beta flag 'context-1m-2025-08-07' supportsImages: true, diff --git a/packages/types/src/providers/bedrock.ts b/packages/types/src/providers/bedrock.ts index dce4e024a0..87e62e1045 100644 --- a/packages/types/src/providers/bedrock.ts +++ b/packages/types/src/providers/bedrock.ts @@ -457,4 +457,7 @@ export const BEDROCK_REGIONS = [ { value: "us-gov-west-1", label: "us-gov-west-1" }, ].sort((a, b) => a.value.localeCompare(b.value)) -export const BEDROCK_CLAUDE_SONNET_4_MODEL_ID = "anthropic.claude-sonnet-4-20250514-v1:0" +export const BEDROCK_1M_CONTEXT_MODEL_IDS = [ + "anthropic.claude-sonnet-4-20250514-v1:0", + "anthropic.claude-sonnet-4-5-20250929-v1:0", +] as const diff --git a/packages/types/src/providers/claude-code.ts b/packages/types/src/providers/claude-code.ts index fb44b57658..a00066d87f 100644 --- a/packages/types/src/providers/claude-code.ts +++ b/packages/types/src/providers/claude-code.ts @@ -40,8 +40,8 @@ export function getClaudeCodeModelId(baseModelId: ClaudeCodeModelId, useVertex = } export const claudeCodeModels = { - "claude-4.5-sonnet": { - ...anthropicModels["claude-4.5-sonnet"], + "claude-sonnet-4-5": { + ...anthropicModels["claude-sonnet-4-5"], supportsImages: false, supportsPromptCache: true, // Claude Code does report cache tokens supportsReasoningEffort: false, diff --git a/src/api/providers/__tests__/anthropic.spec.ts b/src/api/providers/__tests__/anthropic.spec.ts index 7b74c87dfc..b05e50125b 100644 --- a/src/api/providers/__tests__/anthropic.spec.ts +++ b/src/api/providers/__tests__/anthropic.spec.ts @@ -268,10 +268,10 @@ describe("AnthropicHandler", () => { it("should handle Claude 4.5 Sonnet model correctly", () => { const handler = new AnthropicHandler({ apiKey: "test-api-key", - apiModelId: "claude-4.5-sonnet", + apiModelId: "claude-sonnet-4-5", }) const model = handler.getModel() - expect(model.id).toBe("claude-4.5-sonnet") + expect(model.id).toBe("claude-sonnet-4-5") expect(model.info.maxTokens).toBe(64000) expect(model.info.contextWindow).toBe(200000) expect(model.info.supportsReasoningBudget).toBe(true) @@ -280,7 +280,7 @@ describe("AnthropicHandler", () => { it("should enable 1M context for Claude 4.5 Sonnet when beta flag is set", () => { const handler = new AnthropicHandler({ apiKey: "test-api-key", - apiModelId: "claude-4.5-sonnet", + apiModelId: "claude-sonnet-4-5", anthropicBeta1MContext: true, }) const model = handler.getModel() diff --git a/src/api/providers/__tests__/bedrock.spec.ts b/src/api/providers/__tests__/bedrock.spec.ts index 8df495ca9f..47ba5bd1a6 100644 --- a/src/api/providers/__tests__/bedrock.spec.ts +++ b/src/api/providers/__tests__/bedrock.spec.ts @@ -25,7 +25,9 @@ vi.mock("@aws-sdk/client-bedrock-runtime", () => { import { AwsBedrockHandler } from "../bedrock" import { ConverseStreamCommand, BedrockRuntimeClient } from "@aws-sdk/client-bedrock-runtime" -import { BEDROCK_CLAUDE_SONNET_4_MODEL_ID } from "@roo-code/types" +import { BEDROCK_1M_CONTEXT_MODEL_IDS } from "@roo-code/types" + +const BEDROCK_CLAUDE_SONNET_4_MODEL_ID = BEDROCK_1M_CONTEXT_MODEL_IDS[0] import type { Anthropic } from "@anthropic-ai/sdk" diff --git a/src/api/providers/anthropic.ts b/src/api/providers/anthropic.ts index 80ef572b5b..3fb60c0e4f 100644 --- a/src/api/providers/anthropic.ts +++ b/src/api/providers/anthropic.ts @@ -47,14 +47,14 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa // Add 1M context beta flag if enabled for Claude Sonnet 4 and 4.5 if ( - (modelId === "claude-sonnet-4-20250514" || modelId === "claude-4.5-sonnet") && + (modelId === "claude-sonnet-4-20250514" || modelId === "claude-sonnet-4-5") && this.options.anthropicBeta1MContext ) { betas.push("context-1m-2025-08-07") } switch (modelId) { - case "claude-4.5-sonnet": + case "claude-sonnet-4-5": case "claude-sonnet-4-20250514": case "claude-opus-4-1-20250805": case "claude-opus-4-20250514": @@ -114,7 +114,7 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa // Then check for models that support prompt caching switch (modelId) { - case "claude-4.5-sonnet": + case "claude-sonnet-4-5": case "claude-sonnet-4-20250514": case "claude-opus-4-1-20250805": case "claude-opus-4-20250514": @@ -249,7 +249,7 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa let info: ModelInfo = anthropicModels[id] // If 1M context beta is enabled for Claude Sonnet 4 or 4.5, update the model info - if ((id === "claude-sonnet-4-20250514" || id === "claude-4.5-sonnet") && this.options.anthropicBeta1MContext) { + if ((id === "claude-sonnet-4-20250514" || id === "claude-sonnet-4-5") && this.options.anthropicBeta1MContext) { // Use the tier pricing for 1M context const tier = info.tiers?.[0] if (tier) { diff --git a/src/api/providers/bedrock.ts b/src/api/providers/bedrock.ts index c6a0b35df4..e0c63683cb 100644 --- a/src/api/providers/bedrock.ts +++ b/src/api/providers/bedrock.ts @@ -21,7 +21,7 @@ import { BEDROCK_MAX_TOKENS, BEDROCK_DEFAULT_CONTEXT, AWS_INFERENCE_PROFILE_MAPPING, - BEDROCK_CLAUDE_SONNET_4_MODEL_ID, + BEDROCK_1M_CONTEXT_MODEL_IDS, } from "@roo-code/types" import { ApiStream } from "../transform/stream" @@ -378,10 +378,11 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH inferenceConfig.topP = 0.1 } - // Check if 1M context is enabled for Claude Sonnet 4 + // Check if 1M context is enabled for Claude Sonnet 4 / 4.5 // Use parseBaseModelId to handle cross-region inference prefixes const baseModelId = this.parseBaseModelId(modelConfig.id) - const is1MContextEnabled = baseModelId === BEDROCK_CLAUDE_SONNET_4_MODEL_ID && this.options.awsBedrock1MContext + const is1MContextEnabled = + BEDROCK_1M_CONTEXT_MODEL_IDS.includes(baseModelId as any) && this.options.awsBedrock1MContext // Add anthropic_beta for 1M context to additionalModelRequestFields if (is1MContextEnabled) { @@ -976,10 +977,10 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH } } - // Check if 1M context is enabled for Claude Sonnet 4 + // Check if 1M context is enabled for Claude Sonnet 4 / 4.5 // Use parseBaseModelId to handle cross-region inference prefixes const baseModelId = this.parseBaseModelId(modelConfig.id) - if (baseModelId === BEDROCK_CLAUDE_SONNET_4_MODEL_ID && this.options.awsBedrock1MContext) { + if (BEDROCK_1M_CONTEXT_MODEL_IDS.includes(baseModelId as any) && this.options.awsBedrock1MContext) { // Update context window to 1M tokens when 1M context beta is enabled modelConfig.info = { ...modelConfig.info, diff --git a/webview-ui/src/components/settings/providers/Anthropic.tsx b/webview-ui/src/components/settings/providers/Anthropic.tsx index 224d1965b6..feef788d49 100644 --- a/webview-ui/src/components/settings/providers/Anthropic.tsx +++ b/webview-ui/src/components/settings/providers/Anthropic.tsx @@ -23,7 +23,7 @@ export const Anthropic = ({ apiConfiguration, setApiConfigurationField }: Anthro // Check if the current model supports 1M context beta const supports1MContextBeta = - selectedModel?.id === "claude-sonnet-4-20250514" || selectedModel?.id === "claude-4.5-sonnet" + selectedModel?.id === "claude-sonnet-4-20250514" || selectedModel?.id === "claude-sonnet-4-5" const handleInputChange = useCallback( ( diff --git a/webview-ui/src/components/settings/providers/Bedrock.tsx b/webview-ui/src/components/settings/providers/Bedrock.tsx index 6c871e570a..1b3143fa08 100644 --- a/webview-ui/src/components/settings/providers/Bedrock.tsx +++ b/webview-ui/src/components/settings/providers/Bedrock.tsx @@ -2,12 +2,7 @@ import { useCallback, useState, useEffect } from "react" import { Checkbox } from "vscrui" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { - type ProviderSettings, - type ModelInfo, - BEDROCK_REGIONS, - BEDROCK_CLAUDE_SONNET_4_MODEL_ID, -} from "@roo-code/types" +import { type ProviderSettings, type ModelInfo, BEDROCK_REGIONS, BEDROCK_1M_CONTEXT_MODEL_IDS } from "@roo-code/types" import { useAppTranslation } from "@src/i18n/TranslationContext" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, StandardTooltip } from "@src/components/ui" @@ -24,8 +19,9 @@ export const Bedrock = ({ apiConfiguration, setApiConfigurationField, selectedMo const { t } = useAppTranslation() const [awsEndpointSelected, setAwsEndpointSelected] = useState(!!apiConfiguration?.awsBedrockEndpointEnabled) - // Check if the selected model supports 1M context (Claude Sonnet 4) - const supports1MContextBeta = apiConfiguration?.apiModelId === BEDROCK_CLAUDE_SONNET_4_MODEL_ID + // Check if the selected model supports 1M context (Claude Sonnet 4 / 4.5) + const supports1MContextBeta = + !!apiConfiguration?.apiModelId && BEDROCK_1M_CONTEXT_MODEL_IDS.includes(apiConfiguration.apiModelId as any) // Update the endpoint enabled state when the configuration changes useEffect(() => { diff --git a/webview-ui/src/components/ui/hooks/__tests__/useSelectedModel.spec.ts b/webview-ui/src/components/ui/hooks/__tests__/useSelectedModel.spec.ts index 9d8c627b7f..91f6183679 100644 --- a/webview-ui/src/components/ui/hooks/__tests__/useSelectedModel.spec.ts +++ b/webview-ui/src/components/ui/hooks/__tests__/useSelectedModel.spec.ts @@ -5,7 +5,9 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query" import { renderHook } from "@testing-library/react" import type { Mock } from "vitest" -import { ProviderSettings, ModelInfo, BEDROCK_CLAUDE_SONNET_4_MODEL_ID } from "@roo-code/types" +import { ProviderSettings, ModelInfo, BEDROCK_1M_CONTEXT_MODEL_IDS } from "@roo-code/types" + +const BEDROCK_CLAUDE_SONNET_4_MODEL_ID = BEDROCK_1M_CONTEXT_MODEL_IDS[0] import { useSelectedModel } from "../useSelectedModel" import { useRouterModels } from "../useRouterModels" diff --git a/webview-ui/src/components/ui/hooks/useSelectedModel.ts b/webview-ui/src/components/ui/hooks/useSelectedModel.ts index 3a24df2f85..b68e4809f2 100644 --- a/webview-ui/src/components/ui/hooks/useSelectedModel.ts +++ b/webview-ui/src/components/ui/hooks/useSelectedModel.ts @@ -55,7 +55,7 @@ import { qwenCodeDefaultModelId, qwenCodeModels, vercelAiGatewayDefaultModelId, - BEDROCK_CLAUDE_SONNET_4_MODEL_ID, + BEDROCK_1M_CONTEXT_MODEL_IDS, deepInfraDefaultModelId, } from "@roo-code/types" @@ -200,8 +200,8 @@ function getSelectedModel({ } } - // Apply 1M context for Claude Sonnet 4 when enabled - if (id === BEDROCK_CLAUDE_SONNET_4_MODEL_ID && apiConfiguration.awsBedrock1MContext && baseInfo) { + // Apply 1M context for Claude Sonnet 4 / 4.5 when enabled + if (BEDROCK_1M_CONTEXT_MODEL_IDS.includes(id as any) && apiConfiguration.awsBedrock1MContext && baseInfo) { // Create a new ModelInfo object with updated context window const info: ModelInfo = { ...baseInfo,