Skip to content

Commit 124119a

Browse files
authored
test(plugins): sync release contracts (#102777)
* test(plugins): sync release contracts * test(codex): isolate dynamic tool capability test
1 parent fdd19e3 commit 124119a

3 files changed

Lines changed: 53 additions & 11 deletions

File tree

extensions/canvas/index.test.ts

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { AnyAgentTool, OpenClawPluginApi } from "openclaw/plugin-sdk/plugin
33
import { createTestPluginApi } from "openclaw/plugin-sdk/plugin-test-api";
44
import { beforeEach, describe, expect, it, vi } from "vitest";
55
import canvasPlugin from "./index.js";
6+
import { SHOW_WIDGET_REQUIRED_CLIENT_CAPS } from "./src/tool-schema.js";
67

78
const mocks = vi.hoisted(() => {
89
const httpHandler = {
@@ -11,6 +12,7 @@ const mocks = vi.hoisted(() => {
1112
close: vi.fn(async () => {}),
1213
};
1314
const toolExecute = vi.fn(async () => ({ content: [{ type: "text", text: "ok" }] }));
15+
const widgetToolExecute = vi.fn(async () => ({ content: [{ type: "text", text: "widget" }] }));
1416
return {
1517
httpHandler,
1618
createCanvasHttpRouteHandler: vi.fn(() => httpHandler),
@@ -25,6 +27,14 @@ const mocks = vi.hoisted(() => {
2527
parameters: {},
2628
execute: toolExecute,
2729
})),
30+
widgetToolExecute,
31+
createShowWidgetTool: vi.fn(() => ({
32+
label: "Show Widget",
33+
name: "show_widget",
34+
description: "Show Widget",
35+
parameters: {},
36+
execute: widgetToolExecute,
37+
})),
2838
};
2939
});
3040

@@ -45,11 +55,18 @@ vi.mock("./src/tool.js", () => ({
4555
createCanvasTool: mocks.createCanvasTool,
4656
}));
4757

58+
vi.mock("./src/widget-tool.js", () => ({
59+
createShowWidgetTool: mocks.createShowWidgetTool,
60+
}));
61+
4862
function registerCanvas() {
4963
const routes: Array<Parameters<OpenClawPluginApi["registerHttpRoute"]>[0]> = [];
5064
const services: Array<Parameters<OpenClawPluginApi["registerService"]>[0]> = [];
5165
const resolvers: Array<Parameters<OpenClawPluginApi["registerHostedMediaResolver"]>[0]> = [];
52-
const tools: Array<Parameters<OpenClawPluginApi["registerTool"]>[0]> = [];
66+
const tools: Array<{
67+
tool: Parameters<OpenClawPluginApi["registerTool"]>[0];
68+
opts: Parameters<OpenClawPluginApi["registerTool"]>[1];
69+
}> = [];
5370
const cliFeatures: Array<{
5471
registrar: Parameters<OpenClawPluginApi["registerNodeCliFeature"]>[0];
5572
opts: Parameters<OpenClawPluginApi["registerNodeCliFeature"]>[1];
@@ -62,7 +79,7 @@ function registerCanvas() {
6279
registerHttpRoute: (route) => routes.push(route),
6380
registerService: (service) => services.push(service),
6481
registerHostedMediaResolver: (resolver) => resolvers.push(resolver),
65-
registerTool: (tool) => tools.push(tool),
82+
registerTool: (tool, opts) => tools.push({ tool, opts }),
6683
registerNodeCliFeature: (registrar, opts) => cliFeatures.push({ registrar, opts }),
6784
registerNodeInvokePolicy: vi.fn(),
6885
}),
@@ -97,11 +114,13 @@ describe("Canvas plugin entry", () => {
97114
const { resolvers, tools, cliFeatures } = registerCanvas();
98115

99116
expect(resolvers).toHaveLength(1);
100-
expect(tools).toHaveLength(1);
117+
expect(tools).toHaveLength(2);
118+
expect(tools.map(({ opts }) => opts?.name)).toEqual([undefined, "show_widget"]);
101119
expect(cliFeatures).toHaveLength(1);
102120
expect(mocks.resolveCanvasHttpPathToLocalPath).not.toHaveBeenCalled();
103121
expect(mocks.createDefaultCanvasCliDependencies).not.toHaveBeenCalled();
104122
expect(mocks.createCanvasTool).not.toHaveBeenCalled();
123+
expect(mocks.createShowWidgetTool).not.toHaveBeenCalled();
105124

106125
await expect(resolvers[0]?.("/__openclaw__/canvas/documents/id/index.html")).resolves.toBe(
107126
"/tmp/canvas-asset",
@@ -118,21 +137,42 @@ describe("Canvas plugin entry", () => {
118137
expect(mocks.createDefaultCanvasCliDependencies).toHaveBeenCalledTimes(1);
119138
expect(mocks.registerNodesCanvasCommands).toHaveBeenCalledTimes(1);
120139

121-
const toolFactory = tools[0];
122-
expect(typeof toolFactory).toBe("function");
123-
const tool = (toolFactory as Exclude<typeof toolFactory, AnyAgentTool>)({
124-
config: {},
125-
workspaceDir: "/tmp/workspace",
140+
const registeredTools = tools.map(({ tool: toolFactory }) => {
141+
expect(typeof toolFactory).toBe("function");
142+
const tool = (toolFactory as Exclude<typeof toolFactory, AnyAgentTool>)({
143+
config: {},
144+
workspaceDir: "/tmp/workspace",
145+
sessionId: "session-1",
146+
agentId: "agent-1",
147+
});
148+
expect(Array.isArray(tool)).toBe(false);
149+
return tool as AnyAgentTool;
126150
});
127-
expect(Array.isArray(tool)).toBe(false);
128-
expect((tool as AnyAgentTool).name).toBe("canvas");
151+
expect(registeredTools.map((tool) => tool.name)).toEqual(["canvas", "show_widget"]);
152+
expect(registeredTools[1]?.requiredClientCaps).toEqual(SHOW_WIDGET_REQUIRED_CLIENT_CAPS);
129153
expect(mocks.createCanvasTool).not.toHaveBeenCalled();
154+
expect(mocks.createShowWidgetTool).not.toHaveBeenCalled();
130155

131-
await (tool as AnyAgentTool).execute("tool-call", { action: "hide" });
156+
const [canvasTool, showWidgetTool] = registeredTools;
157+
await canvasTool?.execute("tool-call", { action: "hide" });
132158
expect(mocks.createCanvasTool).toHaveBeenCalledWith({
133159
config: {},
134160
workspaceDir: "/tmp/workspace",
135161
});
136162
expect(mocks.toolExecute).toHaveBeenCalledWith("tool-call", { action: "hide" });
163+
164+
await showWidgetTool?.execute("widget-call", {
165+
title: "Status",
166+
widget_code: "<p>ready</p>",
167+
});
168+
expect(mocks.createShowWidgetTool).toHaveBeenCalledWith({
169+
config: {},
170+
sessionId: "session-1",
171+
agentId: "agent-1",
172+
});
173+
expect(mocks.widgetToolExecute).toHaveBeenCalledWith("widget-call", {
174+
title: "Status",
175+
widget_code: "<p>ready</p>",
176+
});
137177
});
138178
});

extensions/codex/src/app-server/dynamic-tool-build.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ describe("Codex app-server dynamic tool build", () => {
280280
const workspaceDir = path.join(tempDir, "workspace");
281281
const params = createParams(path.join(tempDir, "session.jsonl"), workspaceDir);
282282
params.disableTools = false;
283+
params.runtimePlan = createCodexRuntimePlanFixture();
283284
params.clientCaps = ["tool-events", "inline-widgets"];
284285
let receivedClientCaps: string[] | undefined;
285286
setOpenClawCodingToolsFactoryForTests((options) => {

src/plugins/bundled-plugin-metadata.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ const EXPECTED_BUNDLED_STARTUP_PLUGIN_IDS = [
3636
"bonjour",
3737
"browser",
3838
"canvas",
39+
"codex-supervisor",
3940
"device-pair",
4041
"diagnostics-otel",
4142
"diagnostics-prometheus",

0 commit comments

Comments
 (0)