From 1371b66e0f1e3ce7e87e14850b23ab8e89a8c1ce Mon Sep 17 00:00:00 2001 From: Yurii Chukhlib Date: Mon, 26 Jan 2026 12:02:11 +0100 Subject: [PATCH] docs(cron): improve tool description with explicit required fields Fixes #1982 Enhanced cron tool description to help AI agents reliably create cron jobs without guessing enum values or failing validation. Changes: - Marked REQUIRED fields explicitly (schedule, payload, sessionTarget) - Clarified REQUIRED vs OPTIONAL fields for each payload kind - Added concrete examples for each schedule type - Added "choose exactly one" guidance for enum selections - Expanded CRITICAL CONSTRAINTS section with numbered rules - Added "will fail validation if violated" warning This prevents agents from: - Using payload.message instead of payload.text - Mixing main+agentTurn or isolated+systemEvent - Guessing enum values through trial and error --- src/agents/tools/cron-tool.ts | 58 +++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/src/agents/tools/cron-tool.ts b/src/agents/tools/cron-tool.ts index 739b3ada3..bd148e929 100644 --- a/src/agents/tools/cron-tool.ts +++ b/src/agents/tools/cron-tool.ts @@ -147,36 +147,48 @@ ACTIONS: JOB SCHEMA (for add action): { - "name": "string (optional)", - "schedule": { ... }, // Required: when to run - "payload": { ... }, // Required: what to execute - "sessionTarget": "main" | "isolated", // Required - "enabled": true | false // Optional, default true + "name": "string (optional, required for update)", + "schedule": { ... }, // REQUIRED: when to run + "payload": { ... }, // REQUIRED: what to execute + "sessionTarget": "main" | "isolated", // REQUIRED: which session type + "enabled": true | false, // OPTIONAL, default true + "deleteAfterRun": true | false // OPTIONAL, default false (for one-shot jobs) } -SCHEDULE TYPES (schedule.kind): -- "at": One-shot at absolute time - { "kind": "at", "atMs": } -- "every": Recurring interval - { "kind": "every", "everyMs": , "anchorMs": } -- "cron": Cron expression - { "kind": "cron", "expr": "", "tz": "" } +SCHEDULE TYPES (schedule.kind - choose exactly one): +- "at": One-shot job at absolute timestamp (ms since epoch) + { "kind": "at", "atMs": 1699900000000 } -PAYLOAD TYPES (payload.kind): -- "systemEvent": Injects text as system event into session - { "kind": "systemEvent", "text": "" } -- "agentTurn": Runs agent with message (isolated sessions only) - { "kind": "agentTurn", "message": "", "model": "", "thinking": "", "timeoutSeconds": , "deliver": , "channel": "", "to": "", "bestEffortDeliver": } +- "every": Recurring interval (milliseconds) + { "kind": "every", "everyMs": 3600000 } -CRITICAL CONSTRAINTS: -- sessionTarget="main" REQUIRES payload.kind="systemEvent" -- sessionTarget="isolated" REQUIRES payload.kind="agentTurn" +- "cron": Standard cron expression + { "kind": "cron", "expr": "0 9 * * 1-5", "tz": "America/New_York" } + +PAYLOAD TYPES (payload.kind - choose exactly one): +- "systemEvent": Inject text as system event (for sessionTarget="main" ONLY) + { "kind": "systemEvent", "text": "Your reminder message" } + REQUIRED FIELDS: kind, text + +- "agentTurn": Run agent with message (for sessionTarget="isolated" ONLY) + { "kind": "agentTurn", "message": "Your prompt here" } + REQUIRED FIELDS: kind, message + OPTIONAL FIELDS: model, thinking, timeoutSeconds, deliver, channel, to, bestEffortDeliver + +SESSION TARGET (sessionTarget - choose exactly one): +- "main": Main session - REQUIRES payload.kind="systemEvent" +- "isolated": Sub-agent session - REQUIRES payload.kind="agentTurn" + +CRITICAL CONSTRAINTS (will fail validation if violated): +1. sessionTarget="main" MUST use payload.kind="systemEvent" with text field +2. sessionTarget="isolated" MUST use payload.kind="agentTurn" with message field +3. Do NOT mix: main+agentTurn or isolated+systemEvent WAKE MODES (for wake action): -- "next-heartbeat" (default): Wake on next heartbeat -- "now": Wake immediately +- "next-heartbeat" (default): Deliver on next heartbeat cycle +- "now": Deliver immediately -Use jobId as the canonical identifier; id is accepted for compatibility. Use contextMessages (0-10) to add previous messages as context to the job text.`, +Use jobId as the canonical identifier; id is accepted for backward compatibility. Use contextMessages (0-10) to add previous chat messages as context to reminder jobs.`, parameters: CronToolSchema, execute: async (_toolCallId, args) => { const params = args as Record;