Skip to content

Commit 46a21f0

Browse files
committed
Forward runtime tool policy through provider dispatchers
1 parent 8a5cc59 commit 46a21f0

2 files changed

Lines changed: 82 additions & 0 deletions

File tree

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { beforeEach, describe, expect, it, vi } from "vitest";
2+
import type { OpenClawConfig } from "../../config/types.openclaw.js";
3+
import type {
4+
ReplyDispatcherOptions,
5+
ReplyDispatcherWithTypingOptions,
6+
} from "./reply-dispatcher.js";
7+
8+
type BufferedDispatchFn =
9+
typeof import("../dispatch.js").dispatchInboundMessageWithBufferedDispatcher;
10+
type PlainDispatchFn = typeof import("../dispatch.js").dispatchInboundMessageWithDispatcher;
11+
12+
const hoisted = vi.hoisted(() => ({
13+
bufferedDispatchMock: vi.fn(),
14+
plainDispatchMock: vi.fn(),
15+
}));
16+
17+
vi.mock("../dispatch.js", () => ({
18+
dispatchInboundMessageWithBufferedDispatcher: (...args: Parameters<BufferedDispatchFn>) =>
19+
hoisted.bufferedDispatchMock(...args),
20+
dispatchInboundMessageWithDispatcher: (...args: Parameters<PlainDispatchFn>) =>
21+
hoisted.plainDispatchMock(...args),
22+
}));
23+
24+
const { dispatchReplyWithBufferedBlockDispatcher, dispatchReplyWithDispatcher } =
25+
await import("./provider-dispatcher.js");
26+
27+
const dispatchResult = {
28+
queuedFinal: false,
29+
counts: { tool: 0, block: 0, final: 0 },
30+
};
31+
32+
describe("provider dispatcher wrappers", () => {
33+
beforeEach(() => {
34+
vi.clearAllMocks();
35+
hoisted.bufferedDispatchMock.mockResolvedValue(dispatchResult);
36+
hoisted.plainDispatchMock.mockResolvedValue(dispatchResult);
37+
});
38+
39+
it("forwards runtime toolsAllow through the buffered wrapper", async () => {
40+
const dispatcherOptions = {
41+
deliver: async () => ({ visibleReplySent: false }),
42+
} satisfies ReplyDispatcherWithTypingOptions;
43+
44+
await dispatchReplyWithBufferedBlockDispatcher({
45+
ctx: { Body: "hello" },
46+
cfg: {} as OpenClawConfig,
47+
dispatcherOptions,
48+
toolsAllow: ["message"],
49+
});
50+
51+
expect(hoisted.bufferedDispatchMock).toHaveBeenCalledTimes(1);
52+
expect(hoisted.bufferedDispatchMock.mock.calls[0]?.[0]).toEqual(
53+
expect.objectContaining({
54+
dispatcherOptions,
55+
toolsAllow: ["message"],
56+
}),
57+
);
58+
});
59+
60+
it("forwards runtime toolsAllow through the plain wrapper", async () => {
61+
const dispatcherOptions = {
62+
deliver: async () => ({ visibleReplySent: false }),
63+
} satisfies ReplyDispatcherOptions;
64+
65+
await dispatchReplyWithDispatcher({
66+
ctx: { Body: "hello" },
67+
cfg: {} as OpenClawConfig,
68+
dispatcherOptions,
69+
toolsAllow: ["message"],
70+
});
71+
72+
expect(hoisted.plainDispatchMock).toHaveBeenCalledTimes(1);
73+
expect(hoisted.plainDispatchMock.mock.calls[0]?.[0]).toEqual(
74+
expect.objectContaining({
75+
dispatcherOptions,
76+
toolsAllow: ["message"],
77+
}),
78+
);
79+
});
80+
});

src/auto-reply/reply/provider-dispatcher.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export const dispatchReplyWithBufferedBlockDispatcher: DispatchReplyWithBuffered
1818
ctx: params.ctx,
1919
cfg: params.cfg,
2020
dispatcherOptions: params.dispatcherOptions,
21+
toolsAllow: params.toolsAllow,
2122
replyResolver: params.replyResolver,
2223
replyOptions: params.replyOptions,
2324
});
@@ -28,6 +29,7 @@ export const dispatchReplyWithDispatcher: DispatchReplyWithDispatcher = async (p
2829
ctx: params.ctx,
2930
cfg: params.cfg,
3031
dispatcherOptions: params.dispatcherOptions,
32+
toolsAllow: params.toolsAllow,
3133
replyResolver: params.replyResolver,
3234
replyOptions: params.replyOptions,
3335
});

0 commit comments

Comments
 (0)