From 8363a26d2ee07a7f54a701af3d2184bd3f62b4f1 Mon Sep 17 00:00:00 2001 From: Sameer Kankute Date: Fri, 30 Jan 2026 17:33:40 +0530 Subject: [PATCH] Fix: remove unsupported prompt-caching-scope-2026-01-05 header for vertex ai --- .../transformation.py | 25 ++++++++++++++ litellm/types/llms/anthropic.py | 2 +- ...partner_models_anthropic_transformation.py | 33 ++++++++++++++++++- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/litellm/llms/vertex_ai/vertex_ai_partner_models/anthropic/experimental_pass_through/transformation.py b/litellm/llms/vertex_ai/vertex_ai_partner_models/anthropic/experimental_pass_through/transformation.py index fc75376c0cb..9b8ff3ecc2d 100644 --- a/litellm/llms/vertex_ai/vertex_ai_partner_models/anthropic/experimental_pass_through/transformation.py +++ b/litellm/llms/vertex_ai/vertex_ai_partner_models/anthropic/experimental_pass_through/transformation.py @@ -7,6 +7,7 @@ from litellm.types.llms.anthropic import ( ANTHROPIC_BETA_HEADER_VALUES, ANTHROPIC_HOSTED_TOOLS, + ANTHROPIC_PROMPT_CACHING_SCOPE_BETA_HEADER, ) from litellm.types.llms.anthropic_tool_search import get_tool_search_beta_header from litellm.types.llms.vertex_ai import VertexPartnerProvider @@ -65,6 +66,10 @@ def validate_anthropic_messages_environment( if existing_beta: beta_values.update(b.strip() for b in existing_beta.split(",")) + # Use the helper to remove unsupported beta headers + self.remove_unsupported_beta(headers) + beta_values.discard(ANTHROPIC_PROMPT_CACHING_SCOPE_BETA_HEADER) + # Check for web search tool for tool in tools: if isinstance(tool, dict) and tool.get("type", "").startswith(ANTHROPIC_HOSTED_TOOLS.WEB_SEARCH.value): @@ -123,3 +128,23 @@ def transform_anthropic_messages_request( ) # do not pass output_format in request body to vertex ai - vertex ai does not support output_format as yet return anthropic_messages_request + + def remove_unsupported_beta(self, headers: dict) -> None: + """ + Helper method to remove unsupported beta headers from the beta headers. + Modifies headers in place. + """ + unsupported_beta_headers = [ + ANTHROPIC_PROMPT_CACHING_SCOPE_BETA_HEADER + ] + existing_beta = headers.get("anthropic-beta") + if existing_beta: + filtered_beta = [ + b.strip() + for b in existing_beta.split(",") + if b.strip() not in unsupported_beta_headers + ] + if filtered_beta: + headers["anthropic-beta"] = ",".join(filtered_beta) + elif "anthropic-beta" in headers: + del headers["anthropic-beta"] diff --git a/litellm/types/llms/anthropic.py b/litellm/types/llms/anthropic.py index 8d18322d374..eb732576f1a 100644 --- a/litellm/types/llms/anthropic.py +++ b/litellm/types/llms/anthropic.py @@ -647,4 +647,4 @@ class ANTHROPIC_BETA_HEADER_VALUES(str, Enum): ANTHROPIC_OAUTH_TOKEN_PREFIX = "sk-ant-oat" ANTHROPIC_OAUTH_BETA_HEADER = "oauth-2025-04-20" - +ANTHROPIC_PROMPT_CACHING_SCOPE_BETA_HEADER = "prompt-caching-scope-2026-01-05" \ No newline at end of file diff --git a/tests/test_litellm/llms/vertex_ai/vertex_ai_partner_models/anthropic/test_vertex_ai_partner_models_anthropic_transformation.py b/tests/test_litellm/llms/vertex_ai/vertex_ai_partner_models/anthropic/test_vertex_ai_partner_models_anthropic_transformation.py index 7b60a0a3369..3e6c6f6740c 100644 --- a/tests/test_litellm/llms/vertex_ai/vertex_ai_partner_models/anthropic/test_vertex_ai_partner_models_anthropic_transformation.py +++ b/tests/test_litellm/llms/vertex_ai/vertex_ai_partner_models/anthropic/test_vertex_ai_partner_models_anthropic_transformation.py @@ -37,8 +37,9 @@ def test_get_supported_params_thinking(): def test_vertex_ai_anthropic_web_search_header_in_completion(): """Test that web search tool adds the required beta header for Vertex AI completion requests""" from unittest.mock import MagicMock, patch + from litellm.llms.anthropic.common_utils import AnthropicModelInfo - + # Create the config instance model_info = AnthropicModelInfo() @@ -259,3 +260,33 @@ def test_vertex_ai_anthropic_other_models_still_use_tools(): assert "tools" in result_params, "Claude 3 Sonnet should also use tool-based structured output" assert "tool_choice" in result_params, "Tool choice should be present" assert "json_mode" in result_params, "JSON mode should be enabled" + +def test_vertex_ai_partner_models_anthropic_remove_prompt_caching_scope_beta_header(): + """ + Test that remove_unsupported_beta correctly filters out prompt-caching-scope-2026-01-05 + from the anthropic-beta headers. + """ + from litellm.llms.vertex_ai.vertex_ai_partner_models.anthropic.experimental_pass_through.transformation import ( + VertexAIPartnerModelsAnthropicMessagesConfig, + ) + + # This beta header should be removed + PROMPT_CACHING_BETA_HEADER = "prompt-caching-scope-2026-01-05" + headers = { + "anthropic-beta": f"other-feature,{PROMPT_CACHING_BETA_HEADER},web-search-2025-03-05" + } + + config = VertexAIPartnerModelsAnthropicMessagesConfig() + config.remove_unsupported_beta(headers) + + beta_header = headers.get("anthropic-beta") + assert PROMPT_CACHING_BETA_HEADER not in (beta_header or ""), \ + f"{PROMPT_CACHING_BETA_HEADER} should be filtered out" + assert "other-feature" in (beta_header or ""), \ + "Other non-excluded beta headers should remain" + assert "web-search-2025-03-05" in (beta_header or ""), \ + "Other non-excluded beta headers should remain" + # If prompt-caching was the only value, header should be removed completely + headers2 = {"anthropic-beta": PROMPT_CACHING_BETA_HEADER} + config.remove_unsupported_beta(headers2) + assert "anthropic-beta" not in headers2, "Header should be removed if no supported values remain" \ No newline at end of file