
























11import type { AgentToolResult } from "openclaw/plugin-sdk/agent-core";
2+import {
3+onInternalDiagnosticEvent,
4+waitForDiagnosticEventsDrained,
5+type DiagnosticEventPayload,
6+} from "openclaw/plugin-sdk/diagnostic-runtime";
27import type { AnyAgentTool } from "openclaw/plugin-sdk/agent-harness";
38import {
49HEARTBEAT_RESPONSE_TOOL_NAME,
@@ -293,18 +298,33 @@ describe("createCodexDynamicToolBridge", () => {
293298294299it("quarantines dynamic tools with unsupported input schemas", async () => {
295300const warn = vi.spyOn(embeddedAgentLog, "warn").mockImplementation(() => undefined);
301+const diagnosticEvents: DiagnosticEventPayload[] = [];
302+const unsubscribeDiagnostics = onInternalDiagnosticEvent((event) =>
303+diagnosticEvents.push(event),
304+);
296305const badExecute = vi.fn();
297-const bridge = createCodexDynamicToolBridge({
298-tools: [
299-createTool({ name: "message" }),
300-createTool({
301-name: "dofbot_move_angles",
302-parameters: { type: "array", items: { type: "number" } },
303-execute: badExecute,
304-}),
305-],
306-signal: new AbortController().signal,
307-});
306+let bridge!: ReturnType<typeof createCodexDynamicToolBridge>;
307+try {
308+bridge = createCodexDynamicToolBridge({
309+tools: [
310+createTool({ name: "message" }),
311+createTool({
312+name: "dofbot_move_angles",
313+parameters: { type: "array", items: { type: "number" } },
314+execute: badExecute,
315+}),
316+],
317+signal: new AbortController().signal,
318+hookContext: {
319+runId: "run-1",
320+sessionId: "session-1",
321+sessionKey: "agent:main:session-1",
322+},
323+});
324+await waitForDiagnosticEventsDrained();
325+} finally {
326+unsubscribeDiagnostics();
327+}
308328309329expect(bridge.availableSpecs.map((tool) => tool.name)).toEqual(["message"]);
310330expect(bridge.specs.map((tool) => tool.name)).toEqual(["message"]);
@@ -325,6 +345,23 @@ describe("createCodexDynamicToolBridge", () => {
325345],
326346}),
327347);
348+const blockedEvents = diagnosticEvents.filter(
349+(
350+event,
351+): event is Extract<DiagnosticEventPayload, { type: "tool.execution.blocked" }> =>
352+event.type === "tool.execution.blocked",
353+);
354+expect(blockedEvents).toContainEqual(
355+expect.objectContaining({
356+type: "tool.execution.blocked",
357+runId: "run-1",
358+sessionId: "session-1",
359+sessionKey: "agent:main:session-1",
360+toolName: "dofbot_move_angles",
361+deniedReason: "unsupported_tool_schema",
362+reason: 'dofbot_move_angles.inputSchema.type must be "object"',
363+}),
364+);
328365329366const result = await bridge.handleToolCall({
330367threadId: "thread-1",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。