Cron Scheduler
Persistent cron jobs that dispatch to agents on a schedule. Agents can schedule their own jobs usingset_cron (subject to can_manage_cron); list_cron and remove_cron round out the cron surface in mesh_tool.
Supported formats:
- 5-field cron expressions:
minute hour dom month dow(e.g.,0 9 * * 1-5for weekdays at 9am). Minute granularity only — 6-field cron with seconds is NOT supported. - Interval shorthand:
every Ns,every Nm,every Nh,every Nd.
config/cron.json and auto-managed.
The scheduler ticks every 5 seconds (
TICK_INTERVAL=5s). Intervals smaller than 5s won’t fire faster than that.Cron modes
Every cron has one of three modes, set by which fields are present:- Message mode — dispatches a chat message to the agent. The agent runs an LLM turn to handle it.
- Tool mode — fires
tool_namewithtool_paramsdirectly. No LLM involvement, useful for deterministic side-effects. - Heartbeat mode — runs the agent in heartbeat mode (
heartbeat=true). See below.
schedule, message, enabled, suppress_empty, tool_name, tool_params. Other fields are immutable — remove and recreate.
Heartbeat System
Cost-efficient autonomous monitoring. A heartbeat cron runs built-in probes first — cheap, deterministic checks — and only burns LLM tokens when something is actionable. Built-in probes:disk_usage(fires when disk usage > 85%)pending_signals(any unread signals)pending_tasks(any open handoffs)
every 15m. The operator’s heartbeat is force-locked to every 15m and cannot be changed.
When a heartbeat fires, the agent receives an enriched context: its HEARTBEAT.md rules, recent daily logs, probe alerts, and actual pending signal/task content — all in a single message. Iterations are capped at HEARTBEAT_MAX_ITERATIONS=12.
Skip-LLM optimization
The dispatcher will skip the LLM entirely when all four of these conditions hold:- Not a manual trigger (manual
/cron runalways dispatches). HEARTBEAT.mdis the default scaffold (unmodified).- No recent activity exists.
- No probes triggered.
Webhook Endpoints
Named webhook URLs dispatch payloads to agents:- Webhook creation is dashboard-only. There is no
/mesh/webhooksendpoint — open the dashboard (Settings → Integrations) to create a hook and get itshook_id. - Body cap 1 MB (Content-Length pre-check + post-read check). Payload is truncated to 3000 chars when forwarded to the agent, and run through
sanitize_for_prompt()first. - Optional HMAC-SHA256 via
x-webhook-signature. If a secret is configured on the hook, the dispatcher verifies viahmac.compare_digest.
File Watchers
Poll directories for new or modified files matching glob patterns. Polling, not inotify — required for Docker volume compatibility.- Poll interval: 5s (
POLL_INTERVAL=5s, not user-configurable). - First scan is silent. Files present at watcher startup do not trigger the agent — only files added or modified after the watcher comes up. This avoids replaying every existing file on restart.
