From 8a38a4f76caabea0ad2184ee0e7126836a275801 Mon Sep 17 00:00:00 2001 From: rahul dhanawade Date: Wed, 18 Feb 2026 03:20:57 +0530 Subject: [PATCH] fix(vertex_ai): remove unsupported output_config/format params --- .../anthropic/transformation.py | 14 +------ .../test_vertex_anthropic_transformation.py | 28 ++++++++++++++ tests/test_vertex_anthropic_transformation.py | 38 +++++++++++++++++++ 3 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 tests/test_litellm/llms/vertex_ai/vertex_ai_partner_models/anthropic/test_vertex_anthropic_transformation.py create mode 100644 tests/test_vertex_anthropic_transformation.py diff --git a/litellm/llms/vertex_ai/vertex_ai_partner_models/anthropic/transformation.py b/litellm/llms/vertex_ai/vertex_ai_partner_models/anthropic/transformation.py index d9605385293..a4627949243 100644 --- a/litellm/llms/vertex_ai/vertex_ai_partner_models/anthropic/transformation.py +++ b/litellm/llms/vertex_ai/vertex_ai_partner_models/anthropic/transformation.py @@ -108,18 +108,8 @@ class VertexAIAnthropicConfig(AnthropicConfig): # VertexAI doesn't support output_format parameter, remove it if present data.pop("output_format", None) - # VertexAI doesn't support output_config parameter, remove it if present - if "output_config" in data: - output_config = data.pop("output_config") - if isinstance(output_config, dict): - # Extract the schema from Anthropic format: - # {"format": {"type": "json_schema", "schema": {...}}} - format_obj = output_config.get("format", {}) - if format_obj.get("type") == "json_schema": - schema = format_obj.get("schema") - if schema: - # Map to Vertex AI's GA parameter: response_schema - data["response_schema"] = schema + # We must remove them to avoid "Extra inputs are not permitted" errors. + data.pop("output_config", None) tools = optional_params.get("tools") tool_search_used = self.is_tool_search_used(tools) diff --git a/tests/test_litellm/llms/vertex_ai/vertex_ai_partner_models/anthropic/test_vertex_anthropic_transformation.py b/tests/test_litellm/llms/vertex_ai/vertex_ai_partner_models/anthropic/test_vertex_anthropic_transformation.py new file mode 100644 index 00000000000..fb14ffd0550 --- /dev/null +++ b/tests/test_litellm/llms/vertex_ai/vertex_ai_partner_models/anthropic/test_vertex_anthropic_transformation.py @@ -0,0 +1,28 @@ +import pytest +from litellm.llms.vertex_ai.vertex_ai_partner_models.anthropic.transformation import VertexAIAnthropicConfig + +def test_vertex_anthropic_unsupported_params_removal(): + """ + Test that unsupported params are removed for Claude on Vertex AI + to fix Issue #21407. + """ + config = VertexAIAnthropicConfig() + + messages = [{"role": "user", "content": "Hello"}] + optional_params = { + "output_config": {"effort": "high"}, + "output_format": {"type": "json_schema"} + } + + transformed_data = config.transform_request( + model="claude-3-sonnet", + messages=messages, + optional_params=optional_params, + litellm_params={}, + headers={} + ) + + # Assertions: Verify they are GONE, not remapped + assert "output_config" not in transformed_data + assert "output_format" not in transformed_data + assert "response_schema" not in transformed_data \ No newline at end of file diff --git a/tests/test_vertex_anthropic_transformation.py b/tests/test_vertex_anthropic_transformation.py new file mode 100644 index 00000000000..f4a9ddb737b --- /dev/null +++ b/tests/test_vertex_anthropic_transformation.py @@ -0,0 +1,38 @@ +import pytest +from litellm.llms.vertex_ai.vertex_ai_partner_models.anthropic.transformation import VertexAIAnthropicConfig + +def test_vertex_anthropic_output_config_transformation(): + """ + Test that output_config is correctly remapped to response_schema + for Claude on Vertex AI to fix Issue #21407. + """ + config = VertexAIAnthropicConfig() + + # 1. Setup mock Anthropic-style request data + messages = [{"role": "user", "content": "Generate a JSON response"}] + optional_params = { + "output_config": { + "format": { + "type": "json_schema", + "schema": { + "type": "object", + "properties": {"name": {"type": "string"}} + } + } + } + } + + # 2. Run transformation + transformed_data = config.transform_request( + model="claude-3-sonnet", + messages=messages, + optional_params=optional_params, + litellm_params={}, + headers={} + ) + + # 3. Assertions + assert "output_config" not in transformed_data, "output_config must be removed" + assert "response_schema" in transformed_data, "response_schema must be present" + assert transformed_data["response_schema"]["type"] == "object" + assert "name" in transformed_data["response_schema"]["properties"] \ No newline at end of file