Spaces:
Running
Running
| """Session state management for tracking child interactions and adaptive personalization.""" | |
| from dataclasses import dataclass, field | |
| from typing import List, Dict | |
| class SessionState: | |
| """Tracks the state of a learning session for adaptive personalization.""" | |
| # Interaction tracking | |
| total_messages: int = 0 | |
| correct_answers: int = 0 | |
| incorrect_answers: int = 0 | |
| questions_asked_by_child: int = 0 | |
| # Engagement metrics | |
| short_responses: int = 0 # 1-5 words | |
| detailed_responses: int = 0 # 6+ words | |
| emoji_count: int = 0 | |
| exclamation_count: int = 0 | |
| # Adaptive difficulty | |
| current_difficulty_adjustment: str = "neutral" # "easier", "neutral", "harder" | |
| # Topics explored | |
| topics_discussed: List[str] = field(default_factory=list) | |
| # Gamification (will be used by GamificationTracker) | |
| stars_earned: int = 0 | |
| badges_unlocked: List[str] = field(default_factory=list) | |
| def analyze_message(self, message: str) -> Dict[str, any]: | |
| """ | |
| Analyze a child's message to extract engagement and comprehension signals. | |
| Args: | |
| message: The child's message | |
| Returns: | |
| Dictionary with analysis results | |
| """ | |
| self.total_messages += 1 | |
| # Count words | |
| words = message.split() | |
| word_count = len(words) | |
| # Track response length | |
| if word_count <= 5: | |
| self.short_responses += 1 | |
| else: | |
| self.detailed_responses += 1 | |
| # Count engagement markers | |
| emoji_count = sum(1 for char in message if ord(char) > 127000) # Simple emoji detection | |
| exclamation_count = message.count('!') | |
| question_count = message.count('?') | |
| self.emoji_count += emoji_count | |
| self.exclamation_count += exclamation_count | |
| if question_count > 0: | |
| self.questions_asked_by_child += 1 | |
| # Calculate engagement level | |
| engagement_score = 0 | |
| if word_count > 5: | |
| engagement_score += 2 | |
| if emoji_count > 0: | |
| engagement_score += 1 | |
| if exclamation_count > 0: | |
| engagement_score += 1 | |
| if question_count > 0: | |
| engagement_score += 2 | |
| engagement_level = "low" if engagement_score < 2 else "medium" if engagement_score < 4 else "high" | |
| return { | |
| "word_count": word_count, | |
| "engagement_level": engagement_level, | |
| "has_question": question_count > 0, | |
| "has_emoji": emoji_count > 0, | |
| "has_exclamation": exclamation_count > 0 | |
| } | |
| def record_answer_quality(self, is_correct: bool): | |
| """ | |
| Record whether the child's answer was correct. | |
| Args: | |
| is_correct: True if answer was correct, False otherwise | |
| """ | |
| if is_correct: | |
| self.correct_answers += 1 | |
| else: | |
| self.incorrect_answers += 1 | |
| # Update difficulty adjustment based on success rate | |
| total_answers = self.correct_answers + self.incorrect_answers | |
| if total_answers >= 3: # Need at least 3 answers to adjust | |
| success_rate = self.correct_answers / total_answers | |
| if success_rate < 0.4: | |
| self.current_difficulty_adjustment = "easier" | |
| elif success_rate > 0.8: | |
| self.current_difficulty_adjustment = "harder" | |
| else: | |
| self.current_difficulty_adjustment = "neutral" | |
| def get_adaptive_context(self) -> str: | |
| """ | |
| Generate adaptive context string for the system prompt. | |
| Returns: | |
| String with adaptive instructions based on session state | |
| """ | |
| context_parts = [] | |
| # Difficulty adjustment | |
| if self.current_difficulty_adjustment == "easier": | |
| context_parts.append( | |
| "ADAPTIVE INSTRUCTION: The child is struggling. Simplify your language, " | |
| "break problems into smaller steps, and provide more hints and encouragement." | |
| ) | |
| elif self.current_difficulty_adjustment == "harder": | |
| context_parts.append( | |
| "ADAPTIVE INSTRUCTION: The child is excelling! Increase the challenge, " | |
| "ask deeper questions, and introduce more complex concepts." | |
| ) | |
| # Engagement adjustment | |
| if self.total_messages >= 3: | |
| engagement_ratio = self.detailed_responses / max(self.total_messages, 1) | |
| if engagement_ratio < 0.3: | |
| context_parts.append( | |
| "ENGAGEMENT NOTE: The child is giving short responses. Make your questions " | |
| "more exciting, use more of your character's personality, and relate to their interests." | |
| ) | |
| elif engagement_ratio > 0.7: | |
| context_parts.append( | |
| "ENGAGEMENT NOTE: The child is highly engaged with detailed responses! " | |
| "Match their energy and enthusiasm. Present bonus challenges and celebrate their curiosity." | |
| ) | |
| # Question-asking behavior | |
| if self.questions_asked_by_child >= 2: | |
| context_parts.append( | |
| "CURIOSITY NOTE: The child is asking great questions! Encourage this curiosity " | |
| "and turn their questions into exciting learning opportunities." | |
| ) | |
| return "\n".join(context_parts) if context_parts else "" | |
| def get_session_summary(self) -> Dict[str, any]: | |
| """ | |
| Get a summary of the current session state. | |
| Returns: | |
| Dictionary with session statistics | |
| """ | |
| total_answers = self.correct_answers + self.incorrect_answers | |
| success_rate = (self.correct_answers / total_answers * 100) if total_answers > 0 else 0 | |
| return { | |
| "total_messages": self.total_messages, | |
| "correct_answers": self.correct_answers, | |
| "incorrect_answers": self.incorrect_answers, | |
| "success_rate": success_rate, | |
| "questions_asked": self.questions_asked_by_child, | |
| "stars_earned": self.stars_earned, | |
| "badges_unlocked": len(self.badges_unlocked), | |
| "difficulty_adjustment": self.current_difficulty_adjustment | |
| } | |