Ir al contenido

Heartbeat

Latido ejecuta turnos periódicos del agente en la sesión principal para que el modelo pueda resaltar cualquier cosa que requiera atención sin saturarlo.

Latido es un turno de sesión principal programado: no crea registros de tarea en segundo plano. Los registros de tareas son para trabajo desacoplado (ejecuciones de ACP, subagentes, trabajos de cron aislados).

Solución de problemas: Tareas programadas

  1. Elige una cadencia

    Deja los latidos habilitados (el valor predeterminado es 30m, o 1h para la autenticación OAuth/token de Anthropic, incluido el reúso de Claude CLI) o establece tu propia cadencia.

  2. Añade HEARTBEAT.md (opcional)

    Crea una pequeña lista de verificación HEARTBEAT.md o bloque tasks: en el espacio de trabajo del agente.

  3. Decide a dónde deben ir los mensajes de latido

    target: "none" es el valor predeterminado; establece target: "last" para enrutar al último contacto.

  4. Ajustes opcionales

    • Habilita la entrega de razonamiento del latido para mayor transparencia.
    • Utiliza un contexto de arranque ligero si las ejecuciones de latido solo necesitan HEARTBEAT.md.
    • Habilita sesiones aisladas para evitar enviar el historial completo de la conversación en cada latido.
    • Restringe los latidos a las horas activas (hora local).

Configuración de ejemplo:

{
agents: {
defaults: {
heartbeat: {
every: "30m",
target: "last", // explicit delivery to last contact (default is "none")
directPolicy: "allow", // default: allow direct/DM targets; set "block" to suppress
lightContext: true, // optional: only inject HEARTBEAT.md from bootstrap files
isolatedSession: true, // optional: fresh session each run (no conversation history)
skipWhenBusy: true, // optional: also defer when this agent's subagent or nested lanes are busy
// activeHours: { start: "08:00", end: "24:00" },
// includeReasoning: true, // optional: send separate `Thinking` message too
},
},
},
}
  • Intervalo: 30m (o 1h cuando se detecta el modo de autenticación OAuth/token de Anthropic, incluido el reúso de Claude CLI). Establece agents.defaults.heartbeat.every o agents.list[].heartbeat.every por agente; usa 0m para deshabilitar.
  • Cuerpo del mensaje (configurable mediante 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.
  • Tiempo de espera: los turnos de latido no configurados usan agents.defaults.timeoutSeconds si está establecido. De lo contrario, usan la cadencia de latido limitada a 600 segundos. Establece agents.defaults.heartbeat.timeoutSeconds o agents.list[].heartbeat.timeoutSeconds por agente para trabajos de latido más largos.
  • El mensaje de latido (heartbeat prompt) se envía verbatim como mensaje de usuario. El mensaje del sistema incluye una sección “Heartbeat” solo cuando los latidos están habilitados para el agente predeterminado, y la ejecución se marca internamente.
  • Cuando los latidos están deshabilitados con 0m, las ejecuciones normales también omiten HEARTBEAT.md del contexto de arranque (bootstrap) para que el modelo no vea las instrucciones exclusivas de latido.
  • Las horas activas (heartbeat.activeHours) se verifican en la zona horaria configurada. Fuera de la ventana, los latidos se omiten hasta el siguiente tick dentro de la ventana.
  • Los latidos se difieren automáticamente mientras el trabajo de cron está activo o en cola. Establezca heartbeat.skipWhenBusy: true para también diferir un agente en sus propios carriles de subagente con clave de sesión o comandos anidados; los agentes hermanos ya no se detienen solo porque otro agente tiene trabajo de subagente en curso.

El mensaje predeterminado es intencionalmente amplio:

  • Tareas en segundo plano: “Consider outstanding tasks” incita al agente a revisar los seguimientos (bandeja de entrada, calendario, recordatorios, trabajo en cola) y resaltar cualquier cosa urgente.
  • Contacto humano: “Checkup sometimes on your human during day time” incita un mensaje ligero ocasional de “¿necesitas algo?”, pero evita el spam nocturno al usar tu zona horaria local configurada (ver Timezone).

El latido puede reaccionar a las tareas en segundo plano completadas, pero una ejecución de latido en sí misma no crea un registro de tarea.

Si desea que un latido haga algo muy específico (p. ej., “verificar estadísticas de Gmail PubSub” o “verificar el estado de la puerta de enlace”), establezca agents.defaults.heartbeat.prompt (o agents.list[].heartbeat.prompt) en un cuerpo personalizado (enviado verbatim).

  • Si nada requiere atención, responda con HEARTBEAT_OK.
  • Las ejecuciones de latido con capacidad de herramientas pueden, en su lugar, llamar a heartbeat_respond con notify: false para no actualizar visiblemente, o notify: true más notificationText para una alerta. Cuando está presente, la respuesta estructurada de la herramienta tiene prioridad sobre el texto de respaldo.
  • Durante las ejecuciones de heartbeat, OpenClaw trata HEARTBEAT_OK como un ack cuando aparece al principio o al final de la respuesta. El token se elimina y la respuesta se descarta si el contenido restante es ackMaxChars (predeterminado: 300).
  • Si HEARTBEAT_OK aparece en el medio de una respuesta, no se trata de forma especial.
  • Para las alertas, no incluya HEARTBEAT_OK; devuelva solo el texto de la alerta.

Fuera de los heartbeats, los HEARTBEAT_OK extraviados al principio/final de un mensaje se eliminan y registran; un mensaje que sea solo HEARTBEAT_OK se descarta.

{
agents: {
defaults: {
heartbeat: {
every: "30m", // default: 30m (0m disables)
model: "anthropic/claude-opus-4-6",
includeReasoning: false, // default: false (deliver separate Thinking message when available)
lightContext: false, // default: false; true keeps only HEARTBEAT.md from workspace bootstrap files
isolatedSession: false, // default: false; true runs each heartbeat in a fresh session (no conversation history)
skipWhenBusy: false, // default: false; true also waits for this agent's subagent/nested lanes
target: "last", // default: none | options: last | none | <channel id> (core or plugin, e.g. "imessage")
to: "+15551234567", // optional channel-specific override
accountId: "ops-bot", // optional multi-account channel id
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, // max chars allowed after HEARTBEAT_OK
},
},
},
}
  • agents.defaults.heartbeat establece el comportamiento global del heartbeat.
  • agents.list[].heartbeat se fusiona encima; si algún agente tiene un bloque heartbeat, solo esos agentes ejecutan heartbeats.
  • channels.defaults.heartbeat establece los valores predeterminados de visibilidad para todos los canales.
  • channels.<channel>.heartbeat anula los valores predeterminados del canal.
  • channels.<channel>.accounts.<id>.heartbeat (canales multi-cuenta) anula la configuración por canal.

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í puede establecer valores predeterminados compartidos una vez y anular por agente).

Ejemplo: dos agentes, solo el segundo agente ejecuta heartbeats.

{
agents: {
defaults: {
heartbeat: {
every: "30m",
target: "last", // explicit delivery to last contact (default is "none")
},
},
list: [
{ id: "main", default: true },
{
id: "ops",
heartbeat: {
every: "1h",
target: "whatsapp",
to: "+15551234567",
timeoutSeconds: 45,
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.",
},
},
],
},
}

Restrinja los heartbeats al horario laboral en una zona horaria específica:

{
agents: {
defaults: {
heartbeat: {
every: "30m",
target: "last", // explicit delivery to last contact (default is "none")
activeHours: {
start: "09:00",
end: "22:00",
timezone: "America/New_York", // optional; uses your userTimezone if set, otherwise host tz
},
},
},
},
}

Fuera de esta ventana (antes de las 9 a. m. o después de las 10 p. m. hora del Este), los heartbeats se omiten. El siguiente tick programado dentro de la ventana se ejecutará con normalidad.

Si desea que los heartbeats se ejecuten todo el día, use uno de estos patrones:

  • Omita activeHours por completo (sin restricción de ventana de tiempo; este es el comportamiento predeterminado).
  • Establezca una ventana de día completo: activeHours: { start: "00:00", end: "24:00" }.

Use accountId para dirigirse a una cuenta específica en canales multisesión como Telegram:

{
agents: {
list: [
{
id: "ops",
heartbeat: {
every: "1h",
target: "telegram",
to: "12345678:topic:42", // optional: route to a specific topic/thread
accountId: "ops-bot",
},
},
],
},
channels: {
telegram: {
accounts: {
"ops-bot": { botToken: "YOUR_TELEGRAM_BOT_TOKEN" },
},
},
},
}
Intervalo de heartbeat (cadena de duración; unidad predeterminada = minutos). Anulación de modelo opcional para ejecuciones de heartbeat (`provider/model`). Cuando está habilitado, también entrega el mensaje separado `Thinking` cuando está disponible (misma forma que `/reasoning on`). Cuando es verdadero, las ejecuciones de heartbeat usan un contexto de arranque ligero y mantienen solo `HEARTBEAT.md` de los archivos de arranque del espacio de trabajo. Cuando es verdadero, cada heartbeat se ejecuta en una sesión nueva sin historial de conversación previo. Usa el mismo patrón de aislamiento que el cron `sessionTarget: "isolated"`. Reduce drásticamente el costo de tokens por heartbeat. Combina con `lightContext: true` para obtener el máximo ahorro. El enrutamiento de entrega aún usa el contexto de la sesión principal. Cuando es verdadero, las ejecuciones de heartbeat se diferencian en los carriles adicionales ocupados de ese agente: su propio subagente con clave de sesión o trabajo de comando anidado. Los carriles de Cron siempre diferencian los heartbeats, incluso sin esta marca, por lo que los hosts de modelos locales no ejecutan comandos cron y de heartbeat al mismo tiempo. Clave de sesión opcional para ejecuciones de heartbeat.
  • main (predeterminado): sesión principal del agente.
  • Clave de sesión explícita (copie desde openclaw sessions --json o la CLI de sesiones).
  • Formatos de clave de sesión: consulte Sessions y Groups.
- `last`: entregar al último canal externo utilizado. - canal explícito: cualquier canal configurado o id de complemento, por ejemplo `discord`, `matrix`, `telegram`, o `whatsapp`. - `none` (predeterminado): ejecuta el heartbeat pero **no lo entrega** externamente. Controla el comportamiento de entrega directa/DM. `allow`: permite la entrega directa/DM del heartbeat. `block`: suprime la entrega directa/DM (`reason=dm-blocked`). Invalidación de destinatario opcional (id específico del canal, p. ej., E.164 para WhatsApp o un id de chat de Telegram). Para temas/hilos de Telegram, usa `:topic:`. Id de cuenta opcional para canales multicuenta. Cuando es `target: "last"`, el id de cuenta se aplica al último canal resuelto si admite cuentas; de lo contrario, se ignora. Si el id de cuenta no coincide con una cuenta configurada para el canal resuelto, se omite la entrega. Invalida el cuerpo del mensaje predeterminado (no se fusiona). Máximo de caracteres permitidos después de `HEARTBEAT_OK` antes de la entrega. Cuando es verdadero, suprime las cargas útiles de advertencia de errores de herramientas durante las ejecuciones del heartbeat. Máximo de segundos permitidos para un turno de agente de heartbeat antes de que se aborte. Déjalo sin configurar para usar `agents.defaults.timeoutSeconds` cuando esté configurado; de lo contrario, el ritmo del heartbeat se limita a 600 segundos. Restringe las ejecuciones de heartbeat a una ventana de tiempo. Objeto con `start` (HH:MM, inclusivo; use `00:00` para el inicio del día), `end` (HH:MM exclusivo; `24:00` permitido para el final del día) y `timezone` opcional.
  • Omitido o "user": usa su agents.defaults.userTimezone si está configurado; de lo contrario, vuelve a la zona horaria del sistema anfitrión.
  • "local": siempre usa la zona horaria del sistema anfitrión.
  • Cualquier identificador de IANA (por ejemplo, America/New_York): se usa directamente; si no es válido, vuelve al comportamiento "user" anterior.
  • start y end no deben ser iguales para una ventana activa; los valores iguales se tratan como de ancho cero (siempre fuera de la ventana).
  • Fuera de la ventana activa, los heartbeats se omiten hasta el siguiente tick dentro de la ventana.
Sesión y enrutamiento de destino
  • Los latidos se ejecutan en la sesión principal del agente de forma predeterminada (`agent:

:

), o globalcuandosession.scope = “global”. Establezca sessionpara anular a una sesión de canal específica (Discord/WhatsApp/etc.). -sessionsolo afecta el contexto de ejecución; la entrega está controlada portargetyto. - Para entregar a un canal/destinatario específico, configure target+to. Con target: “last”, la entrega utiliza el último canal externo para esa sesión. - Las entregas de latido permiten destinos directos/DM de forma predeterminada. Establezca directPolicy: “block”para suprimir los envíos a destino directo mientras aún se ejecuta el turno de latido. - Si la cola principal, el carril de la sesión de destino, el carril cron o un trabajo cron activo está ocupado, el latido se omite y se reintentará más tarde. - SiskipWhenBusy: true, los subagentes con clave de sesión y carriles anidados de este agente también difieren las ejecuciones de latido. Los carriles ocupados de otros agentes no difieren este agente. - Si target` no se resuelve en ningún destino externo, la ejecución aún ocurre pero no se envía ningún mensaje saliente.

Visibilidad y comportamiento de omisión
  • Si showOk, showAlerts y useIndicator están todos deshabilitados, la ejecución se omite de inmediato como reason=alerts-disabled.
  • Si solo la entrega de alertas está deshabilitada, OpenClaw aún puede ejecutar el latido, actualizar las marcas de tiempo de las tareas vencidas, restaurar la marca de tiempo de inactividad de la sesión y suprimir la carga útil de la alerta externa.
  • Si el destino de latido resuelto admite “typing”, OpenClaw muestra que está escribiendo mientras la ejecución del latido está activa. Esto utiliza el mismo destino al que el latido enviaría la salida del chat, y está deshabilitado por typingMode: "never".
Session lifecycle and audit
  • Las respuestas solo de Heartbeat no mantienen la sesión activa. Los metadatos de Heartbeat pueden actualizar la fila de la sesión, pero la caducidad por inactividad usa lastInteractionAt del último mensaje real de usuario/canal, y la caducidad diaria usa sessionStartedAt.
  • La interfaz de control y el historial de WebChat ocultan las solicitudes de Heartbeat y los reconocimientos solo de OK. La transcripción subyacente de la sesión todavía puede contener esos turnos para auditoría/reproducción.
  • Las tareas en segundo plano desacopladas pueden poner en cola un evento del sistema y activar Heartbeat cuando la sesión principal debería notar algo rápidamente. Esa activación no hace que Heartbeam ejecute una tarea en segundo plano.

De forma predeterminada, los reconocimientos HEARTBEAT_OK se suprimen mientras se entrega el contenido de la alerta. Puede ajustar esto por canal o por cuenta:

channels:
defaults:
heartbeat:
showOk: false # Hide HEARTBEAT_OK (default)
showAlerts: true # Show alert messages (default)
useIndicator: true # Emit indicator events (default)
telegram:
heartbeat:
showOk: true # Show OK acknowledgments on Telegram
whatsapp:
accounts:
work:
heartbeat:
showAlerts: false # Suppress alert delivery for this account

Precedencia: por cuenta → por canal → valores predeterminados del canal → valores predeterminados integrados.

  • showOk: envía un reconocimiento HEARTBEAT_OK cuando el modelo devuelve una respuesta solo de OK.
  • showAlerts: envía el contenido de la alerta cuando el modelo devuelve una respuesta que no es OK.
  • useIndicator: emite eventos indicadores para las superficies de estado de la interfaz de usuario.

Si los tres son falsos, OpenClaw omite la ejecución de Heartbeat por completo (sin llamada al modelo).

channels:
defaults:
heartbeat:
showOk: false
showAlerts: true
useIndicator: true
slack:
heartbeat:
showOk: true # all Slack accounts
accounts:
ops:
heartbeat:
showAlerts: false # suppress alerts for the ops account only
telegram:
heartbeat:
showOk: true
ObjetivoConfiguración
Comportamiento predeterminado (OK silenciosos, alertas activadas)(no se necesita configuración)
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 }
OK solo en un canalchannels.telegram.heartbeat: { showOk: true }

Si existe un archivo HEARTBEAT.md en el espacio de trabajo, el mensaje predeterminado indica al agente que lo lea. Piénselo como su “lista de verificación de Heartbeat”: pequeño, estable y seguro de considerar cada 30 minutos.

En ejecuciones normales, HEARTBEAT.md solo se inyecta cuando la guía de heartbeat está habilitada para el agente predeterminado. Deshabilitar el cadence del heartbeat con 0m o configurar includeSystemPromptSection: false omite su inclusión en el contexto de arranque normal.

En el arnés nativo de Codex, el contenido de HEARTBEAT.md no se inyecta en el turno. Si el archivo existe y tiene contenido que no sea solo espacios en blanco, las instrucciones del modo de colaboración del heartbeat dirigen a Codex al archivo y le indican que lo lea antes de continuar.

Si HEARTBEAT.md existe pero está efectivamente vacío (solo líneas en blanco y encabezados de markdown como # Heading), OpenClaw omite la ejecución del heartbeat para ahorrar llamadas a la API. Esa omisión se reporta como reason=empty-heartbeat-file. Si falta el archivo, el heartbeat aún se ejecuta y el modelo decide qué hacer.

Manténlo pequeño (una lista de verificación breve o recordatorios) para evitar la hinchazón del prompt.

Ejemplo de HEARTBEAT.md:

# Heartbeat checklist
- Quick scan: anything urgent in inboxes?
- If it's daytime, do a lightweight check-in if nothing else is pending.
- If a task is blocked, write down _what is missing_ and ask Peter next time.

HEARTBEAT.md también admite un pequeño bloque estructurado tasks: para verificaciones basadas en intervalos dentro del propio heartbeat.

Ejemplo:

tasks:
- name: inbox-triage
interval: 30m
prompt: "Check for urgent unread emails and flag anything time sensitive."
- name: calendar-scan
interval: 2h
prompt: "Check for upcoming meetings that need prep or follow-up."
# Additional instructions
- Keep alerts short.
- If nothing needs attention after all due tasks, reply HEARTBEAT_OK.
Comportamiento
  • OpenClaw analiza el bloque tasks: y comprueba cada tarea con su propio interval.
  • Solo las tareas vencidas se incluyen en el prompt del heartbeat para ese tick.
  • Si no hay tareas vencidas, el heartbeat se omite por completo (reason=no-tasks-due) para evitar una llamada al modelo desperdiciada.
  • El contenido que no sea de tarea en HEARTBEAT.md se conserva y se agrega como contexto adicional después de la lista de tareas vencidas.
  • Las marcas de tiempo de la última ejecución de la tarea se almacenan en el estado de la sesión (heartbeatTaskState), por lo que los intervalos sobreviven a los reinicios normales.
  • Las marcas de tiempo de las tareas solo avanzan después de que una ejecución del heartbeat completa su ruta normal de respuesta. Las ejecuciones omitidas de empty-heartbeat-file / no-tasks-due no marcan las tareas como completadas.

El modo de tarea es útil cuando deseas que un archivo de heartbeat contenga varias verificaciones periódicas sin pagar por todas ellas en cada tick.

Sí, si se lo pides.

HEARTBEAT.md es solo un archivo normal en el espacio de trabajo del agente, así que puedes decirle al agente (en un chat normal) algo como:

  • “Actualiza HEARTBEAT.md para añadir un chequeo diario del calendario.”
  • “Reescribe HEARTBEAT.md para que sea más breve y se centre en el seguimiento de la bandeja de entrada.”

Si quieres que esto ocurra de manera proactiva, también puedes incluir una línea explícita en tu prompt de heartbeat como: “Si la lista de verificación se vuelve obsoleta, actualiza HEARTBEAT.md con una mejor.”

Puedes poner en cola un evento del sistema y activar un heartbeat inmediato con:

Ventana de terminal
openclaw system event --text "Check for urgent follow-ups" --mode now

Si varios agentes tienen heartbeat configurado, un despertar manual ejecuta inmediatamente cada uno de esos heartbeats de agente.

Usa --mode next-heartbeat para esperar el siguiente tick programado.

Por defecto, los heartbeats entregan solo la carga útil (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 el prefijo Thinking (misma forma que /reasoning on). Esto puede ser útil cuando el agente gestiona múltiples sesiones/codexes y quieres ver por qué decidió hacerte un ping — pero también puede filtrar más detalles internos de los que deseas. Es preferible mantenerlo desactivado en chats grupales.

Los heartbeats ejecutan turnos completos de agente. Intervalos más cortos consumen más tokens. Para reducir el coste:

  • Usa isolatedSession: true para evitar enviar el historial completo de la conversación (de ~100K tokens a ~2-5K por ejecución).
  • Usa lightContext: true para limitar los archivos de inicialización (bootstrap) solo a HEARTBEAT.md.
  • Establece un model más económico (por ejemplo, ollama/llama3.2:1b).
  • Mantén HEARTBEAT.md pequeño.
  • Usa target: "none" si solo quieres actualizaciones del estado interno.

Desbordamiento de contexto después del heartbeat

Sección titulada «Desbordamiento de contexto después del heartbeat»

Si un latido (heartbeat) dejó anteriormente una sesión existente en un modelo local más pequeño, por ejemplo un modelo de Ollama con una ventana de 32k, y el siguiente turno de la sesión principal informa de un desbordamiento de contexto, restablezca el modelo de tiempo de ejecución de la sesión al modelo principal configurado. El mensaje de restablecimiento de OpenClaw indica esto cuando el último modelo de tiempo de ejecución coincide con el heartbeat.model configurado.

Los latidos actuales conservan el modelo de tiempo de ejecución existente de la sesión compartida después de que se completa la ejecución. Aún puede usar isolatedSession: true para ejecutar latidos en una sesión nueva, combinarlo con lightContext: true para obtener el mensaje más pequeño, o elegir un modelo de latido con una ventana de contexto lo suficientemente grande para la sesión compartida.