Messages and delivery
Coda dei comandi
OpenClaw serializza le esecuzioni di risposta automatica in ingresso (su tutti i canali) tramite una piccola coda interna al processo, per impedire collisioni tra più esecuzioni dell'agente, consentendo comunque un parallelismo sicuro tra le sessioni.
Perché
- Le esecuzioni di risposta automatica possono essere costose (chiamate LLM) e possono entrare in conflitto quando più messaggi in ingresso arrivano a breve distanza.
- La serializzazione evita la competizione per le risorse condivise (file di sessione, log, stdin della CLI) e riduce la probabilità di incorrere nei limiti di frequenza dei servizi upstream.
Funzionamento
- Una coda FIFO sensibile alle corsie smaltisce ogni corsia con un limite di concorrenza configurabile (valore predefinito 1 per le corsie non configurate;
mainha come valore predefinito 4,subagent8). runEmbeddedAgentaccoda in base alla chiave di sessione (corsiasession:<key>) per garantire una sola esecuzione attiva per sessione.- Ogni esecuzione di sessione viene quindi accodata in una corsia globale (
mainper impostazione predefinita), così il parallelismo complessivo è limitato daagents.defaults.maxConcurrent. - Quando la registrazione dettagliata è abilitata, le esecuzioni accodate emettono un breve avviso se attendono più di circa 2 secondi prima di iniziare.
- Gli indicatori di digitazione si attivano comunque immediatamente all'accodamento (se supportati dal canale), quindi l'esperienza utente rimane invariata mentre l'esecuzione attende il proprio turno.
Valori predefiniti
Quando non sono impostati, tutte le superfici dei canali in ingresso utilizzano:
mode: "steer"debounceMs: 500cap: 20drop: "summarize"
L'indirizzamento nello stesso turno è il comportamento predefinito. Un prompt che arriva durante un'esecuzione viene inserito nel runtime attivo quando questo può accettare l'indirizzamento, evitando di avviare una seconda esecuzione della sessione. Se l'esecuzione attiva non può accettarlo, OpenClaw attende che termini prima di avviare il prompt.
Modalità della coda
/queue controlla il comportamento dei normali messaggi in ingresso quando una sessione ha già un'esecuzione attiva:
steer: inserisce i messaggi nel runtime attivo. OpenClaw recapita tutti i messaggi di indirizzamento in sospeso dopo che il turno corrente dell'assistente ha terminato di eseguire le chiamate agli strumenti, prima della chiamata LLM successiva; il server dell'app Codex riceve un unicoturn/steeraggregato. Se l'esecuzione non sta trasmettendo attivamente o l'indirizzamento non è disponibile, OpenClaw attende che l'esecuzione attiva termini prima di avviare il prompt.followup: non indirizza. Accoda ogni messaggio per un turno successivo dell'agente, dopo il termine dell'esecuzione corrente.collect: non indirizza. Raggruppa i messaggi accodati in un unico turno successivo dopo la finestra di inattività. Se i messaggi sono destinati a canali/thread diversi, vengono smaltiti singolarmente per preservare l'instradamento.interrupt: interrompe l'esecuzione attiva per quella sessione, quindi esegue il messaggio più recente.
Per la temporizzazione specifica del runtime e il comportamento delle dipendenze, consulta Coda di indirizzamento. Per il comando esplicito /steer <message>, consulta Indirizzamento.
Configura globalmente o per canale tramite messages.queue:
{ messages: { queue: { mode: "steer", debounceMs: 500, cap: 20, drop: "summarize", byChannel: { discord: "collect" }, }, },}Opzioni della coda
Le opzioni si applicano al recapito degli elementi accodati. debounceMs imposta anche la finestra di inattività per l'indirizzamento di Codex in modalità steer:
debounceMs: finestra di inattività prima di smaltire i turni successivi accodati o i batch raccolti; nella modalitàsteerdi Codex, finestra di inattività prima dell'invio di unturn/steeraggregato. I numeri senza unità sono espressi in millisecondi; le opzioni di/queueaccettano le unitàms,s,m,hed.cap: numero massimo di messaggi accodati per sessione. I valori inferiori a1vengono ignorati.drop: "summarize"(predefinito): elimina le voci accodate meno recenti secondo necessità, conserva riepiloghi compatti e li inserisce come prompt successivo sintetico.drop: "old": elimina le voci accodate meno recenti secondo necessità, senza conservarne i riepiloghi.drop: "new": rifiuta il messaggio più recente quando la coda è già piena.
Valori predefiniti: debounceMs: 500, cap: 20, drop: summarize.
Indirizzamento e streaming
Quando lo streaming del canale è partial o block, l'indirizzamento può apparire come una serie di brevi risposte visibili mentre l'esecuzione attiva raggiunge i confini del runtime:
partial: l'anteprima può concludersi anticipatamente, quindi ne viene avviata una nuova dopo l'accettazione dell'indirizzamento.block: blocchi delle dimensioni di una bozza possono produrre lo stesso aspetto sequenziale.- Senza streaming, quando il runtime non può accettare l'indirizzamento nello stesso turno, questo viene convertito in un turno successivo dopo l'esecuzione attiva.
steer non interrompe gli strumenti in esecuzione. Usa /queue interrupt quando il messaggio più recente deve interrompere l'esecuzione corrente.
Precedenza
Per selezionare la modalità, OpenClaw applica il seguente ordine:
- Sostituzione
/queueinline o memorizzata per la sessione. messages.queue.byChannel.<channel>.messages.queue.mode.- Valore predefinito
steer.
Per le opzioni, quelle di /queue inline o memorizzate hanno la precedenza sulla configurazione. Vengono quindi applicati, nell'ordine, il debounce specifico del canale (messages.queue.debounceMsByChannel), i valori predefiniti del debounce del Plugin, le opzioni globali di messages.queue e i valori predefiniti integrati. cap e drop sono opzioni globali o di sessione, non chiavi di configurazione per canale.
Sostituzioni per sessione
- Invia
/queue <steer|followup|collect|interrupt>come comando autonomo per memorizzare la modalità della coda per la sessione corrente. - Le opzioni possono essere combinate:
/queue collect debounce:0.5s cap:25 drop:summarize /queue defaulto/queue resetelimina la sostituzione della sessione.
Annullamento dei turni accodati
Mentre un prompt rimane nella coda followup/collect (ad esempio un chat.send della TUI o della chat web che arriva mentre è attivo un altro turno), il Gateway mantiene un'identità di annullamento gestita dal Gateway per il runId del client finché il contenuto accodato non viene eseguito o eliminato. L'identità segue il contenuto incorporato in un riepilogo di eccedenza.
chat.abortcon unrunIdspecifico annulla quel turno mentre è ancora accodato, se il richiedente è autorizzato (secondo le stesse regole di proprietà delle esecuzioni attive).chat.abortper una sessione senzarunIdannulla prima i turni accodati autorizzati, quindi interrompe le esecuzioni attive autorizzate. Quest'ordine impedisce che lo smaltimento della coda promuova del lavoro in una sessione interrotta solo parzialmente.- La cancellazione dell'intera coda della sessione senza verifiche per richiedente non costituisce il percorso di arresto per le sessioni con più proprietari.
- Le attese in coda non vengono rappresentate come esecuzioni attive dell'agente in
sessions.liste non possiedono la semantica di timeout delle esecuzioni attive; solo la fase attiva la possiede.
I client (inclusa la TUI) inoltrano i prompt ricevuti durante l'esecuzione e lasciano che il Gateway applichi la modalità della coda. Esc//stop usa un'interruzione con ambito di sessione, così la perdita degli handle locali non può lasciare in esecuzione un prompt ancora accodato.
Ambito e garanzie
- Si applica alle esecuzioni di risposta automatica dell'agente su tutti i canali in ingresso che utilizzano la pipeline di risposta del Gateway (WhatsApp web, Telegram, Slack, Discord, Signal, iMessage, chat web e così via).
- La corsia predefinita (
main) è condivisa dall'intero processo per i messaggi in ingresso e gli heartbeat principali; impostaagents.defaults.maxConcurrentper consentire l'esecuzione parallela di più sessioni. - Possono esistere corsie aggiuntive (ad esempio
cron,cron-nested,nested,subagent), così i processi in background possono essere eseguiti in parallelo senza bloccare le risposte in ingresso. I turni isolati dell'agente Cron occupano uno slotcron, mentre la loro esecuzione interna dell'agente usacron-nested; entrambi utilizzanocron.maxConcurrentRuns. I flussinestedcondivisi non Cron mantengono il comportamento della propria corsia. Queste esecuzioni disaccoppiate vengono monitorate come attività in background. - Le corsie per sessione garantiscono che una sola esecuzione dell'agente alla volta acceda a una determinata sessione.
- Nessuna dipendenza esterna né thread di lavoro in background; solo TypeScript e promise.
Risoluzione dei problemi
- Se i comandi sembrano bloccati, abilita i log dettagliati e cerca le righe "queued for ...ms" per verificare che la coda venga smaltita.
- Le esecuzioni del server dell'app Codex che accettano un turno e poi smettono di emettere avanzamenti vengono interrotte dall'adattatore Codex, così la corsia della sessione attiva può essere rilasciata invece di attendere il timeout dell'esecuzione esterna.
- Quando la diagnostica è abilitata, le sessioni che rimangono in
processingoltrediagnostics.stuckSessionWarnMssenza alcun avanzamento osservato relativo a risposta, strumento, stato, blocco o ACP vengono classificate in base all'attività corrente:- Il lavoro attivo con avanzamenti recenti viene registrato come
session.long_running. Anche le chiamate silenziose al modello con un proprietario rimangonosession.long_runningfino adiagnostics.stuckSessionAbortMs, affinché i provider lenti o senza streaming non vengano segnalati prematuramente come bloccati. - Il lavoro attivo senza avanzamenti recenti viene registrato come
session.stalled; le chiamate al modello con un proprietario, le chiamate agli strumenti bloccate e le esecuzioni incorporate bloccate passano asession.stalledal raggiungimento o al superamento della soglia di interruzione. L'attività obsoleta di modelli o strumenti senza proprietario non viene nascosta come esecuzione prolungata. session.stuckè riservato ai dati amministrativi obsoleti e recuperabili della sessione, incluse le sessioni accodate inattive con attività obsoleta di modelli o strumenti senza proprietario.session.stuckattiva sempre un ripristino che può rilasciare la corsia della sessione interessata. Anche una classificazionesession.stalledche superadiagnostics.stuckSessionAbortMs(chiamata a uno strumento bloccata, chiamata al modello bloccata o esecuzione incorporata bloccata) può attivare un ripristino con interruzione attiva; entrambe le classificazioni possono quindi sbloccare una coda, non soltantosession.stuck.- Le righe di avviso ripetute nei log per
session.stuckesession.long_runningapplicano un backoff esponenziale finché la sessione rimane invariata; i tentativi di ripristino continuano comunque a essere eseguiti a ogni impulso dell'heartbeat, indipendentemente dal backoff.
- Il lavoro attivo con avanzamenti recenti viene registrato come