Por quê
- Execuções de resposta automática podem ser caras (chamadas de LLM) e podem colidir quando várias mensagens de entrada chegam muito próximas.
- A serialização evita disputa por recursos compartilhados (arquivos de sessão, logs, stdin da CLI) e reduz a chance de limites de taxa upstream.
Como funciona
- Uma fila FIFO ciente de lanes esvazia cada lane com um limite de concorrência configurável (padrão 1 para lanes não configuradas; main usa 4 por padrão, subagent usa 8).
runEmbeddedAgentenfileira por chave de sessão (lanesession:<key>) para garantir apenas uma execução ativa por sessão.- Cada execução de sessão é então enfileirada em uma lane global (
mainpor padrão), de modo que o paralelismo geral seja limitado poragents.defaults.maxConcurrent. - Quando o logging verboso está ativado, execuções enfileiradas emitem um aviso curto se esperarem mais de ~2s antes de iniciar.
- Indicadores de digitação ainda disparam imediatamente ao enfileirar (quando compatíveis com o canal), portanto a experiência do usuário permanece inalterada enquanto aguardamos nossa vez.
Padrões
Quando não definido, todas as superfícies de canal de entrada usam:mode: "steer"debounceMs: 500cap: 20drop: "summarize"
Modos de fila
/queue controla o que mensagens de entrada normais fazem enquanto uma sessão já tem
uma execução ativa:
steer: injeta mensagens no runtime ativo. O OpenClaw entrega todas as mensagens de direcionamento pendentes depois que o turno atual do assistente termina de executar suas chamadas de ferramenta, antes da próxima chamada de LLM; o app-server do Codex recebe umturn/steerem lote. Se a execução não estiver transmitindo ativamente ou se o direcionamento estiver indisponível, o OpenClaw espera até que a execução ativa termine antes de iniciar o prompt.followup: não direciona. Enfileira cada mensagem para um turno posterior do agente depois que a execução atual termina.collect: não direciona. Agrupa mensagens enfileiradas em um único turno de acompanhamento após a janela de silêncio. Se as mensagens apontarem para canais/threads diferentes, elas são esvaziadas individualmente para preservar o roteamento.interrupt: aborta a execução ativa dessa sessão e então executa a mensagem mais recente.
/steer <message>,
consulte Direcionar.
Configure globalmente ou por canal via messages.queue:
Opções de fila
As opções se aplicam à entrega enfileirada.debounceMs também define a
janela de silêncio de direcionamento do Codex no modo steer:
debounceMs: janela de silêncio antes de esvaziar acompanhamentos enfileirados ou lotes collect; no modosteerdo Codex, janela de silêncio antes de enviarturn/steerem lote. Números simples são milissegundos; as unidadesms,s,m,hedsão aceitas por opções de/queue.cap: máximo de mensagens enfileiradas por sessão. Valores abaixo de1são ignorados.drop: "summarize": padrão. Descarta as entradas enfileiradas mais antigas conforme necessário, mantém resumos compactos e os injeta como um prompt sintético de acompanhamento.drop: "old": descarta as entradas enfileiradas mais antigas conforme necessário, sem preservar resumos.drop: "new": rejeita a mensagem mais recente quando a fila já está cheia.
debounceMs: 500, cap: 20, drop: summarize.
Direcionamento e streaming
Quando o streaming do canal épartial ou block, o direcionamento pode parecer várias
respostas visíveis curtas enquanto a execução ativa alcança limites do runtime:
partial: a prévia pode finalizar cedo e então uma nova prévia começa depois que o direcionamento é aceito.block: blocos do tamanho de rascunho podem criar a mesma aparência sequencial.- Sem streaming, o direcionamento recai para um acompanhamento após a execução ativa quando o runtime não consegue aceitar direcionamento no mesmo turno.
steer não aborta ferramentas em andamento. Use /queue interrupt quando a mensagem
mais recente deve abortar a execução atual.
Precedência
Para seleção de modo, o OpenClaw resolve:- Sobrescrita de
/queueinline ou armazenada por sessão. messages.queue.byChannel.<channel>.messages.queue.mode.steerpadrão.
/queue têm precedência sobre a configuração. Em seguida,
são aplicados debounce específico por canal (messages.queue.debounceMsByChannel), padrões de
debounce do Plugin, opções globais de messages.queue e padrões integrados.
cap e drop são opções globais/de sessão, não chaves de configuração por canal.
Sobrescritas por sessão
- Envie
/queue <steer|followup|collect|interrupt>como um comando independente para armazenar o modo de fila da sessão atual. - Opções podem ser combinadas:
/queue collect debounce:0.5s cap:25 drop:summarize /queue defaultou/queue resetlimpa a sobrescrita da sessão.
Escopo e garantias
- Aplica-se a execuções de agente de resposta automática em todos os canais de entrada que usam o pipeline de resposta do Gateway (WhatsApp web, Telegram, Slack, Discord, Signal, iMessage, webchat, etc.).
- A lane padrão (
main) é ampla ao processo para entradas + heartbeats principais; definaagents.defaults.maxConcurrentpara permitir várias sessões em paralelo. - Lanes adicionais podem existir (por exemplo,
cron,cron-nested,nested,subagent) para que trabalhos em segundo plano possam executar em paralelo sem bloquear respostas de entrada. Turnos isolados de agente cron seguram um slotcronenquanto sua execução interna de agente usacron-nested; ambos usamcron.maxConcurrentRuns. Fluxos compartilhados não cronnestedmantêm seu próprio comportamento de lane. Essas execuções desvinculadas são rastreadas como tarefas em segundo plano. - Lanes por sessão garantem que apenas uma execução de agente toque uma determinada sessão por vez.
- Sem dependências externas ou threads de worker em segundo plano; TypeScript puro + promises.
Solução de problemas
- Se os comandos parecerem travados, ative logs verbosos e procure linhas “queued for …ms” para confirmar que a fila está sendo esvaziada.
- Se você precisar da profundidade da fila, ative logs verbosos e observe as linhas de timing da fila.
- Execuções do app-server do Codex que aceitam um turno e então param de emitir progresso são interrompidas pelo adaptador do Codex para que a lane de sessão ativa possa ser liberada em vez de esperar pelo timeout da execução externa.
- Quando diagnósticos estão ativados, sessões que permanecem em
processingalém dediagnostics.stuckSessionWarnMssem resposta, ferramenta, status, bloco ou progresso ACP observado são classificadas pela atividade atual. Trabalho ativo é registrado comosession.long_running; chamadas de modelo silenciosas com proprietário também permanecemsession.long_runningatédiagnostics.stuckSessionAbortMs, para que provedores lentos ou sem streaming não sejam reportados como parados cedo demais. Trabalho ativo sem progresso recente é registrado comosession.stalled; chamadas de modelo com proprietário mudam parasession.stalledno ou após o limite de abort, e atividade antiga de modelo/ferramenta sem proprietário não é ocultada como longa execução.session.stucké reservado para bookkeeping recuperável de sessão antiga, incluindo sessões enfileiradas ociosas com atividade antiga de modelo/ferramenta sem proprietário, e somente esse caminho pode liberar a lane da sessão afetada para que o trabalho enfileirado seja esvaziado. Diagnósticossession.stuckrepetidos fazem backoff enquanto a sessão permanece inalterada.