Messages and delivery

Mensajes

OpenClaw gestiona los mensajes entrantes mediante una canalización de resolución de sesiones, puesta en cola, streaming, ejecución de herramientas y visibilidad del razonamiento. Esta página traza la ruta desde el mensaje entrante hasta la respuesta.

Flujo de mensajes (alto nivel)

Inbound message
  -> routing/bindings -> session key
  -> queue (if a run is active)
  -> agent run (streaming + tools)
  -> outbound replies (channel limits + chunking)

Los controles clave están en la configuración:

  • messages.* para prefijos, puesta en cola y comportamiento de grupos.
  • agents.defaults.* para valores predeterminados de streaming por bloques y fragmentación.
  • Sobrescrituras de canal (channels.whatsapp.*, channels.telegram.*, etc.) para límites y conmutadores de streaming.

Consulta Configuración para ver el esquema completo.

Deduplicación entrante

Los canales pueden volver a entregar el mismo mensaje tras las reconexiones. OpenClaw mantiene una caché de corta duración indexada por canal/cuenta/par/sesión/id de mensaje para que las entregas duplicadas no disparen otra ejecución del agente.

Debounce entrante

Los mensajes consecutivos rápidos del mismo remitente pueden agruparse en un solo turno del agente mediante messages.inbound. El debounce se delimita por canal + conversación y usa el mensaje más reciente para el enhebrado/los ID de respuesta.

Configuración (valor predeterminado global + sobrescrituras por canal):

{
  messages: {
    inbound: {
      debounceMs: 2000,
      byChannel: {
        whatsapp: 5000,
        slack: 1500,
        discord: 1500,
      },
    },
  },
}

Notas:

  • El debounce se aplica a mensajes solo de texto; los medios/adjuntos se envían de inmediato.
  • Los comandos de control omiten el debounce para permanecer independientes, excepto cuando un canal opta explícitamente por la coalescencia de MD del mismo remitente (por ejemplo, BlueBubbles coalesceSameSenderDms), donde los comandos de MD esperan dentro de la ventana de debounce para que una carga útil enviada en partes pueda unirse al mismo turno del agente.

Sesiones y dispositivos

Las sesiones son propiedad del gateway, no de los clientes.

  • Los chats directos se consolidan en la clave de sesión principal del agente.
  • Los grupos/canales obtienen sus propias claves de sesión.
  • El almacén de sesiones y las transcripciones viven en el host del gateway.

Varios dispositivos/canales pueden asignarse a la misma sesión, pero el historial no se sincroniza completamente de vuelta a cada cliente. Recomendación: usa un dispositivo principal para conversaciones largas a fin de evitar contexto divergente. La Control UI y la TUI siempre muestran la transcripción de sesión respaldada por el gateway, por lo que son la fuente de verdad.

Detalles: Gestión de sesiones.

Metadatos de resultados de herramientas

El content del resultado de herramienta es el resultado visible para el modelo. details del resultado de herramienta son metadatos de runtime para renderizado de UI, diagnóstico, entrega de medios y plugins.

OpenClaw mantiene explícito ese límite:

  • toolResult.details se elimina antes de la repetición del proveedor y la entrada de compaction.
  • Las transcripciones de sesión persistidas conservan solo details acotados; los metadatos sobredimensionados se reemplazan con un resumen compacto marcado como persistedDetailsTruncated: true.
  • Los plugins y las herramientas deben poner el texto que el modelo debe leer en content, no solo en details.

Cuerpos entrantes y contexto de historial

OpenClaw separa el cuerpo del prompt del cuerpo del comando:

  • BodyForAgent: texto principal orientado al modelo para el mensaje actual. Los plugins de canal deben mantenerlo enfocado en el texto actual del remitente que contiene el prompt.
  • Body: reserva de prompt heredada. Puede incluir envoltorios de canal y envoltorios de historial opcionales, pero los canales actuales no deben depender de esto como entrada principal del modelo cuando BodyForAgent está disponible.
  • CommandBody: texto bruto del usuario para análisis de directivas/comandos.
  • RawBody: alias heredado de CommandBody (se mantiene por compatibilidad).

Cuando un canal proporciona historial, usa un envoltorio compartido:

  • [Chat messages since your last reply - for context]
  • [Current message - respond to this]

Para chats no directos (grupos/canales/salas), el cuerpo del mensaje actual se prefija con la etiqueta del remitente (el mismo estilo usado para entradas de historial). Esto mantiene coherentes los mensajes en tiempo real y en cola/historial dentro del prompt del agente.

Los búferes de historial son solo pendientes: incluyen mensajes de grupo que no dispararon una ejecución (por ejemplo, mensajes bloqueados por mención) y excluyen mensajes que ya están en la transcripción de la sesión.

La eliminación de directivas solo se aplica a la sección del mensaje actual, de modo que el historial permanece intacto. Los canales que envuelven historial deben establecer CommandBody (o RawBody) en el texto original del mensaje y mantener Body como el prompt combinado. El historial estructurado, las respuestas, los mensajes reenviados y los metadatos de canal se renderizan como bloques de contexto no confiable con rol de usuario durante el ensamblado del prompt. Los búferes de historial se pueden configurar mediante messages.groupChat.historyLimit (valor predeterminado global) y sobrescrituras por canal como channels.slack.historyLimit o channels.telegram.accounts.<id>.historyLimit (establece 0 para desactivar).

Puesta en cola y seguimientos

Si ya hay una ejecución activa, los mensajes entrantes pueden ponerse en cola, dirigirse a la ejecución actual o recopilarse para un turno de seguimiento.

  • Configura mediante messages.queue (y messages.queue.byChannel).
  • El modo predeterminado es steer, con un debounce de seguimiento de 500 ms cuando el steering recurre a la entrega de seguimiento en cola.
  • Modos: steer, followup, collect, steer-backlog, interrupt y el modo heredado de uno a la vez queue.

Detalles: Cola de comandos y Cola de steering.

Propiedad de ejecución del canal

Los plugins de canal pueden preservar el orden, aplicar debounce a la entrada y aplicar contrapresión de transporte antes de que un mensaje entre en la cola de sesión. No deben imponer un timeout separado alrededor del propio turno del agente. Una vez que un mensaje se enruta a una sesión, el trabajo de larga duración se rige por el ciclo de vida de la sesión, la herramienta y el runtime para que todos los canales informen y se recuperen de turnos lentos de forma coherente.

Streaming, fragmentación y agrupación

El streaming por bloques envía respuestas parciales a medida que el modelo produce bloques de texto. La fragmentación respeta los límites de texto del canal y evita dividir código delimitado.

Configuraciones clave:

  • agents.defaults.blockStreamingDefault (on|off, desactivado de forma predeterminada)
  • agents.defaults.blockStreamingBreak (text_end|message_end)
  • agents.defaults.blockStreamingChunk (minChars|maxChars|breakPreference)
  • agents.defaults.blockStreamingCoalesce (agrupación basada en inactividad)
  • agents.defaults.humanDelay (pausa similar a la humana entre respuestas de bloque)
  • Sobrescrituras de canal: *.blockStreaming y *.blockStreamingCoalesce (los canales que no son Telegram requieren *.blockStreaming: true explícito)

Detalles: Streaming + fragmentación.

Visibilidad de razonamiento y tokens

OpenClaw puede exponer u ocultar el razonamiento del modelo:

  • /reasoning on|off|stream controla la visibilidad.
  • El contenido de razonamiento sigue contando para el uso de tokens cuando lo produce el modelo.
  • Telegram admite streaming de razonamiento en una burbuja de borrador transitoria que se elimina tras la entrega final; usa /reasoning on para una salida de razonamiento persistente.

Detalles: Directivas de pensamiento + razonamiento y Uso de tokens.

Prefijos, enhebrado y respuestas

El formato de mensajes salientes está centralizado en messages:

  • messages.responsePrefix, channels.<channel>.responsePrefix y channels.<channel>.accounts.<id>.responsePrefix (cascada de prefijos salientes), además de channels.whatsapp.messagePrefix (prefijo entrante de WhatsApp)
  • Enhebrado de respuestas mediante replyToMode y valores predeterminados por canal

Detalles: Configuración y documentación de canales.

Respuestas silenciosas

El token silencioso exacto NO_REPLY / no_reply significa "no entregar una respuesta visible para el usuario". Cuando un turno también tiene medios de herramienta pendientes, como audio TTS generado, OpenClaw elimina el texto silencioso pero aun así entrega el adjunto multimedia. OpenClaw resuelve ese comportamiento según el tipo de conversación:

  • Las conversaciones directas no permiten silencio de forma predeterminada y reescriben una respuesta silenciosa desnuda a una breve reserva visible.
  • Los grupos/canales permiten silencio de forma predeterminada.
  • La orquestación interna permite silencio de forma predeterminada.

OpenClaw también usa respuestas silenciosas para fallos internos del ejecutor que ocurren antes de cualquier respuesta del asistente en chats no directos, de modo que los grupos/canales no vean texto genérico de error del gateway. Los chats directos muestran texto compacto de fallo de forma predeterminada; los detalles brutos del ejecutor se muestran solo cuando /verbose está on o full.

Los valores predeterminados viven en agents.defaults.silentReply y agents.defaults.silentReplyRewrite; surfaces.<id>.silentReply y surfaces.<id>.silentReplyRewrite pueden sobrescribirlos por superficie.

Cuando la sesión principal tiene una o más ejecuciones de subagentes generados pendientes, las respuestas silenciosas desnudas se descartan en todas las superficies en lugar de reescribirse, por lo que la sesión principal permanece en silencio hasta que el evento de finalización del hijo entrega la respuesta real.

Relacionado