Spaces:
Sleeping
Sleeping
| import argparse | |
| import os | |
| from datetime import datetime | |
| from dotenv import load_dotenv | |
| from src.graph.build_graph import build_study_graph | |
| from src.graph.state import StudyState | |
| load_dotenv() | |
| def write_session_report(state: StudyState) -> str: | |
| now = datetime.now() | |
| filename = f"session_{now.strftime('%Y%m%d_%H%M%S')}.md" | |
| filepath = os.path.join("output", "session_reports", filename) | |
| questions_asked = state["questions_asked"] | |
| questions_correct = state["questions_correct"] | |
| mastery_score = questions_correct / questions_asked if questions_asked > 0 else 0.0 | |
| reread_count = len(state.get("weak_chunks", [])) | |
| doc_name = os.path.basename(state["document_path"]) | |
| # Find weak areas from low-scoring questions | |
| weak_areas = [] | |
| for entry in state.get("session_history", []): | |
| if entry["score"] < 0.75: | |
| weak_areas.append(entry["question"]) | |
| lines = [ | |
| "# Study Session Report", | |
| f"Date: {now.strftime('%Y-%m-%d')}", | |
| f"Document: {doc_name}", | |
| "", | |
| "## Summary", | |
| f"- Questions asked: {questions_asked}", | |
| f"- Questions correct (score >= 0.75): {questions_correct}", | |
| f"- Final mastery score: {mastery_score:.2f}", | |
| f"- Re-read cycles triggered: {reread_count}", | |
| "", | |
| "## Weak Areas", | |
| ] | |
| if weak_areas: | |
| for area in weak_areas: | |
| lines.append(f"- {area}") | |
| else: | |
| lines.append("- None") | |
| lines.extend(["", "## Q&A Log"]) | |
| for i, entry in enumerate(state.get("session_history", []), 1): | |
| lines.extend([ | |
| f"### Q{i}", | |
| f"Question: {entry['question']}", | |
| f"Answer: {entry['answer']}", | |
| f"Score: {entry['score']}", | |
| f"Reasoning: {entry['reasoning']}", | |
| "", | |
| ]) | |
| os.makedirs(os.path.dirname(filepath), exist_ok=True) | |
| with open(filepath, "w", encoding="utf-8") as f: | |
| f.write("\n".join(lines)) | |
| return filepath | |
| def main(): | |
| parser = argparse.ArgumentParser(description="Adaptive Study Agent") | |
| parser.add_argument("--doc", required=True, help="Path to document (PDF or TXT)") | |
| parser.add_argument("--threshold", type=float, default=0.75, help="Mastery threshold (0.0-1.0)") | |
| parser.add_argument("--persist", action="store_true", help="Persist ChromaDB between runs") | |
| args = parser.parse_args() | |
| if not os.path.exists(args.doc): | |
| print(f"Error: File not found: {args.doc}") | |
| return | |
| # Update mastery threshold if overridden | |
| if args.threshold != 0.75: | |
| from src.graph import edges | |
| edges.MASTERY_THRESHOLD = args.threshold | |
| print(f"Starting study session with: {args.doc}") | |
| print(f"Mastery threshold: {args.threshold}") | |
| print("-" * 50) | |
| graph = build_study_graph() | |
| initial_state: StudyState = { | |
| "document_path": args.doc, | |
| "chunks": [], | |
| "questions_asked": 0, | |
| "questions_correct": 0, | |
| "current_question": "", | |
| "current_answer": "", | |
| "current_score": 0.0, | |
| "weak_chunks": [], | |
| "session_history": [], | |
| "mastery_reached": False, | |
| } | |
| final_state = graph.invoke(initial_state) | |
| report_path = write_session_report(final_state) | |
| print(f"\nSession report saved to: {report_path}") | |
| if __name__ == "__main__": | |
| main() | |