diff --git a/app/routers/mood.py b/app/routers/mood.py index 9f65a86..04728d2 100644 --- a/app/routers/mood.py +++ b/app/routers/mood.py @@ -83,6 +83,15 @@ async def get_mood_recommendations(request: Request, body: MoodRequest): continue movie = candidate_map[jf_id] + + # Validate that the LLM's title matches the actual movie to catch mix-ups + rec_title = rec.get("title", "").strip().lower() + if rec_title and rec_title != movie.title.strip().lower(): + logger.warning( + f"LLM title mismatch: returned '{rec.get('title')}' for jellyfin_id " + f"'{jf_id}' which is actually '{movie.title}' — skipping" + ) + continue recommendations.append( Recommendation( jellyfin_id=movie.jellyfin_id, diff --git a/app/services/llm/base.py b/app/services/llm/base.py index 7678402..344003b 100644 --- a/app/services/llm/base.py +++ b/app/services/llm/base.py @@ -13,6 +13,7 @@ Rules: - Rank by how well they match the described mood, not by rating alone - If the mood mentions kids, children, or family, only recommend age-appropriate content (G, PG, or PG-13) - Return exactly {max_results} recommendations, or fewer only if the library has very few matches +- IMPORTANT: Double-check that your reasoning accurately describes the specific movie you selected. The title, jellyfin_id, and reasoning MUST all refer to the same movie. Do not mix up details between different movies in the list. Respond with ONLY valid JSON in this exact format, no other text: {{