mirror of
https://github.com/farcasclaudiu/openclaw.git
synced 2026-06-28 23:02:02 +03:00
refactor(test): dedupe pi-tools schema union checks
This commit is contained in:
+47
-74
@@ -12,6 +12,51 @@ import { createBrowserTool } from "./tools/browser-tool.js";
|
|||||||
|
|
||||||
const defaultTools = createOpenClawCodingTools();
|
const defaultTools = createOpenClawCodingTools();
|
||||||
|
|
||||||
|
function findUnionKeywordOffenders(
|
||||||
|
tools: Array<{ name: string; parameters: unknown }>,
|
||||||
|
opts?: { onlyNames?: Set<string> },
|
||||||
|
) {
|
||||||
|
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<string, unknown>;
|
||||||
|
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("createOpenClawCodingTools", () => {
|
||||||
describe("Claude/Gemini alias support", () => {
|
describe("Claude/Gemini alias support", () => {
|
||||||
it("adds Claude-style aliases to schemas without dropping metadata", () => {
|
it("adds Claude-style aliases to schemas without dropping metadata", () => {
|
||||||
@@ -213,42 +258,7 @@ describe("createOpenClawCodingTools", () => {
|
|||||||
expect(count?.oneOf).toBeDefined();
|
expect(count?.oneOf).toBeDefined();
|
||||||
});
|
});
|
||||||
it("avoids anyOf/oneOf/allOf in tool schemas", () => {
|
it("avoids anyOf/oneOf/allOf in tool schemas", () => {
|
||||||
const offenders: Array<{
|
expect(findUnionKeywordOffenders(defaultTools)).toEqual([]);
|
||||||
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<string, unknown>;
|
|
||||||
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([]);
|
|
||||||
});
|
});
|
||||||
it("keeps raw core tool schemas union-free", () => {
|
it("keeps raw core tool schemas union-free", () => {
|
||||||
const tools = createOpenClawTools();
|
const tools = createOpenClawTools();
|
||||||
@@ -267,44 +277,7 @@ describe("createOpenClawCodingTools", () => {
|
|||||||
"session_status",
|
"session_status",
|
||||||
"image",
|
"image",
|
||||||
]);
|
]);
|
||||||
const offenders: Array<{
|
expect(findUnionKeywordOffenders(tools, { onlyNames: coreTools })).toEqual([]);
|
||||||
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<string, unknown>;
|
|
||||||
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([]);
|
|
||||||
});
|
});
|
||||||
it("does not expose provider-specific message tools", () => {
|
it("does not expose provider-specific message tools", () => {
|
||||||
const tools = createOpenClawCodingTools({ messageProvider: "discord" });
|
const tools = createOpenClawCodingTools({ messageProvider: "discord" });
|
||||||
|
|||||||
Reference in New Issue
Block a user