feat: 完成 Agent MCP 对接
- 增加 MCP 连接类型、环境检测接口和容器运行环境支持 - 将 Agent 编排改为绑定整体 MCP 并编译为 runtime McpSpec - 优化 MCP 工具展示、审批、草稿试运行和画布回显稳定性
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
package tech.easyflow.ai.mcp;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import tech.easyflow.ai.service.impl.McpServiceImpl;
|
||||
import tech.easyflow.common.web.exceptions.BusinessException;
|
||||
|
||||
/**
|
||||
* {@link McpTransportType} 单元测试。
|
||||
*/
|
||||
public class McpTransportTypeTest {
|
||||
|
||||
/**
|
||||
* 应兼容解析 MCP 配置中常见的连接方式文本。
|
||||
*/
|
||||
@Test
|
||||
public void fromShouldParseSupportedTransportTypes() {
|
||||
Assert.assertEquals(McpTransportType.STDIO, McpTransportType.from("stdio"));
|
||||
Assert.assertEquals(McpTransportType.SSE, McpTransportType.from("sse"));
|
||||
Assert.assertEquals(McpTransportType.SSE, McpTransportType.from("http-sse"));
|
||||
Assert.assertEquals(McpTransportType.HTTP, McpTransportType.from("http"));
|
||||
Assert.assertEquals(McpTransportType.HTTP, McpTransportType.from("http-stream"));
|
||||
Assert.assertEquals(McpTransportType.HTTP, McpTransportType.from("streamable-http"));
|
||||
Assert.assertEquals(McpTransportType.STDIO, McpTransportType.from(null));
|
||||
Assert.assertEquals(McpTransportType.STDIO, McpTransportType.from(" "));
|
||||
}
|
||||
|
||||
/**
|
||||
* 应从 MCP 配置 JSON 中推断首个 server 的连接方式。
|
||||
*/
|
||||
@Test
|
||||
public void getFirstMcpTransportTypeShouldInferFromConfigJson() {
|
||||
Assert.assertEquals("stdio", McpServiceImpl.getFirstMcpTransportType("""
|
||||
{"mcpServers":{"everything":{"command":"npx","args":["-y","@modelcontextprotocol/server-everything"]}}}
|
||||
"""));
|
||||
Assert.assertEquals("http-sse", McpServiceImpl.getFirstMcpTransportType("""
|
||||
{"mcpServers":{"remote":{"transport":"http-sse","url":"http://127.0.0.1:3000/sse"}}}
|
||||
"""));
|
||||
Assert.assertEquals("http-stream", McpServiceImpl.getFirstMcpTransportType("""
|
||||
{"mcpServers":{"remote":{"transport":"http-stream","url":"http://127.0.0.1:3000/mcp"}}}
|
||||
"""));
|
||||
}
|
||||
|
||||
/**
|
||||
* 不支持的连接方式应直接失败,避免保存无法启动的 MCP 配置。
|
||||
*/
|
||||
@Test
|
||||
public void getFirstMcpTransportTypeShouldRejectUnsupportedTransportType() {
|
||||
try {
|
||||
McpServiceImpl.getFirstMcpTransportType("""
|
||||
{"mcpServers":{"remote":{"transport":"websocket","url":"ws://127.0.0.1:3000/mcp"}}}
|
||||
""");
|
||||
Assert.fail("expected BusinessException");
|
||||
} catch (BusinessException exception) {
|
||||
Assert.assertTrue(exception.getMessage().contains("不支持的 MCP 连接方式"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,4 +70,25 @@ public class ChatAssistantAccumulatorTest {
|
||||
Assert.assertEquals(1, secondToolCalls.size());
|
||||
Assert.assertEquals("call-2", secondToolCalls.get(0).get("id"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 工具展示名应进入展示链和 assistant toolCalls,但不覆盖真实工具名。
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void shouldKeepToolDisplayNameWithoutOverridingToolName() {
|
||||
ChatAssistantAccumulator accumulator = new ChatAssistantAccumulator();
|
||||
accumulator.appendToolCall("call-1", "mcp_123_search", "知识库 MCP - search", "{\"q\":\"java\"}");
|
||||
accumulator.appendToolResult("call-1", "mcp_123_search", "知识库 MCP - search", "{\"ok\":true}");
|
||||
|
||||
Map<String, Object> payload = accumulator.buildPayload(null);
|
||||
List<Map<String, Object>> chains = (List<Map<String, Object>>) payload.get("chains");
|
||||
List<Map<String, Object>> messageChain = (List<Map<String, Object>>) payload.get("messageChain");
|
||||
List<Map<String, Object>> toolCalls = (List<Map<String, Object>>) messageChain.get(0).get("toolCalls");
|
||||
|
||||
Assert.assertEquals("mcp_123_search", chains.get(0).get("name"));
|
||||
Assert.assertEquals("知识库 MCP - search", chains.get(0).get("toolDisplayName"));
|
||||
Assert.assertEquals("mcp_123_search", toolCalls.get(0).get("name"));
|
||||
Assert.assertEquals("知识库 MCP - search", toolCalls.get(0).get("toolDisplayName"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user