mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-10 03:28:53 +00:00
fix(azure_ai): strip max_retries from Azure AI Anthropic /v1/messages request body (#18746)
Azure AI Foundry's Anthropic endpoint rejects max_retries, extra_body, and stream_options with "Extra inputs are not permitted". These params can leak into the request body from the router's default litellm params. The chat/completions path already strips them (transformation.py); this applies the same fix to the /v1/messages path. Fixes https://github.com/BerriAI/litellm/issues/18746
This commit is contained in:
parent
5544803b35
commit
9c2f9e95c1
2 changed files with 73 additions and 3 deletions
|
|
@ -1,6 +1,7 @@
|
|||
"""
|
||||
Azure Anthropic messages transformation config - extends AnthropicMessagesConfig with Azure authentication
|
||||
"""
|
||||
|
||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple
|
||||
|
||||
from litellm.llms.anthropic.experimental_pass_through.messages.transformation import (
|
||||
|
|
@ -163,4 +164,10 @@ class AzureAnthropicMessagesConfig(AnthropicMessagesConfig):
|
|||
headers=headers,
|
||||
)
|
||||
self._remove_scope_from_cache_control(anthropic_messages_request)
|
||||
|
||||
# Remove parameters that Azure AI Foundry's Anthropic endpoint rejects.
|
||||
# These may leak into the request body from the router's default litellm
|
||||
# params or from the proxy layer.
|
||||
for unsupported_param in ("max_retries", "extra_body", "stream_options"):
|
||||
anthropic_messages_request.pop(unsupported_param, None)
|
||||
return anthropic_messages_request
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@ class TestAzureAnthropicMessagesConfig:
|
|||
assert result["x-api-key"] == "test-api-key"
|
||||
assert "api-key" not in result
|
||||
|
||||
def test_validate_anthropic_messages_environment_converts_api_key_to_x_api_key(self):
|
||||
def test_validate_anthropic_messages_environment_converts_api_key_to_x_api_key(
|
||||
self,
|
||||
):
|
||||
"""Test that api-key header is converted to x-api-key"""
|
||||
config = AzureAnthropicMessagesConfig()
|
||||
headers = {}
|
||||
|
|
@ -231,7 +233,7 @@ class TestAzureAnthropicMessagesConfig:
|
|||
config = AzureAnthropicMessagesConfig()
|
||||
model = "claude-sonnet-4-5"
|
||||
params = config.get_supported_anthropic_messages_params(model)
|
||||
|
||||
|
||||
assert "messages" in params
|
||||
assert "model" in params
|
||||
assert "max_tokens" in params
|
||||
|
|
@ -281,7 +283,9 @@ class TestAzureAnthropicMessagesConfig:
|
|||
assert "scope" not in result["system"][0]["cache_control"]
|
||||
assert result["system"][0]["cache_control"]["type"] == "ephemeral"
|
||||
assert "scope" not in result["messages"][0]["content"][0]["cache_control"]
|
||||
assert result["messages"][0]["content"][0]["cache_control"]["type"] == "ephemeral"
|
||||
assert (
|
||||
result["messages"][0]["content"][0]["cache_control"]["type"] == "ephemeral"
|
||||
)
|
||||
|
||||
|
||||
class TestProviderConfigManagerAzureAnthropicMessages:
|
||||
|
|
@ -327,3 +331,62 @@ class TestProviderConfigManagerAzureAnthropicMessages:
|
|||
)
|
||||
|
||||
assert config is None
|
||||
|
||||
|
||||
class TestAzureAnthropicMessagesTransformRequest:
|
||||
"""Test that unsupported parameters are stripped from the request body (issue #18746)"""
|
||||
|
||||
def test_transform_request_removes_max_retries(self):
|
||||
"""Test that max_retries is removed from the request body.
|
||||
|
||||
Regression test for https://github.com/BerriAI/litellm/issues/18746
|
||||
Azure AI Foundry rejects max_retries with 'Extra inputs are not permitted'.
|
||||
"""
|
||||
config = AzureAnthropicMessagesConfig()
|
||||
model = "claude-haiku-4-5"
|
||||
messages = [{"role": "user", "content": [{"type": "text", "text": "hi"}]}]
|
||||
optional_params = {
|
||||
"max_tokens": 1000,
|
||||
"max_retries": 0,
|
||||
}
|
||||
litellm_params = GenericLiteLLMParams()
|
||||
headers = {}
|
||||
|
||||
result = config.transform_anthropic_messages_request(
|
||||
model=model,
|
||||
messages=messages,
|
||||
anthropic_messages_optional_request_params=optional_params,
|
||||
litellm_params=litellm_params,
|
||||
headers=headers,
|
||||
)
|
||||
|
||||
assert "max_retries" not in result
|
||||
assert result["model"] == model
|
||||
assert result["max_tokens"] == 1000
|
||||
assert result["messages"] == messages
|
||||
|
||||
def test_transform_request_removes_extra_body_and_stream_options(self):
|
||||
"""Test that extra_body and stream_options are also removed."""
|
||||
config = AzureAnthropicMessagesConfig()
|
||||
model = "claude-haiku-4-5"
|
||||
messages = [{"role": "user", "content": [{"type": "text", "text": "hi"}]}]
|
||||
optional_params = {
|
||||
"max_tokens": 1000,
|
||||
"extra_body": {"foo": "bar"},
|
||||
"stream_options": {"include_usage": True},
|
||||
}
|
||||
litellm_params = GenericLiteLLMParams()
|
||||
headers = {}
|
||||
|
||||
result = config.transform_anthropic_messages_request(
|
||||
model=model,
|
||||
messages=messages,
|
||||
anthropic_messages_optional_request_params=optional_params,
|
||||
litellm_params=litellm_params,
|
||||
headers=headers,
|
||||
)
|
||||
|
||||
assert "extra_body" not in result
|
||||
assert "stream_options" not in result
|
||||
assert result["model"] == model
|
||||
assert result["max_tokens"] == 1000
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue