fix: avoid format keyword in tool schemas

Co-authored-by: marcmarg <marcmarg@users.noreply.github.com>
This commit is contained in:
Marc
2026-01-16 15:50:02 +01:00
committed by Peter Steinberger
parent 38b49aa0f6
commit de31583021
6 changed files with 12 additions and 9 deletions

View File

@@ -107,6 +107,7 @@
- Bug investigations: read source code of relevant npm dependencies and all related local code before concluding; aim for high-confidence root cause.
- Code style: add brief comments for tricky logic; keep files under ~500 LOC when feasible (split/refactor as needed).
- Tool schema guardrails (google-antigravity): avoid `Type.Union` in tool input schemas; no `anyOf`/`oneOf`/`allOf`. Use `stringEnum`/`optionalStringEnum` (Type.Unsafe enum) for string lists, and `Type.Optional(...)` instead of `... | null`. Keep top-level tool schema as `type: "object"` with `properties`.
- Tool schema guardrails: avoid raw `format` property names in tool schemas; some validators treat `format` as a reserved keyword and reject the schema.
- When asked to open a “session” file, open the Pi session logs under `~/.clawdbot/agents/main/sessions/*.jsonl` (newest unless a specific ID is given), not the default `sessions.json`. If logs are needed from another machine, SSH via Tailscale and read the same path there.
- Menubar dimming + restart flow mirrors Trimmy: use `scripts/restart-mac.sh` (kills all Clawdbot variants, runs `swift build`, packages, relaunches). Icon dimming depends on MenuBarExtraAccess wiring in AppMain; keep `appearsDisabled` updates intact when touching the status item.
- Do not rebuild the macOS app over SSH; rebuilds must be run directly on the Mac.

View File

@@ -51,6 +51,8 @@
### Fixes
- WhatsApp: default response prefix only for self-chat, using identity name when set.
- Auth: merge main auth profiles into per-agent stores for sub-agents and document inheritance. (#1013) — thanks @marcmarg.
- Agents: avoid JSON Schema `format` collisions in tool params by renaming snapshot format fields. (#1013) — thanks @marcmarg.
- Fix: make `clawdbot update` auto-update global installs when installed via a package manager.
- Fix: list model picker entries as provider/model pairs for explicit selection. (#970) — thanks @mcinteerj.
- Fix: align OpenAI image-gen defaults with DALL-E 3 standard quality and document output formats. (#880) — thanks @mkbehr.

View File

@@ -129,16 +129,16 @@ describe("createClawdbotCodingTools", () => {
expect(Array.isArray(action?.enum)).toBe(true);
expect(action?.enum).toContain("act");
const format = parameters.properties?.format as
const snapshotFormat = parameters.properties?.snapshotFormat as
| {
type?: unknown;
enum?: unknown[];
anyOf?: unknown[];
}
| undefined;
expect(format?.type).toBe("string");
expect(format?.anyOf).toBeUndefined();
expect(format?.enum).toEqual(["aria", "ai"]);
expect(snapshotFormat?.type).toBe("string");
expect(snapshotFormat?.anyOf).toBeUndefined();
expect(snapshotFormat?.enum).toEqual(["aria", "ai"]);
});
it("inlines local $ref before removing unsupported keywords", () => {
const cleaned = __testing.cleanToolSchemaForGemini({

View File

@@ -91,7 +91,7 @@ export const BrowserToolSchema = Type.Object({
limit: Type.Optional(Type.Number()),
maxChars: Type.Optional(Type.Number()),
mode: optionalStringEnum(BROWSER_SNAPSHOT_MODES),
format: optionalStringEnum(BROWSER_SNAPSHOT_FORMATS),
snapshotFormat: optionalStringEnum(BROWSER_SNAPSHOT_FORMATS),
refs: optionalStringEnum(BROWSER_SNAPSHOT_REFS),
interactive: Type.Optional(Type.Boolean()),
compact: Type.Optional(Type.Boolean()),

View File

@@ -191,8 +191,8 @@ export function createBrowserTool(opts?: {
}
case "snapshot": {
const format =
params.format === "ai" || params.format === "aria"
? (params.format as "ai" | "aria")
params.snapshotFormat === "ai" || params.snapshotFormat === "aria"
? (params.snapshotFormat as "ai" | "aria")
: "ai";
const mode = params.mode === "efficient" ? "efficient" : undefined;
const labels = typeof params.labels === "boolean" ? params.labels : undefined;

View File

@@ -40,7 +40,7 @@ const CanvasToolSchema = Type.Object({
// eval
javaScript: Type.Optional(Type.String()),
// snapshot
format: optionalStringEnum(CANVAS_SNAPSHOT_FORMATS),
outputFormat: optionalStringEnum(CANVAS_SNAPSHOT_FORMATS),
maxWidth: Type.Optional(Type.Number()),
quality: Type.Optional(Type.Number()),
delayMs: Type.Optional(Type.Number()),
@@ -127,7 +127,7 @@ export function createCanvasTool(): AnyAgentTool {
return jsonResult({ ok: true });
}
case "snapshot": {
const formatRaw = typeof params.format === "string" ? params.format.toLowerCase() : "png";
const formatRaw = typeof params.outputFormat === "string" ? params.outputFormat.toLowerCase() : "png";
const format = formatRaw === "jpg" || formatRaw === "jpeg" ? "jpeg" : "png";
const maxWidth =
typeof params.maxWidth === "number" && Number.isFinite(params.maxWidth)