|
| 1 | +import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; |
1 | 2 | import { validateToolArguments } from "openclaw/plugin-sdk/llm"; |
2 | 3 | import { describe, expect, it } from "vitest"; |
3 | 4 | import { getPluginToolMeta } from "../plugins/tools.js"; |
@@ -18,6 +19,7 @@ function makeToolRuntime(
|
18 | 19 | params: { |
19 | 20 | tools?: McpCatalogTool[]; |
20 | 21 | serverName?: string; |
| 22 | +result?: CallToolResult; |
21 | 23 | resultText?: string; |
22 | 24 | } = {}, |
23 | 25 | ): SessionMcpRuntime { |
@@ -63,10 +65,11 @@ function makeToolRuntime(
|
63 | 65 | }, |
64 | 66 | tools, |
65 | 67 | }), |
66 | | -callTool: async () => ({ |
67 | | -content: [{ type: "text", text: params.resultText ?? "FROM-BUNDLE" }], |
68 | | -isError: false, |
69 | | -}), |
| 68 | +callTool: async () => |
| 69 | +params.result ?? { |
| 70 | +content: [{ type: "text", text: params.resultText ?? "FROM-BUNDLE" }], |
| 71 | +isError: false, |
| 72 | +}, |
70 | 73 | dispose: async () => {}, |
71 | 74 | }; |
72 | 75 | } |
@@ -87,6 +90,44 @@ describe("createBundleMcpToolRuntime", () => {
|
87 | 90 | }); |
88 | 91 | }); |
89 | 92 | |
| 93 | +it("keeps structuredContent visible when MCP tools also return text content", async () => { |
| 94 | +const runtime = await materializeBundleMcpToolsForRun({ |
| 95 | +runtime: makeToolRuntime({ |
| 96 | +result: { |
| 97 | +content: [{ type: "text", text: "pong" }], |
| 98 | +structuredContent: { |
| 99 | +threadId: "019e6cdb-8e7f-7cb2-891f-9edb689f6fc7", |
| 100 | +content: "pong", |
| 101 | +}, |
| 102 | +isError: false, |
| 103 | +}, |
| 104 | +}), |
| 105 | +}); |
| 106 | + |
| 107 | +const result = await runtime.tools[0].execute("call-bundle-probe", {}, undefined, undefined); |
| 108 | + |
| 109 | +expectTextContentBlock( |
| 110 | +result.content[0], |
| 111 | +`structuredContent:\n${JSON.stringify( |
| 112 | + { |
| 113 | + threadId: "019e6cdb-8e7f-7cb2-891f-9edb689f6fc7", |
| 114 | + content: "pong", |
| 115 | + }, |
| 116 | + null, |
| 117 | + 2, |
| 118 | + )}`, |
| 119 | +); |
| 120 | +expect(result.content).toHaveLength(1); |
| 121 | +expect(result.details).toEqual({ |
| 122 | +mcpServer: "bundleProbe", |
| 123 | +mcpTool: "bundle_probe", |
| 124 | +structuredContent: { |
| 125 | +threadId: "019e6cdb-8e7f-7cb2-891f-9edb689f6fc7", |
| 126 | +content: "pong", |
| 127 | +}, |
| 128 | +}); |
| 129 | +}); |
| 130 | + |
90 | 131 | it("disambiguates bundle MCP tools that collide with existing tool names", async () => { |
91 | 132 | const runtime = await materializeBundleMcpToolsForRun({ |
92 | 133 | runtime: makeToolRuntime(), |
|