""" 聊天总结 API 路由 处理聊天记录的总结请求 """ import logging from typing import Dict, Any from fastapi import APIRouter, HTTPException, Body from fastapi.responses import JSONResponse from services.chat_service import chat_service from services.chat_summary_service import chat_summary_service from models.internal import SummaryConfig logger = logging.getLogger(__name__) router = APIRouter(prefix="/chats", tags=["chat-summary"]) @router.post("/{role_name}/{chat_name}/summarize") async def summarize_chat_history( role_name: str, chat_name: str, request_data: Dict[str, Any] = Body(...) ): """ 总结聊天历史记录 Args: role_name: 角色名称 chat_name: 聊天名称 request_data: { "startFloor": int, # 总结起始楼层 "endFloor": int, # 总结结束楼层 "summaryConfig": {...}, # 总结配置 "apiConfig": {...} # API配置 } Returns: { "success": bool, "summaryText": str, # 总结文本 "startFloor": int, "endFloor": int, "message": str } """ try: # 1. 提取请求参数 start_floor = request_data.get("startFloor") end_floor = request_data.get("endFloor") summary_config_data = request_data.get("summaryConfig", {}) api_config = request_data.get("apiConfig", {}) if not start_floor or not end_floor: raise HTTPException(status_code=400, detail="缺少 startFloor 或 endFloor 参数") # 2. 加载聊天记录 chat_log = chat_service.get_chat_log(role_name, chat_name) if not chat_log: raise HTTPException(status_code=404, detail=f"聊天记录 '{role_name}/{chat_name}' 不存在") messages = chat_log.messages total_messages = len(messages) # 3. 验证楼层范围 if start_floor < 1 or end_floor > total_messages or start_floor > end_floor: raise HTTPException( status_code=400, detail=f"无效的楼层范围: {start_floor}-{end_floor}(总共{total_messages}条消息)" ) # 4. 构建SummaryConfig对象 summary_config = SummaryConfig(**summary_config_data) logger.info( f"[ChatSummary] 开始总结: {role_name}/{chat_name}, " f"楼层范围: {start_floor}-{end_floor}, " f"包含用户输入: {summary_config.includeUserInput}" ) # 5. 调用总结服务 summary_text = await chat_summary_service.summarize_messages( messages=messages, start_floor=start_floor, end_floor=end_floor, summary_config=summary_config, api_config=api_config ) if not summary_text: raise HTTPException(status_code=500, detail="总结生成失败") logger.info(f"[ChatSummary] 总结完成,长度: {len(summary_text)} 字符") # 6. 更新聊天记录(清空原文 + 替换总结) chat_service.summarize_chat_messages( role_name=role_name, chat_name=chat_name, start_floor=start_floor, end_floor=end_floor, summary_text=summary_text ) return { "success": True, "summaryText": summary_text, "startFloor": start_floor, "endFloor": end_floor, "message": f"成功总结 {end_floor - start_floor + 1} 条消息" } except HTTPException: raise except Exception as e: logger.error(f"[ChatSummary] 总结失败: {str(e)}") import traceback traceback.print_exc() raise HTTPException(status_code=500, detail=f"总结失败: {str(e)}") @router.get("/{role_name}/{chat_name}/summary-status") async def get_summary_status(role_name: str, chat_name: str): """ 获取聊天总结状态 Returns: { "historyMode": str, "summaryCounter": int, "lastSummaryFloor": int, "summaryConfig": {...} } """ try: chat_log = chat_service.get_chat_log(role_name, chat_name) if not chat_log: raise HTTPException(status_code=404, detail="聊天记录不存在") header = chat_log.header return { "historyMode": header.historyMode.value if hasattr(header.historyMode, 'value') else header.historyMode, "summaryCounter": header.summaryCounter or 0, "lastSummaryFloor": getattr(header, 'lastSummaryFloor', 0), "summaryConfig": header.summaryConfig.dict() if header.summaryConfig else None } except HTTPException: raise except Exception as e: logger.error(f"[ChatSummary] 获取总结状态失败: {str(e)}") raise HTTPException(status_code=500, detail=str(e))