fix: enable 1M context window for Claude 3.5 Sonnet models

- Added support for claude-sonnet-4-5 (Claude 3.5 Sonnet) in Anthropic provider's 1M context check
- Added Claude 3.5 Sonnet model IDs to BEDROCK_1M_CONTEXT_MODEL_IDS array
- Added comprehensive tests for both Anthropic and Bedrock providers
- Fixes issue where Claude 3.5 Sonnet showed 200K instead of 1M tokens when 1M context was enabled

Fixes #8417
This commit is contained in:
Roo Code 2025-09-30 16:13:05 +00:00
parent 9f41ee098d
commit 3b22cd02f4
5 changed files with 100 additions and 3 deletions

View file

@ -461,4 +461,6 @@ export const BEDROCK_CLAUDE_SONNET_4_MODEL_ID = "anthropic.claude-sonnet-4-20250
export const BEDROCK_1M_CONTEXT_MODEL_IDS = [
"anthropic.claude-sonnet-4-20250514-v1:0",
"anthropic.claude-sonnet-4-5-20250929-v1:0",
"anthropic.claude-3-5-sonnet-20241022-v2:0",
"anthropic.claude-3-5-sonnet-20240620-v1:0",
] as const

1
tmp-pr-8415/Roo-Code Submodule

@ -0,0 +1 @@
Subproject commit 2c31616e8ade2a3995c3beda2d32d82fac17bf93

1
tmp/pr-8380-Roo-Code Submodule

@ -0,0 +1 @@
Subproject commit 815444000508f67c41ba51175f1d3061364ea0bc

View file

@ -499,7 +499,7 @@ describe("useSelectedModel", () => {
expect(result.current.info?.contextWindow).toBe(200_000)
})
it("should not affect context window for non-Claude Sonnet 4 Bedrock models", () => {
it("should enable 1M context window for Bedrock Claude 3.5 Sonnet when awsBedrock1MContext is true", () => {
const apiConfiguration: ProviderSettings = {
apiProvider: "bedrock",
apiModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
@ -510,6 +510,99 @@ describe("useSelectedModel", () => {
const { result } = renderHook(() => useSelectedModel(apiConfiguration), { wrapper })
expect(result.current.id).toBe("anthropic.claude-3-5-sonnet-20241022-v2:0")
expect(result.current.info?.contextWindow).toBe(1_000_000)
})
it("should enable 1M context window for older Bedrock Claude 3.5 Sonnet when awsBedrock1MContext is true", () => {
const apiConfiguration: ProviderSettings = {
apiProvider: "bedrock",
apiModelId: "anthropic.claude-3-5-sonnet-20240620-v1:0",
awsBedrock1MContext: true,
}
const wrapper = createWrapper()
const { result } = renderHook(() => useSelectedModel(apiConfiguration), { wrapper })
expect(result.current.id).toBe("anthropic.claude-3-5-sonnet-20240620-v1:0")
expect(result.current.info?.contextWindow).toBe(1_000_000)
})
it("should not affect context window for non-Claude Sonnet models", () => {
const apiConfiguration: ProviderSettings = {
apiProvider: "bedrock",
apiModelId: "anthropic.claude-3-opus-20240229-v1:0",
awsBedrock1MContext: true,
}
const wrapper = createWrapper()
const { result } = renderHook(() => useSelectedModel(apiConfiguration), { wrapper })
expect(result.current.id).toBe("anthropic.claude-3-opus-20240229-v1:0")
expect(result.current.info?.contextWindow).toBe(200_000)
})
})
describe("anthropic provider with 1M context", () => {
beforeEach(() => {
mockUseRouterModels.mockReturnValue({
data: {
openrouter: {},
requesty: {},
glama: {},
unbound: {},
litellm: {},
"io-intelligence": {},
},
isLoading: false,
isError: false,
} as any)
mockUseOpenRouterModelProviders.mockReturnValue({
data: {},
isLoading: false,
isError: false,
} as any)
})
it("should enable 1M context window for Claude Sonnet 4 when anthropicBeta1MContext is true", () => {
const apiConfiguration: ProviderSettings = {
apiProvider: "anthropic",
apiModelId: "claude-sonnet-4-20250514",
anthropicBeta1MContext: true,
}
const wrapper = createWrapper()
const { result } = renderHook(() => useSelectedModel(apiConfiguration), { wrapper })
expect(result.current.id).toBe("claude-sonnet-4-20250514")
expect(result.current.info?.contextWindow).toBe(1_000_000)
})
it("should enable 1M context window for Claude 3.5 Sonnet (claude-sonnet-4-5) when anthropicBeta1MContext is true", () => {
const apiConfiguration: ProviderSettings = {
apiProvider: "anthropic",
apiModelId: "claude-sonnet-4-5",
anthropicBeta1MContext: true,
}
const wrapper = createWrapper()
const { result } = renderHook(() => useSelectedModel(apiConfiguration), { wrapper })
expect(result.current.id).toBe("claude-sonnet-4-5")
expect(result.current.info?.contextWindow).toBe(1_000_000)
})
it("should use default context window when anthropicBeta1MContext is false", () => {
const apiConfiguration: ProviderSettings = {
apiProvider: "anthropic",
apiModelId: "claude-sonnet-4-5",
anthropicBeta1MContext: false,
}
const wrapper = createWrapper()
const { result } = renderHook(() => useSelectedModel(apiConfiguration), { wrapper })
expect(result.current.id).toBe("claude-sonnet-4-5")
expect(result.current.info?.contextWindow).toBe(200_000)
})
})

View file

@ -364,10 +364,10 @@ function getSelectedModel({
const id = apiConfiguration.apiModelId ?? anthropicDefaultModelId
const baseInfo = anthropicModels[id as keyof typeof anthropicModels]
// Apply 1M context beta tier pricing for Claude Sonnet 4
// Apply 1M context beta tier pricing for Claude Sonnet 4 and 4.5
if (
provider === "anthropic" &&
id === "claude-sonnet-4-20250514" &&
(id === "claude-sonnet-4-20250514" || id === "claude-sonnet-4-5") &&
apiConfiguration.anthropicBeta1MContext &&
baseInfo
) {