import asyncio import anthropic from app.providers.base import AIProvider from app.schemas.chat import ChatMessage class AnthropicProvider(AIProvider): def __init__(self, config: dict) -> None: self._client = anthropic.AsyncAnthropic(api_key=config.get("api_key", "")) self.model_name = config.get("model", "claude-haiku-4-5-20251001") self.provider_name = "anthropic" async def chat( self, messages: list[ChatMessage], max_tokens: int, temperature: float, ) -> tuple[str, int | None, int | None]: # Anthropic uses a top-level `system=` param, not a role in the messages array system_content = "" user_messages = [] for msg in messages: if msg.role == "system": system_content += msg.content + "\n" else: user_messages.append({"role": msg.role, "content": msg.content}) try: response = await self._client.messages.create( model=self.model_name, max_tokens=max_tokens, temperature=temperature, system=system_content.strip() or anthropic.NOT_GIVEN, messages=user_messages, ) except anthropic.APIConnectionError as exc: raise ProviderConnectionError(str(exc)) from exc except anthropic.APITimeoutError as exc: raise ProviderTimeoutError(str(exc)) from exc except anthropic.APIStatusError as exc: raise ProviderConnectionError(f"Anthropic API error {exc.status_code}: {exc.message}") from exc content = response.content[0].text return content, response.usage.input_tokens, response.usage.output_tokens class ProviderConnectionError(Exception): pass class ProviderTimeoutError(Exception): pass