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)

  1. Deja los heartbeats habilitados (por defecto es 30m, o 1h para OAuth/setup-token de Anthropic) o configura tu propia cadencia.
  2. Crea una pequeña lista de verificación HEARTBEAT.md en el workspace del agente (opcional pero recomendado).
  3. Decide a dónde deben ir los mensajes de heartbeat (target: "none" es el valor por defecto; configura target: "last" para enrutar al último contacto).
  4. Opcional: habilita la entrega de razonamiento del heartbeat para transparencia.
  5. Opcional: usa contexto bootstrap ligero si las ejecuciones de heartbeat solo necesitan HEARTBEAT.md.
  6. 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 (o 1h cuando OAuth/setup-token de Anthropic es el modo de autenticación detectado). Configura agents.defaults.heartbeat.every o por agente agents.list[].heartbeat.every; usa 0m para 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_OK como 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_OK aparece 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.heartbeat configura 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 configura valores por defecto de visibilidad para todos los canales.
  • channels.<channel>.heartbeat sobrescribe 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 activeHours completamente (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 separado Reasoning: cuando está disponible (misma forma que /reasoning on).
  • lightContext: cuando es true, las ejecuciones de heartbeat usan contexto bootstrap ligero y mantienen solo HEARTBEAT.md de 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 --json o 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. Cuando target: "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 de HEARTBEAT_OK antes 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 con start (HH:MM, inclusivo; usa 00:00 para inicio del día), end (HH:MM exclusivo; se permite 24:00 para fin del día), y timezone opcional.
    • Omitido o "user": usa tu agents.defaults.userTimezone si 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.
    • start y end no 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.

Comportamiento de entrega

  • Los heartbeats se ejecutan en la sesión principal del agente por defecto (agent:<id>:<mainKey>), o global cuando session.scope = "global". Configura session para sobrescribir a una sesión de canal específica (Discord/WhatsApp/etc.).
  • session solo afecta el contexto de ejecución; la entrega se controla por target y to.
  • Para entregar a un canal/destinatario específico, configura target + to. Con target: "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 target resuelve 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 updatedAt se 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ón HEARTBEAT_OK cuando 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

ObjetivoConfiguració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 canalchannels.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.md para agregar una verificación diaria del calendario.”
  • “Reescribe HEARTBEAT.md para 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.