From 05744cb9f49e3510b01e7f3296c38505c76305d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E6=BD=AE?= Date: Mon, 19 Jan 2026 09:44:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=B9=E9=87=8F=E4=BF=9D=E5=AD=98=E8=81=8A?= =?UTF-8?q?=E5=A4=A9=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routes/chat.py | 79 ++++++++++++++++++++++++++++++++++++++++++++- utils/__init__.py | 6 +++- utils/api_models.py | 16 +++++++++ 3 files changed, 99 insertions(+), 2 deletions(-) diff --git a/routes/chat.py b/routes/chat.py index dd0e9bf..d415dda 100644 --- a/routes/chat.py +++ b/routes/chat.py @@ -8,7 +8,7 @@ import logging logger = logging.getLogger('app') from utils import ( - Message, ChatRequest, ChatResponse + Message, ChatRequest, ChatResponse, BatchSaveChatRequest, BatchSaveChatResponse ) from utils.api_models import ChatRequestV2 from utils.fastapi_utils import ( @@ -712,3 +712,80 @@ async def get_chat_history( logger.error(f"Error in get_chat_history: {str(e)}") logger.error(f"Full traceback: {error_details}") raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}") + + +@router.post("/api/v1/chat/history/batch", response_model=BatchSaveChatResponse) +async def batch_save_chat_history(request: BatchSaveChatRequest): + """ + 批量保存聊天记录 + + 支持自定义批量保存多条聊天消息到数据库 + + 参数: + session_id: 会话ID + messages: 要保存的消息列表,每条消息包含 role 和 content + bot_id: 机器人ID(可选) + + 请求体示例: + { + "session_id": "test-session-123", + "messages": [ + {"role": "user", "content": "你好"}, + {"role": "assistant", "content": "你好!有什么可以帮助你的吗?"}, + {"role": "user", "content": "咖啡多少钱一杯"} + ], + "bot_id": "63069654-7750-409d-9a58-a0960d899a20" + } + + 返回: + { + "success": true, + "message": "成功保存 3 条消息", + "session_id": "test-session-123", + "saved_count": 3, + "message_ids": ["uuid1", "uuid2", "uuid3"] + } + """ + try: + from agent.chat_history_manager import get_chat_history_manager + + # 参数验证 + if not request.session_id: + raise HTTPException(status_code=400, detail="session_id is required") + + if not request.messages or len(request.messages) == 0: + raise HTTPException(status_code=400, detail="messages list is empty") + + # 转换消息格式 + messages_dict = [ + {"role": msg.role, "content": msg.content} + for msg in request.messages + ] + + manager = get_chat_history_manager() + message_ids = await manager.manager.save_messages( + session_id=request.session_id, + messages=messages_dict, + bot_id=request.bot_id + ) + + # 过滤掉 None 值 + valid_message_ids = [mid for mid in message_ids if mid is not None] + saved_count = len(valid_message_ids) + + return BatchSaveChatResponse( + success=True, + message=f"成功保存 {saved_count} 条消息", + session_id=request.session_id, + saved_count=saved_count, + message_ids=valid_message_ids + ) + + except HTTPException: + raise + except Exception as e: + import traceback + error_details = traceback.format_exc() + logger.error(f"Error in batch_save_chat_history: {str(e)}") + logger.error(f"Full traceback: {error_details}") + raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}") diff --git a/utils/__init__.py b/utils/__init__.py index a905e32..2bfefd0 100644 --- a/utils/__init__.py +++ b/utils/__init__.py @@ -66,7 +66,9 @@ from .api_models import ( TaskStatusResponse, create_success_response, create_error_response, - create_chat_response + create_chat_response, + BatchSaveChatRequest, + BatchSaveChatResponse ) from .multi_project_manager import ( @@ -133,6 +135,8 @@ __all__ = [ 'create_success_response', 'create_error_response', 'create_chat_response', + 'BatchSaveChatRequest', + 'BatchSaveChatResponse', # multi_project_manager 'create_robot_project', diff --git a/utils/api_models.py b/utils/api_models.py index 2db59d3..1f97fb9 100644 --- a/utils/api_models.py +++ b/utils/api_models.py @@ -403,3 +403,19 @@ class ChatHistoryResponse(BaseModel): """聊天历史查询响应""" messages: List[ChatHistoryMessage] = Field(..., description="消息列表,按时间倒序排列") has_more: bool = Field(..., description="是否还有更多历史消息") + + +class BatchSaveChatRequest(BaseModel): + """批量保存聊天记录请求""" + session_id: str = Field(..., description="会话ID (thread_id)") + messages: List[Message] = Field(..., description="要保存的消息列表,支持 user 和 assistant 角色") + bot_id: Optional[str] = Field(None, description="机器人ID") + + +class BatchSaveChatResponse(BaseModel): + """批量保存聊天记录响应""" + success: bool = Field(..., description="是否成功") + message: str = Field(..., description="响应消息") + session_id: str = Field(..., description="会话ID") + saved_count: int = Field(..., description="成功保存的消息数量") + message_ids: List[str] = Field(..., description="保存的消息ID列表")