heartbeat: add empty HEARTBEAT.md compatibility policy

This commit is contained in:
Tak Hoffman
2026-02-14 05:39:54 -06:00
parent e21a7aad54
commit a775d39e64
15 changed files with 233 additions and 50 deletions

View File

@@ -89,7 +89,7 @@ Common signatures:
- `heartbeat skipped` with `reason=quiet-hours` → outside `activeHours`.
- `requests-in-flight` → main lane busy; heartbeat deferred.
- `empty-heartbeat-file``HEARTBEAT.md` exists but has no actionable content.
- `empty-heartbeat-file``HEARTBEAT.md` is comments-only and `heartbeat.emptyFilePolicy` is `skip`.
- `alerts-disabled` → visibility settings suppress outbound heartbeat messages.
## Timezone and activeHours gotchas

View File

@@ -209,6 +209,10 @@ Use `accountId` to target a specific account on multi-account channels like Tele
- `accountId`: optional account id for multi-account channels. When `target: "last"`, the account id applies to the resolved last channel if it supports accounts; otherwise it is ignored. If the account id does not match a configured account for the resolved channel, delivery is skipped.
- `prompt`: overrides the default prompt body (not merged).
- `ackMaxChars`: max chars allowed after `HEARTBEAT_OK` before delivery.
- `emptyFilePolicy`: behavior when `HEARTBEAT.md` exists but has only comments/headers.
- `run`: heartbeat still runs.
- `skip`: skip this heartbeat run with reason `empty-heartbeat-file`.
- Default when unset: `skip` for existing config files (compat), `run` for fresh installs.
- `activeHours`: restricts heartbeat runs to a time window. Object with `start` (HH:MM, inclusive), `end` (HH:MM exclusive; `24:00` allowed for end-of-day), and optional `timezone`.
- Omitted or `"user"`: uses your `agents.defaults.userTimezone` if set, otherwise falls back to the host system timezone.
- `"local"`: always uses the host system timezone.
@@ -297,9 +301,14 @@ If a `HEARTBEAT.md` file exists in the workspace, the default prompt tells the
agent to read it. Think of it as your “heartbeat checklist”: small, stable, and
safe to include every 30 minutes.
If `HEARTBEAT.md` exists but is effectively empty (only blank lines and markdown
headers like `# Heading`), OpenClaw skips the heartbeat run to save API calls.
If the file is missing, the heartbeat still runs and the model decides what to do.
If `HEARTBEAT.md` exists, OpenClaw includes it as optional guidance for heartbeat runs.
If the file is missing, heartbeat still runs and the model decides what to do.
If `HEARTBEAT.md` only has comments/headers, `heartbeat.emptyFilePolicy` controls behavior:
- `run`: heartbeat still runs (fresh-install default)
- `skip`: heartbeat skips this tick (`empty-heartbeat-file`; compat default for existing config files)
To disable heartbeat entirely (scheduler off), set `agents.defaults.heartbeat.every: "0m"`.
Keep it tiny (short checklist or reminders) to avoid prompt bloat.

View File

@@ -7,6 +7,10 @@ read_when:
# HEARTBEAT.md
# Keep this file empty (or with only comments) to skip heartbeat API calls.
# Leave this file missing, empty, or comments-only if you don't want extra heartbeat guidance.
# Set agents.defaults.heartbeat.emptyFilePolicy: "run" if you want heartbeat to run even when this file is comments-only.
# Set agents.defaults.heartbeat.every: "0m" in config to disable heartbeat entirely.
# Add tasks below when you want the agent to check something periodically.

View File

@@ -159,10 +159,13 @@ Example:
By default, OpenClaw runs a heartbeat every 30 minutes with the prompt:
`Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.`
Set `agents.defaults.heartbeat.every: "0m"` to disable.
Set `agents.defaults.heartbeat.every: "0m"` to disable heartbeat scheduling entirely.
- If `HEARTBEAT.md` exists but is effectively empty (only blank lines and markdown headers like `# Heading`), OpenClaw skips the heartbeat run to save API calls.
- If the file is missing, the heartbeat still runs and the model decides what to do.
- If `HEARTBEAT.md` exists, OpenClaw includes it as optional heartbeat guidance.
- If the file is missing, heartbeat still runs and the model decides what to do.
- If `HEARTBEAT.md` only has comments/headers, behavior depends on `agents.defaults.heartbeat.emptyFilePolicy`:
- `run`: heartbeat still runs (fresh-install default)
- `skip`: heartbeat is skipped for that tick (compat default for existing config files)
- If the agent replies with `HEARTBEAT_OK` (optionally with short padding; see `agents.defaults.heartbeat.ackMaxChars`), OpenClaw suppresses outbound delivery for that heartbeat.
- Heartbeats run full agent turns — shorter intervals burn more tokens.