# api/routes_courseware.py """AI Teacher Assistant Agent(Courseware)API:课程愿景、活动设计、课堂助教、QA 优化、教案与 PPT 数据。""" from typing import Optional, List, Any from fastapi import APIRouter, HTTPException from pydantic import BaseModel, Field from api.config import USE_WEAVIATE from api.courseware import ( build_course_vision, design_activities_and_assignments, teaching_copilot, optimize_from_quiz_data, generate_lesson_plan_and_ppt_data, ) router = APIRouter(prefix="/api/courseware", tags=["courseware"]) # ------------------------- Course Vision & Structure Builder ------------------------- class VisionRequest(BaseModel): course_info: str = Field(..., min_length=1, description="课程基本信息") syllabus: str = Field(..., min_length=1, description="教学大纲或要点") history: Optional[list] = Field(None, description="对话历史:[(user_msg, assistant_msg), ...]") class VisionResponse(BaseModel): ok: bool = True content: str = Field(..., description="课程定位、学习目标、知识树(含 References)") weaviate_used: bool = False @router.post("/vision", response_model=VisionResponse) def post_vision(req: VisionRequest): """课程愿景与结构:输出课程定位、学习目标、层级化知识树。""" try: content = build_course_vision( course_info=req.course_info.strip(), syllabus=req.syllabus.strip(), history=req.history, ) return VisionResponse(content=content, weaviate_used=USE_WEAVIATE) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) # ------------------------- Activity & Assignment Designer ------------------------- class ActivitiesRequest(BaseModel): topic: str = Field(..., min_length=1, description="主题/模块") learning_objectives: Optional[str] = Field(None, description="学习目标(可选)") rag_context_override: Optional[str] = Field(None, description="覆盖 RAG 上下文(如上传资料摘要)") history: Optional[list] = Field(None, description="对话历史:[(user_msg, assistant_msg), ...]") class ActivitiesResponse(BaseModel): ok: bool = True content: str = Field(..., description="课堂活动、作业、Rubric(含 References)") weaviate_used: bool = False @router.post("/activities", response_model=ActivitiesResponse) def post_activities(req: ActivitiesRequest): """活动与作业设计:课堂活动、作业、评分标准;支持从上传资料提取知识点。""" try: content = design_activities_and_assignments( topic=req.topic.strip(), learning_objectives=req.learning_objectives.strip() if req.learning_objectives else None, rag_context_override=req.rag_context_override.strip() if req.rag_context_override else None, history=req.history, ) return ActivitiesResponse(content=content, weaviate_used=USE_WEAVIATE) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) # ------------------------- Teaching Copilot & Student Adaptation ------------------------- class StudentProfile(BaseModel): name: Optional[str] = None progress: Optional[str] = None behavior: Optional[str] = None class CopilotRequest(BaseModel): current_content: str = Field(..., min_length=1, description="当前授课内容/问题") student_profiles: Optional[List[StudentProfile]] = Field(None, description="学生画像 Name, Progress, Behavior") history: Optional[list] = Field(None, description="对话历史:[(user_msg, assistant_msg), ...]") class CopilotResponse(BaseModel): ok: bool = True content: str = Field(..., description="实时建议(含 References)") weaviate_used: bool = False @router.post("/copilot", response_model=CopilotResponse) def post_copilot(req: CopilotRequest): """课堂实时助教:根据当前内容与学生画像给出即时建议。""" try: profiles = [p.model_dump() for p in (req.student_profiles or [])] content = teaching_copilot( current_content=req.current_content.strip(), student_profiles=profiles, history=req.history, ) return CopilotResponse(content=content, weaviate_used=USE_WEAVIATE) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) # ------------------------- Course QA Optimizer ------------------------- class QAOptimizeRequest(BaseModel): quiz_summary: str = Field(..., min_length=1, description="学生答题数据摘要(Smart Quiz)") course_topic: Optional[str] = Field(None, description="相关课程主题/章节") history: Optional[list] = Field(None, description="对话历史:[(user_msg, assistant_msg), ...]") class QAOptimizeResponse(BaseModel): ok: bool = True content: str = Field(..., description="薄弱点分析与教学建议(含 References)") weaviate_used: bool = False @router.post("/qa-optimize", response_model=QAOptimizeResponse) def post_qa_optimize(req: QAOptimizeRequest): """基于 Smart Quiz 答题数据分析弱点并给出教学优化建议。""" try: content = optimize_from_quiz_data( quiz_summary=req.quiz_summary.strip(), course_topic=req.course_topic.strip() if req.course_topic else None, history=req.history, ) return QAOptimizeResponse(content=content, weaviate_used=USE_WEAVIATE) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) # ------------------------- Content Generator (Lesson Plan & PPT) ------------------------- class ContentRequest(BaseModel): topic: str = Field(..., min_length=1, description="主题/章节") duration: Optional[str] = Field(None, description="课时/时长建议") outline_points: Optional[str] = Field(None, description="大纲要点") history: Optional[list] = Field(None, description="对话历史:[(user_msg, assistant_msg), ...]") class ContentResponse(BaseModel): ok: bool = True content: str = Field(..., description="Markdown 教案 + PPT 结构化数据(含 References)") weaviate_used: bool = False @router.post("/content", response_model=ContentResponse) def post_content(req: ContentRequest): """生成详细教案(Markdown)与可用于 PPT 的结构化数据。""" try: content = generate_lesson_plan_and_ppt_data( topic=req.topic.strip(), duration=req.duration.strip() if req.duration else None, outline_points=req.outline_points.strip() if req.outline_points else None, history=req.history, ) return ContentResponse(content=content, weaviate_used=USE_WEAVIATE) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) # ------------------------- Status ------------------------- @router.get("/status") def get_courseware_status(): """Courseware Agent 状态与能力列表。""" return { "weaviate_configured": USE_WEAVIATE, "reference_policy": "All outputs include References: [Source: Filename/Page] or [Source: URL]", "modules": [ "vision", # Course Vision & Structure Builder "activities", # Activity & Assignment Designer "copilot", # Teaching Copilot & Student Adaptation "qa-optimize", # Course QA Optimizer "content", # Content Generator (Lesson Plan & PPT) ], }