fix(tools): finalize Vertex schema flattening (#409)

This commit is contained in:
Peter Steinberger
2026-01-07 17:54:19 +00:00
parent a2b3f2c18a
commit c3b3f571e9
4 changed files with 56 additions and 16 deletions

View File

@@ -31,6 +31,39 @@ describe("createClawdbotCodingTools", () => {
expect(parameters.required ?? []).toContain("action");
});
it("flattens anyOf-of-literals to enum for provider compatibility", () => {
const tools = createClawdbotCodingTools();
const browser = tools.find((tool) => tool.name === "browser");
expect(browser).toBeDefined();
const parameters = browser?.parameters as {
properties?: Record<string, unknown>;
};
const action = parameters.properties?.action as
| {
type?: unknown;
enum?: unknown[];
anyOf?: unknown[];
}
| undefined;
expect(action?.type).toBe("string");
expect(action?.anyOf).toBeUndefined();
expect(Array.isArray(action?.enum)).toBe(true);
expect(action?.enum).toContain("act");
const format = parameters.properties?.format as
| {
type?: unknown;
enum?: unknown[];
anyOf?: unknown[];
}
| undefined;
expect(format?.type).toBe("string");
expect(format?.anyOf).toBeUndefined();
expect(format?.enum).toEqual(["aria", "ai"]);
});
it("preserves action enums in normalized schemas", () => {
const tools = createClawdbotCodingTools();
const toolNames = ["browser", "canvas", "nodes", "cron", "gateway"];

View File

@@ -28,25 +28,29 @@ import {
readStringParam,
} from "./common.js";
const BROWSER_ACT_KINDS = [
"click",
"type",
"press",
"hover",
"drag",
"select",
"fill",
"resize",
"wait",
"evaluate",
"close",
] as const;
type BrowserActKind = (typeof BROWSER_ACT_KINDS)[number];
// NOTE: Using a flattened object schema instead of Type.Union([Type.Object(...), ...])
// because Claude API on Vertex AI rejects nested anyOf schemas as invalid JSON Schema.
// The discriminator (kind) determines which properties are relevant; runtime validates.
const BrowserActSchema = Type.Object({
kind: Type.Unsafe<string>({
kind: Type.Unsafe<BrowserActKind>({
type: "string",
enum: [
"click",
"type",
"press",
"hover",
"drag",
"select",
"fill",
"resize",
"wait",
"evaluate",
"close",
],
enum: [...BROWSER_ACT_KINDS],
}),
// Common fields
targetId: Type.Optional(Type.String()),
@@ -67,7 +71,9 @@ const BrowserActSchema = Type.Object({
// select
values: Type.Optional(Type.Array(Type.String())),
// fill - use permissive array of objects
fields: Type.Optional(Type.Array(Type.Object({}, { additionalProperties: true }))),
fields: Type.Optional(
Type.Array(Type.Object({}, { additionalProperties: true })),
),
// resize
width: Type.Optional(Type.Number()),
height: Type.Optional(Type.Number()),