From b05f094ac51dce91eb8c00235226d54a04658c6d Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期一, 23 三月 2026 15:51:17 +0800
Subject: [PATCH] #ai 页面优化
---
rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/McpMountRuntimeFactoryImpl.java | 98 ++++++------------------------------------------
1 files changed, 13 insertions(+), 85 deletions(-)
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/McpMountRuntimeFactoryImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/McpMountRuntimeFactoryImpl.java
index a290fd7..cd8285a 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/McpMountRuntimeFactoryImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/McpMountRuntimeFactoryImpl.java
@@ -1,20 +1,13 @@
package com.vincent.rsf.server.ai.service.impl;
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.ai.config.AiDefaults;
import com.vincent.rsf.server.ai.entity.AiMcpMount;
import com.vincent.rsf.server.ai.service.BuiltinMcpToolRegistry;
import com.vincent.rsf.server.ai.service.MountedToolCallback;
import com.vincent.rsf.server.ai.service.McpMountRuntimeFactory;
-import io.modelcontextprotocol.client.McpClient;
import io.modelcontextprotocol.client.McpSyncClient;
-import io.modelcontextprotocol.client.transport.HttpClientSseClientTransport;
-import io.modelcontextprotocol.client.transport.ServerParameters;
-import io.modelcontextprotocol.client.transport.StdioClientTransport;
-import io.modelcontextprotocol.json.jackson.JacksonMcpJsonMapper;
-import io.modelcontextprotocol.spec.McpSchema;
+import com.vincent.rsf.server.ai.service.impl.mcp.McpClientFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.mcp.SyncMcpToolCallbackProvider;
@@ -22,23 +15,25 @@
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
-import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
-import java.util.LinkedHashMap;
import java.util.List;
-import java.util.Map;
@Slf4j
@Service
@RequiredArgsConstructor
public class McpMountRuntimeFactoryImpl implements McpMountRuntimeFactory {
- private final ObjectMapper objectMapper;
private final BuiltinMcpToolRegistry builtinMcpToolRegistry;
+ private final McpClientFactory mcpClientFactory;
+ /**
+ * 鎶婁竴缁� MCP 鎸傝浇璁板綍瑙f瀽鎴愪竴娆″璇濆彲鐩存帴浣跨敤鐨勮繍琛屾椂瀵硅薄銆�
+ * 璇ユ柟娉曠粺涓�澶勭悊鍐呯疆 MCP銆佽繙绋� SSE MCP 鍜屾湰鍦� STDIO MCP锛�
+ * 鍚屾椂鏀堕泦鎸傝浇鎴愬姛椤广�佸け璐ラ」浠ュ強鏈�缁堟毚闇茬粰妯″瀷鐨勫伐鍏峰洖璋冨垪琛ㄣ��
+ */
@Override
public McpMountRuntime create(List<AiMcpMount> mounts, Long userId) {
List<McpSyncClient> clients = new ArrayList<>();
@@ -55,7 +50,7 @@
mountedNames.add(mount.getName());
continue;
}
- McpSyncClient client = createClient(mount);
+ McpSyncClient client = mcpClientFactory.createClient(mount);
client.initialize();
client.listTools();
clients.add(client);
@@ -75,6 +70,7 @@
}
private List<ToolCallback> wrapMountedCallbacks(List<ToolCallback> source, String mountName) {
+ /** 涓烘瘡涓伐鍏峰洖璋冭ˉ涓婃寕杞芥潵婧愶紝渚夸簬鍚庣画瀹¤銆佽娴嬪拰鍓嶇宸ュ叿杞ㄨ抗灞曠ず銆� */
List<ToolCallback> mountedCallbacks = new ArrayList<>();
for (ToolCallback callback : source) {
if (callback == null) {
@@ -86,6 +82,7 @@
}
private void ensureUniqueToolNames(List<ToolCallback> callbacks) {
+ /** 纭繚澶氭寕杞借仛鍚堝悗涓嶄細鍑虹幇鍚屽悕宸ュ叿锛屽惁鍒欐ā鍨嬩晶鏃犳硶姝g‘鍒嗚鲸宸ュ叿瀹氫箟銆� */
LinkedHashSet<String> duplicateNames = new LinkedHashSet<>();
LinkedHashSet<String> seenNames = new LinkedHashSet<>();
for (ToolCallback callback : callbacks) {
@@ -105,78 +102,6 @@
}
}
- private McpSyncClient createClient(AiMcpMount mount) {
- Duration timeout = Duration.ofMillis(mount.getRequestTimeoutMs() == null
- ? AiDefaults.DEFAULT_TIMEOUT_MS
- : mount.getRequestTimeoutMs());
- JacksonMcpJsonMapper jsonMapper = new JacksonMcpJsonMapper(objectMapper);
- if (AiDefaults.MCP_TRANSPORT_STDIO.equals(mount.getTransportType())) {
- ServerParameters.Builder parametersBuilder = ServerParameters.builder(mount.getCommand());
- List<String> args = readStringList(mount.getArgsJson());
- if (!args.isEmpty()) {
- parametersBuilder.args(args);
- }
- Map<String, String> env = readStringMap(mount.getEnvJson());
- if (!env.isEmpty()) {
- parametersBuilder.env(env);
- }
- StdioClientTransport transport = new StdioClientTransport(parametersBuilder.build(), jsonMapper);
- transport.setStdErrorHandler(message -> log.warn("MCP STDIO stderr [{}]: {}", mount.getName(), message));
- return McpClient.sync(transport)
- .requestTimeout(timeout)
- .initializationTimeout(timeout)
- .clientInfo(new McpSchema.Implementation("rsf-ai-client", "RSF AI Client", "1.0.0"))
- .build();
- }
- if (!AiDefaults.MCP_TRANSPORT_SSE_HTTP.equals(mount.getTransportType())) {
- throw new CoolException("涓嶆敮鎸佺殑 MCP 浼犺緭绫诲瀷: " + mount.getTransportType());
- }
-
- if (!StringUtils.hasText(mount.getServerUrl())) {
- throw new CoolException("MCP 鏈嶅姟鍦板潃涓嶈兘涓虹┖");
- }
- HttpClientSseClientTransport.Builder transportBuilder = HttpClientSseClientTransport.builder(mount.getServerUrl())
- .jsonMapper(jsonMapper)
- .connectTimeout(timeout);
- if (StringUtils.hasText(mount.getEndpoint())) {
- transportBuilder.sseEndpoint(mount.getEndpoint());
- }
- Map<String, String> headers = readStringMap(mount.getHeadersJson());
- if (!headers.isEmpty()) {
- transportBuilder.customizeRequest(builder -> headers.forEach(builder::header));
- }
- return McpClient.sync(transportBuilder.build())
- .requestTimeout(timeout)
- .initializationTimeout(timeout)
- .clientInfo(new McpSchema.Implementation("rsf-ai-client", "RSF AI Client", "1.0.0"))
- .build();
- }
-
- private List<String> readStringList(String json) {
- if (!StringUtils.hasText(json)) {
- return Collections.emptyList();
- }
- try {
- return objectMapper.readValue(json, new TypeReference<List<String>>() {
- });
- } catch (Exception e) {
- throw new CoolException("瑙f瀽 MCP 鍒楄〃閰嶇疆澶辫触: " + e.getMessage());
- }
- }
-
- private Map<String, String> readStringMap(String json) {
- if (!StringUtils.hasText(json)) {
- return Collections.emptyMap();
- }
- try {
- Map<String, String> result = objectMapper.readValue(json, new TypeReference<LinkedHashMap<String, String>>() {
- });
- return result == null ? Collections.emptyMap() : result;
- } catch (Exception e) {
- throw new CoolException("瑙f瀽 MCP Map 閰嶇疆澶辫触: " + e.getMessage());
- }
- }
-
private static class DefaultMcpMountRuntime implements McpMountRuntime {
private final List<McpSyncClient> clients;
@@ -184,6 +109,7 @@
private final List<String> mountedNames;
private final List<String> errors;
+ /** 杩愯鏃跺璞℃湰韬彧鍋氭暟鎹皝瑁呭拰璧勬簮閲婃斁锛屼笉寮曞叆棰濆涓氬姟閫昏緫銆� */
private DefaultMcpMountRuntime(List<McpSyncClient> clients, ToolCallback[] callbacks, List<String> mountedNames, List<String> errors) {
this.clients = clients;
this.callbacks = callbacks;
@@ -213,6 +139,7 @@
@Override
public void close() {
+ /** 缁熶竴鍏抽棴鏈杩愯鏃堕噷鍒涘缓鐨勫閮� MCP Client锛岄伩鍏嶈繛鎺ユ硠婕忋�� */
for (McpSyncClient client : clients) {
try {
client.close();
@@ -228,6 +155,7 @@
private final ToolCallback delegate;
private final String mountName;
+ /** 瑁呴グ鍣ㄤ粎琛ュ厖鎸傝浇鏉ユ簮锛屼笉鏀瑰彉搴曞眰宸ュ叿瀹氫箟鍜岃皟鐢ㄨ涓恒�� */
private MountedToolCallbackImpl(ToolCallback delegate, String mountName) {
this.delegate = delegate;
this.mountName = mountName;
--
Gitblit v1.9.1