Spaces:
Configuration error
Configuration error
from typing import Any, AsyncIterator, Dict, List, Optional, Tuple | |
import httpx | |
from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj | |
from litellm.llms.base_llm.anthropic_messages.transformation import ( | |
BaseAnthropicMessagesConfig, | |
) | |
from litellm.types.llms.anthropic import AnthropicMessagesRequest | |
from litellm.types.llms.anthropic_messages.anthropic_response import ( | |
AnthropicMessagesResponse, | |
) | |
from litellm.types.router import GenericLiteLLMParams | |
from ...common_utils import AnthropicError | |
DEFAULT_ANTHROPIC_API_BASE = "https://api.anthropic.com" | |
DEFAULT_ANTHROPIC_API_VERSION = "2023-06-01" | |
class AnthropicMessagesConfig(BaseAnthropicMessagesConfig): | |
def get_supported_anthropic_messages_params(self, model: str) -> list: | |
return [ | |
"messages", | |
"model", | |
"system", | |
"max_tokens", | |
"stop_sequences", | |
"temperature", | |
"top_p", | |
"top_k", | |
"tools", | |
"tool_choice", | |
"thinking", | |
# TODO: Add Anthropic `metadata` support | |
# "metadata", | |
] | |
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: | |
api_base = api_base or DEFAULT_ANTHROPIC_API_BASE | |
if not api_base.endswith("/v1/messages"): | |
api_base = f"{api_base}/v1/messages" | |
return api_base | |
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]]: | |
if "x-api-key" not in headers and api_key: | |
headers["x-api-key"] = api_key | |
if "anthropic-version" not in headers: | |
headers["anthropic-version"] = DEFAULT_ANTHROPIC_API_VERSION | |
if "content-type" not in headers: | |
headers["content-type"] = "application/json" | |
return headers, api_base | |
def transform_anthropic_messages_request( | |
self, | |
model: str, | |
messages: List[Dict], | |
anthropic_messages_optional_request_params: Dict, | |
litellm_params: GenericLiteLLMParams, | |
headers: dict, | |
) -> Dict: | |
""" | |
No transformation is needed for Anthropic messages | |
This takes in a request in the Anthropic /v1/messages API spec -> transforms it to /v1/messages API spec (i.e) no transformation is needed | |
""" | |
max_tokens = anthropic_messages_optional_request_params.pop("max_tokens", None) | |
if max_tokens is None: | |
raise AnthropicError( | |
message="max_tokens is required for Anthropic /v1/messages API", | |
status_code=400, | |
) | |
####### get required params for all anthropic messages requests ###### | |
anthropic_messages_request: AnthropicMessagesRequest = AnthropicMessagesRequest( | |
messages=messages, | |
max_tokens=max_tokens, | |
model=model, | |
**anthropic_messages_optional_request_params, | |
) | |
return dict(anthropic_messages_request) | |
def transform_anthropic_messages_response( | |
self, | |
model: str, | |
raw_response: httpx.Response, | |
logging_obj: LiteLLMLoggingObj, | |
) -> AnthropicMessagesResponse: | |
""" | |
No transformation is needed for Anthropic messages, since we want the response in the Anthropic /v1/messages API spec | |
""" | |
try: | |
raw_response_json = raw_response.json() | |
except Exception: | |
raise AnthropicError( | |
message=raw_response.text, status_code=raw_response.status_code | |
) | |
return AnthropicMessagesResponse(**raw_response_json) | |
def get_async_streaming_response_iterator( | |
self, | |
model: str, | |
httpx_response: httpx.Response, | |
request_body: dict, | |
litellm_logging_obj: LiteLLMLoggingObj, | |
) -> AsyncIterator: | |
"""Helper function to handle Anthropic streaming responses using the existing logging handlers""" | |
from datetime import datetime | |
from litellm.proxy.pass_through_endpoints.streaming_handler import ( | |
PassThroughStreamingHandler, | |
) | |
from litellm.proxy.pass_through_endpoints.success_handler import ( | |
PassThroughEndpointLogging, | |
) | |
from litellm.types.passthrough_endpoints.pass_through_endpoints import ( | |
EndpointType, | |
) | |
# Create success handler object | |
passthrough_success_handler_obj = PassThroughEndpointLogging() | |
# Use the existing streaming handler for Anthropic | |
start_time = datetime.now() | |
return PassThroughStreamingHandler.chunk_processor( | |
response=httpx_response, | |
request_body=request_body, | |
litellm_logging_obj=litellm_logging_obj, | |
endpoint_type=EndpointType.ANTHROPIC, | |
start_time=start_time, | |
passthrough_success_handler_obj=passthrough_success_handler_obj, | |
url_route="/v1/messages", | |
) | |