diff --git a/src/agents/pi-tools.create-openclaw-coding-tools.adds-claude-style-aliases-schemas-without-dropping.e2e.test.ts b/src/agents/pi-tools.create-openclaw-coding-tools.adds-claude-style-aliases-schemas-without-dropping.e2e.test.ts index d4153740fd..ec571c76e4 100644 --- a/src/agents/pi-tools.create-openclaw-coding-tools.adds-claude-style-aliases-schemas-without-dropping.e2e.test.ts +++ b/src/agents/pi-tools.create-openclaw-coding-tools.adds-claude-style-aliases-schemas-without-dropping.e2e.test.ts @@ -12,6 +12,51 @@ import { createBrowserTool } from "./tools/browser-tool.js"; const defaultTools = createOpenClawCodingTools(); +function findUnionKeywordOffenders( + tools: Array<{ name: string; parameters: unknown }>, + opts?: { onlyNames?: Set }, +) { + const offenders: Array<{ + name: string; + keyword: string; + path: string; + }> = []; + const keywords = new Set(["anyOf", "oneOf", "allOf"]); + + const walk = (value: unknown, path: string, name: string): void => { + if (!value) { + return; + } + if (Array.isArray(value)) { + for (const [index, entry] of value.entries()) { + walk(entry, `${path}[${index}]`, name); + } + return; + } + if (typeof value !== "object") { + return; + } + + const record = value as Record; + for (const [key, entry] of Object.entries(record)) { + const nextPath = path ? `${path}.${key}` : key; + if (keywords.has(key)) { + offenders.push({ name, keyword: key, path: nextPath }); + } + walk(entry, nextPath, name); + } + }; + + for (const tool of tools) { + if (opts?.onlyNames && !opts.onlyNames.has(tool.name)) { + continue; + } + walk(tool.parameters, "", tool.name); + } + + return offenders; +} + describe("createOpenClawCodingTools", () => { describe("Claude/Gemini alias support", () => { it("adds Claude-style aliases to schemas without dropping metadata", () => { @@ -213,42 +258,7 @@ describe("createOpenClawCodingTools", () => { expect(count?.oneOf).toBeDefined(); }); it("avoids anyOf/oneOf/allOf in tool schemas", () => { - const offenders: Array<{ - name: string; - keyword: string; - path: string; - }> = []; - const keywords = new Set(["anyOf", "oneOf", "allOf"]); - - const walk = (value: unknown, path: string, name: string): void => { - if (!value) { - return; - } - if (Array.isArray(value)) { - for (const [index, entry] of value.entries()) { - walk(entry, `${path}[${index}]`, name); - } - return; - } - if (typeof value !== "object") { - return; - } - - const record = value as Record; - for (const [key, entry] of Object.entries(record)) { - const nextPath = path ? `${path}.${key}` : key; - if (keywords.has(key)) { - offenders.push({ name, keyword: key, path: nextPath }); - } - walk(entry, nextPath, name); - } - }; - - for (const tool of defaultTools) { - walk(tool.parameters, "", tool.name); - } - - expect(offenders).toEqual([]); + expect(findUnionKeywordOffenders(defaultTools)).toEqual([]); }); it("keeps raw core tool schemas union-free", () => { const tools = createOpenClawTools(); @@ -267,44 +277,7 @@ describe("createOpenClawCodingTools", () => { "session_status", "image", ]); - const offenders: Array<{ - name: string; - keyword: string; - path: string; - }> = []; - const keywords = new Set(["anyOf", "oneOf", "allOf"]); - - const walk = (value: unknown, path: string, name: string): void => { - if (!value) { - return; - } - if (Array.isArray(value)) { - for (const [index, entry] of value.entries()) { - walk(entry, `${path}[${index}]`, name); - } - return; - } - if (typeof value !== "object") { - return; - } - const record = value as Record; - for (const [key, entry] of Object.entries(record)) { - const nextPath = path ? `${path}.${key}` : key; - if (keywords.has(key)) { - offenders.push({ name, keyword: key, path: nextPath }); - } - walk(entry, nextPath, name); - } - }; - - for (const tool of tools) { - if (!coreTools.has(tool.name)) { - continue; - } - walk(tool.parameters, "", tool.name); - } - - expect(offenders).toEqual([]); + expect(findUnionKeywordOffenders(tools, { onlyNames: coreTools })).toEqual([]); }); it("does not expose provider-specific message tools", () => { const tools = createOpenClawCodingTools({ messageProvider: "discord" });