"""Anthropic Claude provider — uses the official SDK.""" from __future__ import annotations import logging import os from .base import ModelInfo, ProviderResponse logger = logging.getLogger(__name__) # Claude-specific env vars # ANTHROPIC_API_KEY is read by the SDK automatically CLAUDE_MODEL = os.environ.get("CLAUDE_MODEL", "claude-sonnet-4-20250514") MODELS = { "claude-sonnet-4-20250514": ModelInfo( id="claude-sonnet-4-20250514", vision=True, cost_per_input_token=0.000003, cost_per_output_token=0.000015, notes="Best balance of quality/cost with vision", ), "claude-haiku-4-5-20251001": ModelInfo( id="claude-haiku-4-5-20251001", vision=True, cost_per_input_token=0.0000008, cost_per_output_token=0.000004, notes="Fastest, cheapest, good for simple brand ID", ), "claude-opus-4-6": ModelInfo( id="claude-opus-4-6", vision=True, cost_per_input_token=0.000015, cost_per_output_token=0.000075, notes="Highest quality, use for ambiguous cases", ), } class ClaudeProvider: name = "claude" models = MODELS def __init__(self): from anthropic import Anthropic self.client = Anthropic() self.model = CLAUDE_MODEL def call(self, image_b64: str, prompt: str) -> ProviderResponse: message = self.client.messages.create( model=self.model, max_tokens=150, messages=[{ "role": "user", "content": [ { "type": "image", "source": { "type": "base64", "media_type": "image/jpeg", "data": image_b64, }, }, {"type": "text", "text": prompt}, ], }], ) answer = message.content[0].text.strip() total_tokens = message.usage.input_tokens + message.usage.output_tokens return ProviderResponse(answer=answer, total_tokens=total_tokens)