Merge pull request #3102 from xinnan-tech/fix-title-summary

fix:将标题总结从记忆流程中拆分为独立接口,支持异步执行
This commit is contained in:
wengzh
2026-04-16 17:24:56 +08:00
committed by GitHub
9 changed files with 63 additions and 21 deletions
@@ -195,6 +195,18 @@ async def generate_and_save_chat_summary(session_id: str) -> Optional[Dict]:
return None
async def generate_and_save_chat_title(session_id: str) -> Optional[Dict]:
"""生成并保存聊天标题"""
try:
return await ManageApiClient._instance._execute_async_request(
"POST",
f"/agent/chat-title/{session_id}/generate",
)
except Exception as e:
print(f"生成并保存聊天标题失败: {e}")
return None
async def report(
mac_address: str, session_id: str, chat_type: int, content: str, audio, report_time
) -> Optional[Dict]:
+21 -1
View File
@@ -37,7 +37,7 @@ from core.auth import AuthenticationError
from config.config_loader import get_private_config_from_api
from core.providers.tts.dto.dto import ContentType, TTSMessageDTO, SentenceType
from config.logger import setup_logging, build_module_string, create_connection_logger
from config.manage_api_client import DeviceNotFoundException, DeviceBindException
from config.manage_api_client import DeviceNotFoundException, DeviceBindException, generate_and_save_chat_title
from core.utils.prompt_manager import PromptManager
from core.utils.voiceprint_provider import VoiceprintProvider
from core.utils.util import get_system_error_response
@@ -284,6 +284,26 @@ class ConnectionHandler:
async def _save_and_close(self, ws):
"""保存记忆并关闭连接"""
try:
# 守护线程1:独立生成标题(不依赖记忆模型)
if self.session_id:
def generate_title_task():
try:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(
generate_and_save_chat_title(self.session_id)
)
except Exception as e:
self.logger.bind(tag=TAG).error(f"生成标题失败: {e}")
finally:
try:
loop.close()
except Exception:
pass
threading.Thread(target=generate_title_task, daemon=True).start()
# 守护线程2:走老流程记忆保存(仅记忆,不含标题)
if self.memory:
# 使用线程池异步保存记忆
def save_memory_task():
@@ -2,7 +2,6 @@ import json
import traceback
from ..base import MemoryProviderBase, logger
from config.manage_api_client import generate_and_save_chat_summary
from mem0 import MemoryClient
from core.utils.util import check_model_key
@@ -59,11 +58,6 @@ class MemoryProvider(MemoryProviderBase):
except Exception as e:
logger.bind(tag=TAG).error(f"保存记忆失败: {str(e)}")
# Generate and save chat summary (SLM summarizes session title)
# This is independent of Mem0AI's memory saving
if session_id:
await generate_and_save_chat_summary(session_id)
return None
async def query_memory(self, query: str) -> str:
@@ -3,7 +3,6 @@
"""
from ..base import MemoryProviderBase, logger
from config.manage_api_client import generate_and_save_chat_summary
TAG = __name__
@@ -14,8 +13,6 @@ class MemoryProvider(MemoryProviderBase):
async def save_memory(self, msgs, session_id=None):
logger.bind(tag=TAG).debug("mem_report_only mode: No memory saving or summarization is performed.")
if session_id:
await generate_and_save_chat_summary(session_id)
return None
async def query_memory(self, query: str) -> str:
@@ -16,7 +16,6 @@ import traceback
from typing import Optional, Dict, Any
from ..base import MemoryProviderBase, logger
from config.manage_api_client import generate_and_save_chat_summary
TAG = __name__
@@ -211,11 +210,6 @@ class MemoryProvider(MemoryProviderBase):
logger.bind(tag=TAG).error(f"Error saving memory: {str(e)}")
logger.bind(tag=TAG).debug(f"Detailed error: {traceback.format_exc()}")
# Generate and save chat summary (SLM summarizes session title)
# This is independent of PowerMem's memory saving
if session_id:
await generate_and_save_chat_summary(session_id)
return None
async def query_memory(self, query: str) -> str: