File size: 1,581 Bytes
dc124db
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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}