mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 08:43:02 +08:00
refactor(mcp): switch desc.json loading to fastjson2 to avoid desc.json loading error
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
package work.slhaf.partner.core.action.runner.mcp;
|
package work.slhaf.partner.core.action.runner.mcp;
|
||||||
|
|
||||||
import cn.hutool.json.JSONUtil;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import io.modelcontextprotocol.common.McpTransportContext;
|
import io.modelcontextprotocol.common.McpTransportContext;
|
||||||
import io.modelcontextprotocol.json.McpJsonMapper;
|
import io.modelcontextprotocol.json.McpJsonMapper;
|
||||||
@@ -241,7 +241,7 @@ public class DynamicActionMcpManager implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
MetaActionInfo info;
|
MetaActionInfo info;
|
||||||
try {
|
try {
|
||||||
info = JSONUtil.readJSONObject(dir.resolve("desc.json").toFile(), StandardCharsets.UTF_8).toBean(MetaActionInfo.class);
|
info = JSON.parseObject(Files.readString(dir.resolve("desc.json"), StandardCharsets.UTF_8), MetaActionInfo.class);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("desc.json 加载失败: {}", dir);
|
log.error("desc.json 加载失败: {}", dir);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package work.slhaf.partner.core.action.runner.mcp;
|
package work.slhaf.partner.core.action.runner.mcp;
|
||||||
|
|
||||||
import cn.hutool.json.JSONUtil;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import io.modelcontextprotocol.common.McpTransportContext;
|
import io.modelcontextprotocol.common.McpTransportContext;
|
||||||
import io.modelcontextprotocol.json.McpJsonMapper;
|
import io.modelcontextprotocol.json.McpJsonMapper;
|
||||||
@@ -70,7 +70,7 @@ public class McpMetaRegistry implements AutoCloseable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
MetaActionInfo info = JSONUtil.readJSONObject(file, StandardCharsets.UTF_8).toBean(MetaActionInfo.class);
|
MetaActionInfo info = JSON.parseObject(Files.readString(file.toPath(), StandardCharsets.UTF_8), MetaActionInfo.class);
|
||||||
String uri = file.toPath().toUri().toString();
|
String uri = file.toPath().toUri().toString();
|
||||||
descCache.put(uri, JSONObject.toJSONString(info));
|
descCache.put(uri, JSONObject.toJSONString(info));
|
||||||
String actionKey = name.replace(".desc.json", "");
|
String actionKey = name.replace(".desc.json", "");
|
||||||
|
|||||||
@@ -183,11 +183,34 @@ public class LocalRunnerClientTest {
|
|||||||
+ " }";
|
+ " }";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String buildStdioServerEntry(String id, String packageName, Path npmCacheDir) {
|
||||||
|
String cachePath = npmCacheDir.toAbsolutePath().toString().replace("\\", "\\\\");
|
||||||
|
return " \"" + id + "\": {\n"
|
||||||
|
+ " \"command\": \"npx\",\n"
|
||||||
|
+ " \"args\": [\n"
|
||||||
|
+ " \"-y\",\n"
|
||||||
|
+ " \"" + packageName + "\"\n"
|
||||||
|
+ " ],\n"
|
||||||
|
+ " \"env\": {\n"
|
||||||
|
+ " \"NPM_CONFIG_CACHE\": \"" + cachePath + "\",\n"
|
||||||
|
+ " \"npm_config_cache\": \"" + cachePath + "\"\n"
|
||||||
|
+ " }\n"
|
||||||
|
+ " }";
|
||||||
|
}
|
||||||
|
|
||||||
static MetaAction buildMetaAction(MetaAction.Type type, String location, String name, Map<String, Object> params) {
|
static MetaAction buildMetaAction(MetaAction.Type type, String location, String name, Map<String, Object> params) {
|
||||||
|
return buildMetaAction(type, location, name, null, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MetaAction buildMetaAction(MetaAction.Type type,
|
||||||
|
String location,
|
||||||
|
String name,
|
||||||
|
String launcher,
|
||||||
|
Map<String, Object> params) {
|
||||||
MetaAction metaAction = new MetaAction(
|
MetaAction metaAction = new MetaAction(
|
||||||
name,
|
name,
|
||||||
false,
|
false,
|
||||||
null,
|
launcher,
|
||||||
type,
|
type,
|
||||||
location
|
location
|
||||||
);
|
);
|
||||||
@@ -698,12 +721,13 @@ public class LocalRunnerClientTest {
|
|||||||
void testCommonMcpInitialLoad(@TempDir Path tempDir) throws IOException, InterruptedException {
|
void testCommonMcpInitialLoad(@TempDir Path tempDir) throws IOException, InterruptedException {
|
||||||
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();
|
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();
|
||||||
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
||||||
|
Path npmCacheDir = tempDir.resolve("npm-cache");
|
||||||
|
|
||||||
Path mcpDir = tempDir.resolve("action").resolve("mcp");
|
Path mcpDir = tempDir.resolve("action").resolve("mcp");
|
||||||
Files.createDirectories(mcpDir);
|
Files.createDirectories(mcpDir);
|
||||||
Path configFile = mcpDir.resolve("servers.json");
|
Path configFile = mcpDir.resolve("servers.json");
|
||||||
String config = buildCommonMcpConfig(
|
String config = buildCommonMcpConfig(
|
||||||
buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest")
|
buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest", npmCacheDir)
|
||||||
);
|
);
|
||||||
writeCommonMcpConfig(configFile, config);
|
writeCommonMcpConfig(configFile, config);
|
||||||
|
|
||||||
@@ -722,6 +746,7 @@ public class LocalRunnerClientTest {
|
|||||||
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();
|
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();
|
||||||
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
||||||
new LocalRunnerClient(existedMetaActions, executor, tempDir.toString());
|
new LocalRunnerClient(existedMetaActions, executor, tempDir.toString());
|
||||||
|
Path npmCacheDir = tempDir.resolve("npm-cache");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Path mcpDir = tempDir.resolve("action").resolve("mcp");
|
Path mcpDir = tempDir.resolve("action").resolve("mcp");
|
||||||
@@ -729,15 +754,15 @@ public class LocalRunnerClientTest {
|
|||||||
Path configFile = mcpDir.resolve("servers.json");
|
Path configFile = mcpDir.resolve("servers.json");
|
||||||
|
|
||||||
String config = buildCommonMcpConfig(
|
String config = buildCommonMcpConfig(
|
||||||
buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest")
|
buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest", npmCacheDir)
|
||||||
);
|
);
|
||||||
writeCommonMcpConfig(configFile, config);
|
writeCommonMcpConfig(configFile, config);
|
||||||
waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")), 20000);
|
waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")), 20000);
|
||||||
Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")));
|
Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")));
|
||||||
|
|
||||||
String updatedConfig = buildCommonMcpConfig(
|
String updatedConfig = buildCommonMcpConfig(
|
||||||
buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest"),
|
buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest", npmCacheDir),
|
||||||
buildStdioServerEntry("playwright", "@playwright/mcp@latest")
|
buildStdioServerEntry("playwright", "@playwright/mcp@latest", npmCacheDir)
|
||||||
);
|
);
|
||||||
writeCommonMcpConfig(configFile, updatedConfig);
|
writeCommonMcpConfig(configFile, updatedConfig);
|
||||||
waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")), 20000);
|
waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")), 20000);
|
||||||
@@ -757,6 +782,7 @@ public class LocalRunnerClientTest {
|
|||||||
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();
|
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();
|
||||||
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
||||||
new LocalRunnerClient(existedMetaActions, executor, tempDir.toString());
|
new LocalRunnerClient(existedMetaActions, executor, tempDir.toString());
|
||||||
|
Path npmCacheDir = tempDir.resolve("npm-cache");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Path mcpDir = tempDir.resolve("action").resolve("mcp");
|
Path mcpDir = tempDir.resolve("action").resolve("mcp");
|
||||||
@@ -764,8 +790,8 @@ public class LocalRunnerClientTest {
|
|||||||
Path configFile = mcpDir.resolve("servers.json");
|
Path configFile = mcpDir.resolve("servers.json");
|
||||||
|
|
||||||
String config = buildCommonMcpConfig(
|
String config = buildCommonMcpConfig(
|
||||||
buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest"),
|
buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest", npmCacheDir),
|
||||||
buildStdioServerEntry("playwright", "@playwright/mcp@latest")
|
buildStdioServerEntry("playwright", "@playwright/mcp@latest", npmCacheDir)
|
||||||
);
|
);
|
||||||
writeCommonMcpConfig(configFile, config);
|
writeCommonMcpConfig(configFile, config);
|
||||||
waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")), 20000);
|
waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")), 20000);
|
||||||
@@ -774,7 +800,7 @@ public class LocalRunnerClientTest {
|
|||||||
Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")));
|
Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")));
|
||||||
|
|
||||||
String updatedConfig = buildCommonMcpConfig(
|
String updatedConfig = buildCommonMcpConfig(
|
||||||
buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest")
|
buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest", npmCacheDir)
|
||||||
);
|
);
|
||||||
writeCommonMcpConfig(configFile, updatedConfig);
|
writeCommonMcpConfig(configFile, updatedConfig);
|
||||||
|
|
||||||
@@ -791,6 +817,7 @@ public class LocalRunnerClientTest {
|
|||||||
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();
|
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();
|
||||||
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
||||||
new LocalRunnerClient(existedMetaActions, executor, tempDir.toString());
|
new LocalRunnerClient(existedMetaActions, executor, tempDir.toString());
|
||||||
|
Path npmCacheDir = tempDir.resolve("npm-cache");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Path mcpDir = tempDir.resolve("action").resolve("mcp");
|
Path mcpDir = tempDir.resolve("action").resolve("mcp");
|
||||||
@@ -802,7 +829,7 @@ public class LocalRunnerClientTest {
|
|||||||
Assertions.assertFalse(hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")));
|
Assertions.assertFalse(hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")));
|
||||||
|
|
||||||
String config = buildCommonMcpConfig(
|
String config = buildCommonMcpConfig(
|
||||||
buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest")
|
buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest", npmCacheDir)
|
||||||
);
|
);
|
||||||
writeCommonMcpConfig(configFile, config);
|
writeCommonMcpConfig(configFile, config);
|
||||||
waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")), 20000);
|
waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")), 20000);
|
||||||
@@ -830,7 +857,7 @@ public class LocalRunnerClientTest {
|
|||||||
RunnerClient.RunnerResponse response = client.doRun(metaAction);
|
RunnerClient.RunnerResponse response = client.doRun(metaAction);
|
||||||
Assertions.assertNotNull(response);
|
Assertions.assertNotNull(response);
|
||||||
Assertions.assertFalse(response.isOk());
|
Assertions.assertFalse(response.isOk());
|
||||||
Assertions.assertEquals("未知文件类型", response.getData());
|
Assertions.assertTrue(response.getData().contains("parameter command"));
|
||||||
} finally {
|
} finally {
|
||||||
executor.shutdownNow();
|
executor.shutdownNow();
|
||||||
}
|
}
|
||||||
@@ -845,7 +872,7 @@ public class LocalRunnerClientTest {
|
|||||||
try {
|
try {
|
||||||
Path script = tempDir.resolve("run.sh");
|
Path script = tempDir.resolve("run.sh");
|
||||||
Files.writeString(script, "echo ok\n");
|
Files.writeString(script, "echo ok\n");
|
||||||
MetaAction metaAction = buildMetaAction(MetaAction.Type.ORIGIN, script.toString(), "run", Map.of());
|
MetaAction metaAction = buildMetaAction(MetaAction.Type.ORIGIN, script.toString(), "run", "sh", Map.of());
|
||||||
RunnerClient.RunnerResponse response = client.doRun(metaAction);
|
RunnerClient.RunnerResponse response = client.doRun(metaAction);
|
||||||
Assertions.assertNotNull(response);
|
Assertions.assertNotNull(response);
|
||||||
Assertions.assertTrue(response.isOk());
|
Assertions.assertTrue(response.isOk());
|
||||||
@@ -927,12 +954,13 @@ public class LocalRunnerClientTest {
|
|||||||
void testDoRunWithMcpLoadedFromCommonConfig(@TempDir Path tempDir) throws IOException, InterruptedException {
|
void testDoRunWithMcpLoadedFromCommonConfig(@TempDir Path tempDir) throws IOException, InterruptedException {
|
||||||
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();
|
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();
|
||||||
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
||||||
|
Path npmCacheDir = tempDir.resolve("npm-cache");
|
||||||
|
|
||||||
Path mcpDir = tempDir.resolve("action").resolve("mcp");
|
Path mcpDir = tempDir.resolve("action").resolve("mcp");
|
||||||
Files.createDirectories(mcpDir);
|
Files.createDirectories(mcpDir);
|
||||||
Path configFile = mcpDir.resolve("servers.json");
|
Path configFile = mcpDir.resolve("servers.json");
|
||||||
String config = buildCommonMcpConfig(
|
String config = buildCommonMcpConfig(
|
||||||
buildStdioServerEntry("playwright", "@playwright/mcp@latest")
|
buildStdioServerEntry("playwright", "@playwright/mcp@latest", npmCacheDir)
|
||||||
);
|
);
|
||||||
writeCommonMcpConfig(configFile, config);
|
writeCommonMcpConfig(configFile, config);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user