feature: add heartbeat loop for periodic health checks#29
Merged
Conversation
New heartbeat.ts extension — a periodic timer that reads HEARTBEAT.md and injects it as a follow-up prompt (default: every 10 min). - Configurable via env vars (HEARTBEAT_INTERVAL_MS, HEARTBEAT_FILE, HEARTBEAT_ENABLED) - Error backoff: exponential delay on consecutive failures (2x per error, max 1 hour) to prevent token burn - heartbeat tool: status/pause/resume/trigger/config actions - Default checklist checks agent sessions, Slack bridge, email monitor, stale worktrees, and stuck todos - If HEARTBEAT.md is empty or missing, no heartbeat fires (zero cost) - deploy.sh deploys HEARTBEAT.md (always overwrites — admin-managed) Inspired by OpenClaw's HEARTBEAT.md pattern.
Tests cover all pure functions: - readHeartbeatFile: missing/empty/comments-only/headings-only/valid - resolveConfig: interval parsing, minimum floor, file path, defaults - isDisabledByEnv: all boolean-ish values (0/false/no/1/true/yes/null) - computeBackoffMs: exponential progression, MAX cap, monotonicity - Deploy checklist: HEARTBEAT.md exists and has actionable content
Bug: if pi.sendMessage() or saveState() threw, the exception propagated uncaught from the setTimeout callback. The armTimer() call at the end was never reached, permanently killing the heartbeat loop after a single failure. The consecutiveErrors counter was also never incremented, making the backoff machinery dead code. Fix: - try/catch/finally around the entire fire path - Success resets consecutiveErrors to 0 - Catch increments consecutiveErrors (drives exponential backoff) - finally always calls armTimer() so the loop never dies - saveState() in catch is best-effort (nested try/catch) - Removed stale comment referencing nonexistent agent_end handler Added 6 tests simulating the error handling contract.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a periodic heartbeat loop to the control agent so Baudbot becomes proactive instead of purely reactive.
New files
pi/extensions/heartbeat.ts— pi extension that runs asetTimeouttimer, reads~/.pi/agent/HEARTBEAT.mdon each tick, and injects it as a follow-up promptpi/skills/control-agent/HEARTBEAT.md— default checklist deployed to~/.pi/agent/HEARTBEAT.mdHow it works
session_start(default: 10 min interval)HEARTBEAT.md— if empty/missing, skips silently (zero token cost)followUpmessage withtriggerTurn: trueDefault checklist checks
Features
heartbeattool: status / pause / resume / trigger / configappendEntry— run count survives session restartsHEARTBEAT_INTERVAL_MS,HEARTBEAT_FILE,HEARTBEAT_ENABLEDenv varsdeploy.shcopiesHEARTBEAT.md(always overwrites — admin-managed)Inspired by
OpenClaw's
HEARTBEAT.md+ cron service pattern, simplified for our architecture (no separate CronService, no isolated sessions, no job persistence — just a timer + Markdown file).Docs updated
AGENTS.md— repo layoutREADME.md— new Heartbeat section + architecture diagramCONFIGURATION.md— new env vars