Gateway
Heartbeat
Heartbeat ejecuta turnos periódicos del agente en la sesión principal para que el modelo pueda destacar cualquier cosa que necesite atención sin enviarte spam.
Heartbeat es un turno programado de la sesión principal; no crea registros de tarea en segundo plano. Los registros de tareas son para trabajo separado (ejecuciones de ACP, subagentes, trabajos cron aislados).
Solución de problemas: Tareas programadas
Inicio rápido (principiante)
Elige una cadencia
Deja los heartbeats habilitados (el valor predeterminado es 30m, o 1h para autenticación OAuth/token de Anthropic, incluida la reutilización de Claude CLI) o establece tu propia cadencia.
Añade HEARTBEAT.md (opcional)
Crea una pequeña lista de verificación HEARTBEAT.md o un bloque tasks: en el espacio de trabajo del agente.
Decide adónde deben ir los mensajes de heartbeat
target: "none" es el valor predeterminado; establece target: "last" para enrutar al último contacto.
Ajuste opcional
- Habilita la entrega del razonamiento de heartbeat para mayor transparencia.
- Usa contexto de arranque ligero si las ejecuciones de heartbeat solo necesitan
HEARTBEAT.md. - Habilita sesiones aisladas para evitar enviar todo el historial de conversación en cada heartbeat.
- Restringe los heartbeats al horario activo (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 }, }, },}Valores predeterminados
- Intervalo:
30m(o1hcuando la autenticación OAuth/token de Anthropic es el modo de autenticación detectado, incluida la reutilización de Claude CLI). Estableceagents.defaults.heartbeat.everyoagents.list[].heartbeat.everypor agente; usa0mpara deshabilitarlo. - Cuerpo del prompt (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 heartbeat sin configurar usan
agents.defaults.timeoutSecondscuando está establecido. De lo contrario, usan la cadencia de heartbeat limitada a 600 segundos. Estableceagents.defaults.heartbeat.timeoutSecondsoagents.list[].heartbeat.timeoutSecondspor agente para trabajos de heartbeat más largos. - El prompt de heartbeat se envía literalmente como mensaje del usuario. El prompt del sistema incluye una sección "Heartbeat" solo cuando los heartbeats están habilitados para el agente predeterminado, y la ejecución se marca internamente.
- Cuando los heartbeats se deshabilitan con
0m, las ejecuciones normales también omitenHEARTBEAT.mddel contexto de arranque para que el modelo no vea instrucciones exclusivas de heartbeat. - El horario activo (
heartbeat.activeHours) se comprueba en la zona horaria configurada. Fuera de la ventana, los heartbeats se omiten hasta el siguiente tick dentro de la ventana. - Los heartbeats se aplazan automáticamente mientras el trabajo de cron está activo o en cola. Establece
heartbeat.skipWhenBusy: truepara aplazar también un agente en sus propios carriles de subagente con clave de sesión o de comandos anidados; los agentes hermanos ya no se pausan solo porque otro agente tenga trabajo de subagente en curso.
Para qué sirve el prompt de heartbeat
El prompt predeterminado 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 destacar cualquier cosa urgente.
- Contacto con la persona: "Checkup sometimes on your human during day time" impulsa un mensaje ocasional y ligero de "¿necesitas algo?", pero evita el spam nocturno mediante tu zona horaria local configurada (consulta Zona horaria).
Heartbeat puede reaccionar a tareas en segundo plano completadas, pero una ejecución de heartbeat en sí no crea un registro de tarea.
Si quieres que un heartbeat haga algo muy específico (por ejemplo, "revisar estadísticas de Gmail PubSub" o "verificar la salud del gateway"), establece agents.defaults.heartbeat.prompt (o agents.list[].heartbeat.prompt) en un cuerpo personalizado (enviado literalmente).
Contrato de respuesta
- Si nada necesita atención, responde con
HEARTBEAT_OK. - Las ejecuciones de heartbeat con herramientas pueden llamar en su lugar a
heartbeat_respondconnotify: falsepara no mostrar ninguna actualización visible, onotify: truemásnotificationTextpara una alerta. Cuando está presente, la respuesta estructurada de la herramienta tiene prioridad sobre la alternativa de texto. - 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(valor predeterminado: 300). - Si
HEARTBEAT_OKaparece en el medio de una respuesta, no recibe ningún tratamiento 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 sea solo HEARTBEAT_OK se descarta.
Configuración
{ 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 }, }, },}Alcance y precedencia
agents.defaults.heartbeatestablece el comportamiento global de heartbeat.agents.list[].heartbeatse fusiona encima; si algún agente tiene un bloqueheartbeat, solo esos agentes ejecutan heartbeats.channels.defaults.heartbeatestablece los valores predeterminados de visibilidad para todos los canales.channels.<channel>.heartbeatanula los valores predeterminados del canal.channels.<channel>.accounts.<id>.heartbeat(canales multicuenta) anula la configuración por canal.
Heartbeats por agente
Si alguna entrada de agents.list[] incluye un bloque heartbeat, solo esos agentes ejecutan heartbeats. El bloque por agente se fusiona encima de agents.defaults.heartbeat (para que puedas establecer valores predeterminados compartidos una vez y anularlos 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.", }, }, ], },}Ejemplo de horario activo
Restringe 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. 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
activeHourspor completo (sin restricción de ventana horaria; este es el comportamiento predeterminado). - Establece una ventana de día completo:
activeHours: { start: "00:00", end: "24:00" }.
Ejemplo multicuenta
Usa accountId para apuntar a una cuenta específica en canales multicuenta 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" }, }, }, },}Notas de campo
everystringIntervalo de heartbeat (cadena de duración; unidad predeterminada = minutos).
modelstringAnulación opcional del modelo para ejecuciones de heartbeat (provider/model).
includeReasoningbooleandefault: falseCuando está habilitado, también entrega el mensaje Thinking separado cuando está disponible (la misma forma que /reasoning on).
lightContextbooleandefault: falseCuando es true, las ejecuciones de heartbeat usan contexto de arranque ligero y conservan solo HEARTBEAT.md de los archivos de arranque del espacio de trabajo.
isolatedSessionbooleandefault: falseCuando es true, cada heartbeat se ejecuta en una sesión nueva sin historial previo de conversación. Usa el mismo patrón de aislamiento que cron sessionTarget: "isolated". Reduce drásticamente el coste de tokens por heartbeat. Combínalo con lightContext: true para el máximo ahorro. El enrutamiento de entrega sigue usando el contexto de la sesión principal.
skipWhenBusybooleandefault: falseCuando es true, las ejecuciones de heartbeat se aplazan en los carriles ocupados adicionales de ese agente: su propio subagente con clave de sesión o trabajo de comandos anidados. Los carriles de cron siempre aplazan los heartbeats, incluso sin esta marca, por lo que los hosts de modelos locales no ejecutan prompts de cron y heartbeat al mismo tiempo.
sessionstringClave de sesión opcional para ejecuciones de heartbeat.
main(predeterminado): sesión principal del agente.- Clave de sesión explícita (copia desde
openclaw sessions --jsono la CLI de sesiones). - Formatos de clave de sesión: consulta Sesiones y Grupos.
targetstringlast: entregar al último canal externo usado.- canal explícito: cualquier canal configurado o id de plugin, por ejemplo
discord,matrix,telegramowhatsapp. none(predeterminado): ejecutar el heartbeat, pero no entregarlo externamente.
directPolicy"allow" | "block"default: allowControla el comportamiento de entrega directa/DM. allow: permite la entrega directa/DM de heartbeat. block: suprime la entrega directa/DM (reason=dm-blocked).
tostringAnulación opcional del destinatario (id específico del canal, por ejemplo E.164 para WhatsApp o un id de chat de Telegram). Para temas/hilos de Telegram, usa <chatId>:topic:<messageThreadId>.
accountIdstringId de cuenta opcional para canales multicuenta. Cuando 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.
promptstringSobrescribe el cuerpo predeterminado del prompt (no se fusiona).
ackMaxCharsnumberdefault: 300Máximo de caracteres permitidos después de HEARTBEAT_OK antes de la entrega.
suppressToolErrorWarningsbooleanCuando es true, suprime las cargas útiles de advertencia de error de herramientas durante las ejecuciones de Heartbeat.
timeoutSecondsnumberdefault: global timeout or min(every, 600)Segundos máximos permitidos para un turno de agente de Heartbeat antes de abortarlo. Déjalo sin definir para usar agents.defaults.timeoutSeconds cuando esté configurado; de lo contrario, se usa la cadencia de Heartbeat limitada a 600 segundos.
activeHoursobjectRestringe las ejecuciones de Heartbeat a una ventana horaria. Objeto con start (HH:MM, inclusivo; usa 00:00 para el inicio del día), end (HH:MM exclusivo; se permite 24:00 para el fin del día) y timezone opcional.
- Omitido o
"user": usa tuagents.defaults.userTimezonesi está configurado; de lo contrario, recurre a la zona horaria del sistema anfitrión. "local": siempre usa la zona horaria del sistema anfitrión.- Cualquier identificador IANA (por ejemplo,
America/New_York): se usa directamente; si no es válido, recurre al comportamiento de"user"anterior. startyendno deben ser iguales para una ventana activa; los 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.
Comportamiento de entrega
Session and target routing
- Los Heartbeats se ejecutan en la sesión principal del agente de forma predeterminada (
agent:<id>:<mainKey>), o englobalcuandosession.scope = "global". Definesessionpara sobrescribirlo con una sesión de canal específica (Discord/WhatsApp/etc.). sessionsolo afecta al contexto de ejecución; la entrega la controlantargetyto.- Para entregar a un canal/destinatario específico, define
target+to. Contarget: "last", la entrega usa el último canal externo de esa sesión. - Las entregas de Heartbeat permiten destinos directos/DM de forma predeterminada. Define
directPolicy: "block"para suprimir los envíos a destinos directos sin dejar de ejecutar el turno de Heartbeat. - Si la cola principal, el carril de la sesión de destino, el carril de cron o un trabajo de cron activo está ocupado, el Heartbeat se omite y se reintenta más tarde.
- Si
skipWhenBusy: true, el subagente con clave de sesión de este agente y los carriles anidados también difieren las ejecuciones de Heartbeat. Los carriles ocupados de otros agentes no difieren este agente. - Si
targetno se resuelve a ningún destino externo, la ejecución sigue ocurriendo, pero no se envía ningún mensaje saliente.
Visibility and skip behavior
- Si
showOk,showAlertsyuseIndicatorestán todos deshabilitados, la ejecución se omite de entrada comoreason=alerts-disabled. - Si solo está deshabilitada la entrega de alertas, OpenClaw aún puede ejecutar el Heartbeat, actualizar las marcas de tiempo de tareas vencidas, restaurar la marca de tiempo de inactividad de la sesión y suprimir la carga útil de alerta saliente.
- Si el destino de Heartbeat resuelto admite indicación de escritura, OpenClaw muestra escritura mientras la ejecución de Heartbeat está activa. Esto usa el mismo destino al que el Heartbeat enviaría la salida de chat, y se deshabilita con
typingMode: "never".
Session lifecycle and audit
- Las respuestas solo de Heartbeat no mantienen viva la sesión. Los metadatos de Heartbeat pueden actualizar la fila de sesión, pero la expiración por inactividad usa
lastInteractionAtdel último mensaje real de usuario/canal, y la expiración diaria usasessionStartedAt. - El historial de Control UI y WebChat oculta los prompts de Heartbeat y los acuses solo OK. La transcripción de sesión subyacente aún puede contener esos turnos para auditoría/reproducción.
- Las tareas en segundo plano separadas pueden encolar un evento del sistema y despertar Heartbeat cuando la sesión principal debe notar algo rápidamente. Ese despertar no convierte la ejecución de Heartbeat en una tarea en segundo plano.
Controles de visibilidad
De forma predeterminada, los acuses HEARTBEAT_OK se suprimen mientras se entrega el contenido de alerta. Puedes 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 accountPrecedencia: por cuenta → por canal → valores predeterminados del canal → valores predeterminados integrados.
Qué hace cada indicador
showOk: envía un acuseHEARTBEAT_OKcuando el modelo devuelve una respuesta solo OK.showAlerts: envía el contenido de alerta cuando el modelo devuelve una respuesta que no es OK.useIndicator: emite eventos indicadores para superficies de estado de la UI.
Si los tres son false, OpenClaw omite por completo la ejecución de Heartbeat (sin llamada al modelo).
Ejemplos por canal frente a por cuenta
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: truePatrones comunes
| Objetivo | Configuració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 canal | channels.telegram.heartbeat: { showOk: true } |
HEARTBEAT.md (opcional)
Si existe un archivo HEARTBEAT.md en el espacio de trabajo, el prompt predeterminado indica al agente que lo lea. Piensa en él como tu "lista de comprobación de Heartbeat": pequeña, estable y segura para considerarla cada 30 minutos.
En ejecuciones normales, HEARTBEAT.md solo se inyecta cuando la guía de Heartbeat está habilitada para el agente predeterminado. Deshabilitar la cadencia de Heartbeat con 0m o definir includeSystemPromptSection: false lo omite del 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 es espacio en blanco, las instrucciones de modo de colaboración de Heartbeat señalan el archivo a Codex y le indican que lo lea antes de continuar.
Si HEARTBEAT.md existe pero está efectivamente vacío (solo líneas en blanco, comentarios Markdown/HTML, encabezados Markdown como # Heading, marcadores de cercas o stubs de listas de comprobación vacíos), OpenClaw omite la ejecución de Heartbeat para ahorrar llamadas a la API. Esa omisión se informa como reason=empty-heartbeat-file. Si falta el archivo, Heartbeat aún se ejecuta y el modelo decide qué hacer.
Mantenlo diminuto (lista de comprobación breve o recordatorios) para evitar inflar el 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.Bloques tasks:
HEARTBEAT.md también admite un pequeño bloque estructurado tasks: para comprobaciones 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.Behavior
- OpenClaw analiza el bloque
tasks:y comprueba cada tarea contra su propiointerval. - Solo las tareas vencidas se incluyen en el prompt de Heartbeat para ese tick.
- Si no hay tareas vencidas, Heartbeat se omite por completo (
reason=no-tasks-due) para evitar una llamada al modelo desperdiciada. - El contenido que no es de tareas en
HEARTBEAT.mdse conserva y se anexa como contexto adicional después de la lista de tareas vencidas. - Las marcas de tiempo de última ejecución de tareas se almacenan en el estado de sesión (
heartbeatTaskState), por lo que los intervalos sobreviven a reinicios normales. - Las marcas de tiempo de tareas solo avanzan después de que una ejecución de Heartbeat completa su ruta de respuesta normal. Las ejecuciones omitidas
empty-heartbeat-file/no-tasks-dueno marcan tareas como completadas.
El modo de tareas es útil cuando quieres que un archivo de Heartbeat contenga varias comprobaciones periódicas sin pagar por todas en cada tick.
¿Puede el agente actualizar HEARTBEAT.md?
Sí, si se lo pides.
HEARTBEAT.md es simplemente un archivo normal en el espacio de trabajo del agente, así que puedes decirle al agente (en un chat normal) algo como:
- "Actualiza
HEARTBEAT.mdpara agregar una comprobación diaria del calendario." - "Reescribe
HEARTBEAT.mdpara que sea más corto y se enfoque en seguimientos de la bandeja de entrada."
Si quieres que esto ocurra de forma proactiva, también puedes incluir una línea explícita en tu prompt de Heartbeat como: "Si la lista de comprobación queda obsoleta, actualiza HEARTBEAT.md con una mejor."
Despertar manual (a demanda)
Puedes encolar un evento del sistema y activar un Heartbeat inmediato con:
openclaw system event --text "Check for urgent follow-ups" --mode nowSi varios agentes tienen heartbeat configurado, un despertar manual ejecuta inmediatamente cada uno de esos Heartbeats de agente.
Usa --mode next-heartbeat para esperar al siguiente tick programado.
Entrega de razonamiento (opcional)
De forma predeterminada, los Heartbeats entregan solo la carga útil final de "respuesta".
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 varias sesiones/códices y quieres ver por qué decidió avisarte, pero también puede filtrar más detalle interno del que deseas. Prefiere mantenerlo desactivado en chats grupales.
Conciencia de costos
Los Heartbeats ejecutan turnos completos de agente. Los intervalos más cortos consumen más tokens. Para reducir el costo:
- Usa
isolatedSession: truepara evitar enviar el historial completo de conversación (de ~100K tokens a ~2-5K por ejecución). - Usa
lightContext: truepara limitar los archivos de arranque a soloHEARTBEAT.md. - Define un
modelmás barato (por ejemplo,ollama/llama3.2:1b). - Mantén
HEARTBEAT.mdpequeño. - Usa
target: "none"si solo quieres actualizaciones de estado internas.
Desbordamiento de contexto después de Heartbeat
Si un Heartbeat dejó previamente 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 sesión principal informa desbordamiento de contexto, restablece el modelo de runtime de la sesión al modelo primario configurado. El mensaje de restablecimiento de OpenClaw lo indica cuando el último modelo de runtime coincide con heartbeat.model configurado.
Los Heartbeats actuales conservan el modelo de runtime existente de la sesión compartida después de que la ejecución se completa. Aun así, puedes usar isolatedSession: true para ejecutar Heartbeats en una sesión nueva, combinarlo con lightContext: true para el prompt más pequeño o elegir un modelo de Heartbeat con una ventana de contexto lo bastante grande para la sesión compartida.
Relacionado
- Automatización — todos los mecanismos de automatización de un vistazo
- Tareas en segundo plano — cómo se realiza el seguimiento del trabajo desacoplado
- Zona horaria — cómo la zona horaria afecta la programación de Heartbeat
- Solución de problemas — depuración de problemas de automatización