mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-29 22:18:46 +00:00
fix(codex): report quarantined dynamic tools
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
import type { AgentToolResult } from "openclaw/plugin-sdk/agent-core";
|
||||
import {
|
||||
onInternalDiagnosticEvent,
|
||||
waitForDiagnosticEventsDrained,
|
||||
type DiagnosticEventPayload,
|
||||
} from "openclaw/plugin-sdk/diagnostic-runtime";
|
||||
import type { AnyAgentTool } from "openclaw/plugin-sdk/agent-harness";
|
||||
import {
|
||||
HEARTBEAT_RESPONSE_TOOL_NAME,
|
||||
@@ -293,18 +298,33 @@ describe("createCodexDynamicToolBridge", () => {
|
||||
|
||||
it("quarantines dynamic tools with unsupported input schemas", async () => {
|
||||
const warn = vi.spyOn(embeddedAgentLog, "warn").mockImplementation(() => undefined);
|
||||
const diagnosticEvents: DiagnosticEventPayload[] = [];
|
||||
const unsubscribeDiagnostics = onInternalDiagnosticEvent((event) =>
|
||||
diagnosticEvents.push(event),
|
||||
);
|
||||
const badExecute = vi.fn();
|
||||
const bridge = createCodexDynamicToolBridge({
|
||||
tools: [
|
||||
createTool({ name: "message" }),
|
||||
createTool({
|
||||
name: "dofbot_move_angles",
|
||||
parameters: { type: "array", items: { type: "number" } },
|
||||
execute: badExecute,
|
||||
}),
|
||||
],
|
||||
signal: new AbortController().signal,
|
||||
});
|
||||
let bridge!: ReturnType<typeof createCodexDynamicToolBridge>;
|
||||
try {
|
||||
bridge = createCodexDynamicToolBridge({
|
||||
tools: [
|
||||
createTool({ name: "message" }),
|
||||
createTool({
|
||||
name: "dofbot_move_angles",
|
||||
parameters: { type: "array", items: { type: "number" } },
|
||||
execute: badExecute,
|
||||
}),
|
||||
],
|
||||
signal: new AbortController().signal,
|
||||
hookContext: {
|
||||
runId: "run-1",
|
||||
sessionId: "session-1",
|
||||
sessionKey: "agent:main:session-1",
|
||||
},
|
||||
});
|
||||
await waitForDiagnosticEventsDrained();
|
||||
} finally {
|
||||
unsubscribeDiagnostics();
|
||||
}
|
||||
|
||||
expect(bridge.availableSpecs.map((tool) => tool.name)).toEqual(["message"]);
|
||||
expect(bridge.specs.map((tool) => tool.name)).toEqual(["message"]);
|
||||
@@ -325,6 +345,23 @@ describe("createCodexDynamicToolBridge", () => {
|
||||
],
|
||||
}),
|
||||
);
|
||||
const blockedEvents = diagnosticEvents.filter(
|
||||
(
|
||||
event,
|
||||
): event is Extract<DiagnosticEventPayload, { type: "tool.execution.blocked" }> =>
|
||||
event.type === "tool.execution.blocked",
|
||||
);
|
||||
expect(blockedEvents).toContainEqual(
|
||||
expect.objectContaining({
|
||||
type: "tool.execution.blocked",
|
||||
runId: "run-1",
|
||||
sessionId: "session-1",
|
||||
sessionKey: "agent:main:session-1",
|
||||
toolName: "dofbot_move_angles",
|
||||
deniedReason: "unsupported_tool_schema",
|
||||
reason: 'dofbot_move_angles.inputSchema.type must be "object"',
|
||||
}),
|
||||
);
|
||||
|
||||
const result = await bridge.handleToolCall({
|
||||
threadId: "thread-1",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { AgentToolResult } from "openclaw/plugin-sdk/agent-core";
|
||||
import { emitTrustedDiagnosticEvent } from "openclaw/plugin-sdk/diagnostic-runtime";
|
||||
import {
|
||||
createAgentToolResultMiddlewareRunner,
|
||||
createCodexAppServerToolResultExtensionRunner,
|
||||
@@ -118,6 +119,7 @@ export function createCodexDynamicToolBridge(params: {
|
||||
...registeredProjection.quarantinedTools,
|
||||
]);
|
||||
warnQuarantinedDynamicTools(quarantinedTools);
|
||||
emitQuarantinedDynamicToolDiagnostics(quarantinedTools, params.hookContext);
|
||||
const telemetry: CodexDynamicToolBridge["telemetry"] = {
|
||||
didSendViaMessagingTool: false,
|
||||
messagingToolSentTexts: [],
|
||||
@@ -337,6 +339,23 @@ function warnQuarantinedDynamicTools(tools: readonly CodexDynamicToolSchemaQuara
|
||||
);
|
||||
}
|
||||
|
||||
function emitQuarantinedDynamicToolDiagnostics(
|
||||
tools: readonly CodexDynamicToolSchemaQuarantine[],
|
||||
ctx: CodexDynamicToolHookContext | undefined,
|
||||
): void {
|
||||
for (const tool of tools) {
|
||||
emitTrustedDiagnosticEvent({
|
||||
type: "tool.execution.blocked",
|
||||
runId: ctx?.runId,
|
||||
sessionId: ctx?.sessionId,
|
||||
sessionKey: ctx?.sessionKey,
|
||||
toolName: tool.tool,
|
||||
deniedReason: "unsupported_tool_schema",
|
||||
reason: tool.violations.join(", "),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function dedupeQuarantinedDynamicTools(
|
||||
tools: readonly CodexDynamicToolSchemaQuarantine[],
|
||||
): CodexDynamicToolSchemaQuarantine[] {
|
||||
|
||||
Reference in New Issue
Block a user