feat: /heartbeat — recurring session re-entry prompt fired when idle - #79681
Merged
Conversation
/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).
Contributor
૮ >ﻌ< ა ci reviewran on ba2ae96
|
8 tasks
This was referenced Aug 6, 2026
12 tasks
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.
Summary
/heartbeat every <interval> <prompt>gives a session one recurring instruction that re-enters the conversation as a normal user turn whenever the session is idle and the interval has elapsed. Adapted from the session-heartbeat concept in Prime Intellect's Prime-Agent (/heartbeat).P4 of tracker #79686 — closes #62648.
Deltas vs the tracker's proposed shape (for review)
steer/follow-up delivery modes can layer on once P1 establishes that vocabulary — the injection point (adapter FIFO /_pending_input) is mode-agnostic.How it works
_pending_input; gateway: one gateway-wide async poller injects through the adapter FIFO. A busy session coalesces its tick to the next idle poll — heartbeats never interrupt a running turn.SessionDB.state_meta(heartbeat:<session_id>), survives/resume, and migrates across compression session rotations alongside/goalstate.hermes cron. The docs page draws that boundary explicitly (heartbeat = this conversation's context, cron = isolated jobs)./hbalias; Slack routes via/hermes heartbeat(50-slash cap). The ghost-text suggester now prefers the shortest prefix match so/hestill suggests/helprather than/heartbeat.Changes
hermes_cli/heartbeat.py(new): interval parsing (10m,every 2h, …),HeartbeatState/HeartbeatManager, due/coalesce logic, SessionDB persistence, rotation migration.cli.py:_get_heartbeat_manager,_start_heartbeat_watchdog, dispatch.hermes_cli/cli_commands_mixin.py:/heartbeathandler.gateway/run.py/gateway/slash_commands.py: handler for all platforms, watch registry + poller, mid-run dispatch.agent/conversation_compression.py: heartbeat migration at session rotation (next to goal migration).hermes_cli/commands.py: CommandDef (+/hb), Slack via-/hermes routing, shortest-prefix ghost text.heartbeat.md(registered insidebars.ts), slash-command reference (both tables).tests/hermes_cli/test_heartbeat.py: 21 tests.Validation
test_commands.pyincl. Slack/Telegram parity + ghost text,test_goals.py)Infographic