mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-27 01:23:55 +08:00
增加mcp调用超时检测逻辑
This commit is contained in:
@@ -322,9 +322,6 @@ class ConnectionHandler:
|
|||||||
|
|
||||||
# Define intent functions
|
# Define intent functions
|
||||||
functions = self.func_handler.get_functions()
|
functions = self.func_handler.get_functions()
|
||||||
mcpfuncs = self.mcp_manager.get_all_tools() # MCP工具
|
|
||||||
functions.extend(mcpfuncs)
|
|
||||||
print("functions with mcp", functions)
|
|
||||||
response_message = []
|
response_message = []
|
||||||
processed_chars = 0 # 跟踪已处理的字符位置
|
processed_chars = 0 # 跟踪已处理的字符位置
|
||||||
|
|
||||||
@@ -482,11 +479,17 @@ class ConnectionHandler:
|
|||||||
args_dict
|
args_dict
|
||||||
), self.loop).result()
|
), self.loop).result()
|
||||||
# meta=None content=[TextContent(type='text', text='北京当前天气:\n温度: 21°C\n天气: 晴\n湿度: 6%\n风向: 西北 风\n风力等级: 5级', annotations=None)] isError=False
|
# meta=None content=[TextContent(type='text', text='北京当前天气:\n温度: 21°C\n天气: 晴\n湿度: 6%\n风向: 西北 风\n风力等级: 5级', annotations=None)] isError=False
|
||||||
self.logger.bind(tag=TAG).info(f"tool_result:{tool_result}")
|
content_text = ""
|
||||||
if tool_result is not None:
|
if tool_result is not None and tool_result.content is not None:
|
||||||
if tool_result.content is not None:
|
for content in tool_result.content:
|
||||||
print(tool_result.content)
|
content_type = content.type
|
||||||
return ActionResponse(action=Action.REQLLM, result=tool_result.content[0].text, response="")
|
if content_type == "text":
|
||||||
|
content_text = content.text
|
||||||
|
elif content_type == "image":
|
||||||
|
pass
|
||||||
|
|
||||||
|
if len(content_text) > 0:
|
||||||
|
return ActionResponse(action=Action.REQLLM, result=content_text, response="")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.bind(tag=TAG).error(f"MCP工具调用错误: {e}")
|
self.logger.bind(tag=TAG).error(f"MCP工具调用错误: {e}")
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import asyncio
|
from datetime import timedelta
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from contextlib import AsyncExitStack
|
from contextlib import AsyncExitStack
|
||||||
import os, shutil
|
import os, shutil
|
||||||
@@ -26,8 +26,10 @@ class MCPClient:
|
|||||||
if self.config["command"] == "npx"
|
if self.config["command"] == "npx"
|
||||||
else self.config["command"]
|
else self.config["command"]
|
||||||
)
|
)
|
||||||
|
|
||||||
env={**os.environ, **self.config["env"]}
|
env={**os.environ}
|
||||||
|
if self.config.get("env"):
|
||||||
|
env.update(self.config["env"])
|
||||||
|
|
||||||
server_params = StdioServerParameters(
|
server_params = StdioServerParameters(
|
||||||
command=command,
|
command=command,
|
||||||
@@ -37,7 +39,8 @@ class MCPClient:
|
|||||||
|
|
||||||
stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))
|
stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))
|
||||||
self.stdio, self.write = stdio_transport
|
self.stdio, self.write = stdio_transport
|
||||||
self.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))
|
time_out_delta = timedelta(seconds=10)
|
||||||
|
self.session = await self.exit_stack.enter_async_context(ClientSession(read_stream=self.stdio, write_stream=self.write, read_timeout_seconds=time_out_delta))
|
||||||
|
|
||||||
await self.session.initialize()
|
await self.session.initialize()
|
||||||
|
|
||||||
@@ -61,7 +64,21 @@ class MCPClient:
|
|||||||
|
|
||||||
async def call_tool(self, tool_name: str, tool_args: dict):
|
async def call_tool(self, tool_name: str, tool_args: dict):
|
||||||
self.logger.bind(tag=TAG).info(f"MCPClient Calling tool {tool_name} with args: {tool_args}")
|
self.logger.bind(tag=TAG).info(f"MCPClient Calling tool {tool_name} with args: {tool_args}")
|
||||||
response = await self.session.call_tool(tool_name, tool_args)
|
try:
|
||||||
|
response = await self.session.call_tool(tool_name, tool_args)
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.bind(tag=TAG).error(f"Error calling tool {tool_name}: {e}")
|
||||||
|
from types import SimpleNamespace
|
||||||
|
error_content = SimpleNamespace(
|
||||||
|
type='text',
|
||||||
|
text=f"Error calling tool {tool_name}: {e}"
|
||||||
|
)
|
||||||
|
error_response = SimpleNamespace(
|
||||||
|
content=[error_content],
|
||||||
|
isError=True
|
||||||
|
)
|
||||||
|
return error_response
|
||||||
|
self.logger.bind(tag=TAG).info(f"MCPClient Response from tool {tool_name}: {response}")
|
||||||
return response
|
return response
|
||||||
|
|
||||||
async def cleanup(self):
|
async def cleanup(self):
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
"""MCP服务管理器"""
|
"""MCP服务管理器"""
|
||||||
import json
|
import os, json
|
||||||
from typing import Dict, Any, List
|
from typing import Dict, Any, List
|
||||||
from .MCPClient import MCPClient
|
from .MCPClient import MCPClient
|
||||||
from config.logger import setup_logging
|
from config.logger import setup_logging
|
||||||
@@ -16,9 +16,12 @@ class MCPManager:
|
|||||||
初始化MCP管理器
|
初始化MCP管理器
|
||||||
"""
|
"""
|
||||||
self.conn = conn
|
self.conn = conn
|
||||||
self.config_path = get_project_dir() + 'data/.mcp_server_settings.json'
|
|
||||||
self.client: Dict[str, MCPClient] = {}
|
|
||||||
self.logger = setup_logging()
|
self.logger = setup_logging()
|
||||||
|
self.config_path = get_project_dir() + 'data/.mcp_server_settings.json'
|
||||||
|
if os.path.exists(self.config_path) == False:
|
||||||
|
self.config_path = ""
|
||||||
|
self.logger.bind(tag=TAG).warning(f"请检查mcp服务配置文件:data/.mcp_server_settings.json")
|
||||||
|
self.client: Dict[str, MCPClient] = {}
|
||||||
self.tools = []
|
self.tools = []
|
||||||
|
|
||||||
def load_config(self) -> Dict[str, Any]:
|
def load_config(self) -> Dict[str, Any]:
|
||||||
@@ -26,6 +29,9 @@ class MCPManager:
|
|||||||
Returns:
|
Returns:
|
||||||
Dict[str, Any]: 服务配置字典
|
Dict[str, Any]: 服务配置字典
|
||||||
"""
|
"""
|
||||||
|
if len(self.config_path) == 0:
|
||||||
|
return {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(self.config_path, 'r', encoding='utf-8') as f:
|
with open(self.config_path, 'r', encoding='utf-8') as f:
|
||||||
config = json.load(f)
|
config = json.load(f)
|
||||||
|
|||||||
Reference in New Issue
Block a user