mirror of
https://github.com/tiennm99/litellm.git
synced 2026-08-05 10:24:03 +00:00
Add v1/messages support for azure anthropic models
This commit is contained in:
@@ -19,7 +19,7 @@ Azure Foundry supports the following Claude models:
|
||||
| Provider Route on LiteLLM | `azure/` (add this prefix to Claude model names - e.g. `azure/claude-sonnet-4-5`) |
|
||||
| Provider Doc | [Azure Foundry Claude Models ↗](https://learn.microsoft.com/en-us/azure/ai-services/foundry-models/claude) |
|
||||
| API Endpoint | `https://<resource-name>.services.ai.azure.com/anthropic/v1/messages` |
|
||||
| Supported Endpoints | `/chat/completions`, `/anthropic/v1/messages` (passthrough) |
|
||||
| Supported Endpoints | `/chat/completions`, `/anthropic/v1/messages`|
|
||||
|
||||
## Key Features
|
||||
|
||||
|
||||
@@ -4,5 +4,9 @@ Azure Anthropic provider - supports Claude models via Azure Foundry
|
||||
from .handler import AzureAnthropicChatCompletion
|
||||
from .transformation import AzureAnthropicConfig
|
||||
|
||||
__all__ = ["AzureAnthropicChatCompletion", "AzureAnthropicConfig"]
|
||||
try:
|
||||
from .messages_transformation import AzureAnthropicMessagesConfig
|
||||
__all__ = ["AzureAnthropicChatCompletion", "AzureAnthropicConfig", "AzureAnthropicMessagesConfig"]
|
||||
except ImportError:
|
||||
__all__ = ["AzureAnthropicChatCompletion", "AzureAnthropicConfig"]
|
||||
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
"""
|
||||
Azure Anthropic messages transformation config - extends AnthropicMessagesConfig with Azure authentication
|
||||
"""
|
||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple
|
||||
|
||||
import httpx
|
||||
|
||||
from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj, verbose_logger
|
||||
from litellm.llms.anthropic.experimental_pass_through.messages.transformation import (
|
||||
AnthropicMessagesConfig,
|
||||
)
|
||||
from litellm.llms.azure.common_utils import BaseAzureLLM
|
||||
from litellm.types.llms.anthropic_messages.anthropic_response import (
|
||||
AnthropicMessagesResponse,
|
||||
)
|
||||
from litellm.types.router import GenericLiteLLMParams
|
||||
|
||||
if TYPE_CHECKING:
|
||||
pass
|
||||
|
||||
|
||||
class AzureAnthropicMessagesConfig(AnthropicMessagesConfig):
|
||||
"""
|
||||
Azure Anthropic messages configuration that extends AnthropicMessagesConfig.
|
||||
The only difference is authentication - Azure uses x-api-key header (not api-key)
|
||||
and Azure endpoint format.
|
||||
"""
|
||||
|
||||
def validate_anthropic_messages_environment(
|
||||
self,
|
||||
headers: dict,
|
||||
model: str,
|
||||
messages: List[Any],
|
||||
optional_params: dict,
|
||||
litellm_params: dict,
|
||||
api_key: Optional[str] = None,
|
||||
api_base: Optional[str] = None,
|
||||
) -> Tuple[dict, Optional[str]]:
|
||||
"""
|
||||
Validate environment and set up Azure authentication headers for /v1/messages endpoint.
|
||||
Azure Anthropic uses x-api-key header (not api-key).
|
||||
"""
|
||||
from litellm.secret_managers.main import get_secret_str
|
||||
|
||||
# Convert dict to GenericLiteLLMParams if needed
|
||||
if isinstance(litellm_params, dict):
|
||||
if api_key and "api_key" not in litellm_params:
|
||||
litellm_params = {**litellm_params, "api_key": api_key}
|
||||
litellm_params_obj = GenericLiteLLMParams(**litellm_params)
|
||||
else:
|
||||
litellm_params_obj = litellm_params or GenericLiteLLMParams()
|
||||
if api_key and not litellm_params_obj.api_key:
|
||||
litellm_params_obj.api_key = api_key
|
||||
|
||||
# Use Azure authentication logic
|
||||
headers = BaseAzureLLM._base_validate_azure_environment(
|
||||
headers=headers, litellm_params=litellm_params_obj
|
||||
)
|
||||
|
||||
# Azure Anthropic uses x-api-key header (not api-key)
|
||||
# Convert api-key to x-api-key if present
|
||||
if "api-key" in headers and "x-api-key" not in headers:
|
||||
headers["x-api-key"] = headers.pop("api-key")
|
||||
|
||||
# Set anthropic-version header
|
||||
if "anthropic-version" not in headers:
|
||||
headers["anthropic-version"] = "2023-06-01"
|
||||
|
||||
# Set content-type header
|
||||
if "content-type" not in headers:
|
||||
headers["content-type"] = "application/json"
|
||||
|
||||
# Update headers with optional anthropic beta features
|
||||
headers = self._update_headers_with_optional_anthropic_beta(
|
||||
headers=headers,
|
||||
context_management=optional_params.get("context_management"),
|
||||
)
|
||||
|
||||
return headers, api_base
|
||||
|
||||
def get_complete_url(
|
||||
self,
|
||||
api_base: Optional[str],
|
||||
api_key: Optional[str],
|
||||
model: str,
|
||||
optional_params: dict,
|
||||
litellm_params: dict,
|
||||
stream: Optional[bool] = None,
|
||||
) -> str:
|
||||
"""
|
||||
Get the complete URL for Azure Anthropic /v1/messages endpoint.
|
||||
Azure Foundry endpoint format: https://<resource-name>.services.ai.azure.com/anthropic/v1/messages
|
||||
"""
|
||||
from litellm.secret_managers.main import get_secret_str
|
||||
|
||||
api_base = api_base or get_secret_str("AZURE_API_BASE")
|
||||
if api_base is None:
|
||||
raise ValueError(
|
||||
"Missing Azure API Base - Please set `api_base` or `AZURE_API_BASE` environment variable. "
|
||||
"Expected format: https://<resource-name>.services.ai.azure.com/anthropic"
|
||||
)
|
||||
|
||||
# Ensure the URL ends with /v1/messages
|
||||
api_base = api_base.rstrip("/")
|
||||
if api_base.endswith("/v1/messages"):
|
||||
# Already correct
|
||||
pass
|
||||
elif api_base.endswith("/anthropic/v1/messages"):
|
||||
# Already correct
|
||||
pass
|
||||
else:
|
||||
# Check if /anthropic is already in the path
|
||||
if "/anthropic" in api_base:
|
||||
# /anthropic exists, ensure we end with /anthropic/v1/messages
|
||||
# Extract the base URL up to and including /anthropic
|
||||
parts = api_base.split("/anthropic", 1)
|
||||
api_base = parts[0] + "/anthropic"
|
||||
else:
|
||||
# /anthropic not in path, add it
|
||||
api_base = api_base + "/anthropic"
|
||||
# Add /v1/messages
|
||||
api_base = api_base + "/v1/messages"
|
||||
|
||||
return api_base
|
||||
|
||||
@@ -7341,6 +7341,12 @@ class ProviderConfigManager:
|
||||
)
|
||||
|
||||
return VertexAIPartnerModelsAnthropicMessagesConfig()
|
||||
elif litellm.LlmProviders.AZURE_ANTHROPIC == provider:
|
||||
from litellm.llms.azure.anthropic.messages_transformation import (
|
||||
AzureAnthropicMessagesConfig,
|
||||
)
|
||||
|
||||
return AzureAnthropicMessagesConfig()
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
|
||||
Reference in New Issue
Block a user