diff --git a/litellm/llms/bedrock/chat/invoke_transformations/anthropic_claude3_transformation.py b/litellm/llms/bedrock/chat/invoke_transformations/anthropic_claude3_transformation.py index f003c0ed95..53e0822979 100644 --- a/litellm/llms/bedrock/chat/invoke_transformations/anthropic_claude3_transformation.py +++ b/litellm/llms/bedrock/chat/invoke_transformations/anthropic_claude3_transformation.py @@ -103,7 +103,7 @@ class AmazonAnthropicClaudeConfig(AmazonInvokeConfig, AnthropicConfig): model=model, optional_params=optional_params, computer_tool_used=self.is_computer_tool_used(tools), - prompt_caching_set=self.is_cache_control_set(messages), + prompt_caching_set=False, file_id_used=self.is_file_id_used(messages), mcp_server_used=self.is_mcp_server_used(optional_params.get("mcp_servers")), ) diff --git a/litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py b/litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py index aea8a4b5a8..32be1a780a 100644 --- a/litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py +++ b/litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py @@ -157,7 +157,7 @@ class AmazonAnthropicClaudeMessagesConfig( model=model, optional_params=anthropic_messages_optional_request_params, computer_tool_used=anthropic_model_info.is_computer_tool_used(tools), - prompt_caching_set=anthropic_model_info.is_cache_control_set(messages_typed), + prompt_caching_set=False, file_id_used=anthropic_model_info.is_file_id_used(messages_typed), mcp_server_used=anthropic_model_info.is_mcp_server_used( anthropic_messages_optional_request_params.get("mcp_servers") diff --git a/tests/test_litellm/llms/bedrock/test_anthropic_beta_support.py b/tests/test_litellm/llms/bedrock/test_anthropic_beta_support.py index 1b9e1b5284..bd64670517 100644 --- a/tests/test_litellm/llms/bedrock/test_anthropic_beta_support.py +++ b/tests/test_litellm/llms/bedrock/test_anthropic_beta_support.py @@ -5,14 +5,19 @@ Tests that anthropic-beta headers are correctly processed and passed to AWS Bedr for enabling beta features like 1M context window, computer use tools, etc. """ -import pytest -from unittest.mock import patch, MagicMock import json +from unittest.mock import MagicMock, patch + +import pytest -from litellm.llms.bedrock.common_utils import get_anthropic_beta_from_headers from litellm.llms.bedrock.chat.converse_transformation import AmazonConverseConfig -from litellm.llms.bedrock.chat.invoke_transformations.anthropic_claude3_transformation import AmazonAnthropicClaudeConfig -from litellm.llms.bedrock.messages.invoke_transformations.anthropic_claude3_transformation import AmazonAnthropicClaudeMessagesConfig +from litellm.llms.bedrock.chat.invoke_transformations.anthropic_claude3_transformation import ( + AmazonAnthropicClaudeConfig, +) +from litellm.llms.bedrock.common_utils import get_anthropic_beta_from_headers +from litellm.llms.bedrock.messages.invoke_transformations.anthropic_claude3_transformation import ( + AmazonAnthropicClaudeMessagesConfig, +) class TestAnthropicBetaHeaderSupport: @@ -56,7 +61,8 @@ class TestAnthropicBetaHeaderSupport: ) assert "anthropic_beta" in result - assert result["anthropic_beta"] == ["context-1m-2025-08-07", "computer-use-2024-10-22"] + # Beta flags are stored as sets, so order may vary + assert set(result["anthropic_beta"]) == {"context-1m-2025-08-07", "computer-use-2024-10-22"} def test_converse_transformation_anthropic_beta(self): """Test that Converse API transformation includes anthropic_beta in additionalModelRequestFields.""" @@ -163,4 +169,122 @@ class TestAnthropicBetaHeaderSupport: ) assert "anthropic_beta" in result - assert result["anthropic_beta"] == supported_features \ No newline at end of file + # Beta flags are stored as sets, so order may vary + assert set(result["anthropic_beta"]) == set(supported_features) + + def test_prompt_caching_no_beta_header_messages_api(self): + """Test that prompt caching (cache_control) does NOT add prompt-caching-2024-07-31 beta header for Bedrock. + + Bedrock recognizes prompt caching via the request body (cache_control field), + not through beta headers. This test verifies the fix. + """ + config = AmazonAnthropicClaudeMessagesConfig() + headers = {} + + # Messages with cache_control set (prompt caching enabled) + messages = [ + { + "role": "user", + "content": [ + { + "type": "text", + "text": "Hello", + "cache_control": {"type": "ephemeral"} + } + ] + } + ] + + result = config.transform_anthropic_messages_request( + model="us.anthropic.claude-sonnet-4-5-20250929-v1:0", + messages=messages, + anthropic_messages_optional_request_params={"max_tokens": 100}, + litellm_params={}, + headers=headers + ) + + # Verify prompt-caching-2024-07-31 is NOT in anthropic_beta + if "anthropic_beta" in result: + assert "prompt-caching-2024-07-31" not in result["anthropic_beta"], ( + "prompt-caching-2024-07-31 should not be added as a beta header for Bedrock. " + "Bedrock recognizes prompt caching via cache_control in the request body, not beta headers." + ) + else: + # It's also valid if anthropic_beta is not present at all + assert True + + def test_prompt_caching_no_beta_header_chat_api(self): + """Test that prompt caching (cache_control) does NOT add prompt-caching-2024-07-31 beta header for Bedrock Chat API. + + Bedrock recognizes prompt caching via the request body (cache_control field), + not through beta headers. This test verifies the fix. + """ + config = AmazonAnthropicClaudeConfig() + headers = {} + + # Messages with cache_control set (prompt caching enabled) + messages = [ + { + "role": "user", + "content": [ + { + "type": "text", + "text": "Hello", + "cache_control": {"type": "ephemeral"} + } + ] + } + ] + + result = config.transform_request( + model="us.anthropic.claude-sonnet-4-5-20250929-v1:0", + messages=messages, + optional_params={}, + litellm_params={}, + headers=headers + ) + + # Verify prompt-caching-2024-07-31 is NOT in anthropic_beta + if "anthropic_beta" in result: + assert "prompt-caching-2024-07-31" not in result["anthropic_beta"], ( + "prompt-caching-2024-07-31 should not be added as a beta header for Bedrock. " + "Bedrock recognizes prompt caching via cache_control in the request body, not beta headers." + ) + else: + # It's also valid if anthropic_beta is not present at all + assert True + + def test_prompt_caching_with_other_beta_headers(self): + """Test that prompt caching doesn't interfere with other valid beta headers.""" + config = AmazonAnthropicClaudeMessagesConfig() + headers = {"anthropic-beta": "context-1m-2025-08-07"} + + # Messages with cache_control set + messages = [ + { + "role": "user", + "content": [ + { + "type": "text", + "text": "Hello", + "cache_control": {"type": "ephemeral"} + } + ] + } + ] + + result = config.transform_anthropic_messages_request( + model="us.anthropic.claude-sonnet-4-5-20250929-v1:0", + messages=messages, + anthropic_messages_optional_request_params={"max_tokens": 100}, + litellm_params={}, + headers=headers + ) + + # Should have the user-provided beta header but NOT prompt-caching + if "anthropic_beta" in result: + assert "context-1m-2025-08-07" in result["anthropic_beta"] + assert "prompt-caching-2024-07-31" not in result["anthropic_beta"] + else: + # If no beta headers, that's also fine + assert True \ No newline at end of file