Files
hermes-agent/website/docs/user-guide/features/heartbeat.md
Teknium 6518aa184e feat: /heartbeat — recurring session re-entry prompt fired when idle
/heartbeat every <interval> <prompt> gives the current session one
recurring instruction. When the session is idle and the interval has
elapsed, the prompt is injected as a plain user turn — same
conversation, same context, prompt cache and role alternation
untouched.

- CLI: idle-poll watchdog thread (wake-word watchdog pattern) feeding
  _pending_input; gateway: single gateway-wide async poller injecting
  through the adapter FIFO. Busy sessions coalesce their tick to the
  next idle poll.
- Missed ticks coalesce (anchor resets on fire) — a busy hour yields
  ONE heartbeat turn, never a backlog. Real user messages always win.
- 60s interval floor; injected prompt carries a don't-invent-work
  guard so idle heartbeats don't generate busywork.
- State persists in SessionDB.state_meta (heartbeat:<session_id>),
  survives /resume, migrates across compression session rotations
  alongside /goal state.
- Session-scoped and in-process by design — durable cross-process
  schedules remain the cron subsystem's job (docs draw the boundary).
- Slack stays under the 50-slash cap via /hermes heartbeat; ghost-text
  suggester now prefers the shortest prefix match so /he still
  suggests /help.

Adapted from the session-heartbeat concept in Prime Intellect's
Prime-Agent (/heartbeat).
2026-08-05 22:32:55 -07:00

3.5 KiB

sidebar_position, title, description
sidebar_position title description
17 Session Heartbeats A recurring prompt that re-enters your current session whenever it's idle — /heartbeat every 10m Check the deployment.

Session Heartbeats (/heartbeat)

/heartbeat gives the current session one recurring instruction. Whenever the session is idle and the interval has elapsed, the prompt fires as a normal user turn — same conversation, same context, same prompt cache.

/heartbeat every 10m Check the deployment and report meaningful changes

Inspired by Prime-Agent's /heartbeat. The Hermes adaptation keeps the strict message-flow invariants: the heartbeat is injected only between turns (never mid-run), as a plain user-role message.

Heartbeat vs cron: which one do I want?

They look similar but serve different jobs:

/heartbeat hermes cron
Runs in This conversation — full context, memory of the discussion A fresh isolated session per tick
Survives process restart State survives (SessionDB); firing resumes next time the session is driven Yes — fully durable scheduler
How many One per session Unlimited jobs
Best for "Keep an eye on X in this thread while we work" Standing jobs, reports, watchdogs, deliveries

Rule of thumb: if the recurring prompt needs the conversation's context, use /heartbeat. If it's a self-contained job, use cron.

Commands

Command What it does
/heartbeat every <interval> <prompt> Set (or replace) the session's heartbeat. Intervals: 90s, 10m, 2h, 1d (minimum 60s).
/heartbeat or /heartbeat status Show the heartbeat, its interval, and time to next fire.
/heartbeat pause Stop firing without clearing.
/heartbeat resume Resume (re-anchors the timer — no instant stale fire).
/heartbeat clear Remove the heartbeat.

/hb is an alias. Works on the CLI and gateway platforms (on Slack, use /hermes heartbeat …).

Behavior details

  • Idle-only. A heartbeat never interrupts a running turn. If the agent is busy when the tick comes due, it fires at the next idle poll.
  • Missed ticks coalesce. If the session was busy (or the process wasn't running) through several intervals, you get one heartbeat turn, not a backlog. The timer re-anchors on every fire.
  • User messages win. A queued user message always takes priority; the heartbeat waits for the input queue to drain.
  • Cache-safe. The injected prompt is an ordinary user message. No system-prompt mutation, no toolset change.
  • Persistence. State lives in SessionDB.state_meta keyed by heartbeat:<session_id> — it survives /resume and rides across context-compression session rotations. Firing requires the owning process (CLI session or gateway) to be running; for schedules that must survive anything, use cron.
  • Don't-invent-work guard. The injected prompt tells the agent to reply briefly and stop when nothing meaningful changed, so an idle heartbeat doesn't generate busywork.

Example

You: /heartbeat every 15m Check whether the CI run for PR #1234 finished; summarize the result when it does

  ♥ Heartbeat set (every 15m): Check whether the CI run for PR #1234 finished; ...

[15 minutes of you working on other things in the same session]

Hermes: [Heartbeat — recurring instruction, fires every 15m]
  💻 gh pr checks 1234   (1.2s)
  CI is still running (14/37 checks complete). Nothing to report yet.

When the answer stops changing, /heartbeat clear it — or let it keep watch.