From 8818bb9b0158cba0150f49336a2ce7bfd2a170f5 Mon Sep 17 00:00:00 2001 From: iizotov Date: Mon, 29 Jun 2026 23:45:13 +1000 Subject: [PATCH] fix(bedrock): map Claude opus/sonnet 4.6+ to 1M context window The Bedrock static context table only had entries up to the 4-6 generation and capped all Claude models at 200K. Newer model IDs (opus/sonnet 4-7, 4-8) silently inherited 200K via the generic "anthropic.claude-opus-4" / "...-sonnet-4" substring fallback, contradicting the native Anthropic table in model_metadata.py which already maps these to 1M. Map opus/sonnet 4-6/4-7/4-8 to 1_000_000 on Bedrock. Haiku 4.5, sonnet 4.5, legacy Claude 4 and 3.x stay at 200K (no 1M window). Add opus-4-8 coverage and haiku/sonnet-4-5 200K guards. --- agent/bedrock_adapter.py | 17 ++++++++++++++--- tests/agent/test_bedrock_adapter.py | 19 +++++++++++++++++-- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/agent/bedrock_adapter.py b/agent/bedrock_adapter.py index d5dab7bafff2..34f3d62d83b4 100644 --- a/agent/bedrock_adapter.py +++ b/agent/bedrock_adapter.py @@ -1296,9 +1296,20 @@ def classify_bedrock_error(error_message: str) -> str: # detection is unavailable. BEDROCK_CONTEXT_LENGTHS: Dict[str, int] = { - # Anthropic Claude models on Bedrock - "anthropic.claude-opus-4-6": 200_000, - "anthropic.claude-sonnet-4-6": 200_000, + # Anthropic Claude models on Bedrock. + # The opus/sonnet 4.6+ generations expose a 1M context window on Bedrock, + # matching the native Anthropic API (see DEFAULT_CONTEXT_LENGTHS in + # agent/model_metadata.py, which already maps these to 1M). Keys are + # matched by longest-substring, so the versioned 4-6/4-7/4-8 entries win + # over the generic "anthropic.claude-opus-4" / "...-sonnet-4" fallbacks. + "anthropic.claude-opus-4-8": 1_000_000, + "anthropic.claude-opus-4-7": 1_000_000, + "anthropic.claude-opus-4-6": 1_000_000, + "anthropic.claude-sonnet-4-8": 1_000_000, + "anthropic.claude-sonnet-4-7": 1_000_000, + "anthropic.claude-sonnet-4-6": 1_000_000, + # Claude 4.5 and older Claude 4 / 3.x remain at the 200K Bedrock window. + # Haiku 4.5 specifically is 200K (no 1M window). "anthropic.claude-sonnet-4-5": 200_000, "anthropic.claude-haiku-4-5": 200_000, "anthropic.claude-opus-4": 200_000, diff --git a/tests/agent/test_bedrock_adapter.py b/tests/agent/test_bedrock_adapter.py index ac2b557aeace..7e8263c9879c 100644 --- a/tests/agent/test_bedrock_adapter.py +++ b/tests/agent/test_bedrock_adapter.py @@ -1165,13 +1165,28 @@ def test_unknown_error(self): class TestBedrockContextLength: """Test Bedrock model context length lookup.""" + def test_claude_opus_4_8(self): + from agent.bedrock_adapter import get_bedrock_context_length + # opus 4.8 exposes the 1M window on Bedrock (matches native Anthropic). + assert get_bedrock_context_length("anthropic.claude-opus-4-8-20250514-v1:0") == 1_000_000 + def test_claude_opus_4_6(self): from agent.bedrock_adapter import get_bedrock_context_length - assert get_bedrock_context_length("anthropic.claude-opus-4-6-20250514-v1:0") == 200_000 + assert get_bedrock_context_length("anthropic.claude-opus-4-6-20250514-v1:0") == 1_000_000 def test_claude_sonnet_versioned(self): from agent.bedrock_adapter import get_bedrock_context_length - assert get_bedrock_context_length("anthropic.claude-sonnet-4-6-20250514-v1:0") == 200_000 + assert get_bedrock_context_length("anthropic.claude-sonnet-4-6-20250514-v1:0") == 1_000_000 + + def test_claude_haiku_4_5_stays_200k(self): + from agent.bedrock_adapter import get_bedrock_context_length + # Haiku 4.5 has no 1M window — must stay at the 200K Bedrock limit and + # not get swept up by the opus/sonnet 4.x bump. + assert get_bedrock_context_length("anthropic.claude-haiku-4-5-20250514-v1:0") == 200_000 + + def test_claude_sonnet_4_5_stays_200k(self): + from agent.bedrock_adapter import get_bedrock_context_length + assert get_bedrock_context_length("anthropic.claude-sonnet-4-5-20250514-v1:0") == 200_000 def test_nova_pro(self): from agent.bedrock_adapter import get_bedrock_context_length