Spaces:
Sleeping
Sleeping
| """Helpers to load and persist the UserProfile from/to SQLite.""" | |
| from .db import get_profile, upsert_profile | |
| from .models import UserProfile | |
| def load_profile(session_id: str) -> UserProfile: | |
| """Fetch profile from DB, or create a fresh one if it doesn't exist.""" | |
| row = get_profile(session_id) | |
| if row: | |
| return UserProfile(**row) | |
| return UserProfile(session_id=session_id) | |
| def update_profile(profile: UserProfile, topic: str, gap_magnitude: int, solved: bool) -> UserProfile: | |
| """ | |
| Update the profile in-memory after a reasoning evaluation: | |
| - Increment weak_topics score for the identified topic | |
| - Recalculate avg_gap with exponential moving average (alpha=0.3) | |
| - Increment turn count and solved count | |
| """ | |
| topic_key = topic.strip().lower() | |
| profile.weak_topics[topic_key] = profile.weak_topics.get(topic_key, 0) + gap_magnitude | |
| # EMA for avg_gap | |
| alpha = 0.3 | |
| profile.avg_gap = (alpha * gap_magnitude) + ((1 - alpha) * profile.avg_gap) | |
| profile.total_turns += 1 | |
| if solved: | |
| profile.solved_problems += 1 | |
| return profile | |
| def persist_profile(profile: UserProfile) -> None: | |
| """Save the updated profile back to SQLite.""" | |
| upsert_profile(profile.model_dump()) | |
| def top_weak_topics(profile: UserProfile, n: int = 3) -> list[str]: | |
| """Return the top-N weakest topics by cumulative score.""" | |
| sorted_topics = sorted(profile.weak_topics.items(), key=lambda x: x[1], reverse=True) | |
| return [t[0] for t in sorted_topics[:n]] | |