# agents.py import os import json import random # Try to import zhipuai client ZHIPU_AVAILABLE = False client = None ZHIPU_KEY = os.getenv("zhipuai_api_key") if ZHIPU_KEY: try: from zhipuai import ZhipuAI client = ZhipuAI(api_key=ZHIPU_KEY) ZHIPU_AVAILABLE = True except Exception: ZHIPU_AVAILABLE = False class AnalyzerAgent: """Simple objective analyzer for MCQ answers.""" def analyze(self, student_answers, correct_answers): """ student_answers: list of strings like 'A', 'B', 'C' or actual choice text correct_answers: list of strings (prefer letter 'A'..'D' or exact text) Returns (score, analysis_list) """ score = 0 analysis = [] for i, (s, c) in enumerate(zip(student_answers, correct_answers), start=1): s_norm = (s or "").strip() c_norm = (c or "").strip() ok = False if c_norm == "": ok = False elif len(c_norm) == 1 and c_norm.upper() in ["A","B","C","D"]: ok = (s_norm.upper() == c_norm.upper()) else: ok = (s_norm.lower() == c_norm.lower()) if ok: score += 1 analysis.append(f"Q{i}: ✅") else: analysis.append(f"Q{i}: ❌ (Your: {s_norm} | Key: {c_norm})") return score, analysis class CoachAgent: """Provides AI feedback using ZhipuAI if available.""" def __init__(self): self.client = client def coach(self, context_text): """ context_text: a small JSON/string summarizing student's performance. Returns an advice string. """ if not ZHIPU_AVAILABLE or self.client is None: # Fallback advice return "AI coach not configured. Set environment variable 'zhipuai_api_key' to enable AI analysis.\nGeneral advice: Review the wrong questions, focus on weak topics, and practice time management." try: prompt = ( "You are an experienced SPM coach. Given the student's summary, provide concise actionable advice (3-5 bullets).\n\n" f"Student summary:\n{context_text}\n\nAdvice:" ) resp = self.client.chat.completions.create( model="glm-4", messages=[{"role":"user","content":prompt}], temperature=0.2, ) out = resp.choices[0].message["content"].strip() return out except Exception as e: return f"AI coach error: {str(e)}" class PredictiveAgent: """(Optional) Use LLM to forecast likely topics/questions.""" def __init__(self): self.client = client def predict(self, subject, year_range="2018-2024"): if not ZHIPU_AVAILABLE or self.client is None: return "Predicted question (LLM not configured)." prompt = ( f"Analyze SPM {subject} past papers between {year_range}. " "Identify recurring topics and predict 5 high-probability short objective questions." ) try: resp = self.client.chat.completions.create( model="glm-4", messages=[{"role":"user","content":prompt}], temperature=0.3, ) return resp.choices[0].message["content"].strip() except Exception as e: return f"Prediction error: {str(e)}"