fix(cron-tool): use generic object schema for job/patch to fix Claude via Antigravity (#280)

This commit is contained in:
Muhammed Mukhthar CM
2026-01-06 13:43:09 +05:30
committed by GitHub
parent c27dd75135
commit 42d1c2448e

View File

@@ -3,11 +3,23 @@ import {
normalizeCronJobCreate, normalizeCronJobCreate,
normalizeCronJobPatch, normalizeCronJobPatch,
} from "../../cron/normalize.js"; } from "../../cron/normalize.js";
import { CronAddParamsSchema } from "../../gateway/protocol/schema.js";
import { type AnyAgentTool, jsonResult, readStringParam } from "./common.js"; import { type AnyAgentTool, jsonResult, readStringParam } from "./common.js";
import { callGatewayTool, type GatewayCallOptions } from "./gateway.js"; import { callGatewayTool, type GatewayCallOptions } from "./gateway.js";
const CronJobPatchSchema = Type.Partial(CronAddParamsSchema); // NOTE: We use Type.Object({}, { additionalProperties: true }) for job/patch
// instead of CronAddParamsSchema/CronJobPatchSchema because:
//
// 1. CronAddParamsSchema contains nested Type.Union (for schedule, payload, etc.)
// 2. TypeBox compiles Type.Union to JSON Schema `anyOf`
// 3. pi-ai's sanitizeSchemaForGoogle() strips `anyOf` from nested properties
// 4. This leaves empty schemas `{}` which Claude rejects as invalid
//
// The actual validation happens at runtime via normalizeCronJobCreate/Patch
// and the gateway's validateCronAddParams. This schema just needs to accept
// any object so the AI can pass through the job definition.
//
// See: https://github.com/anthropics/anthropic-cookbook/blob/main/misc/tool_use_best_practices.md
// Claude requires valid JSON Schema 2020-12 with explicit types.
const CronToolSchema = Type.Union([ const CronToolSchema = Type.Union([
Type.Object({ Type.Object({
@@ -28,7 +40,7 @@ const CronToolSchema = Type.Union([
gatewayUrl: Type.Optional(Type.String()), gatewayUrl: Type.Optional(Type.String()),
gatewayToken: Type.Optional(Type.String()), gatewayToken: Type.Optional(Type.String()),
timeoutMs: Type.Optional(Type.Number()), timeoutMs: Type.Optional(Type.Number()),
job: CronAddParamsSchema, job: Type.Object({}, { additionalProperties: true }),
}), }),
Type.Object({ Type.Object({
action: Type.Literal("update"), action: Type.Literal("update"),
@@ -36,7 +48,7 @@ const CronToolSchema = Type.Union([
gatewayToken: Type.Optional(Type.String()), gatewayToken: Type.Optional(Type.String()),
timeoutMs: Type.Optional(Type.Number()), timeoutMs: Type.Optional(Type.Number()),
id: Type.String(), id: Type.String(),
patch: CronJobPatchSchema, patch: Type.Object({}, { additionalProperties: true }),
}), }),
Type.Object({ Type.Object({
action: Type.Literal("remove"), action: Type.Literal("remove"),