From ff9fbe7fe25792727ae4894ecd3bd189e73b7f98 Mon Sep 17 00:00:00 2001 From: Ishaan Jaffer Date: Sat, 14 Feb 2026 12:00:48 -0800 Subject: [PATCH] test_other_constraints_preserved --- ...odel_prices_and_context_window_backup.json | 60 ------------------- .../test_anthropic_structured_output.py | 48 ++++++++------- 2 files changed, 27 insertions(+), 81 deletions(-) diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index 27dec38ce9..95d8ba2ff6 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -1113,66 +1113,6 @@ "supports_vision": true, "tool_use_system_prompt_tokens": 346 }, - "au.anthropic.claude-opus-4-6-v1:0": { - "cache_creation_input_token_cost": 6.875e-06, - "cache_creation_input_token_cost_above_200k_tokens": 1.375e-05, - "cache_read_input_token_cost": 5.5e-07, - "cache_read_input_token_cost_above_200k_tokens": 1.1e-06, - "input_cost_per_token": 5.5e-06, - "input_cost_per_token_above_200k_tokens": 1.1e-05, - "litellm_provider": "bedrock_converse", - "max_input_tokens": 200000, - "max_output_tokens": 128000, - "max_tokens": 128000, - "mode": "chat", - "output_cost_per_token": 2.75e-05, - "output_cost_per_token_above_200k_tokens": 4.125e-05, - "search_context_cost_per_query": { - "search_context_size_high": 0.01, - "search_context_size_low": 0.01, - "search_context_size_medium": 0.01 - }, - "supports_assistant_prefill": false, - "supports_computer_use": true, - "supports_function_calling": true, - "supports_pdf_input": true, - "supports_prompt_caching": true, - "supports_reasoning": true, - "supports_response_schema": true, - "supports_tool_choice": true, - "supports_vision": true, - "tool_use_system_prompt_tokens": 346 - }, - "au.anthropic.claude-opus-4-6-v1:0": { - "cache_creation_input_token_cost": 6.875e-06, - "cache_creation_input_token_cost_above_200k_tokens": 1.375e-05, - "cache_read_input_token_cost": 5.5e-07, - "cache_read_input_token_cost_above_200k_tokens": 1.1e-06, - "input_cost_per_token": 5.5e-06, - "input_cost_per_token_above_200k_tokens": 1.1e-05, - "litellm_provider": "bedrock_converse", - "max_input_tokens": 200000, - "max_output_tokens": 128000, - "max_tokens": 128000, - "mode": "chat", - "output_cost_per_token": 2.75e-05, - "output_cost_per_token_above_200k_tokens": 4.125e-05, - "search_context_cost_per_query": { - "search_context_size_high": 0.01, - "search_context_size_low": 0.01, - "search_context_size_medium": 0.01 - }, - "supports_assistant_prefill": false, - "supports_computer_use": true, - "supports_function_calling": true, - "supports_pdf_input": true, - "supports_prompt_caching": true, - "supports_reasoning": true, - "supports_response_schema": true, - "supports_tool_choice": true, - "supports_vision": true, - "tool_use_system_prompt_tokens": 346 - }, "anthropic.claude-sonnet-4-20250514-v1:0": { "cache_creation_input_token_cost": 3.75e-06, "cache_read_input_token_cost": 3e-07, diff --git a/tests/test_litellm/llms/anthropic/test_anthropic_structured_output.py b/tests/test_litellm/llms/anthropic/test_anthropic_structured_output.py index 7f6b68881d..521da6e8c6 100644 --- a/tests/test_litellm/llms/anthropic/test_anthropic_structured_output.py +++ b/tests/test_litellm/llms/anthropic/test_anthropic_structured_output.py @@ -5,9 +5,10 @@ This test file verifies that Pydantic models with various constraints are properly converted to Anthropic-compatible JSON schemas. """ +from typing import List + import pytest from pydantic import BaseModel, Field -from typing import List class TestAnthropicStructuredOutput: @@ -23,7 +24,7 @@ class TestAnthropicStructuredOutput: Related issue: https://github.com/BerriAI/litellm/issues/19444 """ from litellm.llms.anthropic.chat.transformation import AnthropicConfig - + # Define a Pydantic model with max_length on a List field class ResponseModel(BaseModel): items: List[str] = Field(max_length=5, description="List of items") @@ -130,40 +131,45 @@ class TestAnthropicStructuredOutput: def test_other_constraints_preserved(self): """ - Test that other valid constraints are preserved. + Test that string and numeric constraints are moved to description. + + Anthropic's output_format API doesn't support minLength/maxLength for + strings or minimum/maximum for numbers. Per Anthropic's SDK approach, + these constraints are removed from the schema and added to the + description text instead. """ from litellm.llms.anthropic.chat.transformation import AnthropicConfig - + class ResponseModel(BaseModel): name: str = Field(max_length=100, min_length=1, description="Name") age: int = Field(ge=0, le=150, description="Age") items: List[str] = Field(description="Items list") - + config = AnthropicConfig() json_schema = config.get_json_schema_from_pydantic_object(ResponseModel) - + response_format = { "type": "json_schema", - "json_schema": json_schema["json_schema"] + "json_schema": json_schema["json_schema"], } - + output_format = config.map_response_format_to_anthropic_output_format( response_format ) - + assert output_format is not None transformed_schema = output_format["schema"] - - # String constraints should be preserved + + # String constraints moved to description (not preserved in schema) name_schema = transformed_schema["properties"]["name"] - assert "maxLength" in name_schema - assert "minLength" in name_schema - assert name_schema["maxLength"] == 100 - assert name_schema["minLength"] == 1 - - # Number constraints should be preserved + assert "maxLength" not in name_schema + assert "minLength" not in name_schema + assert "maximum length: 100" in name_schema["description"] + assert "minimum length: 1" in name_schema["description"] + + # Number constraints moved to description (not preserved in schema) age_schema = transformed_schema["properties"]["age"] - assert "minimum" in age_schema - assert "maximum" in age_schema - assert age_schema["minimum"] == 0 - assert age_schema["maximum"] == 150 + assert "minimum" not in age_schema + assert "maximum" not in age_schema + assert "minimum value: 0" in age_schema["description"] + assert "maximum value: 150" in age_schema["description"]