Heartbeat: add ultrathink marker

This commit is contained in:
Peter Steinberger
2025-11-27 03:15:51 +01:00
parent f869cd4b79
commit 8d995a8529
3 changed files with 5 additions and 5 deletions

View File

@@ -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 <uuid>` 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 <E.164>` or `--all`; if `allowFrom` is just `"*"`, you must choose a target with one of those flags.

View File

@@ -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

View File

@@ -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<typeof loadConfig>,