From a47ae8ef16f20c0f9872d7019496948d61aa25a5 Mon Sep 17 00:00:00 2001 From: FuQuan233 Date: Fri, 7 Nov 2025 16:59:19 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20=E6=9B=B4=E6=96=B0=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E5=88=97=E8=A1=A8=E7=BC=93=E5=AD=98=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8D=E5=B7=A5=E5=85=B7=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nonebot_plugin_llmchat/__init__.py | 21 ++++++--- nonebot_plugin_llmchat/mcpclient.py | 73 +++++++++++++++-------------- 2 files changed, 51 insertions(+), 43 deletions(-) diff --git a/nonebot_plugin_llmchat/__init__.py b/nonebot_plugin_llmchat/__init__.py index a311dc0..9317a6b 100755 --- a/nonebot_plugin_llmchat/__init__.py +++ b/nonebot_plugin_llmchat/__init__.py @@ -278,7 +278,7 @@ async def handle_message(event: GroupMessageEvent | PrivateMessageEvent): task.add_done_callback(tasks.discard) tasks.add(task) -async def process_images(event: GroupMessageEvent) -> list[str]: +async def process_images(event: GroupMessageEvent | PrivateMessageEvent) -> list[str]: base64_images = [] for segement in event.get_message(): if segement.type == "image": @@ -478,12 +478,19 @@ async def process_messages(context_id: int, is_group: bool = True): # 发送工具调用提示 await handler.send(Message(f"正在使用{mcp_client.get_friendly_name(tool_name)}")) - result = await mcp_client.call_tool( - tool_name, - tool_args, - group_id=event.group_id, - bot_id=str(event.self_id) - ) + if is_group: + result = await mcp_client.call_tool( + tool_name, + tool_args, + group_id=event.group_id, + bot_id=str(event.self_id) + ) + else: + result = await mcp_client.call_tool( + tool_name, + tool_args, + bot_id=str(event.self_id) + ) new_messages.append({ "role": "tool", diff --git a/nonebot_plugin_llmchat/mcpclient.py b/nonebot_plugin_llmchat/mcpclient.py index 9a53865..8861dd9 100644 --- a/nonebot_plugin_llmchat/mcpclient.py +++ b/nonebot_plugin_llmchat/mcpclient.py @@ -106,45 +106,46 @@ class MCPClient: return SessionContext() + async def init_tools_cache(self): + """初始化工具列表缓存""" + if not self._cache_initialized: + available_tools = [] + logger.info(f"初始化工具列表缓存,需要连接{len(self.server_config)}个服务器") + for server_name in self.server_config.keys(): + logger.debug(f"正在从服务器[{server_name}]获取工具列表") + async with self._create_session_context(server_name) as session: + response = await session.list_tools() + tools = response.tools + logger.debug(f"在服务器[{server_name}]中找到{len(tools)}个工具") + + available_tools.extend( + { + "type": "function", + "function": { + "name": f"mcp__{server_name}__{tool.name}", + "description": tool.description, + "parameters": tool.inputSchema, + }, + } + for tool in tools + ) + + # 缓存工具列表 + self._tools_cache = available_tools + self._cache_initialized = True + + logger.info(f"工具列表缓存完成,共缓存{len(available_tools)}个工具") + + + async def get_available_tools(self, is_group: bool): """获取可用工具列表,使用缓存机制""" - if self._tools_cache is not None: - logger.debug("返回缓存的工具列表") - return self._tools_cache - - logger.info(f"初始化工具列表缓存,需要连接{len(self.server_config)}个服务器") - available_tools = [] - + await self.init_tools_cache() + available_tools = self._tools_cache.copy() if self._tools_cache else [] if is_group: - # 添加OneBot内置工具,仅在群聊中可用 - onebot_tools = self.onebot_tools.get_available_tools() - available_tools.extend(onebot_tools) - logger.debug(f"添加了{len(onebot_tools)}个OneBot内置工具") - - # 添加MCP服务器工具 - for server_name in self.server_config.keys(): - logger.debug(f"正在从服务器[{server_name}]获取工具列表") - async with self._create_session_context(server_name) as session: - response = await session.list_tools() - tools = response.tools - logger.debug(f"在服务器[{server_name}]中找到{len(tools)}个工具") - - available_tools.extend( - { - "type": "function", - "function": { - "name": f"mcp__{server_name}__{tool.name}", - "description": tool.description, - "parameters": tool.inputSchema, - }, - } - for tool in tools - ) - - # 缓存工具列表 - self._tools_cache = available_tools - self._cache_initialized = True - logger.info(f"工具列表缓存完成,共缓存{len(available_tools)}个工具") + # 群聊场景,包含OneBot工具和MCP工具 + available_tools.extend(self.onebot_tools.get_available_tools()) + logger.debug(f"获取可用工具列表,共{len(available_tools)}个工具") return available_tools async def call_tool(self, tool_name: str, tool_args: dict, group_id: int | None = None, bot_id: str | None = None):