diff --git a/internal/tools/cron.go b/internal/tools/cron.go index b6428754..68711381 100644 --- a/internal/tools/cron.go +++ b/internal/tools/cron.go @@ -28,44 +28,91 @@ func (t *CronTool) SetConfigPermStore(s store.ConfigPermissionStore) { func (t *CronTool) Name() string { return "cron" } func (t *CronTool) Description() string { - return `Manage Gateway cron jobs (status/list/add/update/remove/run/runs). + return `Manage Gateway cron jobs. + Always send a JSON object with an "action" field. -ACTIONS: -- status: Check cron scheduler status -- list: List jobs (use includeDisabled:true to include disabled) -- add: Create job (requires job object, see schema below) -- update: Modify job (requires jobId + patch object) -- remove: Delete job (requires jobId) -- run: Trigger job immediately (requires jobId) -- runs: Get job run history (requires jobId) + VALID ACTIONS AND EXACT PAYLOAD SHAPES: + 1) status + { + "action": "status" + } -JOB SCHEMA (for add action): -{ - "name": "string (required, lowercase slug)", - "schedule": { ... }, // Required: when to run - "message": "string", // Required: what message to send to the agent - "deliver": true|false, // Optional: deliver result to channel (default false) - "channel": "channel-name", // Optional: target channel for delivery (auto-filled from context) - "to": "chat-id", // Optional: target chat/recipient ID - "agentId": "agent-uuid", // Optional: which agent handles the job (default: current) - "deleteAfterRun": true // Optional: auto-delete after execution (default true for "at" schedule) -} + 2) list + { + "action": "list", + "includeDisabled": true|false // optional, default false + } -SCHEDULE TYPES (schedule.kind): -- "at": One-shot at absolute time - { "kind": "at", "atMs": } -- "every": Recurring interval - { "kind": "every", "everyMs": } -- "cron": Cron expression - { "kind": "cron", "expr": "<5-field cron expression>", "tz": "" } + 3) add + { + "action": "add", + "job": { + "name": "string", // required, lowercase slug: [a-z0-9-]+ + "schedule": { ... }, // required + "message": "string", // required + "deliver": true|false, // optional, default false + "channel": "string", // optional + "to": "string", // optional + "agentId": "string", // optional, defaults to current agent + "deleteAfterRun": true|false // optional, default true for schedule.kind="at" + } + } -CRITICAL CONSTRAINTS: -- "name" must be a valid slug (lowercase letters, numbers, hyphens only) -- For action="add": send the job inside "job", "message" is required and "schedule" is required -- For action="update", send changes inside "patch" -- Default: jobs run as isolated agent turns with the specified message -- Before creating or updating a scheduled job, call the datetime tool first to get the precise current time and unix_ms timestamp. Do NOT guess or estimate timestamps. -- Use "jobId" as the canonical identifier; "id" is accepted for compatibility.` + 4) update + { + "action": "update", + "jobId": "string", // required + "patch": { + "name": "string", // optional + "schedule": { ... }, // optional + "message": "string", // optional + "deliver": true|false, // optional + "channel": "string", // optional + "to": "string", // optional + "agentId": "string", // optional + "deleteAfterRun": true|false, // optional + "disabled": true|false // optional + } + } + + 5) remove + { + "action": "remove", + "jobId": "string" + } + + 6) run + { + "action": "run", + "jobId": "string" + } + + 7) runs + { + "action": "runs", + "jobId": "string" + } + + SCHEDULE SCHEMA: + + - at: + { "kind": "at", "atMs": } + + - every: + { "kind": "every", "everyMs": } + + - cron: + { "kind": "cron", "expr": "<5-field cron expression>", "tz": "" } + + RULES: + - For action="add", send the job inside "job". Do not place job fields at the root level. + - For action="update", send changes inside "patch". Do not place patch fields at the root level. + - Always use "jobId". Do not use "id" unless explicitly required by older compatibility code. + - "name", "schedule", and "message" are required for add. + - "name" must match: lowercase letters, numbers, hyphens only. + - Before creating or updating a scheduled job, call the datetime tool first to get the precise current time and unix_ms timestamp. Never guess timestamps. + - Omit optional fields when unknown; do not invent placeholder values like "", 0, or null unless required. + - Jobs run as isolated agent turns using the provided "message".` } func (t *CronTool) Parameters() map[string]any {