mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 08:43:02 +08:00
fix(LocalRunnerClient): support cleaning non-existing MCP Servers' tools while MCP configuration files changed in CommonMcp
This commit is contained in:
@@ -1269,13 +1269,13 @@ public class LocalRunnerClient extends RunnerClient {
|
|||||||
|
|
||||||
private void checkAndReload(boolean trustCache) {
|
private void checkAndReload(boolean trustCache) {
|
||||||
/*
|
/*
|
||||||
for each file cannot present all mcp configurations,
|
for each file cannot present all mcp configurations,
|
||||||
we need to load all at once, and then compare them with existed records.
|
we need to load all at once, and then compare them with existed records.
|
||||||
we will record existing mcp paramsCacheMap and id-params map for which is changed.
|
we will record existing mcp paramsCacheMap and id-params map for which is changed.
|
||||||
|
|
||||||
recording changedMap only cannot figure out which mcp was deleted,
|
recording changedMap only cannot figure out which mcp was deleted,
|
||||||
so existingMcpIdSet attr is required
|
so existingMcpIdSet attr is required
|
||||||
*/
|
*/
|
||||||
val changedMap = new HashMap<String, McpClientTransportParams>();
|
val changedMap = new HashMap<String, McpClientTransportParams>();
|
||||||
val existingMcpIdSet = new HashSet<String>();
|
val existingMcpIdSet = new HashSet<String>();
|
||||||
|
|
||||||
@@ -1349,6 +1349,8 @@ public class LocalRunnerClient extends RunnerClient {
|
|||||||
// new mcp clients and outdated clients has been updated in above logic
|
// new mcp clients and outdated clients has been updated in above logic
|
||||||
// this part focus on removing non-existing mcp
|
// this part focus on removing non-existing mcp
|
||||||
mcpClients.keySet().removeIf(id -> !existingMcpIdSet.contains(id));
|
mcpClients.keySet().removeIf(id -> !existingMcpIdSet.contains(id));
|
||||||
|
// clear relevant tools' action info
|
||||||
|
existedMetaActions.keySet().removeIf(id -> !existingMcpIdSet.contains(id.split("::")[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean fileChanged(File file, McpConfigFileRecord fileRecord) {
|
private boolean fileChanged(File file, McpConfigFileRecord fileRecord) {
|
||||||
|
|||||||
@@ -701,6 +701,40 @@ public class LocalRunnerClientTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCommonMcpRemoveEntryFromConfig(@TempDir Path tempDir) throws IOException, InterruptedException {
|
||||||
|
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();
|
||||||
|
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
||||||
|
new LocalRunnerClient(existedMetaActions, executor, tempDir.toString());
|
||||||
|
|
||||||
|
try {
|
||||||
|
Path mcpDir = tempDir.resolve("action").resolve("mcp");
|
||||||
|
Files.createDirectories(mcpDir);
|
||||||
|
Path configFile = mcpDir.resolve("servers.json");
|
||||||
|
|
||||||
|
String config = buildCommonMcpConfig(
|
||||||
|
buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest"),
|
||||||
|
buildStdioServerEntry("playwright", "@playwright/mcp@latest")
|
||||||
|
);
|
||||||
|
writeCommonMcpConfig(configFile, config);
|
||||||
|
waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")), 20000);
|
||||||
|
waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")), 20000);
|
||||||
|
Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")));
|
||||||
|
Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")));
|
||||||
|
|
||||||
|
String updatedConfig = buildCommonMcpConfig(
|
||||||
|
buildStdioServerEntry("mcp-deepwiki", "mcp-deepwiki@latest")
|
||||||
|
);
|
||||||
|
writeCommonMcpConfig(configFile, updatedConfig);
|
||||||
|
|
||||||
|
waitForCondition(() -> !hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")), 20000);
|
||||||
|
Assertions.assertFalse(hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")));
|
||||||
|
Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("mcp-deepwiki::")));
|
||||||
|
} finally {
|
||||||
|
executor.shutdownNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCommonMcpInvalidJsonRecovery(@TempDir Path tempDir) throws IOException, InterruptedException {
|
void testCommonMcpInvalidJsonRecovery(@TempDir Path tempDir) throws IOException, InterruptedException {
|
||||||
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();
|
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();
|
||||||
|
|||||||
Reference in New Issue
Block a user