Hermes scheduled tasks and loops
Natural-language cron, no-agent watchdogs, and the loop that lives in a session
Hermes schedules work two ways. Cron jobs live outside a session: the gateway ticks every sixty seconds, runs due jobs in fresh agent sessions and delivers the result. Loops live inside one: a prompt re-run on a cadence in the conversation you are in. Both are created in plain language, and the docs are unusually careful about what happens when a job fails, delivers nothing, or is misconfigured.
Cron: what it does
- One-shot or recurring jobs, created from chat, the CLI, or by asking in a sentence, with zero, one or several skills attached.
- Delivery back to the origin chat, to local files, to a named platform or channel, or fanned out to every connected home channel.
- A model resolution order: the job’s own pin, then a cron-fleet default, then the global default, snapshotted at creation so changing your chat model never moves the fleet.
- Cron-run sessions cannot create more cron jobs, to prevent runaway scheduling loops.
Before any agent machinery is built, the scheduler validates the job: the provider key resolves, attached skills have what they need, delivery targets have credentials. A failing job is marked blocked, one alert goes out, and no model call is made, so a misconfigured job never spends tokens. Execution and delivery are tracked separately: a run that succeeded but never reached the target is a delivery failure with its reason, never a plain ok.
Cron-run sessions cannot recursively create more cron jobs. Hermes disables cron management tools inside cron executions to prevent runaway scheduling loops.
No-agent mode
For watchdogs, disk and memory alerts, heartbeats and CI pings, a job can run a script on a schedule with no model at all: stdout is delivered verbatim, empty stdout is a silent tick, and a non-zero exit or a timeout delivers an error alert so a broken watchdog cannot fail silently. You can describe the watchdog in chat and the agent writes the script and the job.
Loops: inside the session
- A loop re-runs a prompt or a slash command on a cadence in the current session; each wakeup is a real turn against current state.
- Fixed interval when an external clock drives the work; self-paced, backing off while the replies stop changing, when the work drives the rhythm.
- It ends when the agent declares completion, after a run cap, when a judged condition is met, when you stop it, or at a backstop budget of a hundred ticks by default.
- Unattended work that must survive a closed terminal belongs in cron, not in a loop.
Under systemd
Each due job is handed to a worker in a transient user scope so a gateway restart mid-job does not kill it, provided the gateway user has a login session with lingering enabled; otherwise cron degrades to a plain external process. Every attempt is recorded in a local ledger with a terminal state, and an abandoned attempt is marked unknown rather than rerun. OpenClaw automations is OpenClaw’s answer to the same problems, for comparison.
On Diali
The gateway, the service and the lingering session are ours; the job definitions, the delivery targets and the model pins are yours, in plain language from any channel. Hosted Hermes on Diali is the hosted version; Hermes vs OpenClaw compares the two engines’ scheduling alongside the rest.
- Cron lives outside the session; loops live inside it.
- A misconfigured job is blocked before it spends a token.
- Delivery failure is its own status, never a plain ok.
Stop reading about it, build one
Set up an agent, pick a channel, and have it working inside the app you already keep open.
