mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 21:44:32 +00:00
fix(hooks): propagate run/tool IDs for tool hook correlation (#32360)
* Plugin SDK: add run and tool call fields to tool hooks * Agents: propagate runId and toolCallId in before_tool_call * Agents: thread runId through tool wrapper context * Runner: pass runId into tool hook context * Compaction: pass runId into tool hook context * Agents: scope after_tool_call start data by run * Tests: cover run and tool IDs in before_tool_call hooks * Tests: add run-scoped after_tool_call collision coverage * Hooks: scope adjusted tool params by run * Tests: cover run-scoped adjusted param collisions * Hooks: preserve active tool start metadata until end * Changelog: add tool-hook correlation note
This commit is contained in:
@@ -3,7 +3,11 @@ import { resetDiagnosticSessionStateForTest } from "../logging/diagnostic-sessio
|
||||
import { getGlobalHookRunner } from "../plugins/hook-runner-global.js";
|
||||
import { toClientToolDefinitions, toToolDefinitions } from "./pi-tool-definition-adapter.js";
|
||||
import { wrapToolWithAbortSignal } from "./pi-tools.abort.js";
|
||||
import { wrapToolWithBeforeToolCallHook } from "./pi-tools.before-tool-call.js";
|
||||
import {
|
||||
__testing as beforeToolCallTesting,
|
||||
consumeAdjustedParamsForToolCall,
|
||||
wrapToolWithBeforeToolCallHook,
|
||||
} from "./pi-tools.before-tool-call.js";
|
||||
|
||||
vi.mock("../plugins/hook-runner-global.js");
|
||||
|
||||
@@ -37,6 +41,7 @@ describe("before_tool_call hook integration", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
resetDiagnosticSessionStateForTest();
|
||||
beforeToolCallTesting.adjustedParamsByToolCallId.clear();
|
||||
hookRunner = installMockHookRunner();
|
||||
});
|
||||
|
||||
@@ -123,6 +128,7 @@ describe("before_tool_call hook integration", () => {
|
||||
agentId: "main",
|
||||
sessionKey: "main",
|
||||
sessionId: "ephemeral-main",
|
||||
runId: "run-main",
|
||||
});
|
||||
const extensionContext = {} as Parameters<typeof tool.execute>[3];
|
||||
|
||||
@@ -132,15 +138,51 @@ describe("before_tool_call hook integration", () => {
|
||||
{
|
||||
toolName: "read",
|
||||
params: {},
|
||||
runId: "run-main",
|
||||
toolCallId: "call-5",
|
||||
},
|
||||
{
|
||||
toolName: "read",
|
||||
agentId: "main",
|
||||
sessionKey: "main",
|
||||
sessionId: "ephemeral-main",
|
||||
runId: "run-main",
|
||||
toolCallId: "call-5",
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps adjusted params isolated per run when toolCallId collides", async () => {
|
||||
hookRunner.hasHooks.mockReturnValue(true);
|
||||
hookRunner.runBeforeToolCall
|
||||
.mockResolvedValueOnce({ params: { marker: "A" } })
|
||||
.mockResolvedValueOnce({ params: { marker: "B" } });
|
||||
const execute = vi.fn().mockResolvedValue({ content: [], details: { ok: true } });
|
||||
// oxlint-disable-next-line typescript/no-explicit-any
|
||||
const toolA = wrapToolWithBeforeToolCallHook({ name: "Read", execute } as any, {
|
||||
runId: "run-a",
|
||||
});
|
||||
// oxlint-disable-next-line typescript/no-explicit-any
|
||||
const toolB = wrapToolWithBeforeToolCallHook({ name: "Read", execute } as any, {
|
||||
runId: "run-b",
|
||||
});
|
||||
const extensionContextA = {} as Parameters<typeof toolA.execute>[3];
|
||||
const extensionContextB = {} as Parameters<typeof toolB.execute>[3];
|
||||
const sharedToolCallId = "shared-call";
|
||||
|
||||
await toolA.execute(sharedToolCallId, { path: "/tmp/a.txt" }, undefined, extensionContextA);
|
||||
await toolB.execute(sharedToolCallId, { path: "/tmp/b.txt" }, undefined, extensionContextB);
|
||||
|
||||
expect(consumeAdjustedParamsForToolCall(sharedToolCallId, "run-a")).toEqual({
|
||||
path: "/tmp/a.txt",
|
||||
marker: "A",
|
||||
});
|
||||
expect(consumeAdjustedParamsForToolCall(sharedToolCallId, "run-b")).toEqual({
|
||||
path: "/tmp/b.txt",
|
||||
marker: "B",
|
||||
});
|
||||
expect(consumeAdjustedParamsForToolCall(sharedToolCallId, "run-a")).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("before_tool_call hook deduplication (#15502)", () => {
|
||||
|
||||
Reference in New Issue
Block a user