Scheduler Tools
Defer and repeat tool calls or workflows on a time-based or event-driven schedule.
Scheduler tools let agents create, inspect, and cancel scheduled tasks powered by the Governor system. You describe the schedule in natural language and provide the tool or workflow to run — the system parses the schedule, installs the appropriate triggers, and fires the task at the right time. All Scheduler tools are available at data-grout@1/scheduler.*@1.
Important: Scheduled tasks require an active Governor session to fire. The scheduler auto-provisions a lightweight Governor session (5 credits/hour) when creating a task, so you do not need to call governor.enable manually. However, if the Governor session is explicitly ended via governor.disable, scheduled tasks will be paused until the session is restarted. Calling governor.enable before scheduling gives you a full-featured Governor with percepts and enrichment on top of the scheduler.
You can also pass a schedule parameter directly to discovery.perform or flow.into to schedule any single tool call or workflow without calling scheduler.create explicitly.
scheduler.create@1
Schedule a tool call or multi-step workflow for deferred or recurring execution. Accepts a natural language schedule description alongside either a tool name (single call) or a plan array (multi-step workflow).
Two execution models are supported:
-
Time-based (e.g.
"daily at 9am","in 30 minutes"): scheduled directly at the computed time -
Event-driven (e.g.
"whenever 10 new leads arrive"): trigger-based execution powered by the Governor system
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
schedule |
string | yes | – |
Natural language schedule description (e.g. "every 5 minutes", "daily at 9am UTC", "every Monday at 8:30am") |
tool |
string | conditionally | – |
Full tool name to execute on each trigger. Provide either tool or plan |
args |
object | no |
{} |
Arguments to pass to the tool on each execution |
plan |
array | conditionally | – |
A flow.into-style plan array for multi-step workflows. Provide either tool or plan |
refract |
string | no | – |
Optional prism.refract goal to apply to the tool output on each execution |
chart |
string | no | – |
Optional prism.chart goal to apply to the tool output on each execution |
max_fires |
integer | no | unlimited | Maximum number of times to fire. Omit for unlimited recurring execution |
Example: recurring tool call
{
"name": "data-grout@1/scheduler.create@1",
"arguments": {
"schedule": "every weekday at 8am UTC",
"tool": "quickbooks@1/get-all-overdue-invoices@1",
"args": { "days_overdue": 30 },
"refract": "list customers with total overdue > $1000 sorted by amount descending"
}
}
Response:
{
"success": true,
"scheduled_task_id": "550e8400-e29b-41d4-a716-446655440000",
"schedule_type": "time_based",
"schedule": {
"cron": "0 8 * * 1-5",
"description": "Every weekday at 08:00 UTC"
},
"next_fire_at": "2026-03-03T08:00:00Z",
"recurs": true,
"message": "Scheduled: every weekday at 8am UTC"
}
Example: one-time deferred workflow
{
"name": "data-grout@1/scheduler.create@1",
"arguments": {
"schedule": "in 2 hours",
"plan": [
{
"id": "sync_leads",
"tool": "salesforce@1/get-all-leads@1",
"args": { "status": "New" }
},
{
"id": "notify",
"tool": "data-grout@1/flow.request-approval@1",
"args": {
"action": "Import new leads",
"details": "$sync_leads.count leads ready to import"
}
}
],
"max_fires": 1
}
}
Example: inline scheduling on discovery.perform
schedule must be a top-level discovery.perform parameter, not nested inside args. Nesting it inside args will cause immediate execution with no scheduling.
{
"name": "data-grout@1/discovery.perform@1",
"arguments": {
"tool": "quickbooks@1/get-all-invoices@1",
"args": { "status": "open" },
"schedule": "every day at 6pm"
}
}
This is equivalent to calling scheduler.create with the same tool, args, and schedule.
scheduler.list@1
List active, pending, paused, and completed scheduled tasks for the current user.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
agent_id |
string | no | – | Filter by a specific agent ID. Omit to list all tasks for the user |
status |
string | no |
"all" |
Filter by status: "active", "pending", "paused", "completed", "cancelled", "all" |
Example
{
"name": "data-grout@1/scheduler.list@1",
"arguments": {
"status": "active"
}
}
Response:
{
"success": true,
"tasks": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"schedule_goal": "every weekday at 8am UTC",
"tool_name": "quickbooks@1/get-all-overdue-invoices@1",
"status": "active",
"recurs": true,
"next_fire_at": "2026-03-03T08:00:00Z",
"last_fired_at": "2026-03-02T08:00:01Z",
"fire_count": 12,
"max_fires": null,
"cron_expression": "0 8 * * 1-5",
"description": "Every weekday at 08:00 UTC",
"created_at": "2026-02-17T14:22:00Z"
}
],
"total": 1
}
scheduler.cancel@1
Cancel an active or pending scheduled task by its ID. Use scheduler.list to find task IDs.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
task_id |
string | yes | – | The scheduled task UUID to cancel |
Example
{
"name": "data-grout@1/scheduler.cancel@1",
"arguments": {
"task_id": "550e8400-e29b-41d4-a716-446655440000"
}
}
Response:
{
"success": true,
"message": "Scheduled task cancelled: every weekday at 8am UTC",
"task_id": "550e8400-e29b-41d4-a716-446655440000"
}
Typical usage patterns
Recurring data sync with post-processing:
{
"schedule": "every hour",
"tool": "salesforce@1/get-all-leads@1",
"args": { "status": "New", "limit": 500 },
"refract": "count by owner and flag owners with more than 20 new leads"
}
Deferred one-shot task:
{
"schedule": "in 30 minutes",
"tool": "quickbooks@1/send-invoice@1",
"args": { "invoice_id": "INV-1042" },
"max_fires": 1
}
Scheduled workflow that needs human approval:
Combine scheduler.create with a plan that includes flow.request-approval as a step. The approval gate fires mid-workflow each time the schedule triggers.
Event-Driven Scheduling
Event-driven schedules use the Governor system’s Reflex layer to fire tasks based on conditions rather than fixed times. When you create an event-driven schedule, the system:
- Parses the trigger using the Governor Reflection LLM to extract the condition
- Installs percepts — lightweight sensors that watch for relevant events
-
Asserts Prolog facts —
scheduled_task/5andschedule_trigger/4facts into the Governor’s fact space - Evaluates triggers via Reflex — the symbolic Prolog layer checks conditions on each percept event (zero LLM tokens per check)
-
Fires the task when conditions are met, recording
schedule_fired/4facts
Percept Types
The Governor supports several percept types that can trigger event-driven schedules:
| Percept | Description | Example trigger |
|---|---|---|
cron |
Time-based conditions evaluated as Prolog facts |
"every hour between 9am and 5pm" |
file_watch |
File system change notifications |
"whenever the sales report is updated" |
webhook |
External webhook events |
"when a new Stripe payment arrives" |
process |
System process status changes |
"when the ETL job finishes" |
How Reflex evaluation works
Event-driven schedules are evaluated symbolically (no LLM):
- A percept fires (e.g., a file changes)
-
The percept handler asserts a fact into the Prolog fact space (e.g.,
file_changed(Path, Timestamp)) - Reflex queries the trigger’s Prolog rule against the current fact space
-
If the rule succeeds, the
GovernorScheduleExecutorOban worker runs the scheduled tool/plan -
The fact
schedule_fired(TaskId, Agent, Timestamp, Result)is asserted for audit
This means that after initial setup, recurring trigger evaluation costs zero LLM tokens — all the logic runs in SWI-Prolog.
Example: event-driven schedule
{
"name": "data-grout@1/scheduler.create@1",
"arguments": {
"schedule": "whenever 10 new leads arrive in Salesforce",
"tool": "salesforce@1/get-all-leads@1",
"args": { "status": "New", "limit": 10 },
"refract": "summarize lead sources and flag any from enterprise companies"
}
}
Response:
{
"success": true,
"scheduled_task_id": "7f1a2b3c-...",
"schedule_type": "event_driven",
"schedule": {
"trigger": "lead_count_threshold",
"condition": "10 new leads",
"percept_type": "webhook"
},
"recurs": true,
"message": "Scheduled: fires whenever 10 new leads arrive"
}
Governor billing
Event-driven schedules require an active Governor session. Billing:
- Full Governor session (active monitoring): 50 credits/hour
- Schedule-only mode (just firing on percepts): 5 credits/hour
- The schedule executor itself charges normal tool costs when it fires
Reflection loop
For complex event-driven schedules, the Governor’s Reflection loop can learn new patterns:
- If a simple percept isn’t sufficient, Reflection (LLM, up to 5 iterations) analyzes the schedule goal
- It may synthesize new Prolog rules and install new percepts automatically
-
The
GovernorScheduleReflectorOban worker reviews active schedules every 6 hours - Schedules whose Governor sessions have gone inactive are automatically paused