Operating GEODEHow-to
Schedule tasks
Natural language and cron, with jitter. A daily report as a single command.
On this page
Scheduling happens inside a session, through two entry points. Ask in natural language and the agent creates the job with the schedule_job tool; for direct control, use the /schedule slash command. A shell one-shot like geode "..." is not supported. Created jobs fire inside the serve daemon.
Natural language
geode
> every weekday at 9am, summarize AI news for meThe agent calls the schedule_job tool (core/tools/definitions.json), splitting the schedule expression from the prompt to run. When the job fires, that prompt runs as a fresh agentic execution.
Direct control with /schedule
Quote the schedule and the action separately. A job without an action is rejected; it would fire and do nothing (core/cli/commands/schedule.py).
> /schedule # list jobs + templates
> /schedule create "daily at 9:00" "summarize today's AI news"
> /schedule status <id>
> /schedule disable <id> # pause
> /schedule enable <id>
> /schedule run <id> # fire right now
> /schedule delete <id>Schedule expressions are parsed by NLScheduleParser(core/scheduler/nl_scheduler.py), rule-based with no LLM call.
| Pattern | Examples |
|---|---|
| Intervals | "every 5 minutes", "every 2 hours", "every 30s" |
| Cron-like phrases | "daily at 9:00", "weekly on monday", "hourly", "every weekday at 14:00" |
| Active hours | "every 5m during 09:00-22:00" |
| Job naming | "run analysis every 5m" names the job analysis |
Jitter and the execution environment
To keep jobs sharing the same nominal time from firing at once, a deterministic forward offset derived from sha256 of the job ID is added to the fire time. The same job always gets the same offset; different jobs spread out. The offset is capped at 10% of the interval or 15 minutes, whichever is smaller (core/scheduler/jitter.py). Fired jobs run as SCHEDULER-mode sessions: a 300-second wall-clock cap, and with no user present to approve, run_bash and delegate_task are denied (core/server/supervised/services.py).
Failure modes
| Symptom | Cause | Fix |
|---|---|---|
| Nothing fires at the scheduled time | The serve daemon is down | The scheduler lives inside the daemon. Check with pgrep -f "geode serve" and run geode again. |
| The job is not created | Missing action or unquoted arguments | Quote both arguments: /schedule create "schedule" "action". |
| Fires a few minutes late | Intentional jitter | Expected. A deterministic offset prevents the thundering herd. |
| A long job gets cut off | The 300-second SCHEDULER-mode cap | Split the work into smaller jobs, or run long research directly in a session. |
Next
- Scheduler internals. Parsing, persistence, and the firing path.
- Messaging integrations. Get results delivered to Slack.
Moved from the GEODE repository’s documentation site. Source commit de077a4 · View the source on GitHub