mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 05:07:38 +00:00
test: migrate suites to e2e coverage layout
This commit is contained in:
@@ -1,200 +0,0 @@
|
||||
/**
|
||||
* Test: after_tool_call hook wiring (pi-embedded-subscribe.handlers.tools.ts)
|
||||
*/
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const hookMocks = vi.hoisted(() => ({
|
||||
runner: {
|
||||
hasHooks: vi.fn(() => false),
|
||||
runAfterToolCall: vi.fn(async () => {}),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock("../plugins/hook-runner-global.js", () => ({
|
||||
getGlobalHookRunner: () => hookMocks.runner,
|
||||
}));
|
||||
|
||||
// Mock agent events (used by handlers)
|
||||
vi.mock("../infra/agent-events.js", () => ({
|
||||
emitAgentEvent: vi.fn(),
|
||||
}));
|
||||
|
||||
describe("after_tool_call hook wiring", () => {
|
||||
beforeEach(() => {
|
||||
hookMocks.runner.hasHooks.mockReset();
|
||||
hookMocks.runner.hasHooks.mockReturnValue(false);
|
||||
hookMocks.runner.runAfterToolCall.mockReset();
|
||||
hookMocks.runner.runAfterToolCall.mockResolvedValue(undefined);
|
||||
});
|
||||
|
||||
it("calls runAfterToolCall in handleToolExecutionEnd when hook is registered", async () => {
|
||||
hookMocks.runner.hasHooks.mockReturnValue(true);
|
||||
|
||||
const { handleToolExecutionEnd, handleToolExecutionStart } =
|
||||
await import("../agents/pi-embedded-subscribe.handlers.tools.js");
|
||||
|
||||
const ctx = {
|
||||
params: {
|
||||
runId: "test-run-1",
|
||||
session: { messages: [] },
|
||||
agentId: "main",
|
||||
sessionKey: "test-session",
|
||||
onBlockReplyFlush: undefined,
|
||||
},
|
||||
state: {
|
||||
toolMetaById: new Map<string, string | undefined>(),
|
||||
toolMetas: [] as Array<{ toolName?: string; meta?: string }>,
|
||||
toolSummaryById: new Set<string>(),
|
||||
lastToolError: undefined,
|
||||
pendingMessagingTexts: new Map<string, string>(),
|
||||
pendingMessagingTargets: new Map<string, unknown>(),
|
||||
messagingToolSentTexts: [] as string[],
|
||||
messagingToolSentTextsNormalized: [] as string[],
|
||||
messagingToolSentTargets: [] as unknown[],
|
||||
blockBuffer: "",
|
||||
},
|
||||
log: { debug: vi.fn(), warn: vi.fn() },
|
||||
flushBlockReplyBuffer: vi.fn(),
|
||||
shouldEmitToolResult: () => false,
|
||||
shouldEmitToolOutput: () => false,
|
||||
emitToolSummary: vi.fn(),
|
||||
emitToolOutput: vi.fn(),
|
||||
trimMessagingToolSent: vi.fn(),
|
||||
};
|
||||
|
||||
await handleToolExecutionStart(
|
||||
ctx as never,
|
||||
{
|
||||
type: "tool_execution_start",
|
||||
toolName: "read",
|
||||
toolCallId: "call-1",
|
||||
args: { path: "/tmp/file.txt" },
|
||||
} as never,
|
||||
);
|
||||
|
||||
await handleToolExecutionEnd(
|
||||
ctx as never,
|
||||
{
|
||||
type: "tool_execution_end",
|
||||
toolName: "read",
|
||||
toolCallId: "call-1",
|
||||
isError: false,
|
||||
result: { content: [{ type: "text", text: "file contents" }] },
|
||||
} as never,
|
||||
);
|
||||
|
||||
await vi.waitFor(() => {
|
||||
expect(hookMocks.runner.runAfterToolCall).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
const [event, context] = hookMocks.runner.runAfterToolCall.mock.calls[0];
|
||||
expect(event.toolName).toBe("read");
|
||||
expect(event.params).toEqual({ path: "/tmp/file.txt" });
|
||||
expect(event.error).toBeUndefined();
|
||||
expect(typeof event.durationMs).toBe("number");
|
||||
expect(context.toolName).toBe("read");
|
||||
});
|
||||
|
||||
it("includes error in after_tool_call event on tool failure", async () => {
|
||||
hookMocks.runner.hasHooks.mockReturnValue(true);
|
||||
|
||||
const { handleToolExecutionEnd, handleToolExecutionStart } =
|
||||
await import("../agents/pi-embedded-subscribe.handlers.tools.js");
|
||||
|
||||
const ctx = {
|
||||
params: {
|
||||
runId: "test-run-2",
|
||||
session: { messages: [] },
|
||||
onBlockReplyFlush: undefined,
|
||||
},
|
||||
state: {
|
||||
toolMetaById: new Map<string, string | undefined>(),
|
||||
toolMetas: [] as Array<{ toolName?: string; meta?: string }>,
|
||||
toolSummaryById: new Set<string>(),
|
||||
lastToolError: undefined,
|
||||
pendingMessagingTexts: new Map<string, string>(),
|
||||
pendingMessagingTargets: new Map<string, unknown>(),
|
||||
messagingToolSentTexts: [] as string[],
|
||||
messagingToolSentTextsNormalized: [] as string[],
|
||||
messagingToolSentTargets: [] as unknown[],
|
||||
blockBuffer: "",
|
||||
},
|
||||
log: { debug: vi.fn(), warn: vi.fn() },
|
||||
flushBlockReplyBuffer: vi.fn(),
|
||||
shouldEmitToolResult: () => false,
|
||||
shouldEmitToolOutput: () => false,
|
||||
emitToolSummary: vi.fn(),
|
||||
emitToolOutput: vi.fn(),
|
||||
trimMessagingToolSent: vi.fn(),
|
||||
};
|
||||
|
||||
await handleToolExecutionStart(
|
||||
ctx as never,
|
||||
{
|
||||
type: "tool_execution_start",
|
||||
toolName: "exec",
|
||||
toolCallId: "call-err",
|
||||
args: { command: "fail" },
|
||||
} as never,
|
||||
);
|
||||
|
||||
await handleToolExecutionEnd(
|
||||
ctx as never,
|
||||
{
|
||||
type: "tool_execution_end",
|
||||
toolName: "exec",
|
||||
toolCallId: "call-err",
|
||||
isError: true,
|
||||
result: { status: "error", error: "command failed" },
|
||||
} as never,
|
||||
);
|
||||
|
||||
await vi.waitFor(() => {
|
||||
expect(hookMocks.runner.runAfterToolCall).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
const [event] = hookMocks.runner.runAfterToolCall.mock.calls[0];
|
||||
expect(event.error).toBeDefined();
|
||||
});
|
||||
|
||||
it("does not call runAfterToolCall when no hooks registered", async () => {
|
||||
hookMocks.runner.hasHooks.mockReturnValue(false);
|
||||
|
||||
const { handleToolExecutionEnd } =
|
||||
await import("../agents/pi-embedded-subscribe.handlers.tools.js");
|
||||
|
||||
const ctx = {
|
||||
params: { runId: "r", session: { messages: [] } },
|
||||
state: {
|
||||
toolMetaById: new Map<string, string | undefined>(),
|
||||
toolMetas: [] as Array<{ toolName?: string; meta?: string }>,
|
||||
toolSummaryById: new Set<string>(),
|
||||
lastToolError: undefined,
|
||||
pendingMessagingTexts: new Map<string, string>(),
|
||||
pendingMessagingTargets: new Map<string, unknown>(),
|
||||
messagingToolSentTexts: [] as string[],
|
||||
messagingToolSentTextsNormalized: [] as string[],
|
||||
messagingToolSentTargets: [] as unknown[],
|
||||
},
|
||||
log: { debug: vi.fn(), warn: vi.fn() },
|
||||
shouldEmitToolResult: () => false,
|
||||
shouldEmitToolOutput: () => false,
|
||||
emitToolSummary: vi.fn(),
|
||||
emitToolOutput: vi.fn(),
|
||||
trimMessagingToolSent: vi.fn(),
|
||||
};
|
||||
|
||||
await handleToolExecutionEnd(
|
||||
ctx as never,
|
||||
{
|
||||
type: "tool_execution_end",
|
||||
toolName: "exec",
|
||||
toolCallId: "call-2",
|
||||
isError: false,
|
||||
result: {},
|
||||
} as never,
|
||||
);
|
||||
|
||||
expect(hookMocks.runner.runAfterToolCall).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user