import json import logging import anthropic from app.config import settings from app.models import Movie from app.services.llm.base import SYSTEM_PROMPT, LLMProvider, build_user_message logger = logging.getLogger("movie-night.llm.anthropic") class AnthropicProvider(LLMProvider): def __init__(self): self.client = anthropic.AsyncAnthropic(api_key=settings.llm_api_key) self.model = settings.llm_model or "claude-sonnet-4-6" async def get_recommendations(self, mood: str, candidates: list[Movie], max_results: int = 6) -> list[dict]: system = SYSTEM_PROMPT.format(max_results=max_results) user_msg = build_user_message(mood, candidates) logger.info(f"Calling Anthropic ({self.model}) with {len(candidates)} candidates") response = await self.client.messages.create( model=self.model, max_tokens=2048, system=system, messages=[{"role": "user", "content": user_msg}], ) text = response.content[0].text.strip() # Parse JSON response try: data = json.loads(text) return data.get("recommendations", []) except json.JSONDecodeError: # Try to extract JSON from the response start = text.find("{") end = text.rfind("}") + 1 if start >= 0 and end > start: try: data = json.loads(text[start:end]) return data.get("recommendations", []) except json.JSONDecodeError: pass logger.error(f"Failed to parse LLM response: {text[:200]}") return []