From 8f60e503c1363f9d67f5719bd8634e3dd0caec22 Mon Sep 17 00:00:00 2001 From: Koushik2406 Date: Sun, 3 May 2026 21:45:42 +0530 Subject: [PATCH] feat(anthropic): support native JSON mode for Claude 4.7 and audit max_completion_tokens --- litellm/llms/anthropic/chat/transformation.py | 7 ++ tests/test_litellm/test_parity_gap.py | 71 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 tests/test_litellm/test_parity_gap.py diff --git a/litellm/llms/anthropic/chat/transformation.py b/litellm/llms/anthropic/chat/transformation.py index 35624c93b37..bdfebd429f9 100644 --- a/litellm/llms/anthropic/chat/transformation.py +++ b/litellm/llms/anthropic/chat/transformation.py @@ -1054,6 +1054,13 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig): "sonnet-4-6", "sonnet_4.6", "sonnet_4_6", + "sonnet-4.7", + "sonnet-4-7", + "sonnet_4.7", + "sonnet_4_7", + "4.7-sonnet", + "4-7-sonnet", + "4_7_sonnet", } ): _output_format = ( diff --git a/tests/test_litellm/test_parity_gap.py b/tests/test_litellm/test_parity_gap.py new file mode 100644 index 00000000000..8e1866d9726 --- /dev/null +++ b/tests/test_litellm/test_parity_gap.py @@ -0,0 +1,71 @@ + +import pytest +from litellm.llms.anthropic.chat.transformation import AnthropicConfig + +def test_anthropic_response_format_parity_claude_4_7(): + """ + Test that Claude 4.7 correctly maps response_format to native output_format. + """ + config = AnthropicConfig() + + # Test with Claude 4.7 Sonnet - typical model name format + model = "claude-4-7-sonnet-20261031" + non_default_params = { + "response_format": { + "type": "json_schema", + "json_schema": { + "name": "test", + "schema": {"type": "object", "properties": {"foo": {"type": "string"}}} + } + } + } + optional_params = {} + + mapped_params = config.map_openai_params( + non_default_params=non_default_params, + optional_params=optional_params, + model=model, + drop_params=False + ) + + # Verify it uses native output_format + assert "output_format" in mapped_params, f"Claude 4.7 should use native output_format, but it was not found in {mapped_params.keys()}" + assert mapped_params["output_format"]["type"] == "json_schema" + assert "tool_choice" not in mapped_params or mapped_params["tool_choice"]["type"] != "tool", "Should not fall back to tool calling for JSON mode on Claude 4.7" + +def test_anthropic_max_completion_tokens_parity(): + """ + Test that max_completion_tokens correctly maps to max_tokens for Anthropic. + """ + config = AnthropicConfig() + model = "claude-3-5-sonnet-20240620" + non_default_params = {"max_completion_tokens": 500} + optional_params = {} + + mapped_params = config.map_openai_params( + non_default_params=non_default_params, + optional_params=optional_params, + model=model, + drop_params=False + ) + + assert mapped_params["max_tokens"] == 500 + +def test_bedrock_max_completion_tokens_parity(): + """ + Test that max_completion_tokens correctly maps to maxTokens for Bedrock. + """ + from litellm.llms.bedrock.chat.converse_transformation import AmazonConverseConfig + config = AmazonConverseConfig() + model = "anthropic.claude-3-5-sonnet-v1:0" + non_default_params = {"max_completion_tokens": 750} + optional_params = {} + + mapped_params = config.map_openai_params( + non_default_params=non_default_params, + optional_params=optional_params, + model=model, + drop_params=False + ) + + assert mapped_params["maxTokens"] == 750