from fastapi import APIRouter, Depends from sqlalchemy.orm import Session from starlette.responses import StreamingResponse from app.core.response import ApiResponse, ok from app.core.user_context import UserContext, get_user_context from app.db.session import get_db from app.schemas.learning_assistant import ( LearningAssistantChatRequest, LearningAssistantSessionCreateRequest, LearningAssistantSessionResponse, ) from app.services.learning_assistant_service import LearningAssistantService router = APIRouter() @router.post("/sessions", response_model=ApiResponse[LearningAssistantSessionResponse]) async def create_learning_assistant_session( payload: LearningAssistantSessionCreateRequest, ctx: UserContext = Depends(get_user_context), db: Session = Depends(get_db), ): """学习助手会话创建:进入 AI 学习助手页面时生成短期会话 ID。""" result = LearningAssistantService(db).create_session(ctx, payload) return ok(result) @router.post("/sessions/{assistant_session_id}/chat/stream", response_class=StreamingResponse) async def stream_learning_assistant_session_chat( assistant_session_id: str, payload: LearningAssistantChatRequest, ctx: UserContext = Depends(get_user_context), db: Session = Depends(get_db), ): """学习助手会话式流式问答:绑定短期会话上下文,返回 SSE 增量回答。""" service = LearningAssistantService(db) assistant_session = service.validate_session(ctx, assistant_session_id) stream = service.stream_session_chat(ctx, payload, assistant_session) return _sse_response(stream) def _sse_response(stream) -> StreamingResponse: """SSE 响应封装:关闭代理缓冲,避免前端长时间看不到增量内容。""" return StreamingResponse( stream, media_type="text/event-stream", headers={"Cache-Control": "no-cache", "Connection": "keep-alive", "X-Accel-Buffering": "no"}, )