From d5884d0974d17d96225a5d80e432de33a5ee6552 Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期四, 19 三月 2026 13:10:21 +0800
Subject: [PATCH] #AI.日志与审计

---
 rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiMcpMountServiceImpl.java |   61 +++++++++++++++++++++++++++++-
 1 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiMcpMountServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiMcpMountServiceImpl.java
index 5bde192..3ef9423 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiMcpMountServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiMcpMountServiceImpl.java
@@ -72,7 +72,10 @@
         AiMcpMount mount = requireMount(mountId, tenantId);
         long startedAt = System.currentTimeMillis();
         try (McpMountRuntimeFactory.McpMountRuntime runtime = mcpMountRuntimeFactory.create(List.of(mount), userId)) {
-            List<AiMcpToolPreviewDto> tools = buildToolPreviewDtos(runtime.getToolCallbacks());
+            List<AiMcpToolPreviewDto> tools = buildToolPreviewDtos(runtime.getToolCallbacks(),
+                    AiDefaults.MCP_TRANSPORT_BUILTIN.equals(mount.getTransportType())
+                            ? builtinMcpToolRegistry.listBuiltinToolCatalog(mount.getBuiltinCode())
+                            : List.of());
             if (!runtime.getErrors().isEmpty()) {
                 String message = String.join("锛�", runtime.getErrors());
                 updateHealthStatus(mount.getId(), AiDefaults.MCP_HEALTH_UNHEALTHY, message, System.currentTimeMillis() - startedAt);
@@ -114,6 +117,48 @@
             updateHealthStatus(mount.getId(), AiDefaults.MCP_HEALTH_UNHEALTHY, message, elapsedMs);
             AiMcpMount latest = requireMount(mount.getId(), tenantId);
             return buildConnectivityDto(latest, message, elapsedMs, 0);
+        }
+    }
+
+    @Override
+    public AiMcpConnectivityTestDto testDraftConnectivity(AiMcpMount mount, Long userId, Long tenantId) {
+        ensureTenantId(tenantId);
+        if (userId == null) {
+            throw new CoolException("褰撳墠鐧诲綍鐢ㄦ埛涓嶅瓨鍦�");
+        }
+        if (mount == null) {
+            throw new CoolException("MCP 鎸傝浇鍙傛暟涓嶈兘涓虹┖");
+        }
+        mount.setTenantId(tenantId);
+        fillDefaults(mount);
+        ensureRequiredFields(mount, tenantId);
+        long startedAt = System.currentTimeMillis();
+        try (McpMountRuntimeFactory.McpMountRuntime runtime = mcpMountRuntimeFactory.create(List.of(mount), userId)) {
+            long elapsedMs = System.currentTimeMillis() - startedAt;
+            if (!runtime.getErrors().isEmpty()) {
+                return AiMcpConnectivityTestDto.builder()
+                        .mountId(mount.getId())
+                        .mountName(mount.getName())
+                        .healthStatus(AiDefaults.MCP_HEALTH_UNHEALTHY)
+                        .message(String.join("锛�", runtime.getErrors()))
+                        .initElapsedMs(elapsedMs)
+                        .toolCount(runtime.getToolCallbacks().length)
+                        .testedAt(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))
+                        .build();
+            }
+            return AiMcpConnectivityTestDto.builder()
+                    .mountId(mount.getId())
+                    .mountName(mount.getName())
+                    .healthStatus(AiDefaults.MCP_HEALTH_HEALTHY)
+                    .message("鑽夌杩為�氭�ф祴璇曟垚鍔燂紝瑙f瀽鍑� " + runtime.getToolCallbacks().length + " 涓伐鍏�")
+                    .initElapsedMs(elapsedMs)
+                    .toolCount(runtime.getToolCallbacks().length)
+                    .testedAt(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))
+                    .build();
+        } catch (CoolException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new CoolException("鑽夌杩為�氭�ф祴璇曞け璐�: " + e.getMessage());
         }
     }
 
@@ -274,17 +319,29 @@
         }
     }
 
-    private List<AiMcpToolPreviewDto> buildToolPreviewDtos(ToolCallback[] callbacks) {
+    private List<AiMcpToolPreviewDto> buildToolPreviewDtos(ToolCallback[] callbacks, List<AiMcpToolPreviewDto> governedCatalog) {
         List<AiMcpToolPreviewDto> tools = new ArrayList<>();
+        Map<String, AiMcpToolPreviewDto> catalogMap = new java.util.LinkedHashMap<>();
+        for (AiMcpToolPreviewDto item : governedCatalog) {
+            if (item == null || !StringUtils.hasText(item.getName())) {
+                continue;
+            }
+            catalogMap.put(item.getName(), item);
+        }
         for (ToolCallback callback : callbacks) {
             if (callback == null || callback.getToolDefinition() == null) {
                 continue;
             }
+            AiMcpToolPreviewDto governedItem = catalogMap.get(callback.getToolDefinition().name());
             tools.add(AiMcpToolPreviewDto.builder()
                     .name(callback.getToolDefinition().name())
                     .description(callback.getToolDefinition().description())
                     .inputSchema(callback.getToolDefinition().inputSchema())
                     .returnDirect(callback.getToolMetadata() == null ? null : callback.getToolMetadata().returnDirect())
+                    .toolGroup(governedItem == null ? null : governedItem.getToolGroup())
+                    .toolPurpose(governedItem == null ? null : governedItem.getToolPurpose())
+                    .queryBoundary(governedItem == null ? null : governedItem.getQueryBoundary())
+                    .exampleQuestions(governedItem == null ? List.of() : governedItem.getExampleQuestions())
                     .build());
         }
         return tools;

--
Gitblit v1.9.1