mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-26 00:53:54 +08:00
fix: sanitize MCP tool names for OpenAI
This commit is contained in:
@@ -9,6 +9,7 @@ from mcp import ClientSession, StdioServerParameters
|
||||
from mcp.client.stdio import stdio_client
|
||||
from mcp.client.sse import sse_client
|
||||
from config.logger import setup_logging
|
||||
from core.utils.util import sanitize_tool_name
|
||||
|
||||
TAG = __name__
|
||||
|
||||
@@ -23,7 +24,9 @@ class MCPClient:
|
||||
self._shutdown_evt = asyncio.Event()
|
||||
|
||||
self.session: Optional[ClientSession] = None
|
||||
self.tools: List = []
|
||||
self.tools: List = [] # original tool objects
|
||||
self.tools_dict: Dict[str, Any] = {}
|
||||
self.name_mapping: Dict[str, str] = {}
|
||||
|
||||
async def initialize(self):
|
||||
if self._worker_task:
|
||||
@@ -32,7 +35,7 @@ class MCPClient:
|
||||
await self._ready_evt.wait()
|
||||
|
||||
self.logger.bind(tag=TAG).info(
|
||||
f"Connected, tools = {[t.name for t in self.tools]}"
|
||||
f"Connected, tools = {[name for name in self.name_mapping.values()]}"
|
||||
)
|
||||
|
||||
async def cleanup(self):
|
||||
@@ -48,27 +51,28 @@ class MCPClient:
|
||||
self._worker_task = None
|
||||
|
||||
def has_tool(self, name: str) -> bool:
|
||||
return any(t.name == name for t in self.tools)
|
||||
return name in self.tools_dict
|
||||
|
||||
def get_available_tools(self):
|
||||
return [
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": t.name,
|
||||
"description": t.description,
|
||||
"parameters": t.inputSchema,
|
||||
"name": name,
|
||||
"description": tool.description,
|
||||
"parameters": tool.inputSchema,
|
||||
},
|
||||
}
|
||||
for t in self.tools
|
||||
for name, tool in self.tools_dict.items()
|
||||
]
|
||||
|
||||
async def call_tool(self, name: str, args: dict):
|
||||
if not self.session:
|
||||
raise RuntimeError("MCPClient not initialized")
|
||||
|
||||
real_name = self.name_mapping.get(name, name)
|
||||
loop = self._worker_task.get_loop()
|
||||
coro = self.session.call_tool(name, args)
|
||||
coro = self.session.call_tool(real_name, args)
|
||||
|
||||
if loop is asyncio.get_running_loop():
|
||||
return await coro
|
||||
@@ -123,6 +127,10 @@ class MCPClient:
|
||||
|
||||
# 获取工具
|
||||
self.tools = (await self.session.list_tools()).tools
|
||||
for t in self.tools:
|
||||
sanitized = sanitize_tool_name(t.name)
|
||||
self.tools_dict[sanitized] = t
|
||||
self.name_mapping[sanitized] = t.name
|
||||
|
||||
self._ready_evt.set()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user