






























@@ -93,6 +93,7 @@ function applyRuntimeToolsAllow<T extends { name: string }>(tools: T[], toolsAll
9393}
94949595type OpenClawCodingTool = ReturnType<typeof createOpenClawCodingTools>[number];
96+type OpenClawToolsOptions = NonNullable<Parameters<typeof createOpenClawTools>[0]>;
96979798function toolNameList(tools: readonly { name: string }[]): string[] {
9899return tools.map((tool) => tool.name);
@@ -113,6 +114,28 @@ function requireToolExecute(tool: OpenClawCodingTool): NonNullable<OpenClawCodin
113114return tool.execute;
114115}
115116117+function latestCreateOpenClawToolsOptions(): OpenClawToolsOptions {
118+const calls = vi.mocked(createOpenClawTools).mock.calls;
119+const lastCall = calls.at(-1);
120+const options = lastCall?.[0];
121+if (!options) {
122+throw new Error("expected createOpenClawTools call");
123+}
124+return options;
125+}
126+127+function expectListIncludes(
128+list: readonly string[] | undefined,
129+expected: readonly string[],
130+): void {
131+if (!list) {
132+throw new Error("expected string list");
133+}
134+for (const value of expected) {
135+expect(list.includes(value)).toBe(true);
136+}
137+}
138+116139describe("createOpenClawCodingTools", () => {
117140const testConfig: OpenClawConfig = {};
118141@@ -129,9 +152,7 @@ describe("createOpenClawCodingTools", () => {
129152const values = new Set<string>();
130153collectActionValues(action, values);
131154132-expect([...values]).toEqual(
133-expect.arrayContaining(["restart", "config.get", "config.patch", "config.apply"]),
134-);
155+expectListIncludes([...values], ["restart", "config.get", "config.patch", "config.apply"]);
135156});
136157137158it("exposes only an explicitly authorized owner-only tool to non-owner sessions", () => {
@@ -193,11 +214,9 @@ describe("createOpenClawCodingTools", () => {
193214runtimeToolAllowlist: ["memory_search", "memory_get"],
194215});
195216196-expect(createOpenClawToolsMock).toHaveBeenCalledWith(
197-expect.objectContaining({
198-pluginToolAllowlist: expect.arrayContaining(["memory_search", "memory_get"]),
199-}),
200-);
217+expect(createOpenClawToolsMock).toHaveBeenCalledTimes(1);
218+const options = latestCreateOpenClawToolsOptions();
219+expectListIncludes(options.pluginToolAllowlist, ["memory_search", "memory_get"]);
201220});
202221203222it("passes source reply delivery mode to OpenClaw tool construction", () => {
@@ -210,11 +229,8 @@ describe("createOpenClawCodingTools", () => {
210229sourceReplyDeliveryMode: "message_tool_only",
211230});
212231213-expect(createOpenClawToolsMock).toHaveBeenCalledWith(
214-expect.objectContaining({
215-sourceReplyDeliveryMode: "message_tool_only",
216-}),
217-);
232+expect(createOpenClawToolsMock).toHaveBeenCalledTimes(1);
233+expect(latestCreateOpenClawToolsOptions().sourceReplyDeliveryMode).toBe("message_tool_only");
218234});
219235220236it("skips unrelated tool families when construction is planned from a narrow allowlist", () => {
@@ -258,11 +274,8 @@ describe("createOpenClawCodingTools", () => {
258274},
259275});
260276261-expect(createOpenClawToolsMock).toHaveBeenCalledWith(
262-expect.objectContaining({
263-disablePluginTools: true,
264-}),
265-);
277+expect(createOpenClawToolsMock).toHaveBeenCalledTimes(1);
278+expect(latestCreateOpenClawToolsOptions().disablePluginTools).toBe(true);
266279});
267280268281it("keeps plugin-only construction off the OpenClaw core factory", () => {
@@ -293,11 +306,11 @@ describe("createOpenClawCodingTools", () => {
293306config: { tools: { alsoAllow: ["lobster"] } },
294307});
295308296-expect(createOpenClawToolsMock).toHaveBeenCalledWith(
297- expect.objectContaining({
298- pluginToolAllowlist: ["lobster", DEFAULT_PLUGIN_TOOLS_ALLOWLIST_ENTRY],
299-}),
300-);
309+expect(createOpenClawToolsMock).toHaveBeenCalledTimes(1);
310+expect(latestCreateOpenClawToolsOptions().pluginToolAllowlist).toStrictEqual([
311+"lobster",
312+DEFAULT_PLUGIN_TOOLS_ALLOWLIST_ENTRY,
313+]);
301314});
302315303316it("passes explicit denylist entries to OpenClaw tool factory planning", () => {
@@ -308,11 +321,8 @@ describe("createOpenClawCodingTools", () => {
308321config: { tools: { deny: ["pdf"] } },
309322});
310323311-expect(createOpenClawToolsMock).toHaveBeenCalledWith(
312-expect.objectContaining({
313-pluginToolDenylist: expect.arrayContaining(["pdf"]),
314-}),
315-);
324+expect(createOpenClawToolsMock).toHaveBeenCalledTimes(1);
325+expectListIncludes(latestCreateOpenClawToolsOptions().pluginToolDenylist, ["pdf"]);
316326});
317327318328it("records core tool-prep stages for hot-path diagnostics", () => {
@@ -324,23 +334,21 @@ describe("createOpenClawCodingTools", () => {
324334senderIsOwner: true,
325335});
326336327-expect(stages).toEqual(
328-expect.arrayContaining([
329-"tool-policy",
330-"workspace-policy",
331-"base-coding-tools",
332-"shell-tools",
333-"openclaw-tools:test-helper",
334-"openclaw-tools",
335-"message-provider-policy",
336-"model-provider-policy",
337-"authorization-policy",
338-"schema-normalization",
339-"tool-hooks",
340-"abort-wrappers",
341-"deferred-followup-descriptions",
342-]),
343-);
337+expectListIncludes(stages, [
338+"tool-policy",
339+"workspace-policy",
340+"base-coding-tools",
341+"shell-tools",
342+"openclaw-tools:test-helper",
343+"openclaw-tools",
344+"message-provider-policy",
345+"model-provider-policy",
346+"authorization-policy",
347+"schema-normalization",
348+"tool-hooks",
349+"abort-wrappers",
350+"deferred-followup-descriptions",
351+]);
344352expect(stages.indexOf("tool-policy")).toBeLessThan(stages.indexOf("workspace-policy"));
345353expect(stages.indexOf("workspace-policy")).toBeLessThan(stages.indexOf("base-coding-tools"));
346354expect(stages.indexOf("openclaw-tools:test-helper")).toBeLessThan(
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。