From 8d995a8529cb06b32074251c3b1f31f754e8aa62 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 27 Nov 2025 03:15:51 +0100 Subject: [PATCH] Heartbeat: add ultrathink marker --- README.md | 4 ++-- docs/heartbeat.md | 4 ++-- src/web/auto-reply.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b39fead46..33a9aa9e6 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ Best practice: use a dedicated WhatsApp account (separate SIM/eSIM or business a command: ["claude", "--dangerously-skip-permissions", "{{BodyStripped}}"], claudeOutputFormat: "text", session: { scope: "per-sender", resetTriggers: ["/new"], idleMinutes: 60 }, - heartbeatMinutes: 30 // optional; pings Claude every 30m and only sends if it omits HEARTBEAT_OK + heartbeatMinutes: 30 // optional; pings Claude every 30m with "HEARTBEAT ultrathink" and only sends if it omits HEARTBEAT_OK } } } @@ -123,7 +123,7 @@ Best practice: use a dedicated WhatsApp account (separate SIM/eSIM or business a #### Heartbeat pings (command mode) - When `heartbeatMinutes` is set (default 30 for `mode: "command"`), the relay periodically runs your command/Claude session with a heartbeat prompt. -- If Claude replies exactly `HEARTBEAT_OK`, the message is suppressed; otherwise the reply (or media) is forwarded. Suppressions are still logged so you know the heartbeat ran. +- Heartbeat body is `HEARTBEAT ultrathink` (so the model can recognize the probe); if Claude replies exactly `HEARTBEAT_OK`, the message is suppressed; otherwise the reply (or media) is forwarded. Suppressions are still logged so you know the heartbeat ran. - Override session freshness for heartbeats with `session.heartbeatIdleMinutes` (defaults to `session.idleMinutes`). Heartbeat skips do **not** bump `updatedAt`, so sessions still expire normally. - Trigger one manually with `warelay heartbeat` (web provider only, `--verbose` prints session info). Use `--session-id ` to force resuming a specific Claude session, `--all` to ping every active session, `warelay relay:heartbeat` for a full relay run with an immediate heartbeat, or `--heartbeat-now` on `relay`/`relay:heartbeat:tmux`. - When multiple active sessions exist, `warelay heartbeat` requires `--to ` or `--all`; if `allowFrom` is just `"*"`, you must choose a target with one of those flags. diff --git a/docs/heartbeat.md b/docs/heartbeat.md index 77c58db0f..9d37bd695 100644 --- a/docs/heartbeat.md +++ b/docs/heartbeat.md @@ -1,9 +1,9 @@ # Heartbeat polling plan (2025-11-26) -Goal: add a simple heartbeat poll for command-based auto-replies (Claude-driven) that only notifies users when something matters, using the `HEARTBEAT_OK` sentinel. +Goal: add a simple heartbeat poll for command-based auto-replies (Claude-driven) that only notifies users when something matters, using the `HEARTBEAT_OK` sentinel. The heartbeat body we send is `HEARTBEAT ultrathink` so the model can easily spot it. ## Prompt contract -- Extend the Claude system/identity text to explain: “If this is a heartbeat poll and nothing needs attention, reply exactly `HEARTBEAT_OK` and nothing else. For any alert, do **not** include `HEARTBEAT_OK`; just return the alert text.” +- Extend the Claude system/identity text to explain: “If this is a heartbeat poll and nothing needs attention, reply exactly `HEARTBEAT_OK` and nothing else. For any alert, do **not** include `HEARTBEAT_OK`; just return the alert text.” Heartbeat prompt body is `HEARTBEAT ultrathink`. - Keep existing WhatsApp length guidance; forbid burying the sentinel inside alerts. ## Config & defaults diff --git a/src/web/auto-reply.ts b/src/web/auto-reply.ts index 0890857db..543be1378 100644 --- a/src/web/auto-reply.ts +++ b/src/web/auto-reply.ts @@ -47,7 +47,7 @@ const formatDuration = (ms: number) => const DEFAULT_REPLY_HEARTBEAT_MINUTES = 30; export const HEARTBEAT_TOKEN = "HEARTBEAT_OK"; -export const HEARTBEAT_PROMPT = "HEARTBEAT"; +export const HEARTBEAT_PROMPT = "HEARTBEAT ultrathink"; export function resolveReplyHeartbeatMinutes( cfg: ReturnType,