"""tutor/model_loader.py β€” generates child-facing feedback (templates + optional LLM).""" from __future__ import annotations import os, random from typing import Optional _CORRECT = { "en": ["Amazing work! πŸŽ‰ You got it!","Superstar! ⭐ That's exactly right!", "Brilliant! 🌟 You're on fire!","Perfect! Keep it up! πŸš€","You nailed it! 🎊"], "fr": ["Bravo ! πŸŽ‰ C'est exactement Γ§a !","Super ! ⭐ Tu es fantastique !", "Excellent ! 🌟 Continue comme Γ§a !","Parfait ! πŸ₯³ Tu es une Γ©toile !"], "kin": ["Byiza cyane! πŸŽ‰ Wabitsinze!","Ntangaza! ⭐ Uravuga ukuri!", "Komeza! 🌟 Uri inzobere!","Superbe! πŸ₯³ Urashoboye!"], "sw": ["Vizuri sana! πŸŽ‰ Umeshinda!","Hongera! ⭐ Jibu sahihi!", "Endelea hivyo! 🌟 Umefaulu!","Bora sana! πŸ₯³ Ushindi!"], } _WRONG = { "en": ["Almost! Give it another try πŸ’ͺ","Not quite β€” you can do it! 🌈", "Good try! Think again πŸ€”","Keep going β€” try once more! πŸ’«"], "fr": ["Presque ! Essaie encore πŸ’ͺ","Pas tout Γ  fait β€” tu peux le faire ! 🌈", "Bon essai ! RΓ©flΓ©chis encore πŸ€”"], "kin": ["Hafi! Gerageza nanone πŸ’ͺ","Ntabwo ari byo β€” gerageza! 🌈","Gerageza nanone! πŸ€”"], "sw": ["Karibu! Jaribu tena πŸ’ͺ","Si sahihi β€” unaweza! 🌈","Jaribu tena! πŸ€”"], } _sdk_checked = False _sdk_ok = False def _check_sdk(): global _sdk_checked, _sdk_ok if _sdk_checked: return _sdk_ok _sdk_checked = True try: import anthropic # type: ignore # noqa _sdk_ok = bool(os.environ.get("ANTHROPIC_API_KEY")) except ImportError: pass return _sdk_ok def _llm_feedback(is_correct, answer, lang, child_text) -> Optional[str]: if not _check_sdk(): return None try: import anthropic # type: ignore client = anthropic.Anthropic() outcome = "correct" if is_correct else "incorrect" msg = client.messages.create( model="claude-haiku-4-5-20251001", max_tokens=60, messages=[{"role":"user","content": f"You are a warm math tutor for a child aged 5-9. " f"Child answered '{child_text}', correct answer is {answer}, " f"their answer was {outcome}. Reply in language '{lang}' " f"with ONE short encouraging sentence (max 12 words)."}]) return msg.content[0].text.strip() except Exception: return None def generate_feedback(is_correct: bool, answer: int, lang: str = "en", child_text: str = "") -> str: llm = _llm_feedback(is_correct, answer, lang, child_text) if llm: return llm bank = _CORRECT if is_correct else _WRONG return random.choice(bank.get(lang, bank["en"]))