diff --git a/litellm/llms/anthropic/common_utils.py b/litellm/llms/anthropic/common_utils.py index e36658825b1..d1ad32ee0a8 100644 --- a/litellm/llms/anthropic/common_utils.py +++ b/litellm/llms/anthropic/common_utils.py @@ -1254,9 +1254,7 @@ class AnthropicModelInfo(BaseLLMModelInfo): wif_minted: bool = False, context_1m_requested: bool = False, ) -> dict: - betas: Final[set[str]] = set() - if context_1m_requested: - betas.add(ANTHROPIC_BETA_HEADER_VALUES.CONTEXT_1M_2025_08_07.value) + betas: Final = set() # Anthropic no longer requires the prompt-caching beta header # Prompt caching now works automatically when cache_control is used in messages # Reference: https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching @@ -1313,6 +1311,7 @@ class AnthropicModelInfo(BaseLLMModelInfo): betas.update(user_anthropic_beta_headers) all_betas: Final = betas.union( + (ANTHROPIC_BETA_HEADER_VALUES.CONTEXT_1M_2025_08_07.value,) if context_1m_requested else (), (ANTHROPIC_THINKING_DISPLAY_UPDATES_BETA_HEADER,) if is_thinking_display_updates_used else (), (ANTHROPIC_MID_CONVERSATION_TOOL_CHANGES_BETA_HEADER,) if is_mid_conversation_tool_change_used else (), ) diff --git a/tests/unit/llms/anthropic/chat/test_anthropic_chat_transformation.py b/tests/unit/llms/anthropic/chat/test_anthropic_chat_transformation.py index 6fe5be19fb9..41879e67654 100644 --- a/tests/unit/llms/anthropic/chat/test_anthropic_chat_transformation.py +++ b/tests/unit/llms/anthropic/chat/test_anthropic_chat_transformation.py @@ -9827,14 +9827,17 @@ def test_transform_request_treats_context_1m_model_as_its_base_model(optional_pa headers={}, ) - assert transform("claude-sonnet-4-6[1m]") == transform("claude-sonnet-4-6") + assert transform("claude-sonnet-5-5[1m]") == transform("claude-sonnet-5-5") @pytest.mark.parametrize( "model,expected_betas", [ - ("anthropic/claude-sonnet-4-6[1m]", {"context-1m-2025-08-07", "interleaved-thinking-2025-05-14"}), - ("anthropic/claude-sonnet-4-6", {"interleaved-thinking-2025-05-14"}), + ( + "anthropic/claude-sonnet-5-5[1m]", + {ANTHROPIC_BETA_HEADER_VALUES.CONTEXT_1M_2025_08_07.value, "interleaved-thinking-2025-05-14"}, + ), + ("anthropic/claude-sonnet-5-5", {"interleaved-thinking-2025-05-14"}), ], ) async def test_acompletion_context_1m_suffix_sends_base_model_with_beta( @@ -9852,7 +9855,7 @@ async def test_acompletion_context_1m_suffix_sends_base_model_with_beta( "id": "msg_context_1m", "type": "message", "role": "assistant", - "model": "claude-sonnet-4-6", + "model": "claude-sonnet-5-5", "content": [{"type": "text", "text": "hi"}], "stop_reason": "end_turn", "usage": {"input_tokens": 1, "output_tokens": 1}, @@ -9867,5 +9870,5 @@ async def test_acompletion_context_1m_suffix_sends_base_model_with_beta( ) request: Final = route.calls.last.request - assert json.loads(request.content)["model"] == "claude-sonnet-4-6" + assert json.loads(request.content)["model"] == "claude-sonnet-5-5" assert {beta.strip() for beta in request.headers["anthropic-beta"].split(",")} == expected_betas diff --git a/tests/unit/llms/anthropic/pass_through/messages/test_anthropic_messages_context_1m.py b/tests/unit/llms/anthropic/pass_through/messages/test_anthropic_messages_context_1m.py index 4525769a7cf..0b5a8bec354 100644 --- a/tests/unit/llms/anthropic/pass_through/messages/test_anthropic_messages_context_1m.py +++ b/tests/unit/llms/anthropic/pass_through/messages/test_anthropic_messages_context_1m.py @@ -6,13 +6,36 @@ import respx import litellm from litellm import Router +from litellm.llms.anthropic.pass_through.messages.transformation import AnthropicMessagesConfig +from litellm.types.llms.anthropic import ANTHROPIC_BETA_HEADER_VALUES + + +@pytest.mark.parametrize("model,expects_context_1m", [("claude-sonnet-5-5[1m]", True), ("claude-sonnet-5-5", False)]) +def test_sync_messages_environment_adds_context_1m_beta_only_for_suffixed_model( + model: str, expects_context_1m: bool +) -> None: + headers, _ = AnthropicMessagesConfig().validate_anthropic_messages_environment( + headers={"anthropic-beta": "interleaved-thinking-2025-05-14"}, + model=model, + messages=[{"role": "user", "content": "hi"}], + optional_params={}, + litellm_params={}, + api_key="test", + ) + + betas: Final = {beta.strip() for beta in headers["anthropic-beta"].split(",")} + assert (ANTHROPIC_BETA_HEADER_VALUES.CONTEXT_1M_2025_08_07.value in betas) is expects_context_1m + assert "interleaved-thinking-2025-05-14" in betas @pytest.mark.parametrize( "deployment_model,expected_betas", [ - ("anthropic/claude-sonnet-4-6[1m]", {"context-1m-2025-08-07", "interleaved-thinking-2025-05-14"}), - ("anthropic/claude-sonnet-4-6", {"interleaved-thinking-2025-05-14"}), + ( + "anthropic/claude-sonnet-5-5[1m]", + {ANTHROPIC_BETA_HEADER_VALUES.CONTEXT_1M_2025_08_07.value, "interleaved-thinking-2025-05-14"}, + ), + ("anthropic/claude-sonnet-5-5", {"interleaved-thinking-2025-05-14"}), ], ) async def test_router_messages_context_1m_deployment_sends_base_model_with_beta( @@ -30,7 +53,7 @@ async def test_router_messages_context_1m_deployment_sends_base_model_with_beta( "id": "msg_context_1m", "type": "message", "role": "assistant", - "model": "claude-sonnet-4-6", + "model": "claude-sonnet-5-5", "content": [{"type": "text", "text": "hi"}], "stop_reason": "end_turn", "usage": {"input_tokens": 1, "output_tokens": 1}, @@ -39,19 +62,19 @@ async def test_router_messages_context_1m_deployment_sends_base_model_with_beta( router: Final = Router( model_list=[ { - "model_name": "claude-sonnet-4-6[1m]", + "model_name": "claude-sonnet-5-5[1m]", "litellm_params": {"model": deployment_model, "api_key": "test"}, } ] ) await router.aanthropic_messages( - model="claude-sonnet-4-6[1m]", + model="claude-sonnet-5-5[1m]", messages=[{"role": "user", "content": "hi"}], max_tokens=16, extra_headers={"anthropic-beta": "interleaved-thinking-2025-05-14"}, ) request: Final = route.calls.last.request - assert json.loads(request.content)["model"] == "claude-sonnet-4-6" + assert json.loads(request.content)["model"] == "claude-sonnet-5-5" assert {beta.strip() for beta in request.headers["anthropic-beta"].split(",")} == expected_betas diff --git a/tests/unit/llms/anthropic/test_anthropic_common_utils.py b/tests/unit/llms/anthropic/test_anthropic_common_utils.py index 20afc5b7e40..2ee3644dc76 100644 --- a/tests/unit/llms/anthropic/test_anthropic_common_utils.py +++ b/tests/unit/llms/anthropic/test_anthropic_common_utils.py @@ -4524,12 +4524,12 @@ def test_shared_legacy_thinking_translation_drops_a_non_numeric_budget_under_dro @pytest.mark.parametrize( "model,base_model", [ - ("claude-sonnet-4-6[1m]", "claude-sonnet-4-6"), - ("claude-sonnet-4-6[1M]", "claude-sonnet-4-6"), - ("claude-sonnet-4-6", "claude-sonnet-4-6"), - ("claude-[1m]-sonnet-4-6", "claude-[1m]-sonnet-4-6"), - ("claude-sonnet-4-6[1m][1m]", "claude-sonnet-4-6[1m]"), - ("claude-sonnet-4-6[200k]", "claude-sonnet-4-6[200k]"), + ("claude-sonnet-5-5[1m]", "claude-sonnet-5-5"), + ("claude-sonnet-5-5[1M]", "claude-sonnet-5-5"), + ("claude-sonnet-5-5", "claude-sonnet-5-5"), + ("claude-[1m]-sonnet-5-5", "claude-[1m]-sonnet-5-5"), + ("claude-sonnet-5-5[1m][1m]", "claude-sonnet-5-5[1m]"), + ("claude-sonnet-5-5[200k]", "claude-sonnet-5-5[200k]"), ], ) def test_context_1m_suffix_is_only_a_trailing_marker(model: str, base_model: str) -> None: @@ -4539,11 +4539,12 @@ def test_context_1m_suffix_is_only_a_trailing_marker(model: str, base_model: str assert has_context_1m_suffix(model) is (model != base_model) -@pytest.mark.parametrize("model,expects_context_1m", [("claude-sonnet-4-6[1m]", True), ("claude-sonnet-4-6", False)]) +@pytest.mark.parametrize("model,expects_context_1m", [("claude-sonnet-5-5[1m]", True), ("claude-sonnet-5-5", False)]) def test_validate_environment_adds_context_1m_beta_only_for_suffixed_model( model: str, expects_context_1m: bool ) -> None: from litellm.llms.anthropic.common_utils import AnthropicModelInfo + from litellm.types.llms.anthropic import ANTHROPIC_BETA_HEADER_VALUES headers: Final = AnthropicModelInfo().validate_environment( headers={"anthropic-beta": "interleaved-thinking-2025-05-14"}, @@ -4555,5 +4556,5 @@ def test_validate_environment_adds_context_1m_beta_only_for_suffixed_model( ) betas: Final = {beta.strip() for beta in headers["anthropic-beta"].split(",")} - assert ("context-1m-2025-08-07" in betas) is expects_context_1m + assert (ANTHROPIC_BETA_HEADER_VALUES.CONTEXT_1M_2025_08_07.value in betas) is expects_context_1m assert "interleaved-thinking-2025-05-14" in betas