ソースを参照

本地工具注册

Grizzly 5 ヶ月 前
コミット
7945f3f874

+ 27 - 2
src/main/java/edu/nju/software/aipaasagent/mcp/manage/McpClientService.java

@@ -112,8 +112,33 @@ public class McpClientService {
         rebuild();
     }
     public void getOrRebuild(){
-        //mcpAsyncClientMap 检查服务是否正常
-        //不正常则 rebuild
+        if (mcpAsyncClientMap.isEmpty()) {
+            log.warn("MCP 客户端 map 为空,执行重建");
+            rebuild();
+            return;
+        }
+
+        boolean needRebuild = false;
+        List<String> failedNodes = new ArrayList<>();
+
+        // 检查每个客户端是否正常
+        for (Map.Entry<String, McpAsyncClient> entry : mcpAsyncClientMap.entrySet()) {
+            String nodeName = entry.getKey();
+            McpAsyncClient client = entry.getValue();
+            try {
+                // 简单的健康检查:调用 listTools()
+                client.listTools().block();
+            } catch (Exception e) {
+                log.warn("节点 [{}] 健康检查失败:{}", nodeName, e.getMessage());
+                failedNodes.add(nodeName);
+                needRebuild = true;
+            }
+        }
+
+        if (needRebuild) {
+            log.warn("发现 {} 个节点异常,执行重建:{}", failedNodes.size(), String.join(", ", failedNodes));
+            rebuild();
+        }
     }
 
     // 2. 增加同步锁,防止多线程同时重构

+ 19 - 9
src/main/java/edu/nju/software/aipaasagent/mcp/manage/ToolRegister.java

@@ -62,7 +62,7 @@ public class ToolRegister {
      * 根据配置获取在线工具列表
      * 利用 Spring AI 官方 McpToolCallbackProvider 实现自动转换
      */
-    private ToolCallback createMcpToolCallback(McpSchema.Tool tool, McpAsyncClient client) {
+    private ToolCallback createMcpToolCallback(McpSchema.Tool tool, String nodeName) {
         // 1. 将 inputSchema 转换为正确的 JSON 字符串格式
         String inputSchemaJson;
         try {
@@ -95,19 +95,26 @@ public class ToolRegister {
                     log.info("[MCP Tool] 执行工具 - 工具名:{},入参:{}",
                             toolDefinition.name(), toolInput);
 
-                    // 3. String 入参转 Map(适配旧版本 call(String) 签名)
+                    // 3. 每次调用时从 map 中获取最新的 client
+                    McpAsyncClient client = mcpClientService.getMcpClientMap().get(nodeName);
+                    if (client == null) {
+                        log.error("[MCP Tool] 未找到 MCP 节点:{}", nodeName);
+                        return "Error: 未找到 MCP 节点 " + nodeName;
+                    }
+
+                    // 4. String 入参转 Map(适配旧版本 call(String) 签名)
                     Map<String, Object> inputMap = McpToolUtils.parseJsonToMap(toolInput);
 
-                    // 4. 【关键修复3】移除重复创建 CallToolRequest 的代码
+                    // 5. 创建 CallToolRequest
                     McpSchema.CallToolRequest request = new McpSchema.CallToolRequest(
                             toolDefinition.name(),
                             inputMap
                     );
 
-                    // 5. 调用 MCP 客户端(旧版本用 block() 同步等待)
+                    // 6. 调用 MCP 客户端(旧版本用 block() 同步等待)
                     McpSchema.CallToolResult result = client.callTool(request).block();
 
-                    // 6. 正确处理返回结果
+                    // 7. 正确处理返回结果
                     if (result != null && result.content() != null && !result.content().isEmpty()) {
                         Object firstContent = result.content().get(0);
                         String resultStr = firstContent != null ? firstContent.toString() : "无返回内容";
@@ -119,7 +126,7 @@ public class ToolRegister {
                     log.warn("[MCP Tool] 工具执行成功但未返回内容 - 工具名:{}", toolDefinition.name());
                     return "工具执行成功但未返回内容";
                 } catch (Exception e) {
-                    log.error("[MCP Tool] 执行工具出错 - 工具名:{}", tool.name(), e);
+                    log.error("[MCP Tool] 执行工具出错 - 工具名:{},节点:{}", tool.name(), nodeName, e);
                     return "Error: " + e.getMessage();
                 }
             }
@@ -243,6 +250,9 @@ public class ToolRegister {
     public List<ToolCallback> getTools() {
         List<ToolCallback> allTools = new ArrayList<>();
 
+        // 检查并重建 MCP 客户端
+        mcpClientService.getOrRebuild();
+
         // 获取当前 Agent 配置
         AgentConfiguration config = agentConfigRegistry.getConfig();
         if (config == null) {
@@ -314,7 +324,7 @@ public class ToolRegister {
                         if (toolNames != null && !toolNames.isEmpty()) {
                             for (McpSchema.Tool tool : allTools) {
                                 if (toolNames.contains(tool.name())) {
-                                    ToolCallback callback = createMcpToolCallback(tool, client);
+                                    ToolCallback callback = createMcpToolCallback(tool, nodeName);
                                     toolCallbacks.add(callback);
                                     log.info("✅ 加载工具:{} (节点:{})", tool.name(), nodeName);
                                 }
@@ -322,7 +332,7 @@ public class ToolRegister {
                         } else {
                             // 没有配置工具列表,加载该节点所有工具
                             for (McpSchema.Tool tool : allTools) {
-                                ToolCallback callback = createMcpToolCallback(tool, client);
+                                ToolCallback callback = createMcpToolCallback(tool, nodeName);
                                 toolCallbacks.add(callback);
                                 log.info("✅ 加载工具:{} (节点:{})", tool.name(), nodeName);
                             }
@@ -341,7 +351,7 @@ public class ToolRegister {
                     McpSchema.ListToolsResult toolsResult = client.listTools().block();
                     if (toolsResult != null && toolsResult.tools() != null) {
                         for (McpSchema.Tool tool : toolsResult.tools()) {
-                            ToolCallback callback = createMcpToolCallback(tool, client);
+                            ToolCallback callback = createMcpToolCallback(tool, nodeName);
                             toolCallbacks.add(callback);
                             log.info("✅ 加载工具:{} (节点:{})", tool.name(), nodeName);
                         }