Study-with-ChampAI / agents /quiz_agent.py
SolusOps's picture
feat: agents package
dc124db verified
Raw
History Blame Contribute Delete
2.05 kB
from __future__ import annotations
from typing import List
from quiz.models import Question, Quest
from services.model_router import ModelRouter
from services.json_parser import extract_json
from config.prompts import QUIZ_AGENT_BATCH_SYSTEM
class QuizAgent:
def __init__(self, router: ModelRouter): self._router = router
def generate_for_quest(self, quest: Quest, source_text: str = "",
questions_per_quest: int = 3, language: str = "en") -> List[Question]:
"""
Single Nemotron call generates all questions for a quest (regular + boss).
source_text grounds questions in actual material, reducing hallucination.
"""
source_snippet = source_text[:800] if source_text else "No source provided."
prompt = (
f"Quest: {quest.name}\n"
f"Topics: {', '.join(quest.topics)}\n"
f"Boss topic: {quest.boss_topic}\n"
f"Language: {language}\n"
f"Source material:\n{source_snippet}\n\n"
f"Generate {questions_per_quest} regular questions (is_boss:false) "
f"and 1 boss question (is_boss:true) as the last item."
)
raw = self._router.reason(prompt, QUIZ_AGENT_BATCH_SYSTEM)
try:
data = extract_json(raw)
except ValueError as exc:
raise ValueError(f"QuizAgent: {exc}") from exc
questions = []
for q_data in data.get("questions", []):
questions.append(Question(
text=q_data["question"],
topic=q_data.get("topic", quest.boss_topic),
options=q_data["options"],
correct_idx=q_data["correct_idx"],
explanation=q_data.get("explanation", ""),
difficulty=q_data.get("difficulty", "medium"),
q_type=q_data.get("type", "mcq"),
is_boss=q_data.get("is_boss", False),
source_excerpt=source_snippet[:200],
language=language,
))
return questions