Spaces:
Running
Running
| from __future__ import annotations | |
| from typing import Dict, List | |
| from quiz.models import QuizSession | |
| from quiz.scoring import compute_mastery_delta, should_unlock_revision_quest, mastery_recommendation | |
| from storage.mastery import MasteryStore | |
| class ProgressAgent: | |
| """ | |
| Deterministic mastery calculation. No LLM call. | |
| Aggregates correct/total per topic from the session and persists to MasteryStore. | |
| """ | |
| def __init__(self, mastery_store: MasteryStore): self._mastery = mastery_store | |
| def update_from_session(self, session: QuizSession) -> Dict: | |
| topic_stats: Dict[str, Dict[str, int]] = {} | |
| for q in session.questions: | |
| if q.topic not in topic_stats: | |
| topic_stats[q.topic] = {"correct": 0, "total": 0} | |
| topic_stats[q.topic]["total"] += 1 | |
| if q.topic not in session.wrong_topics: | |
| topic_stats[q.topic]["correct"] += 1 | |
| mastery_updates = [] | |
| for topic, stats in topic_stats.items(): | |
| self._mastery.update(topic, stats["correct"], stats["total"]) | |
| mastery_updates.append({"topic": topic, "correct": stats["correct"], "total": stats["total"]}) | |
| weak = [u["topic"] for u in mastery_updates | |
| if should_unlock_revision_quest(compute_mastery_delta(u["correct"], u["total"]))] | |
| overall = session.score / len(session.questions) if session.questions else 0.0 | |
| recommendation = mastery_recommendation(overall) | |
| return {"mastery_updates": mastery_updates, "weak_topics": weak, "recommendation": recommendation} | |