Heartbeat (Gateway)
¿Heartbeat o Cron? Consulta Cron vs Heartbeat para orientación sobre cuándo usar cada uno.
Heartbeat ejecuta turnos periódicos del agente en la sesión principal para que el modelo pueda sacar a la luz cualquier cosa que necesite atención sin saturarte de mensajes.
Solución de problemas: /automation/troubleshooting
Inicio rápido (principiante)
- Deja los heartbeats habilitados (por defecto es
30m, o1hpara OAuth/setup-token de Anthropic) o configura tu propia cadencia. - Crea una pequeña lista de verificación
HEARTBEAT.mden el workspace del agente (opcional pero recomendado). - Decide a dónde deben ir los mensajes de heartbeat (
target: "none"es el valor por defecto; configuratarget: "last"para enrutar al último contacto). - Opcional: habilita la entrega de razonamiento del heartbeat para transparencia.
- Opcional: usa contexto bootstrap ligero si las ejecuciones de heartbeat solo necesitan
HEARTBEAT.md. - Opcional: restringe los heartbeats a horas activas (hora local).
Ejemplo de configuración:
{
agents: {
defaults: {
heartbeat: {
every: "30m",
target: "last", // entrega explícita al último contacto (por defecto es "none")
directPolicy: "allow", // por defecto: permitir objetivos directos/DM; configura "block" para suprimir
lightContext: true, // opcional: solo inyectar HEARTBEAT.md de archivos bootstrap
// activeHours: { start: "08:00", end: "24:00" },
// includeReasoning: true, // opcional: enviar también mensaje separado de `Reasoning:`
},
},
},
}
Valores por defecto
- Intervalo:
30m(o1hcuando OAuth/setup-token de Anthropic es el modo de autenticación detectado). Configuraagents.defaults.heartbeat.everyo por agenteagents.list[].heartbeat.every; usa0mpara deshabilitar. - Cuerpo del prompt (configurable vía
agents.defaults.heartbeat.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. - El prompt del heartbeat se envía textualmente como el mensaje del usuario. El prompt del sistema incluye una sección “Heartbeat” y la ejecución se marca internamente.
- Las horas activas (
heartbeat.activeHours) se verifican en la zona horaria configurada. Fuera de la ventana, los heartbeats se omiten hasta el siguiente tick dentro de la ventana.
Para qué sirve el prompt del heartbeat
El prompt por defecto es intencionalmente amplio:
- Tareas en segundo plano: “Consider outstanding tasks” impulsa al agente a revisar seguimientos (bandeja de entrada, calendario, recordatorios, trabajo en cola) y sacar a la luz cualquier cosa urgente.
- Verificación humana: “Checkup sometimes on your human during day time” impulsa un mensaje ligero ocasional de “¿necesitas algo?”, pero evita spam nocturno usando tu zona horaria local configurada (consulta /concepts/timezone).
Si quieres que un heartbeat haga algo muy específico (por ejemplo “verificar estadísticas de Gmail PubSub”
o “verificar salud del gateway”), configura agents.defaults.heartbeat.prompt (o
agents.list[].heartbeat.prompt) con un cuerpo personalizado (enviado textualmente).
Contrato de respuesta
- Si nada necesita atención, responde con
HEARTBEAT_OK. - Durante las ejecuciones de heartbeat, OpenClaw trata
HEARTBEAT_OKcomo confirmación cuando aparece al inicio o final de la respuesta. El token se elimina y la respuesta se descarta si el contenido restante es <=ackMaxChars(por defecto: 300). - Si
HEARTBEAT_OKaparece en el medio de una respuesta, no se trata de forma especial. - Para alertas, no incluyas
HEARTBEAT_OK; devuelve solo el texto de la alerta.
Fuera de los heartbeats, un HEARTBEAT_OK suelto al inicio/final de un mensaje se elimina
y se registra; un mensaje que es solo HEARTBEAT_OK se descarta.
Configuración
{
agents: {
defaults: {
heartbeat: {
every: "30m", // por defecto: 30m (0m deshabilita)
model: "anthropic/claude-opus-4-6",
includeReasoning: false, // por defecto: false (entrega mensaje separado Reasoning: cuando está disponible)
lightContext: false, // por defecto: false; true mantiene solo HEARTBEAT.md de archivos bootstrap del workspace
target: "last", // por defecto: none | opciones: last | none | <id de canal> (core o plugin, ej. "bluebubbles")
to: "+15551234567", // sustitución opcional específica del canal
accountId: "ops-bot", // id de canal multi-cuenta opcional
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.",
ackMaxChars: 300, // máximo de caracteres permitidos después de HEARTBEAT_OK
},
},
},
}
Alcance y precedencia
agents.defaults.heartbeatconfigura el comportamiento global del heartbeat.agents.list[].heartbeatse fusiona encima; si algún agente tiene un bloqueheartbeat, solo esos agentes ejecutan heartbeats.channels.defaults.heartbeatconfigura valores por defecto de visibilidad para todos los canales.channels.<channel>.heartbeatsobrescribe los valores por defecto del canal.channels.<channel>.accounts.<id>.heartbeat(canales multi-cuenta) sobrescribe la configuración por canal.
Heartbeats por agente
Si alguna entrada agents.list[] incluye un bloque heartbeat, solo esos agentes
ejecutan heartbeats. El bloque por agente se fusiona encima de agents.defaults.heartbeat
(así puedes configurar valores por defecto compartidos una vez y sobrescribir por agente).
Ejemplo: dos agentes, solo el segundo agente ejecuta heartbeats.
{
agents: {
defaults: {
heartbeat: {
every: "30m",
target: "last", // entrega explícita al último contacto (por defecto es "none")
},
},
list: [
{ id: "main", default: true },
{
id: "ops",
heartbeat: {
every: "1h",
target: "whatsapp",
to: "+15551234567",
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.",
},
},
],
},
}
Ejemplo de horas activas
Restringe los heartbeats a horario laboral en una zona horaria específica:
{
agents: {
defaults: {
heartbeat: {
every: "30m",
target: "last", // entrega explícita al último contacto (por defecto es "none")
activeHours: {
start: "09:00",
end: "22:00",
timezone: "America/New_York", // opcional; usa tu userTimezone si está configurado, sino la zona horaria del host
},
},
},
},
}
Fuera de esta ventana (antes de las 9am o después de las 10pm hora del Este), los heartbeats se omiten. El siguiente tick programado dentro de la ventana se ejecutará normalmente.
Configuración 24/7
Si quieres que los heartbeats se ejecuten todo el día, usa uno de estos patrones:
- Omite
activeHourscompletamente (sin restricción de ventana horaria; este es el comportamiento por defecto). - Configura una ventana de día completo:
activeHours: { start: "00:00", end: "24:00" }.
No configures el mismo horario para start y end (por ejemplo 08:00 a 08:00).
Eso se trata como una ventana de ancho cero, así que los heartbeats siempre se omiten.
Ejemplo multi-cuenta
Usa accountId para apuntar a una cuenta específica en canales multi-cuenta como Telegram:
{
agents: {
list: [
{
id: "ops",
heartbeat: {
every: "1h",
target: "telegram",
to: "12345678:topic:42", // opcional: enrutar a un topic/hilo específico
accountId: "ops-bot",
},
},
],
},
channels: {
telegram: {
accounts: {
"ops-bot": { botToken: "YOUR_TELEGRAM_BOT_TOKEN" },
},
},
},
}
Notas de campos
every: intervalo del heartbeat (cadena de duración; unidad por defecto = minutos).model: sustitución opcional del modelo para ejecuciones de heartbeat (provider/model).includeReasoning: cuando está habilitado, también entrega el mensaje separadoReasoning:cuando está disponible (misma forma que/reasoning on).lightContext: cuando es true, las ejecuciones de heartbeat usan contexto bootstrap ligero y mantienen soloHEARTBEAT.mdde los archivos bootstrap del workspace.session: clave de sesión opcional para ejecuciones de heartbeat.main(por defecto): sesión principal del agente.- Clave de sesión explícita (copia de
openclaw sessions --jsono el CLI de sesiones). - Formatos de clave de sesión: consulta Sesiones y Grupos.
target:last: entregar al último canal externo usado.- canal explícito:
whatsapp/telegram/discord/googlechat/slack/msteams/signal/imessage. none(por defecto): ejecutar el heartbeat pero no entregar externamente.
directPolicy: controla el comportamiento de entrega directa/DM:allow(por defecto): permitir entrega directa/DM del heartbeat.block: suprimir entrega directa/DM (reason=dm-blocked).
to: sustitución opcional del destinatario (id específico del canal, ej. E.164 para WhatsApp o un id de chat de Telegram). Para topics/hilos de Telegram, usa<chatId>:topic:<messageThreadId>.accountId: id de cuenta opcional para canales multi-cuenta. Cuandotarget: "last", el id de cuenta se aplica al último canal resuelto si soporta cuentas; de lo contrario se ignora. Si el id de cuenta no coincide con una cuenta configurada para el canal resuelto, la entrega se omite.prompt: sobrescribe el cuerpo del prompt por defecto (no se fusiona).ackMaxChars: máximo de caracteres permitidos después deHEARTBEAT_OKantes de la entrega.suppressToolErrorWarnings: cuando es true, suprime payloads de advertencia de error de herramientas durante ejecuciones de heartbeat.activeHours: restringe las ejecuciones de heartbeat a una ventana horaria. Objeto constart(HH:MM, inclusivo; usa00:00para inicio del día),end(HH:MM exclusivo; se permite24:00para fin del día), ytimezoneopcional.- Omitido o
"user": usa tuagents.defaults.userTimezonesi está configurado, sino usa la zona horaria del sistema host. "local": siempre usa la zona horaria del sistema host.- Cualquier identificador IANA (ej.
America/New_York): se usa directamente; si es inválido, recurre al comportamiento"user"anterior. startyendno deben ser iguales para una ventana activa; valores iguales se tratan como ancho cero (siempre fuera de la ventana).- Fuera de la ventana activa, los heartbeats se omiten hasta el siguiente tick dentro de la ventana.
- Omitido o
Comportamiento de entrega
- Los heartbeats se ejecutan en la sesión principal del agente por defecto (
agent:<id>:<mainKey>), oglobalcuandosession.scope = "global". Configurasessionpara sobrescribir a una sesión de canal específica (Discord/WhatsApp/etc.). sessionsolo afecta el contexto de ejecución; la entrega se controla portargetyto.- Para entregar a un canal/destinatario específico, configura
target+to. Contarget: "last", la entrega usa el último canal externo para esa sesión. - Las entregas de heartbeat permiten objetivos directos/DM por defecto. Configura
directPolicy: "block"para suprimir envíos a objetivos directos mientras se sigue ejecutando el turno del heartbeat. - Si la cola principal está ocupada, el heartbeat se omite y se reintenta después.
- Si
targetresuelve a ningún destino externo, la ejecución aún ocurre pero no se envía ningún mensaje saliente. - Las respuestas solo de heartbeat no mantienen viva la sesión; el último
updatedAtse restaura para que la expiración por inactividad se comporte normalmente.
Controles de visibilidad
Por defecto, las confirmaciones HEARTBEAT_OK se suprimen mientras el contenido de alerta se
entrega. Puedes ajustar esto por canal o por cuenta:
channels:
defaults:
heartbeat:
showOk: false # Ocultar HEARTBEAT_OK (por defecto)
showAlerts: true # Mostrar mensajes de alerta (por defecto)
useIndicator: true # Emitir eventos de indicador (por defecto)
telegram:
heartbeat:
showOk: true # Mostrar confirmaciones OK en Telegram
whatsapp:
accounts:
work:
heartbeat:
showAlerts: false # Suprimir entrega de alertas para esta cuenta
Precedencia: por cuenta → por canal → valores por defecto del canal → valores por defecto integrados.
Qué hace cada flag
showOk: envía una confirmaciónHEARTBEAT_OKcuando el modelo devuelve una respuesta solo de OK.showAlerts: envía el contenido de alerta cuando el modelo devuelve una respuesta no OK.useIndicator: emite eventos de indicador para superficies de estado de UI.
Si las tres son false, OpenClaw omite la ejecución del heartbeat completamente (sin llamada al modelo).
Ejemplos por canal vs por cuenta
channels:
defaults:
heartbeat:
showOk: false
showAlerts: true
useIndicator: true
slack:
heartbeat:
showOk: true # todas las cuentas de Slack
accounts:
ops:
heartbeat:
showAlerts: false # suprimir alertas solo para la cuenta ops
telegram:
heartbeat:
showOk: true
Patrones comunes
| Objetivo | Configuración |
|---|---|
| Comportamiento por defecto (OKs silenciosos, alertas sí) | (sin configuración necesaria) |
| Totalmente silencioso (sin mensajes, sin indicador) | channels.defaults.heartbeat: { showOk: false, showAlerts: false, useIndicator: false } |
| Solo indicador (sin mensajes) | channels.defaults.heartbeat: { showOk: false, showAlerts: false, useIndicator: true } |
| OKs en un solo canal | channels.telegram.heartbeat: { showOk: true } |
HEARTBEAT.md (opcional)
Si existe un archivo HEARTBEAT.md en el workspace, el prompt por defecto le dice al
agente que lo lea. Piensa en ello como tu “lista de verificación del heartbeat”: pequeña, estable y
segura de incluir cada 30 minutos.
Si HEARTBEAT.md existe pero está efectivamente vacío (solo líneas en blanco y encabezados
markdown como # Encabezado), OpenClaw omite la ejecución del heartbeat para ahorrar llamadas API.
Si el archivo falta, el heartbeat aún se ejecuta y el modelo decide qué hacer.
Mantenlo pequeño (lista corta de verificación o recordatorios) para evitar inflación del prompt.
Ejemplo de HEARTBEAT.md:
# Lista de verificación del heartbeat
- Escaneo rápido: ¿algo urgente en las bandejas de entrada?
- Si es de día, haz una verificación ligera si no hay nada más pendiente.
- Si una tarea está bloqueada, anota _qué falta_ y pregunta a Peter la próxima vez.
¿Puede el agente actualizar HEARTBEAT.md?
Sí — si se lo pides.
HEARTBEAT.md es simplemente un archivo normal en el workspace del agente, así que puedes decirle
al agente (en un chat normal) algo como:
- “Actualiza
HEARTBEAT.mdpara agregar una verificación diaria del calendario.” - “Reescribe
HEARTBEAT.mdpara que sea más corto y enfocado en seguimientos de la bandeja de entrada.”
Si quieres que esto suceda de forma proactiva, también puedes incluir una línea explícita en tu prompt del heartbeat como: “Si la lista de verificación se vuelve obsoleta, actualiza HEARTBEAT.md con una mejor.”
Nota de seguridad: no pongas secretos (claves API, números de teléfono, tokens privados) en
HEARTBEAT.md — se convierte en parte del contexto del prompt.
Activación manual (bajo demanda)
Puedes encolar un evento del sistema y activar un heartbeat inmediato con:
openclaw system event --text "Check for urgent follow-ups" --mode now
Si múltiples agentes tienen heartbeat configurado, una activación manual ejecuta cada uno de esos
heartbeats de agente inmediatamente.
Usa --mode next-heartbeat para esperar al siguiente tick programado.
Entrega de razonamiento (opcional)
Por defecto, los heartbeats entregan solo el payload de “respuesta” final.
Si quieres transparencia, habilita:
agents.defaults.heartbeat.includeReasoning: true
Cuando está habilitado, los heartbeats también entregarán un mensaje separado con prefijo
Reasoning: (misma forma que /reasoning on). Esto puede ser útil cuando el agente
gestiona múltiples sesiones/codexes y quieres ver por qué decidió avisarte
— pero también puede filtrar más detalle interno del que deseas. Es preferible mantenerlo
desactivado en chats grupales.
Conciencia de costos
Los heartbeats ejecutan turnos completos del agente. Intervalos más cortos gastan más tokens. Mantén
HEARTBEAT.md pequeño y considera un model más barato o target: "none" si solo
quieres actualizaciones de estado internas.