fix(azure_ai): strip scope from cache_control for Anthropic messages
Azure AI Foundry's Anthropic endpoint does not support the scope field in cache_control. Strip it from both system and messages before sending. Made-with: Cursor
This commit is contained in:
parent
cc989b1171
commit
482bc93910
@ -1,7 +1,7 @@
|
||||
"""
|
||||
Azure Anthropic messages transformation config - extends AnthropicMessagesConfig with Azure authentication
|
||||
"""
|
||||
from typing import TYPE_CHECKING, Any, List, Optional, Tuple
|
||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple
|
||||
|
||||
from litellm.llms.anthropic.experimental_pass_through.messages.transformation import (
|
||||
AnthropicMessagesConfig,
|
||||
@ -114,3 +114,53 @@ class AzureAnthropicMessagesConfig(AnthropicMessagesConfig):
|
||||
|
||||
return api_base
|
||||
|
||||
def _remove_scope_from_cache_control(
|
||||
self, anthropic_messages_request: Dict
|
||||
) -> None:
|
||||
"""
|
||||
Remove `scope` field from cache_control for Azure AI Foundry.
|
||||
|
||||
Azure AI Foundry's Anthropic endpoint does not support the `scope` field
|
||||
(e.g., "global" for cross-request caching). Only `type` and `ttl` are supported.
|
||||
|
||||
Processes both `system` and `messages` content blocks.
|
||||
"""
|
||||
def _sanitize(cache_control: Any) -> None:
|
||||
if isinstance(cache_control, dict):
|
||||
cache_control.pop("scope", None)
|
||||
|
||||
def _process_content_list(content: list) -> None:
|
||||
for item in content:
|
||||
if isinstance(item, dict) and "cache_control" in item:
|
||||
_sanitize(item["cache_control"])
|
||||
|
||||
if "system" in anthropic_messages_request:
|
||||
system = anthropic_messages_request["system"]
|
||||
if isinstance(system, list):
|
||||
_process_content_list(system)
|
||||
|
||||
if "messages" in anthropic_messages_request:
|
||||
for message in anthropic_messages_request["messages"]:
|
||||
if isinstance(message, dict) and "content" in message:
|
||||
content = message["content"]
|
||||
if isinstance(content, list):
|
||||
_process_content_list(content)
|
||||
|
||||
def transform_anthropic_messages_request(
|
||||
self,
|
||||
model: str,
|
||||
messages: List[Dict],
|
||||
anthropic_messages_optional_request_params: Dict,
|
||||
litellm_params: GenericLiteLLMParams,
|
||||
headers: dict,
|
||||
) -> Dict:
|
||||
anthropic_messages_request = super().transform_anthropic_messages_request(
|
||||
model=model,
|
||||
messages=messages,
|
||||
anthropic_messages_optional_request_params=anthropic_messages_optional_request_params,
|
||||
litellm_params=litellm_params,
|
||||
headers=headers,
|
||||
)
|
||||
self._remove_scope_from_cache_control(anthropic_messages_request)
|
||||
return anthropic_messages_request
|
||||
|
||||
|
||||
@ -239,6 +239,50 @@ class TestAzureAnthropicMessagesConfig:
|
||||
assert "tools" in params
|
||||
assert "tool_choice" in params
|
||||
|
||||
def test_transform_anthropic_messages_request_removes_scope_from_cache_control(
|
||||
self,
|
||||
):
|
||||
"""Test that scope is removed from cache_control (Azure AI Foundry doesn't support it)"""
|
||||
config = AzureAnthropicMessagesConfig()
|
||||
model = "claude-sonnet-4-5"
|
||||
messages = [
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "Hello",
|
||||
"cache_control": {"type": "ephemeral", "scope": "global"},
|
||||
}
|
||||
],
|
||||
}
|
||||
]
|
||||
anthropic_messages_optional_request_params = {
|
||||
"max_tokens": 1024,
|
||||
"system": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "You are an AI assistant.",
|
||||
"cache_control": {"type": "ephemeral", "scope": "global"},
|
||||
}
|
||||
],
|
||||
}
|
||||
litellm_params = GenericLiteLLMParams()
|
||||
headers = {}
|
||||
|
||||
result = config.transform_anthropic_messages_request(
|
||||
model=model,
|
||||
messages=messages,
|
||||
anthropic_messages_optional_request_params=anthropic_messages_optional_request_params,
|
||||
litellm_params=litellm_params,
|
||||
headers=headers,
|
||||
)
|
||||
|
||||
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"
|
||||
|
||||
|
||||
class TestProviderConfigManagerAzureAnthropicMessages:
|
||||
"""Test ProviderConfigManager returns correct config for Azure AI Anthropic Messages API"""
|
||||
|
||||
Loading…
Reference in New Issue
Block a user