Messages and delivery

Cola de comandos

Serializamos las ejecuciones de respuesta automática entrantes (todos los canales) mediante una pequeña cola en proceso para evitar que varias ejecuciones de agente colisionen, mientras seguimos permitiendo paralelismo seguro entre sesiones.

Por qué

  • Las ejecuciones de respuesta automática pueden ser costosas (llamadas a LLM) y pueden colisionar cuando llegan varios mensajes entrantes con poca diferencia de tiempo.
  • Serializar evita la competencia por recursos compartidos (archivos de sesión, registros, stdin de la CLI) y reduce la probabilidad de límites de tasa ascendentes.

Cómo funciona

  • Una cola FIFO consciente de carriles vacía cada carril con un límite de concurrencia configurable (1 por defecto para carriles no configurados; main tiene 4 por defecto, subagente 8).
  • runEmbeddedPiAgent encola por clave de sesión (carril session:<key>) para garantizar solo una ejecución activa por sesión.
  • Cada ejecución de sesión se encola después en un carril global (main por defecto) para que el paralelismo total quede limitado por agents.defaults.maxConcurrent.
  • Cuando el registro detallado está activado, las ejecuciones en cola emiten un aviso breve si esperaron más de ~2 s antes de iniciarse.
  • Los indicadores de escritura siguen activándose inmediatamente al encolar (cuando el canal los admite), por lo que la experiencia del usuario no cambia mientras esperamos nuestro turno.

Valores predeterminados

Cuando no se configuran, todas las superficies de canales entrantes usan:

  • mode: "steer"
  • debounceMs: 500
  • cap: 20
  • drop: "summarize"

steer es el valor predeterminado porque mantiene receptivo el turno del modelo activo sin iniciar una segunda ejecución de sesión. Vacía todos los mensajes de direccionamiento que llegaron antes del siguiente límite del modelo. Si la ejecución actual no puede aceptar direccionamiento, OpenClaw recurre a una entrada de cola de seguimiento.

Modos de cola

Los mensajes entrantes pueden dirigir la ejecución actual, esperar un turno de seguimiento o hacer ambas cosas:

  • steer: encola mensajes de direccionamiento en el runtime activo. Pi entrega todos los mensajes de direccionamiento pendientes después de que el turno actual del asistente termine de ejecutar sus llamadas a herramientas, antes de la siguiente llamada a LLM; el servidor de aplicaciones de Codex recibe un turn/steer por lotes. Si la ejecución no está transmitiendo activamente o el direccionamiento no está disponible, OpenClaw recurre a una entrada de cola de seguimiento.
  • queue (heredado): direccionamiento antiguo de uno en uno. Pi entrega un mensaje de direccionamiento en cola en cada límite del modelo; el servidor de aplicaciones de Codex recibe solicitudes turn/steer separadas. Prefiere steer salvo que necesites el comportamiento serializado anterior.
  • followup: encola cada mensaje para un turno de agente posterior después de que finalice la ejecución actual.
  • collect: fusiona los mensajes en cola en un único turno de seguimiento después de la ventana de silencio. Si los mensajes apuntan a distintos canales/hilos, se vacían individualmente para preservar el enrutamiento.
  • steer-backlog (también steer+backlog): dirige ahora y conserva el mismo mensaje para un turno de seguimiento.
  • interrupt (heredado): cancela la ejecución activa de esa sesión y luego ejecuta el mensaje más reciente.

Steer-backlog significa que puedes recibir una respuesta de seguimiento después de la ejecución dirigida, por lo que las superficies de transmisión pueden parecer duplicadas. Prefiere collect/steer si quieres una respuesta por cada mensaje entrante.

Para conocer el comportamiento de tiempos y dependencias específico del runtime, consulta Cola de direccionamiento. Para el comando explícito /steer <message>, consulta Dirigir.

Configura globalmente o por canal mediante messages.queue:

{
  messages: {
    queue: {
      mode: "steer",
      debounceMs: 500,
      cap: 20,
      drop: "summarize",
      byChannel: { discord: "collect" },
    },
  },
}

Opciones de cola

Las opciones se aplican a followup, collect y steer-backlog (y a steer o al queue heredado cuando el direccionamiento recurre a seguimiento):

  • debounceMs: ventana de silencio antes de vaciar seguimientos en cola. Los números sin unidad son milisegundos; las unidades ms, s, m, h y d son aceptadas por las opciones de /queue.
  • cap: máximo de mensajes en cola por sesión. Los valores inferiores a 1 se ignoran.
  • drop: "summarize": predeterminado. Descarta las entradas en cola más antiguas según sea necesario, conserva resúmenes compactos e inyéctalos como una indicación de seguimiento sintética.
  • drop: "old": descarta las entradas en cola más antiguas según sea necesario, sin conservar resúmenes.
  • drop: "new": rechaza el mensaje más reciente cuando la cola ya está llena.

Valores predeterminados: debounceMs: 500, cap: 20, drop: summarize.

Precedencia

Para la selección de modo, OpenClaw resuelve:

  1. Anulación /queue por sesión, en línea o almacenada.
  2. messages.queue.byChannel.<channel>.
  3. messages.queue.mode.
  4. steer predeterminado.

Para las opciones, las opciones /queue en línea o almacenadas tienen prioridad sobre la configuración. Después se aplican el debounce específico del canal (messages.queue.debounceMsByChannel), los valores predeterminados de debounce del Plugin, las opciones globales de messages.queue y los valores predeterminados integrados. cap y drop son opciones globales/de sesión, no claves de configuración por canal.

Anulaciones por sesión

  • Envía /queue <mode> como comando independiente para almacenar el modo de la sesión actual.
  • Las opciones se pueden combinar: /queue collect debounce:0.5s cap:25 drop:summarize
  • /queue default o /queue reset borra la anulación de sesión.

Alcance y garantías

  • Se aplica a ejecuciones de agentes de respuesta automática en todos los canales entrantes que usan la canalización de respuesta del Gateway (WhatsApp web, Telegram, Slack, Discord, Signal, iMessage, webchat, etc.).
  • El carril predeterminado (main) abarca todo el proceso para entrantes + heartbeats principales; configura agents.defaults.maxConcurrent para permitir varias sesiones en paralelo.
  • Pueden existir carriles adicionales (p. ej., cron, cron-nested, nested, subagent) para que los trabajos en segundo plano puedan ejecutarse en paralelo sin bloquear las respuestas entrantes. Los turnos de agente cron aislados mantienen una ranura cron mientras su ejecución interna de agente usa cron-nested; ambos usan cron.maxConcurrentRuns. Los flujos nested compartidos que no son cron conservan su propio comportamiento de carril. Estas ejecuciones desacopladas se rastrean como tareas en segundo plano.
  • Los carriles por sesión garantizan que solo una ejecución de agente toque una sesión determinada a la vez.
  • Sin dependencias externas ni hilos de trabajador en segundo plano; TypeScript puro + promesas.

Solución de problemas

  • Si los comandos parecen atascados, activa los registros detallados y busca líneas "queued for ...ms" para confirmar que la cola se está vaciando.
  • Si necesitas la profundidad de la cola, activa los registros detallados y observa las líneas de tiempo de cola.
  • Las ejecuciones del servidor de aplicaciones de Codex que aceptan un turno y luego dejan de emitir progreso son interrumpidas por el adaptador de Codex para que el carril de sesión activo pueda liberarse en lugar de esperar el tiempo de espera de la ejecución externa.
  • Cuando los diagnósticos están activados, las sesiones que permanecen en processing más allá de diagnostics.stuckSessionWarnMs sin respuesta, herramienta, estado, bloque ni progreso de ACP observado se clasifican por actividad actual. El trabajo activo se registra como session.long_running; el trabajo activo sin progreso reciente se registra como session.stalled; session.stuck se reserva para contabilidad de sesión obsoleta sin trabajo activo, y solo esa ruta puede liberar el carril de sesión afectado para que el trabajo en cola se vacíe. Los diagnósticos session.stuck repetidos aplican retroceso mientras la sesión permanece sin cambios.

Relacionado