feat(FN-3717): add OpenClaw MCP bridge (+5 more)
Commits merged: - docs(FN-3717): update openclaw runtime and settings docs - test(FN-3717): fix openclaw engine test typing - test(FN-3717): strengthen openclaw bridge coverage - feat(FN-3717): complete Step 2 — wire engine and bundle delivery - fix(FN-3717): address openclaw bridge review feedback - feat(FN-3717): complete Step 1 — add OpenClaw MCP bridge Files changed: .changeset/fn-3717-openclaw-tool-bridge.md | 5 ++ docs/settings-reference.md | 28 +++++--- packages/cli/src/__tests__/bundle-output.test.ts | 9 +++ packages/cli/tsup.config.ts | 7 ++ .../src/__tests__/openclaw-runtime-e2e.test.ts | 28 ++++++++ .../__tests__/openclaw-runtime-integration.test.ts | 10 +++ plugins/fusion-plugin-openclaw-runtime/README.md | 13 ++++ .../src/__tests__/cli-spawn.test.ts | 82 +++++++++++++++++++--- .../src/__tests__/mcp-config.test.ts | 45 ++++++++++++ .../src/__tests__/runtime-adapter.test.ts | 46 ++++++++++++ .../fusion-plugin-openclaw-runtime/src/index.ts | 5 ++ .../src/mcp-config.ts | 60 ++++++++++++++++ .../src/mcp-schema-server.cjs | 59 ++++++++++++++++ .../src/pi-module.ts | 52 ++++++++++++-- .../src/runtime-adapter.ts | 26 +++++++ .../fusion-plugin-openclaw-runtime/src/types.ts | 4 ++ 16 files changed, 457 insertions(+), 22 deletions(-) Fusion-Task-Id: FN-3717
This commit is contained in:
@@ -7,11 +7,13 @@ const {
|
||||
mockCreateCliSession,
|
||||
mockPromptCli,
|
||||
mockDescribeCliModel,
|
||||
mockConfigureOpenClawMcpServer,
|
||||
} = vi.hoisted(() => ({
|
||||
mockResolveCliConfig: vi.fn(),
|
||||
mockCreateCliSession: vi.fn(),
|
||||
mockPromptCli: vi.fn(),
|
||||
mockDescribeCliModel: vi.fn(),
|
||||
mockConfigureOpenClawMcpServer: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("../pi-module.js", () => ({
|
||||
@@ -19,6 +21,7 @@ vi.mock("../pi-module.js", () => ({
|
||||
createCliSession: mockCreateCliSession,
|
||||
promptCli: mockPromptCli,
|
||||
describeCliModel: mockDescribeCliModel,
|
||||
configureOpenClawMcpServer: mockConfigureOpenClawMcpServer,
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -41,6 +44,7 @@ beforeEach(() => {
|
||||
callbacks,
|
||||
}));
|
||||
mockDescribeCliModel.mockReturnValue("openclaw/main");
|
||||
mockConfigureOpenClawMcpServer.mockResolvedValue(undefined);
|
||||
});
|
||||
|
||||
describe("OpenClawRuntimeAdapter — identity", () => {
|
||||
@@ -58,6 +62,48 @@ describe("OpenClawRuntimeAdapter — identity", () => {
|
||||
});
|
||||
|
||||
describe("OpenClawRuntimeAdapter — createSession", () => {
|
||||
it("configures MCP bridge when custom tools are present", async () => {
|
||||
const adapter = new OpenClawRuntimeAdapter({ agentId: "ops" });
|
||||
await adapter.createSession({
|
||||
cwd: "/repo",
|
||||
systemPrompt: "You are helpful",
|
||||
tools: [
|
||||
{ name: "read", description: "builtin", parameters: { type: "object" } },
|
||||
{ name: "fn_task_list", description: "list", parameters: { type: "object", properties: {} } },
|
||||
],
|
||||
});
|
||||
|
||||
expect(mockConfigureOpenClawMcpServer).toHaveBeenCalledOnce();
|
||||
expect(mockCreateCliSession).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ mcpProfile: expect.stringContaining("fusion-") }),
|
||||
);
|
||||
});
|
||||
|
||||
it("configures MCP bridge when tools arrive through customTools", async () => {
|
||||
const adapter = new OpenClawRuntimeAdapter({ agentId: "ops" });
|
||||
await adapter.createSession({
|
||||
cwd: "/repo",
|
||||
systemPrompt: "You are helpful",
|
||||
customTools: [{ name: "fn_task_show", description: "custom", parameters: { type: "object" } }],
|
||||
});
|
||||
|
||||
expect(mockConfigureOpenClawMcpServer).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("does not configure MCP bridge when only built-in tools are provided", async () => {
|
||||
const adapter = new OpenClawRuntimeAdapter({ agentId: "ops" });
|
||||
await adapter.createSession({
|
||||
cwd: "/repo",
|
||||
systemPrompt: "You are helpful",
|
||||
tools: [{ name: "read", description: "builtin", parameters: { type: "object" } }],
|
||||
});
|
||||
|
||||
expect(mockConfigureOpenClawMcpServer).not.toHaveBeenCalled();
|
||||
expect(mockCreateCliSession).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ mcpProfile: undefined }),
|
||||
);
|
||||
});
|
||||
|
||||
it("delegates to createCliSession with systemPrompt + agentId + callbacks", async () => {
|
||||
const adapter = new OpenClawRuntimeAdapter({ agentId: "ops" });
|
||||
const onText = vi.fn();
|
||||
|
||||
Reference in New Issue
Block a user