50 lines
1.9 KiB
Python
50 lines
1.9 KiB
Python
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"},
|
|
)
|