mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-22 23:23:55 +08:00
Merge branch 'knowledge-base-fix' of https://github.com/xinnan-tech/xiaozhi-esp32-server into Knowledge-Base
This commit is contained in:
@@ -446,7 +446,7 @@ class ConnectionHandler:
|
||||
)
|
||||
if enhanced_prompt:
|
||||
self.change_system_prompt(enhanced_prompt)
|
||||
self.logger.bind(tag=TAG).info("系统提示词已增强更新")
|
||||
self.logger.bind(tag=TAG).debug("系统提示词已增强更新")
|
||||
|
||||
def _init_report_threads(self):
|
||||
"""初始化ASR和TTS上报线程"""
|
||||
|
||||
@@ -43,15 +43,15 @@ async def handleHelloMessage(conn, msg_json):
|
||||
audio_params = msg_json.get("audio_params")
|
||||
if audio_params:
|
||||
format = audio_params.get("format")
|
||||
conn.logger.bind(tag=TAG).info(f"客户端音频格式: {format}")
|
||||
conn.logger.bind(tag=TAG).debug(f"客户端音频格式: {format}")
|
||||
conn.audio_format = format
|
||||
conn.welcome_msg["audio_params"] = audio_params
|
||||
features = msg_json.get("features")
|
||||
if features:
|
||||
conn.logger.bind(tag=TAG).info(f"客户端特性: {features}")
|
||||
conn.logger.bind(tag=TAG).debug(f"客户端特性: {features}")
|
||||
conn.features = features
|
||||
if features.get("mcp"):
|
||||
conn.logger.bind(tag=TAG).info("客户端支持MCP")
|
||||
conn.logger.bind(tag=TAG).debug("客户端支持MCP")
|
||||
conn.mcp_client = MCPClient()
|
||||
# 发送初始化
|
||||
asyncio.create_task(send_mcp_initialize_message(conn))
|
||||
|
||||
@@ -174,7 +174,7 @@ class ASRProvider(ASRProviderBase):
|
||||
|
||||
self.task_id = uuid.uuid4().hex
|
||||
|
||||
logger.bind(tag=TAG).info(f"WebSocket连接建立成功, task_id: {self.task_id}")
|
||||
logger.bind(tag=TAG).debug(f"WebSocket连接建立成功, task_id: {self.task_id}")
|
||||
|
||||
self.is_processing = True
|
||||
self.server_ready = False # 重置服务器准备状态
|
||||
@@ -202,7 +202,7 @@ class ASRProvider(ASRProviderBase):
|
||||
}
|
||||
}
|
||||
await self.asr_ws.send(json.dumps(start_request, ensure_ascii=False))
|
||||
logger.bind(tag=TAG).info("已发送开始请求,等待服务器准备...")
|
||||
logger.bind(tag=TAG).debug("已发送开始请求,等待服务器准备...")
|
||||
|
||||
async def _forward_results(self, conn):
|
||||
"""转发识别结果"""
|
||||
@@ -231,7 +231,7 @@ class ASRProvider(ASRProviderBase):
|
||||
# 收到TranscriptionStarted表示服务器准备好接收音频数据
|
||||
if message_name == "TranscriptionStarted":
|
||||
self.server_ready = True
|
||||
logger.bind(tag=TAG).info("服务器已准备,开始发送缓存音频...")
|
||||
logger.bind(tag=TAG).debug("服务器已准备,开始发送缓存音频...")
|
||||
|
||||
# 发送缓存音频
|
||||
if conn.asr_audio:
|
||||
@@ -281,7 +281,7 @@ class ASRProvider(ASRProviderBase):
|
||||
|
||||
async def _cleanup(self, conn):
|
||||
"""清理资源"""
|
||||
logger.bind(tag=TAG).info(f"开始ASR会话清理 | 当前状态: processing={self.is_processing}, server_ready={self.server_ready}")
|
||||
logger.bind(tag=TAG).debug(f"开始ASR会话清理 | 当前状态: processing={self.is_processing}, server_ready={self.server_ready}")
|
||||
|
||||
# 清理连接的音频缓存
|
||||
if conn and hasattr(conn, 'asr_audio_for_voiceprint'):
|
||||
@@ -304,17 +304,17 @@ class ASRProvider(ASRProviderBase):
|
||||
"appkey": self.appkey
|
||||
}
|
||||
}
|
||||
logger.bind(tag=TAG).info("正在发送ASR终止请求")
|
||||
logger.bind(tag=TAG).debug("正在发送ASR终止请求")
|
||||
await self.asr_ws.send(json.dumps(stop_msg, ensure_ascii=False))
|
||||
await asyncio.sleep(0.1)
|
||||
logger.bind(tag=TAG).info("ASR终止请求已发送")
|
||||
logger.bind(tag=TAG).debug("ASR终止请求已发送")
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).error(f"ASR终止请求发送失败: {e}")
|
||||
|
||||
# 状态重置(在终止请求发送后)
|
||||
self.is_processing = False
|
||||
self.server_ready = False
|
||||
logger.bind(tag=TAG).info("ASR状态已重置")
|
||||
logger.bind(tag=TAG).debug("ASR状态已重置")
|
||||
|
||||
# 清理任务
|
||||
if self.forward_task and not self.forward_task.done():
|
||||
@@ -337,7 +337,7 @@ class ASRProvider(ASRProviderBase):
|
||||
finally:
|
||||
self.asr_ws = None
|
||||
|
||||
logger.bind(tag=TAG).info("ASR会话清理完成")
|
||||
logger.bind(tag=TAG).debug("ASR会话清理完成")
|
||||
|
||||
async def speech_to_text(self, opus_data, session_id, audio_format):
|
||||
"""获取识别结果"""
|
||||
|
||||
@@ -101,7 +101,7 @@ class ASRProviderBase(ABC):
|
||||
self.speech_to_text(asr_audio_task, conn.session_id, conn.audio_format)
|
||||
)
|
||||
end_time = time.monotonic()
|
||||
logger.bind(tag=TAG).info(f"ASR耗时: {end_time - start_time:.3f}s")
|
||||
logger.bind(tag=TAG).debug(f"ASR耗时: {end_time - start_time:.3f}s")
|
||||
return result
|
||||
finally:
|
||||
loop.close()
|
||||
@@ -158,7 +158,7 @@ class ASRProviderBase(ABC):
|
||||
|
||||
# 性能监控
|
||||
total_time = time.monotonic() - total_start_time
|
||||
logger.bind(tag=TAG).info(f"总处理耗时: {total_time:.3f}s")
|
||||
logger.bind(tag=TAG).debug(f"总处理耗时: {total_time:.3f}s")
|
||||
|
||||
# 检查文本长度
|
||||
text_len, _ = remove_punctuation_and_length(raw_text)
|
||||
|
||||
@@ -42,7 +42,7 @@ class MemoryProvider(MemoryProviderBase):
|
||||
if message.role != "system"
|
||||
]
|
||||
result = self.client.add(
|
||||
messages, user_id=self.role_id, output_format=self.api_version
|
||||
messages, user_id=self.role_id
|
||||
)
|
||||
logger.bind(tag=TAG).debug(f"Save memory result: {result}")
|
||||
except Exception as e:
|
||||
@@ -53,9 +53,12 @@ class MemoryProvider(MemoryProviderBase):
|
||||
if not self.use_mem0:
|
||||
return ""
|
||||
try:
|
||||
results = self.client.search(
|
||||
query, user_id=self.role_id, output_format=self.api_version
|
||||
)
|
||||
if not getattr(self, "role_id", None):
|
||||
return ""
|
||||
|
||||
filters = {"user_id": self.role_id}
|
||||
|
||||
results = self.client.search(query, filters=filters)
|
||||
if not results or "results" not in results:
|
||||
return ""
|
||||
|
||||
|
||||
@@ -106,14 +106,14 @@ async def send_mcp_message(conn, payload: dict):
|
||||
|
||||
try:
|
||||
await conn.websocket.send(message)
|
||||
logger.bind(tag=TAG).info(f"成功发送MCP消息: {message}")
|
||||
logger.bind(tag=TAG).debug(f"成功发送MCP消息: {message}")
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).error(f"发送MCP消息失败: {e}")
|
||||
|
||||
|
||||
async def handle_mcp_message(conn, mcp_client: MCPClient, payload: dict):
|
||||
"""处理MCP消息,包括初始化、工具列表和工具调用响应等"""
|
||||
logger.bind(tag=TAG).info(f"处理MCP消息: {str(payload)[:100]}")
|
||||
logger.bind(tag=TAG).debug(f"处理MCP消息: {str(payload)[:100]}")
|
||||
|
||||
if not isinstance(payload, dict):
|
||||
logger.bind(tag=TAG).error("MCP消息缺少payload字段或格式错误")
|
||||
@@ -138,7 +138,7 @@ async def handle_mcp_message(conn, mcp_client: MCPClient, payload: dict):
|
||||
if isinstance(server_info, dict):
|
||||
name = server_info.get("name")
|
||||
version = server_info.get("version")
|
||||
logger.bind(tag=TAG).info(
|
||||
logger.bind(tag=TAG).debug(
|
||||
f"客户端MCP服务器信息: name={name}, version={version}"
|
||||
)
|
||||
return
|
||||
@@ -195,11 +195,11 @@ async def handle_mcp_message(conn, mcp_client: MCPClient, payload: dict):
|
||||
|
||||
next_cursor = result.get("nextCursor", "")
|
||||
if next_cursor:
|
||||
logger.bind(tag=TAG).info(f"有更多工具,nextCursor: {next_cursor}")
|
||||
logger.bind(tag=TAG).debug(f"有更多工具,nextCursor: {next_cursor}")
|
||||
await send_mcp_tools_list_continue_request(conn, next_cursor)
|
||||
else:
|
||||
await mcp_client.set_ready(True)
|
||||
logger.bind(tag=TAG).info("所有工具已获取,MCP客户端准备就绪")
|
||||
logger.bind(tag=TAG).debug("所有工具已获取,MCP客户端准备就绪")
|
||||
|
||||
# 刷新工具缓存,确保MCP工具被包含在函数列表中
|
||||
if hasattr(conn, "func_handler") and conn.func_handler:
|
||||
@@ -255,7 +255,7 @@ async def send_mcp_initialize_message(conn):
|
||||
},
|
||||
},
|
||||
}
|
||||
logger.bind(tag=TAG).info("发送MCP初始化消息")
|
||||
logger.bind(tag=TAG).debug("发送MCP初始化消息")
|
||||
await send_mcp_message(conn, payload)
|
||||
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ class UnifiedToolHandler:
|
||||
self._initialize_home_assistant()
|
||||
|
||||
self.finish_init = True
|
||||
self.logger.info("统一工具处理器初始化完成")
|
||||
self.logger.debug("统一工具处理器初始化完成")
|
||||
|
||||
# 输出当前支持的所有工具列表
|
||||
self.current_support_functions()
|
||||
|
||||
@@ -20,7 +20,7 @@ class ToolManager:
|
||||
"""注册工具执行器"""
|
||||
self.executors[tool_type] = executor
|
||||
self._invalidate_cache()
|
||||
self.logger.info(f"注册工具执行器: {tool_type.value}")
|
||||
self.logger.debug(f"注册工具执行器: {tool_type.value}")
|
||||
|
||||
def _invalidate_cache(self):
|
||||
"""使缓存失效"""
|
||||
@@ -109,7 +109,7 @@ class ToolManager:
|
||||
def refresh_tools(self):
|
||||
"""刷新工具缓存"""
|
||||
self._invalidate_cache()
|
||||
self.logger.info("工具缓存已刷新")
|
||||
self.logger.debug("工具缓存已刷新")
|
||||
|
||||
def get_tool_statistics(self) -> Dict[str, int]:
|
||||
"""获取工具统计信息"""
|
||||
|
||||
@@ -189,7 +189,7 @@ class TTSProvider(TTSProviderBase):
|
||||
self.task_id = uuid.uuid4().hex
|
||||
logger.bind(tag=TAG).info(f"使用已有链接..., task_id: {self.task_id}")
|
||||
return self.ws
|
||||
logger.bind(tag=TAG).info("开始建立新连接...")
|
||||
logger.bind(tag=TAG).debug("开始建立新连接...")
|
||||
|
||||
self.ws = await websockets.connect(
|
||||
self.ws_url,
|
||||
@@ -199,7 +199,7 @@ class TTSProvider(TTSProviderBase):
|
||||
close_timeout=10,
|
||||
)
|
||||
self.task_id = uuid.uuid4().hex
|
||||
logger.bind(tag=TAG).info(f"WebSocket连接建立成功, task_id: {self.task_id}")
|
||||
logger.bind(tag=TAG).debug(f"WebSocket连接建立成功, task_id: {self.task_id}")
|
||||
self.last_active_time = time.time()
|
||||
return self.ws
|
||||
except Exception as e:
|
||||
@@ -227,14 +227,14 @@ class TTSProvider(TTSProviderBase):
|
||||
if message.sentence_type == SentenceType.FIRST:
|
||||
# 初始化参数
|
||||
try:
|
||||
logger.bind(tag=TAG).info("开始启动TTS会话...")
|
||||
logger.bind(tag=TAG).debug("开始启动TTS会话...")
|
||||
future = asyncio.run_coroutine_threadsafe(
|
||||
self.start_session(self.task_id),
|
||||
loop=self.conn.loop,
|
||||
)
|
||||
future.result()
|
||||
self.before_stop_play_files.clear()
|
||||
logger.bind(tag=TAG).info("TTS会话启动成功")
|
||||
logger.bind(tag=TAG).debug("TTS会话启动成功")
|
||||
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).error(f"启动TTS会话失败: {str(e)}")
|
||||
@@ -265,7 +265,7 @@ class TTSProvider(TTSProviderBase):
|
||||
self._process_audio_file_stream(message.content_file, callback=lambda audio_data: self.handle_audio_file(audio_data, message.content_detail))
|
||||
if message.sentence_type == SentenceType.LAST:
|
||||
try:
|
||||
logger.bind(tag=TAG).info("开始结束TTS会话...")
|
||||
logger.bind(tag=TAG).debug("开始结束TTS会话...")
|
||||
future = asyncio.run_coroutine_threadsafe(
|
||||
self.finish_session(self.task_id),
|
||||
loop=self.conn.loop,
|
||||
@@ -313,7 +313,7 @@ class TTSProvider(TTSProviderBase):
|
||||
raise
|
||||
|
||||
async def start_session(self, task_id):
|
||||
logger.bind(tag=TAG).info("开始会话~~")
|
||||
logger.bind(tag=TAG).debug("开始会话~~")
|
||||
try:
|
||||
# 会话开始时检测上个会话的监听状态
|
||||
if (
|
||||
@@ -352,7 +352,7 @@ class TTSProvider(TTSProviderBase):
|
||||
}
|
||||
await self.ws.send(json.dumps(start_request))
|
||||
self.last_active_time = time.time()
|
||||
logger.bind(tag=TAG).info("会话启动请求已发送")
|
||||
logger.bind(tag=TAG).debug("会话启动请求已发送")
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).error(f"启动会话失败: {str(e)}")
|
||||
# 确保清理资源
|
||||
@@ -360,7 +360,7 @@ class TTSProvider(TTSProviderBase):
|
||||
raise
|
||||
|
||||
async def finish_session(self, task_id):
|
||||
logger.bind(tag=TAG).info(f"关闭会话~~{task_id}")
|
||||
logger.bind(tag=TAG).debug(f"关闭会话~~{task_id}")
|
||||
try:
|
||||
if self.ws:
|
||||
stop_request = {
|
||||
@@ -373,7 +373,7 @@ class TTSProvider(TTSProviderBase):
|
||||
}
|
||||
}
|
||||
await self.ws.send(json.dumps(stop_request))
|
||||
logger.bind(tag=TAG).info("会话结束请求已发送")
|
||||
logger.bind(tag=TAG).debug("会话结束请求已发送")
|
||||
self.last_active_time = time.time()
|
||||
if self._monitor_task:
|
||||
try:
|
||||
|
||||
@@ -186,7 +186,7 @@ class TTSProvider(TTSProviderBase):
|
||||
if self.ws:
|
||||
logger.bind(tag=TAG).info(f"使用已有链接...")
|
||||
return self.ws
|
||||
logger.bind(tag=TAG).info("开始建立新连接...")
|
||||
logger.bind(tag=TAG).debug("开始建立新连接...")
|
||||
ws_header = {
|
||||
"X-Api-App-Key": self.appId,
|
||||
"X-Api-Access-Key": self.access_token,
|
||||
@@ -196,11 +196,11 @@ class TTSProvider(TTSProviderBase):
|
||||
self.ws = await websockets.connect(
|
||||
self.ws_url, additional_headers=ws_header, max_size=1000000000
|
||||
)
|
||||
logger.bind(tag=TAG).info("WebSocket连接建立成功")
|
||||
logger.bind(tag=TAG).debug("WebSocket连接建立成功")
|
||||
|
||||
# 连接建立成功后,启动监听任务
|
||||
if self._monitor_task is None or self._monitor_task.done():
|
||||
logger.bind(tag=TAG).info("启动监听任务...")
|
||||
logger.bind(tag=TAG).debug("启动监听任务...")
|
||||
self._monitor_task = asyncio.create_task(self._start_monitor_tts_response())
|
||||
|
||||
return self.ws
|
||||
@@ -238,16 +238,16 @@ class TTSProvider(TTSProviderBase):
|
||||
try:
|
||||
if not getattr(self.conn, "sentence_id", None):
|
||||
self.conn.sentence_id = uuid.uuid4().hex
|
||||
logger.bind(tag=TAG).info(f"自动生成新的 会话ID: {self.conn.sentence_id}")
|
||||
logger.bind(tag=TAG).debug(f"自动生成新的 会话ID: {self.conn.sentence_id}")
|
||||
|
||||
logger.bind(tag=TAG).info("开始启动TTS会话...")
|
||||
logger.bind(tag=TAG).debu("开始启动TTS会话...")
|
||||
future = asyncio.run_coroutine_threadsafe(
|
||||
self.start_session(self.conn.sentence_id),
|
||||
loop=self.conn.loop,
|
||||
)
|
||||
future.result()
|
||||
self.before_stop_play_files.clear()
|
||||
logger.bind(tag=TAG).info("TTS会话启动成功")
|
||||
logger.bind(tag=TAG).debug("TTS会话启动成功")
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).error(f"启动TTS会话失败: {str(e)}")
|
||||
continue
|
||||
@@ -277,7 +277,7 @@ class TTSProvider(TTSProviderBase):
|
||||
self._process_audio_file_stream(message.content_file, callback=lambda audio_data: self.handle_audio_file(audio_data, message.content_detail))
|
||||
if message.sentence_type == SentenceType.LAST:
|
||||
try:
|
||||
logger.bind(tag=TAG).info("开始结束TTS会话...")
|
||||
logger.bind(tag=TAG).debug("开始结束TTS会话...")
|
||||
future = asyncio.run_coroutine_threadsafe(
|
||||
self.finish_session(self.conn.sentence_id),
|
||||
loop=self.conn.loop,
|
||||
@@ -320,7 +320,7 @@ class TTSProvider(TTSProviderBase):
|
||||
raise
|
||||
|
||||
async def start_session(self, session_id):
|
||||
logger.bind(tag=TAG).info(f"开始会话~~{session_id}")
|
||||
logger.bind(tag=TAG).debug(f"开始会话~~{session_id}")
|
||||
try:
|
||||
# 等待上一个会话结束,最多等待3次
|
||||
for _ in range(3):
|
||||
@@ -351,7 +351,7 @@ class TTSProvider(TTSProviderBase):
|
||||
event=EVENT_StartSession, speaker=self.voice
|
||||
)
|
||||
await self.send_event(self.ws, header, optional, payload)
|
||||
logger.bind(tag=TAG).info("会话启动请求已发送")
|
||||
logger.bind(tag=TAG).debug("会话启动请求已发送")
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).error(f"启动会话失败: {str(e)}")
|
||||
# 确保清理资源
|
||||
@@ -359,7 +359,7 @@ class TTSProvider(TTSProviderBase):
|
||||
raise
|
||||
|
||||
async def finish_session(self, session_id):
|
||||
logger.bind(tag=TAG).info(f"关闭会话~~{session_id}")
|
||||
logger.bind(tag=TAG).debug(f"关闭会话~~{session_id}")
|
||||
try:
|
||||
if self.ws:
|
||||
header = Header(
|
||||
@@ -372,7 +372,7 @@ class TTSProvider(TTSProviderBase):
|
||||
).as_bytes()
|
||||
payload = str.encode("{}")
|
||||
await self.send_event(self.ws, header, optional, payload)
|
||||
logger.bind(tag=TAG).info("会话结束请求已发送")
|
||||
logger.bind(tag=TAG).debug("会话结束请求已发送")
|
||||
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).error(f"关闭会话失败: {str(e)}")
|
||||
@@ -381,7 +381,7 @@ class TTSProvider(TTSProviderBase):
|
||||
raise
|
||||
|
||||
async def cancel_session(self,session_id):
|
||||
logger.bind(tag=TAG).info(f"取消会话,释放服务端资源~~{session_id}")
|
||||
logger.bind(tag=TAG).debug(f"取消会话,释放服务端资源~~{session_id}")
|
||||
try:
|
||||
if self.ws:
|
||||
header = Header(
|
||||
@@ -394,7 +394,7 @@ class TTSProvider(TTSProviderBase):
|
||||
).as_bytes()
|
||||
payload = str.encode("{}")
|
||||
await self.send_event(self.ws, header, optional, payload)
|
||||
logger.bind(tag=TAG).info("会话取消请求已发送")
|
||||
logger.bind(tag=TAG).debug("会话取消请求已发送")
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).error(f"取消会话失败: {str(e)}")
|
||||
# 确保清理资源
|
||||
|
||||
@@ -184,7 +184,7 @@ class PromptManager:
|
||||
local_address = self._get_location_info(client_ip)
|
||||
# 获取天气信息(使用全局缓存)
|
||||
self._get_weather_info(conn, local_address)
|
||||
self.logger.bind(tag=TAG).info(f"上下文信息更新完成")
|
||||
self.logger.bind(tag=TAG).debug(f"上下文信息更新完成")
|
||||
|
||||
except Exception as e:
|
||||
self.logger.bind(tag=TAG).error(f"更新上下文信息失败: {e}")
|
||||
|
||||
Reference in New Issue
Block a user