Cola de Comandos
Diseño de cola de comandos que serializa ejecuciones de auto-respuesta entrantes
Serializamos las ejecuciones de auto-respuesta entrantes (todos los canales) a través de una pequeña cola en proceso para prevenir colisiones de múltiples ejecuciones de agente, mientras todavía permitimos paralelismo seguro entre sesiones.
Por qué
- Las ejecuciones de auto-respuesta pueden ser costosas (llamadas LLM) y pueden colisionar cuando múltiples mensajes entrantes llegan cercanos en el tiempo.
- Serializar evita competir por recursos compartidos (archivos de sesión, logs, stdin CLI) y reduce la posibilidad de límites de tasa upstream.
Cómo funciona
- Una cola FIFO consciente de carriles drena cada carril con un límite de concurrencia configurable (predeterminado 1 para carriles no configurados; main por defecto 4, subagent 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 entonces en un ''carril global'' (''main'' por defecto) para que el paralelismo general esté limitado por ''agents.defaults.maxConcurrent''.
- Cuando el logging verbose está habilitado, las ejecuciones encoladas emiten un breve aviso si esperaron más de ~2s antes de iniciar.
- Los indicadores de escritura todavía se activan inmediatamente al encolar (cuando el canal lo soporta) para que la experiencia del usuario no cambie mientras esperamos nuestro turno.
Modos de cola (por canal)
Los mensajes entrantes pueden dirigir la ejecución actual, esperar un turno de seguimiento, o hacer ambos:
- ''steer'': inyectar inmediatamente en la ejecución actual (cancela llamadas de herramienta pendientes después del próximo límite de herramienta). Si no está transmitiendo, recurre a followup.
- ''followup'': encolar para el próximo turno de agente después de que la ejecución actual termine.
- `drop`: política de desbordamiento (`old`, `new`, `summarize`).
- ''steer-backlog'' (aka ''steer+backlog''): dirigir ahora ''y'' preservar el mensaje para un turno de seguimiento.
- ''interrupt'' (legacy): abortar la ejecución activa para esa sesión, luego ejecutar el mensaje más nuevo.
- ''queue'' (alias legacy): igual que ''steer''.
Steer-backlog significa que puedes obtener una respuesta de seguimiento después de la ejecución dirigida, así
que las superficies de streaming pueden parecer duplicados. Prefiere ''collect''/''steer'' si quieres
una respuesta por mensaje entrante.
Envía ''/queue collect'' como comando independiente (por sesión) o establece ''messages.queue.byChannel.discord: "collect"''.
Predeterminados (cuando no están establecidos en config):
- Todas las superficies → ''collect''
Configura globalmente o por canal via ''messages.queue'':
{
messages: {
queue: {
mode: "collect",
debounceMs: 1000,
cap: 20,
drop: "summarize",
byChannel: { discord: "collect" },
},
},
}Opciones de cola
Las opciones aplican a ''followup'', ''collect'', y ''steer-backlog'' (y a ''steer'' cuando recurre a followup):
- ''debounceMs'': esperar quietud antes de iniciar un turno de seguimiento (previene "continuar, continuar").
- ''cap'': máx mensajes encolados por sesión.
- ''drop'': política de desbordamiento (''old'', ''new'', ''summarize'').
Summarize mantiene una lista corta de viñetas de mensajes descartados y la inyecta como un prompt de seguimiento sintético. Predeterminados: ''debounceMs: 1000'', ''cap: 20'', ''drop: summarize''.
Anulaciones por sesión
- Envía ''/queue <mode>'' como comando independiente para almacenar el modo para la sesión actual.
- Las opciones se pueden combinar: ''/queue collect debounce:2s cap:25 drop:summarize''
- ''/queue default'' o ''/queue reset'' limpia la anulación de sesión.
Alcance y garantías
- Aplica a ejecuciones de agente de auto-respuesta en todos los canales entrantes que usan el pipeline de respuesta del gateway (WhatsApp web, Telegram, Slack, Discord, Signal, iMessage, webchat, etc.).
- El carril predeterminado (''main'') es de proceso completo para entrantes + latidos principales; establece ''agents.defaults.maxConcurrent'' para permitir múltiples sesiones en paralelo.
- Pueden existir carriles adicionales (ej. ''cron'', ''subagent'') para que trabajos en segundo plano puedan ejecutarse en paralelo sin bloquear respuestas entrantes.
- Los carriles por sesión garantizan que solo una ejecución de agente toca una sesión dada a la vez.
- Sin dependencias externas o hilos de trabajo en segundo plano; TypeScript puro + promesas.
Solución de problemas
- Si los comandos parecen atascados, habilita logs verbose y busca líneas "queued for …ms" para confirmar que la cola está drenando.
- Si necesitas profundidad de cola, habilita logs verbose y observa las líneas de timing de cola.