How it works
- Every interval, the daemon checks the agent’s active hours. Outside them, it skips the run.
- It looks for
HEARTBEAT.mdin the agent’s working directory. If the file is missing or empty, it skips the run. - It sends a heartbeat prompt to the agent’s main session. The prompt tells the agent to read
HEARTBEAT.mdand do what is pending. - If the reply ends with
HEARTBEAT_OK, Ravi posts nothing. Any other reply goes to the chat where the main session last talked.
Set it up
1
Find the agent's working directory
Workspace is the agent’s working directory (the same cwd as in ravi agents show main). The file goes there, for example ~/ravi/main/HEARTBEAT.md.2
Write HEARTBEAT.md
3
Enable it
enable keeps the current one (30 minutes if it was never set). The first run happens one interval after you enable it.4
Limit it to working hours (optional)
5
Run it once now
The prompt the agent receives
Every run sends this fixed prompt (it is in Portuguese) to the agent’s main session:HEARTBEAT.md in your workspace, do the pending tasks, and if there is nothing to do, answer exactly HEARTBEAT_OK; anything else is sent to the user. Put your own instructions in HEARTBEAT.md, not in the prompt.
Staying quiet with HEARTBEAT_OK
Ravi drops any reply whose text ends withHEARTBEAT_OK, including the text before it. The agent either reports something or answers HEARTBEAT_OK, never both. The daemon log shows Heartbeat OK for a dropped reply.
Where the reply goes
A scheduled run goes to the agent’s main session and replies in the chat where that session last talked.ravi heartbeat set main account <name> picks the channel account when you have more than one.
If the main session never talks in a chat (for example, when each DM has its own session), the reply stays in the session. Read it with ravi sessions read <session-name>, or tell the agent in HEARTBEAT.md how to report, for example Report with: ravi sessions inform <your-chat-session> "<summary>".
Manual runs
- If
HEARTBEAT.mdis missing or empty,triggerdoes nothing and exits 0 withstatus: "skipped"(--json). No--executeis needed for that check. - If the file has content,
triggerwithout--executeis a dry-run: it exits 3 and shows the plan. - With
--execute, the prompt is sent right away, even when the heartbeat is disabled or outside active hours. - A manual run has no chat attached to the prompt, so its reply goes to the main session’s attached chat, if it has one, and otherwise stays in the session.
Settings
Active hours use the clock of the machine running the daemon. The start is inclusive and the end is exclusive. A window that crosses midnight works:
22:00-06:00.
Changes take effect right away. A changed interval restarts that agent’s timer, and restarting the daemon restarts every timer, so the next run comes one full interval later.
heartbeat set <agent> model is stored and shown by ravi heartbeat show, but the current runtime does not use it: heartbeat runs use the main session’s model. If a periodic check must run on a cheaper model, use a cron job with --isolated and set the model of its session with ravi sessions set-model <session> haiku after the first run. An isolated job never posts to a chat, so tell it in the message how to report.Check status
Heartbeat or cron job?
Use a heartbeat for an open-ended “look around and tell me if something needs me”. Use cron jobs for specific tasks at specific times, and triggers to react to events as they happen.
Troubleshooting
The heartbeat never runs
The heartbeat never runs
ravi heartbeat show main:Enabled: yes, the interval, and active hours that include the current time on the daemon machine.HEARTBEAT.mdexists in the workspace shown there and is not empty.ravi daemon status: the daemon is running. Only one daemon runs heartbeats when several share the same setup.ravi daemon logs -f: a run logsTriggering heartbeat.
It runs, but nothing is posted
It runs, but nothing is posted
Heartbeat OKin the daemon log means the agent answeredHEARTBEAT_OK.ravi sessions read <main-session>shows what the agent replied.- See Where the reply goes if the main session has no chat.