diff --git a/litellm/anthropic_beta_headers_manager.py b/litellm/anthropic_beta_headers_manager.py index efa57ca0586..97d223088fa 100644 --- a/litellm/anthropic_beta_headers_manager.py +++ b/litellm/anthropic_beta_headers_manager.py @@ -367,6 +367,42 @@ def update_headers_with_filtered_beta( return headers +def update_request_with_filtered_beta( + headers: dict, + request_data: dict, + provider: str, +) -> tuple[dict, dict]: + """ + Update both headers and request body beta fields based on provider support. + Modifies both dicts in place and returns them. + + Args: + headers: Request headers dict (will be modified in place) + request_data: Request body dict (will be modified in place) + provider: Provider name + + Returns: + Tuple of (updated headers, updated request_data) + """ + headers = update_headers_with_filtered_beta(headers=headers, provider=provider) + + existing_body_betas = request_data.get("anthropic_beta") + if not existing_body_betas: + return headers, request_data + + filtered_body_betas = filter_and_transform_beta_headers( + beta_headers=existing_body_betas, + provider=provider, + ) + + if filtered_body_betas: + request_data["anthropic_beta"] = filtered_body_betas + else: + request_data.pop("anthropic_beta", None) + + return headers, request_data + + def get_unsupported_headers(provider: str) -> List[str]: """ Get all beta headers that are unsupported by a provider (have null values in mapping). diff --git a/litellm/llms/anthropic/chat/handler.py b/litellm/llms/anthropic/chat/handler.py index 72cc7ecd9cc..5eebebc2e23 100644 --- a/litellm/llms/anthropic/chat/handler.py +++ b/litellm/llms/anthropic/chat/handler.py @@ -23,6 +23,9 @@ import litellm.litellm_core_utils import litellm.types import litellm.types.utils +from litellm.anthropic_beta_headers_manager import ( + update_request_with_filtered_beta, +) from litellm.constants import RESPONSE_FORMAT_TOOL_NAME from litellm.litellm_core_utils.core_helpers import map_finish_reason from litellm.llms.custom_httpx.http_handler import ( @@ -58,9 +61,6 @@ from ...base import BaseLLM from ..common_utils import AnthropicError, process_anthropic_headers -from litellm.anthropic_beta_headers_manager import ( - update_headers_with_filtered_beta, -) from .transformation import AnthropicConfig if TYPE_CHECKING: @@ -339,10 +339,6 @@ def completion( litellm_params=litellm_params, ) - headers = update_headers_with_filtered_beta( - headers=headers, provider=custom_llm_provider - ) - config = ProviderConfigManager.get_provider_chat_config( model=model, provider=LlmProviders(custom_llm_provider), @@ -360,6 +356,12 @@ def completion( headers=headers, ) + headers, data = update_request_with_filtered_beta( + headers=headers, + request_data=data, + provider=custom_llm_provider, + ) + ## LOGGING logging_obj.pre_call( input=messages, diff --git a/tests/test_litellm/test_anthropic_beta_headers_filtering.py b/tests/test_litellm/test_anthropic_beta_headers_filtering.py index a2c5608828a..447419b27d7 100644 --- a/tests/test_litellm/test_anthropic_beta_headers_filtering.py +++ b/tests/test_litellm/test_anthropic_beta_headers_filtering.py @@ -17,6 +17,7 @@ import litellm from litellm.anthropic_beta_headers_manager import ( filter_and_transform_beta_headers, + update_request_with_filtered_beta, ) @@ -116,6 +117,32 @@ def test_unknown_headers_filtered_out(self, provider): unknown not in filtered ), f"Unknown header '{unknown}' should be filtered out for {provider}" + def test_update_request_with_filtered_beta_vertex_ai(self): + """Test combined filtering for both HTTP headers and request body betas.""" + headers = { + "anthropic-beta": "files-api-2025-04-14,context-management-2025-06-27,code-execution-2025-05-22" + } + request_data = { + "anthropic_beta": [ + "files-api-2025-04-14", + "context-management-2025-06-27", + "code-execution-2025-05-22", + ] + } + + filtered_headers, filtered_request_data = update_request_with_filtered_beta( + headers=headers, + request_data=request_data, + provider="vertex_ai", + ) + + assert ( + filtered_headers.get("anthropic-beta") == "context-management-2025-06-27" + ) + assert filtered_request_data.get("anthropic_beta") == [ + "context-management-2025-06-27" + ] + @pytest.mark.asyncio async def test_anthropic_messages_http_headers_filtering(self): """Test that Anthropic messages API filters HTTP headers correctly."""