mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-03 14:34:07 +00:00
test(agents): use neutral tool schema fixtures (#88848)
This commit is contained in:
@@ -303,7 +303,7 @@ describe("createCodexDynamicToolBridge", () => {
|
||||
tools: [
|
||||
createTool({ name: "message" }),
|
||||
createTool({
|
||||
name: "dofbot_move_angles",
|
||||
name: "fuzzplugin_move_angles",
|
||||
parameters: { type: "array", items: { type: "number" } },
|
||||
execute: badExecute,
|
||||
}),
|
||||
@@ -324,17 +324,17 @@ describe("createCodexDynamicToolBridge", () => {
|
||||
expect(bridge.specs.map((tool) => tool.name)).toEqual(["message"]);
|
||||
expect(bridge.telemetry.quarantinedTools).toEqual([
|
||||
{
|
||||
tool: "dofbot_move_angles",
|
||||
violations: ['dofbot_move_angles.inputSchema.type must be "object"'],
|
||||
tool: "fuzzplugin_move_angles",
|
||||
violations: ['fuzzplugin_move_angles.inputSchema.type must be "object"'],
|
||||
},
|
||||
]);
|
||||
expect(warn).toHaveBeenCalledWith(
|
||||
expect.stringContaining("dofbot_move_angles"),
|
||||
expect.stringContaining("fuzzplugin_move_angles"),
|
||||
expect.objectContaining({
|
||||
tools: [
|
||||
{
|
||||
tool: "dofbot_move_angles",
|
||||
violations: ['dofbot_move_angles.inputSchema.type must be "object"'],
|
||||
tool: "fuzzplugin_move_angles",
|
||||
violations: ['fuzzplugin_move_angles.inputSchema.type must be "object"'],
|
||||
},
|
||||
],
|
||||
}),
|
||||
@@ -349,9 +349,9 @@ describe("createCodexDynamicToolBridge", () => {
|
||||
runId: "run-1",
|
||||
sessionId: "session-1",
|
||||
sessionKey: "agent:main:session-1",
|
||||
toolName: "dofbot_move_angles",
|
||||
toolName: "fuzzplugin_move_angles",
|
||||
deniedReason: "unsupported_tool_schema",
|
||||
reason: 'dofbot_move_angles.inputSchema.type must be "object"',
|
||||
reason: 'fuzzplugin_move_angles.inputSchema.type must be "object"',
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -360,13 +360,13 @@ describe("createCodexDynamicToolBridge", () => {
|
||||
turnId: "turn-1",
|
||||
callId: "call-1",
|
||||
namespace: null,
|
||||
tool: "dofbot_move_angles",
|
||||
tool: "fuzzplugin_move_angles",
|
||||
arguments: {},
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
success: false,
|
||||
contentItems: [{ type: "inputText", text: "Unknown OpenClaw tool: dofbot_move_angles" }],
|
||||
contentItems: [{ type: "inputText", text: "Unknown OpenClaw tool: fuzzplugin_move_angles" }],
|
||||
});
|
||||
expect(badExecute).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -60,10 +60,10 @@ describe("ToolsEffectiveResultSchema", () => {
|
||||
...toolsEffectiveResult(),
|
||||
notices: [
|
||||
{
|
||||
id: "unsupported-tool-schema:dofbot_move_angles",
|
||||
id: "unsupported-tool-schema:fuzzplugin_move_angles",
|
||||
severity: "warning",
|
||||
message:
|
||||
'Tool "dofbot_move_angles" from plugin "dofbot" has an unsupported runtime input schema and was quarantined before model projection.',
|
||||
'Tool "fuzzplugin_move_angles" from plugin "fuzzplugin" has an unsupported runtime input schema and was quarantined before model projection.',
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -76,7 +76,7 @@ describe("ToolsEffectiveResultSchema", () => {
|
||||
...toolsEffectiveResult(),
|
||||
notices: [
|
||||
{
|
||||
id: "unsupported-tool-schema:dofbot_move_angles",
|
||||
id: "unsupported-tool-schema:fuzzplugin_move_angles",
|
||||
severity: "warning",
|
||||
message: "Unsupported schema.",
|
||||
extra: true,
|
||||
|
||||
@@ -757,7 +757,7 @@ describe("session MCP runtime", () => {
|
||||
cfg: {
|
||||
mcp: {
|
||||
servers: {
|
||||
dofbot: {
|
||||
fuzzplugin: {
|
||||
command: process.execPath,
|
||||
args: [serverPath],
|
||||
},
|
||||
@@ -771,7 +771,7 @@ describe("session MCP runtime", () => {
|
||||
|
||||
expect(catalog.servers).toEqual({});
|
||||
expect(catalog.tools).toEqual([]);
|
||||
expect(catalog.diagnostics?.[0]?.serverName).toBe("dofbot");
|
||||
expect(catalog.diagnostics?.[0]?.serverName).toBe("fuzzplugin");
|
||||
expect(catalog.diagnostics?.[0]?.message).toContain("Invalid input: expected");
|
||||
expect(catalog.diagnostics?.[0]?.message).toContain("object");
|
||||
} finally {
|
||||
|
||||
@@ -167,9 +167,9 @@ describe("createBundleMcpToolRuntime", () => {
|
||||
it("preserves catalog diagnostics when MCP servers fail tool listing", async () => {
|
||||
const diagnostics = [
|
||||
{
|
||||
serverName: "dofbot",
|
||||
safeServerName: "dofbot",
|
||||
launchSummary: "node dofbot-mcp.mjs",
|
||||
serverName: "fuzzplugin",
|
||||
safeServerName: "fuzzplugin",
|
||||
launchSummary: "node fuzzplugin-mcp.mjs",
|
||||
message: 'tools[0].inputSchema.type expected "object"',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -473,8 +473,8 @@ describe("compactEmbeddedAgentSessionDirect hooks", () => {
|
||||
execute: async () => ({ text: "ok" }),
|
||||
},
|
||||
{
|
||||
name: "dofbot_move_angles",
|
||||
label: "Dofbot Move Angles",
|
||||
name: "fuzzplugin_move_angles",
|
||||
label: "Fuzzplugin Move Angles",
|
||||
description: "Move robot joints.",
|
||||
parameters: { type: "array", items: { type: "number" } },
|
||||
execute: async () => ({ text: "bad" }),
|
||||
|
||||
@@ -294,8 +294,8 @@ describe("runEmbeddedAttempt context engine sessionKey forwarding", () => {
|
||||
execute: async () => ({ text: "ok" }),
|
||||
},
|
||||
{
|
||||
name: "dofbot_move_angles",
|
||||
label: "Dofbot Move Angles",
|
||||
name: "fuzzplugin_move_angles",
|
||||
label: "Fuzzplugin Move Angles",
|
||||
description: "Move robot joints.",
|
||||
parameters: {
|
||||
type: "object",
|
||||
|
||||
@@ -321,8 +321,8 @@ describe("resolveEffectiveToolInventory", () => {
|
||||
tools: [
|
||||
mockTool({ name: "exec", label: "Exec", description: "Run shell commands" }),
|
||||
mockTool({
|
||||
name: "dofbot_move_angles",
|
||||
label: "Dofbot Move Angles",
|
||||
name: "fuzzplugin_move_angles",
|
||||
label: "Fuzzplugin Move Angles",
|
||||
description: "Move robot joints",
|
||||
parameters: {
|
||||
type: "object",
|
||||
@@ -332,7 +332,7 @@ describe("resolveEffectiveToolInventory", () => {
|
||||
},
|
||||
}),
|
||||
],
|
||||
pluginMeta: { dofbot_move_angles: { pluginId: "dofbot" } },
|
||||
pluginMeta: { fuzzplugin_move_angles: { pluginId: "fuzzplugin" } },
|
||||
});
|
||||
|
||||
const result = resolveEffectiveToolInventoryLocal7({ cfg: {} });
|
||||
@@ -340,10 +340,10 @@ describe("resolveEffectiveToolInventory", () => {
|
||||
expect(result.groups.flatMap((group) => group.tools.map((tool) => tool.id))).toEqual(["exec"]);
|
||||
expect(result.notices).toEqual([
|
||||
{
|
||||
id: "unsupported-tool-schema:dofbot_move_angles",
|
||||
id: "unsupported-tool-schema:fuzzplugin_move_angles",
|
||||
severity: "warning",
|
||||
message:
|
||||
'Tool "dofbot_move_angles" from plugin "dofbot" has an unsupported runtime input schema (dofbot_move_angles.parameters.properties.target.$dynamicRef) and was quarantined before model projection. Fix or disable the owner, or remove the tool from active allowlists.',
|
||||
'Tool "fuzzplugin_move_angles" from plugin "fuzzplugin" has an unsupported runtime input schema (fuzzplugin_move_angles.parameters.properties.target.$dynamicRef) and was quarantined before model projection. Fix or disable the owner, or remove the tool from active allowlists.',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -434,16 +434,16 @@ describe("doctor repair sequencing", () => {
|
||||
|
||||
it("emits active tool schema projection warnings during doctor repair", async () => {
|
||||
mocks.collectActiveToolSchemaProjectionWarnings.mockReturnValueOnce([
|
||||
'- agents.main: active tool "dofbot_move_angles" from plugin "dofbot" has unsupported runtime input schema.',
|
||||
'- agents.main: active tool "fuzzplugin_move_angles" from plugin "fuzzplugin" has unsupported runtime input schema.',
|
||||
]);
|
||||
|
||||
const result = await runDoctorRepairSequence({
|
||||
state: {
|
||||
cfg: {
|
||||
tools: { allow: ["dofbot_move_angles"] },
|
||||
tools: { allow: ["fuzzplugin_move_angles"] },
|
||||
} as OpenClawConfig,
|
||||
candidate: {
|
||||
tools: { allow: ["dofbot_move_angles"] },
|
||||
tools: { allow: ["fuzzplugin_move_angles"] },
|
||||
} as OpenClawConfig,
|
||||
pendingChanges: false,
|
||||
fixHints: [],
|
||||
@@ -453,11 +453,11 @@ describe("doctor repair sequencing", () => {
|
||||
|
||||
expect(result.changeNotes).toStrictEqual([]);
|
||||
expect(result.warningNotes).toContain(
|
||||
'- agents.main: active tool "dofbot_move_angles" from plugin "dofbot" has unsupported runtime input schema.',
|
||||
'- agents.main: active tool "fuzzplugin_move_angles" from plugin "fuzzplugin" has unsupported runtime input schema.',
|
||||
);
|
||||
expect(mocks.collectActiveToolSchemaProjectionWarnings).toHaveBeenCalledWith({
|
||||
cfg: {
|
||||
tools: { allow: ["dofbot_move_angles"] },
|
||||
tools: { allow: ["fuzzplugin_move_angles"] },
|
||||
},
|
||||
env: process.env,
|
||||
});
|
||||
|
||||
@@ -85,23 +85,23 @@ describe("active tool schema doctor warnings", () => {
|
||||
it("warns with plugin ownership for active tools blocked by runtime projection", () => {
|
||||
toolState.tools = [
|
||||
tool("message", { type: "object", properties: {} }),
|
||||
tool("dofbot_move_angles", { type: "array", items: { type: "number" } }),
|
||||
tool("fuzzplugin_move_angles", { type: "array", items: { type: "number" } }),
|
||||
];
|
||||
toolState.pluginIds = { dofbot_move_angles: "dofbot" };
|
||||
toolState.pluginIds = { fuzzplugin_move_angles: "fuzzplugin" };
|
||||
|
||||
expect(
|
||||
collectActiveToolSchemaProjectionWarnings({
|
||||
cfg: {
|
||||
plugins: {
|
||||
entries: {
|
||||
dofbot: { enabled: true },
|
||||
fuzzplugin: { enabled: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
env: { HOME: "/tmp/openclaw-test" },
|
||||
}),
|
||||
).toEqual([
|
||||
'- agents.main: active tool "dofbot_move_angles" from plugin "dofbot" has unsupported runtime input schema (dofbot_move_angles.parameters.type must be "object"). OpenClaw will quarantine this tool at runtime; fix or disable the plugin, or remove the tool from active allowlists.',
|
||||
'- agents.main: active tool "fuzzplugin_move_angles" from plugin "fuzzplugin" has unsupported runtime input schema (fuzzplugin_move_angles.parameters.type must be "object"). OpenClaw will quarantine this tool at runtime; fix or disable the plugin, or remove the tool from active allowlists.',
|
||||
]);
|
||||
expect(toolState.createTools).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ toolPolicyAuditLogLevel: "debug" }),
|
||||
@@ -136,8 +136,10 @@ describe("active tool schema doctor warnings", () => {
|
||||
});
|
||||
|
||||
it("does not validate disabled plugin mode", () => {
|
||||
toolState.tools = [tool("dofbot_move_angles", { type: "array", items: { type: "number" } })];
|
||||
toolState.pluginIds = { dofbot_move_angles: "dofbot" };
|
||||
toolState.tools = [
|
||||
tool("fuzzplugin_move_angles", { type: "array", items: { type: "number" } }),
|
||||
];
|
||||
toolState.pluginIds = { fuzzplugin_move_angles: "fuzzplugin" };
|
||||
|
||||
expect(
|
||||
collectActiveToolSchemaProjectionWarnings({
|
||||
@@ -151,7 +153,7 @@ describe("active tool schema doctor warnings", () => {
|
||||
|
||||
it("validates provider-normalized runtime schemas before reporting doctor health", () => {
|
||||
const healthyTool = tool("message", { type: "object", properties: {} });
|
||||
const dynamicTool = tool("dofbot_move_angles", { type: "object", properties: {} });
|
||||
const dynamicTool = tool("fuzzplugin_move_angles", { type: "object", properties: {} });
|
||||
toolState.runtimeModel = {
|
||||
id: "gpt-5.5",
|
||||
name: "GPT-5.5",
|
||||
@@ -161,7 +163,7 @@ describe("active tool schema doctor warnings", () => {
|
||||
compat: { unsupportedToolSchemaKeywords: ["$dynamicRef"] },
|
||||
};
|
||||
toolState.tools = [healthyTool, dynamicTool];
|
||||
toolState.pluginIds = { dofbot_move_angles: "dofbot" };
|
||||
toolState.pluginIds = { fuzzplugin_move_angles: "fuzzplugin" };
|
||||
toolState.normalizeTools.mockImplementation(({ tools, modelApi, model }) => {
|
||||
if (
|
||||
modelApi !== "openai-responses" ||
|
||||
@@ -171,8 +173,8 @@ describe("active tool schema doctor warnings", () => {
|
||||
return tools;
|
||||
}
|
||||
return tools.map((entry) =>
|
||||
entry.name === "dofbot_move_angles"
|
||||
? tool("dofbot_move_angles", {
|
||||
entry.name === "fuzzplugin_move_angles"
|
||||
? tool("fuzzplugin_move_angles", {
|
||||
type: "object",
|
||||
properties: {
|
||||
target: { $dynamicRef: "#target" },
|
||||
@@ -192,14 +194,14 @@ describe("active tool schema doctor warnings", () => {
|
||||
},
|
||||
plugins: {
|
||||
entries: {
|
||||
dofbot: { enabled: true },
|
||||
fuzzplugin: { enabled: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
env: { HOME: "/tmp/openclaw-test" },
|
||||
}),
|
||||
).toEqual([
|
||||
'- agents.main: active tool "dofbot_move_angles" from plugin "dofbot" has unsupported runtime input schema (dofbot_move_angles.parameters.properties.target.$dynamicRef). OpenClaw will quarantine this tool at runtime; fix or disable the plugin, or remove the tool from active allowlists.',
|
||||
'- agents.main: active tool "fuzzplugin_move_angles" from plugin "fuzzplugin" has unsupported runtime input schema (fuzzplugin_move_angles.parameters.properties.target.$dynamicRef). OpenClaw will quarantine this tool at runtime; fix or disable the plugin, or remove the tool from active allowlists.',
|
||||
]);
|
||||
expect(toolState.createTools).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
@@ -253,7 +255,7 @@ describe("active tool schema doctor warnings", () => {
|
||||
|
||||
expect(
|
||||
collectActiveToolSchemaProjectionWarnings({
|
||||
cfg: { plugins: { entries: { dofbot: { enabled: true } } } },
|
||||
cfg: { plugins: { entries: { fuzzplugin: { enabled: true } } } },
|
||||
env: { HOME: "/tmp/openclaw-test" },
|
||||
}),
|
||||
).toEqual([
|
||||
|
||||
@@ -388,17 +388,17 @@ describe("doctor preview warnings", () => {
|
||||
|
||||
it("includes active tool schema projection warnings", async () => {
|
||||
activeToolSchemaState.warnings = [
|
||||
'- agents.main: active tool "dofbot_move_angles" from plugin "dofbot" has unsupported runtime input schema.',
|
||||
'- agents.main: active tool "fuzzplugin_move_angles" from plugin "fuzzplugin" has unsupported runtime input schema.',
|
||||
];
|
||||
|
||||
const warnings = await collectDoctorPreviewWarnings({
|
||||
cfg: { tools: { allow: ["dofbot_move_angles"] } },
|
||||
cfg: { tools: { allow: ["fuzzplugin_move_angles"] } },
|
||||
doctorFixCommand: "openclaw doctor --fix",
|
||||
});
|
||||
|
||||
expect(warnings.some((warning) => warning.includes('active tool "dofbot_move_angles"'))).toBe(
|
||||
true,
|
||||
);
|
||||
expect(
|
||||
warnings.some((warning) => warning.includes('active tool "fuzzplugin_move_angles"')),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("warns but skips auto-removal when plugin discovery has errors", async () => {
|
||||
|
||||
@@ -85,8 +85,8 @@ describe("doctor runtime tool schema checks", () => {
|
||||
it("reports active bundle MCP tool schemas that would be quarantined before a model turn", async () => {
|
||||
mocks.createBundleMcpToolRuntime.mockReturnValueOnce({
|
||||
tools: [
|
||||
bundleMcpTool("dofbot__healthy", { type: "object", properties: {} }),
|
||||
bundleMcpTool("dofbot__dofbot_move_angles", {
|
||||
bundleMcpTool("fuzzplugin__healthy", { type: "object", properties: {} }),
|
||||
bundleMcpTool("fuzzplugin__move_angles", {
|
||||
type: "array",
|
||||
items: { type: "number" },
|
||||
}),
|
||||
@@ -98,7 +98,7 @@ describe("doctor runtime tool schema checks", () => {
|
||||
collectRuntimeToolSchemaFindings({
|
||||
mcp: {
|
||||
servers: {
|
||||
dofbot: { command: "node", args: ["dofbot-mcp.mjs"] },
|
||||
fuzzplugin: { command: "node", args: ["fuzzplugin-mcp.mjs"] },
|
||||
},
|
||||
},
|
||||
}),
|
||||
@@ -106,10 +106,10 @@ describe("doctor runtime tool schema checks", () => {
|
||||
checkId: "core/doctor/runtime-tool-schemas",
|
||||
severity: "error",
|
||||
message:
|
||||
"Agent main tool dofbot__dofbot_move_angles from plugin bundle-mcp has an unsupported input schema for runtime projection.",
|
||||
"Agent main tool fuzzplugin__move_angles from plugin bundle-mcp has an unsupported input schema for runtime projection.",
|
||||
path: "mcp.servers",
|
||||
target: "dofbot__dofbot_move_angles",
|
||||
requirement: 'dofbot__dofbot_move_angles.parameters.type must be "object"',
|
||||
target: "fuzzplugin__move_angles",
|
||||
requirement: 'fuzzplugin__move_angles.parameters.type must be "object"',
|
||||
fixHint:
|
||||
"Disable or update the offending MCP server/tool so its parameters are a JSON object schema, then rerun doctor.",
|
||||
});
|
||||
@@ -181,9 +181,9 @@ describe("doctor runtime tool schema checks", () => {
|
||||
tools: [],
|
||||
diagnostics: [
|
||||
{
|
||||
serverName: "dofbot",
|
||||
safeServerName: "dofbot",
|
||||
launchSummary: "node dofbot-mcp.mjs",
|
||||
serverName: "fuzzplugin",
|
||||
safeServerName: "fuzzplugin",
|
||||
launchSummary: "node fuzzplugin-mcp.mjs",
|
||||
message: 'tools[0].inputSchema.type: Invalid input: expected "object"',
|
||||
},
|
||||
],
|
||||
@@ -194,7 +194,7 @@ describe("doctor runtime tool schema checks", () => {
|
||||
collectRuntimeToolSchemaFindings({
|
||||
mcp: {
|
||||
servers: {
|
||||
dofbot: { command: "node", args: ["dofbot-mcp.mjs"] },
|
||||
fuzzplugin: { command: "node", args: ["fuzzplugin-mcp.mjs"] },
|
||||
},
|
||||
},
|
||||
}),
|
||||
@@ -202,8 +202,8 @@ describe("doctor runtime tool schema checks", () => {
|
||||
checkId: "core/doctor/runtime-tool-schemas",
|
||||
severity: "error",
|
||||
message:
|
||||
'Configured MCP server "dofbot" could not expose runtime tools for schema validation.',
|
||||
path: "mcp.servers.dofbot",
|
||||
'Configured MCP server "fuzzplugin" could not expose runtime tools for schema validation.',
|
||||
path: "mcp.servers.fuzzplugin",
|
||||
requirement: 'tools[0].inputSchema.type: Invalid input: expected "object"',
|
||||
fixHint:
|
||||
"Fix or disable the offending MCP server, then rerun doctor before relying on assistant tool startup.",
|
||||
@@ -216,9 +216,9 @@ describe("doctor runtime tool schema checks", () => {
|
||||
tools: [],
|
||||
diagnostics: [
|
||||
{
|
||||
serverName: "dofbot",
|
||||
safeServerName: "dofbot",
|
||||
launchSummary: "node dofbot-mcp.mjs",
|
||||
serverName: "fuzzplugin",
|
||||
safeServerName: "fuzzplugin",
|
||||
launchSummary: "node fuzzplugin-mcp.mjs",
|
||||
message: 'tools[0].inputSchema.type: Invalid input: expected "object"',
|
||||
},
|
||||
],
|
||||
@@ -227,17 +227,17 @@ describe("doctor runtime tool schema checks", () => {
|
||||
|
||||
await expect(
|
||||
collectRuntimeToolSchemaFindings({
|
||||
tools: { allow: ["dofbot__healthy"] },
|
||||
tools: { allow: ["fuzzplugin__healthy"] },
|
||||
mcp: {
|
||||
servers: {
|
||||
dofbot: { command: "node", args: ["dofbot-mcp.mjs"] },
|
||||
fuzzplugin: { command: "node", args: ["fuzzplugin-mcp.mjs"] },
|
||||
},
|
||||
},
|
||||
}),
|
||||
).resolves.toContainEqual(
|
||||
expect.objectContaining({
|
||||
checkId: "core/doctor/runtime-tool-schemas",
|
||||
path: "mcp.servers.dofbot",
|
||||
path: "mcp.servers.fuzzplugin",
|
||||
}),
|
||||
);
|
||||
});
|
||||
@@ -249,7 +249,7 @@ describe("doctor runtime tool schema checks", () => {
|
||||
{
|
||||
serverName: "my__server",
|
||||
safeServerName: "my__server",
|
||||
launchSummary: "node dofbot-mcp.mjs",
|
||||
launchSummary: "node fuzzplugin-mcp.mjs",
|
||||
message: 'tools[0].inputSchema.type: Invalid input: expected "object"',
|
||||
},
|
||||
],
|
||||
@@ -261,7 +261,7 @@ describe("doctor runtime tool schema checks", () => {
|
||||
tools: { allow: ["my__server__healthy"] },
|
||||
mcp: {
|
||||
servers: {
|
||||
my__server: { command: "node", args: ["dofbot-mcp.mjs"] },
|
||||
my__server: { command: "node", args: ["fuzzplugin-mcp.mjs"] },
|
||||
},
|
||||
},
|
||||
}),
|
||||
@@ -278,9 +278,9 @@ describe("doctor runtime tool schema checks", () => {
|
||||
tools: [],
|
||||
diagnostics: [
|
||||
{
|
||||
serverName: "dofbot",
|
||||
safeServerName: "dofbot",
|
||||
launchSummary: "node dofbot-mcp.mjs",
|
||||
serverName: "fuzzplugin",
|
||||
safeServerName: "fuzzplugin",
|
||||
launchSummary: "node fuzzplugin-mcp.mjs",
|
||||
message: 'tools[0].inputSchema.type: Invalid input: expected "object"',
|
||||
},
|
||||
],
|
||||
@@ -292,14 +292,14 @@ describe("doctor runtime tool schema checks", () => {
|
||||
tools: { allow: ["*__healthy"] },
|
||||
mcp: {
|
||||
servers: {
|
||||
dofbot: { command: "node", args: ["dofbot-mcp.mjs"] },
|
||||
fuzzplugin: { command: "node", args: ["fuzzplugin-mcp.mjs"] },
|
||||
},
|
||||
},
|
||||
}),
|
||||
).resolves.toContainEqual(
|
||||
expect.objectContaining({
|
||||
checkId: "core/doctor/runtime-tool-schemas",
|
||||
path: "mcp.servers.dofbot",
|
||||
path: "mcp.servers.fuzzplugin",
|
||||
}),
|
||||
);
|
||||
});
|
||||
@@ -307,7 +307,7 @@ describe("doctor runtime tool schema checks", () => {
|
||||
it("reports unsupported schemas exposed only to a non-default configured agent", async () => {
|
||||
mocks.createOpenClawCodingTools.mockImplementation((options) =>
|
||||
options?.agentId === "worker"
|
||||
? [tool("dofbot_move_angles", { type: "array", items: { type: "number" } })]
|
||||
? [tool("fuzzplugin_move_angles", { type: "array", items: { type: "number" } })]
|
||||
: [tool("healthy", { type: "object", properties: {} })],
|
||||
);
|
||||
|
||||
@@ -324,10 +324,10 @@ describe("doctor runtime tool schema checks", () => {
|
||||
checkId: "core/doctor/runtime-tool-schemas",
|
||||
severity: "error",
|
||||
message:
|
||||
"Agent worker tool dofbot_move_angles has an unsupported input schema for runtime projection.",
|
||||
path: "tools.dofbot_move_angles",
|
||||
target: "dofbot_move_angles",
|
||||
requirement: 'dofbot_move_angles.parameters.type must be "object"',
|
||||
"Agent worker tool fuzzplugin_move_angles has an unsupported input schema for runtime projection.",
|
||||
path: "tools.fuzzplugin_move_angles",
|
||||
target: "fuzzplugin_move_angles",
|
||||
requirement: 'fuzzplugin_move_angles.parameters.type must be "object"',
|
||||
fixHint:
|
||||
"Disable or update the offending plugin/tool so its parameters are a JSON object schema, then rerun doctor.",
|
||||
});
|
||||
@@ -344,13 +344,13 @@ describe("doctor runtime tool schema checks", () => {
|
||||
it("skips ACP-only agents because they do not use embedded tool projection", async () => {
|
||||
mocks.createOpenClawCodingTools.mockImplementation((options) =>
|
||||
options?.agentId === "acp-worker"
|
||||
? [tool("dofbot_move_angles", { type: "array", items: { type: "number" } })]
|
||||
? [tool("fuzzplugin_move_angles", { type: "array", items: { type: "number" } })]
|
||||
: [tool("healthy", { type: "object", properties: {} })],
|
||||
);
|
||||
mocks.createBundleMcpToolRuntime.mockImplementation(
|
||||
async (options: { workspaceDir: string }) => ({
|
||||
tools: options.workspaceDir.includes("acp")
|
||||
? [bundleMcpTool("dofbot__bad", { type: "array", items: { type: "number" } })]
|
||||
? [bundleMcpTool("fuzzplugin__bad", { type: "array", items: { type: "number" } })]
|
||||
: [],
|
||||
dispose: mocks.disposeBundleRuntime,
|
||||
}),
|
||||
@@ -386,7 +386,7 @@ describe("doctor runtime tool schema checks", () => {
|
||||
async (options: { workspaceDir: string }) => ({
|
||||
tools: options.workspaceDir.includes("worker")
|
||||
? [
|
||||
bundleMcpTool("dofbot__dofbot_move_angles", {
|
||||
bundleMcpTool("fuzzplugin__move_angles", {
|
||||
type: "array",
|
||||
items: { type: "number" },
|
||||
}),
|
||||
@@ -409,10 +409,10 @@ describe("doctor runtime tool schema checks", () => {
|
||||
checkId: "core/doctor/runtime-tool-schemas",
|
||||
severity: "error",
|
||||
message:
|
||||
"Agent worker tool dofbot__dofbot_move_angles from plugin bundle-mcp has an unsupported input schema for runtime projection.",
|
||||
"Agent worker tool fuzzplugin__move_angles from plugin bundle-mcp has an unsupported input schema for runtime projection.",
|
||||
path: "mcp.servers",
|
||||
target: "dofbot__dofbot_move_angles",
|
||||
requirement: 'dofbot__dofbot_move_angles.parameters.type must be "object"',
|
||||
target: "fuzzplugin__move_angles",
|
||||
requirement: 'fuzzplugin__move_angles.parameters.type must be "object"',
|
||||
fixHint:
|
||||
"Disable or update the offending MCP server/tool so its parameters are a JSON object schema, then rerun doctor.",
|
||||
});
|
||||
@@ -429,7 +429,7 @@ describe("doctor runtime tool schema checks", () => {
|
||||
it("does not report bundle MCP schemas filtered out by the final runtime tool policy", async () => {
|
||||
mocks.createBundleMcpToolRuntime.mockReturnValueOnce({
|
||||
tools: [
|
||||
bundleMcpTool("dofbot__dofbot_move_angles", {
|
||||
bundleMcpTool("fuzzplugin__move_angles", {
|
||||
type: "array",
|
||||
items: { type: "number" },
|
||||
}),
|
||||
@@ -442,7 +442,7 @@ describe("doctor runtime tool schema checks", () => {
|
||||
tools: { deny: ["bundle-mcp"] },
|
||||
mcp: {
|
||||
servers: {
|
||||
dofbot: { command: "node", args: ["dofbot-mcp.mjs"] },
|
||||
fuzzplugin: { command: "node", args: ["fuzzplugin-mcp.mjs"] },
|
||||
},
|
||||
},
|
||||
}),
|
||||
@@ -454,9 +454,9 @@ describe("doctor runtime tool schema checks", () => {
|
||||
tools: [],
|
||||
diagnostics: [
|
||||
{
|
||||
serverName: "dofbot",
|
||||
safeServerName: "dofbot",
|
||||
launchSummary: "node dofbot-mcp.mjs",
|
||||
serverName: "fuzzplugin",
|
||||
safeServerName: "fuzzplugin",
|
||||
launchSummary: "node fuzzplugin-mcp.mjs",
|
||||
message: 'tools[0].inputSchema.type: Invalid input: expected "object"',
|
||||
},
|
||||
],
|
||||
@@ -468,7 +468,7 @@ describe("doctor runtime tool schema checks", () => {
|
||||
tools: { deny: ["bundle-mcp"] },
|
||||
mcp: {
|
||||
servers: {
|
||||
dofbot: { command: "node", args: ["dofbot-mcp.mjs"] },
|
||||
fuzzplugin: { command: "node", args: ["fuzzplugin-mcp.mjs"] },
|
||||
},
|
||||
},
|
||||
}),
|
||||
@@ -480,9 +480,9 @@ describe("doctor runtime tool schema checks", () => {
|
||||
tools: [],
|
||||
diagnostics: [
|
||||
{
|
||||
serverName: "dofbot",
|
||||
safeServerName: "dofbot",
|
||||
launchSummary: "node dofbot-mcp.mjs",
|
||||
serverName: "fuzzplugin",
|
||||
safeServerName: "fuzzplugin",
|
||||
launchSummary: "node fuzzplugin-mcp.mjs",
|
||||
message: 'tools[0].inputSchema.type: Invalid input: expected "object"',
|
||||
},
|
||||
],
|
||||
@@ -491,10 +491,10 @@ describe("doctor runtime tool schema checks", () => {
|
||||
|
||||
await expect(
|
||||
collectRuntimeToolSchemaFindings({
|
||||
tools: { deny: ["dofbot__*"] },
|
||||
tools: { deny: ["fuzzplugin__*"] },
|
||||
mcp: {
|
||||
servers: {
|
||||
dofbot: { command: "node", args: ["dofbot-mcp.mjs"] },
|
||||
fuzzplugin: { command: "node", args: ["fuzzplugin-mcp.mjs"] },
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
@@ -680,10 +680,10 @@ describe("registerCoreHealthChecks", () => {
|
||||
checkId: "core/doctor/runtime-tool-schemas",
|
||||
severity: "error",
|
||||
message:
|
||||
"Tool dofbot_move_angles from plugin dofbot has an unsupported input schema for runtime projection.",
|
||||
path: "plugins.entries.dofbot",
|
||||
target: "dofbot_move_angles",
|
||||
requirement: 'dofbot_move_angles.parameters.type must be "object"',
|
||||
"Tool fuzzplugin_move_angles from plugin fuzzplugin has an unsupported input schema for runtime projection.",
|
||||
path: "plugins.entries.fuzzplugin",
|
||||
target: "fuzzplugin_move_angles",
|
||||
requirement: 'fuzzplugin_move_angles.parameters.type must be "object"',
|
||||
},
|
||||
];
|
||||
},
|
||||
@@ -702,7 +702,7 @@ describe("registerCoreHealthChecks", () => {
|
||||
expect.objectContaining({
|
||||
checkId: "core/doctor/runtime-tool-schemas",
|
||||
severity: "error",
|
||||
target: "dofbot_move_angles",
|
||||
target: "fuzzplugin_move_angles",
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -350,10 +350,10 @@ describe("doctor health contributions", () => {
|
||||
checkId: "core/doctor/runtime-tool-schemas",
|
||||
severity: "error",
|
||||
message:
|
||||
"Tool dofbot_move_angles from plugin dofbot has an unsupported input schema for runtime projection.",
|
||||
path: "plugins.entries.dofbot",
|
||||
target: "dofbot_move_angles",
|
||||
requirement: 'dofbot_move_angles.parameters.type must be "object"',
|
||||
"Tool fuzzplugin_move_angles from plugin fuzzplugin has an unsupported input schema for runtime projection.",
|
||||
path: "plugins.entries.fuzzplugin",
|
||||
target: "fuzzplugin_move_angles",
|
||||
requirement: 'fuzzplugin_move_angles.parameters.type must be "object"',
|
||||
fixHint:
|
||||
"Disable or update the offending plugin/tool so its parameters are a JSON object schema, then rerun doctor.",
|
||||
},
|
||||
@@ -375,11 +375,11 @@ describe("doctor health contributions", () => {
|
||||
|
||||
expect(ctx.healthOk).toBe(false);
|
||||
expect(mocks.note).toHaveBeenCalledWith(
|
||||
expect.stringContaining("Tool dofbot_move_angles from plugin dofbot"),
|
||||
expect.stringContaining("Tool fuzzplugin_move_angles from plugin fuzzplugin"),
|
||||
"Doctor warnings",
|
||||
);
|
||||
expect(mocks.note).toHaveBeenCalledWith(
|
||||
expect.stringContaining('issue: dofbot_move_angles.parameters.type must be "object"'),
|
||||
expect.stringContaining('issue: fuzzplugin_move_angles.parameters.type must be "object"'),
|
||||
"Doctor warnings",
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user