Streaming + chunking
OpenClaw ha due livelli di streaming separati:- Streaming a blocchi (canali): emette blocchi completati mentre l’assistente scrive. Si tratta di normali messaggi del canale (non delta di token).
- Preview streaming (Telegram/Discord/Slack): aggiorna un messaggio di anteprima temporaneo durante la generazione.
Streaming a blocchi (messaggi del canale)
Lo streaming a blocchi invia l’output dell’assistente in blocchi grossolani man mano che diventa disponibile.text_delta/events: eventi di streaming del modello (possono essere radi per i modelli non streaming).chunker:EmbeddedBlockChunkerche applica limiti min/max + preferenza di interruzione.channel send: messaggi effettivi in uscita (risposte a blocchi).
agents.defaults.blockStreamingDefault:"on"/"off"(predefinito off).- Override per canale:
*.blockStreaming(e varianti per account) per forzare"on"/"off"per canale. agents.defaults.blockStreamingBreak:"text_end"o"message_end".agents.defaults.blockStreamingChunk:{ minChars, maxChars, breakPreference? }.agents.defaults.blockStreamingCoalesce:{ minChars?, maxChars?, idleMs? }(unisce i blocchi in streaming prima dell’invio).- Limite rigido del canale:
*.textChunkLimit(ad esempiochannels.whatsapp.textChunkLimit). - Modalità chunk del canale:
*.chunkMode(lengthpredefinito,newlinedivide sulle righe vuote, cioè ai confini dei paragrafi, prima del chunking per lunghezza). - Limite morbido Discord:
channels.discord.maxLinesPerMessage(predefinito 17) divide le risposte alte per evitare il clipping nell’interfaccia.
text_end: trasmette i blocchi non appena il chunker li emette; svuota il buffer a ognitext_end.message_end: attende che il messaggio dell’assistente termini, poi svuota l’output bufferizzato.
message_end usa comunque il chunker se il testo bufferizzato supera maxChars, quindi può emettere più chunk alla fine.
Algoritmo di chunking (limiti basso/alto)
Il chunking a blocchi è implementato daEmbeddedBlockChunker:
- Limite basso: non emette finché il buffer non è >=
minChars(a meno che non sia forzato). - Limite alto: preferisce divisioni prima di
maxChars; se forzato, divide amaxChars. - Preferenza di interruzione:
paragraph→newline→sentence→whitespace→ interruzione rigida. - Code fence: non divide mai all’interno delle fence; quando è forzato a
maxChars, chiude e riapre la fence per mantenere valido il Markdown.
maxChars è vincolato al textChunkLimit del canale, quindi non puoi superare i limiti per canale.
Coalescenza (unione dei blocchi in streaming)
Quando lo streaming a blocchi è abilitato, OpenClaw può unire chunk di blocchi consecutivi prima di inviarli. Questo riduce lo “spam di singole righe” pur continuando a fornire un output progressivo.- La coalescenza attende intervalli di inattività (
idleMs) prima di svuotare il buffer. - I buffer sono limitati da
maxCharse vengono svuotati se lo superano. minCharsimpedisce l’invio di frammenti minuscoli finché non si accumula abbastanza testo (lo svuotamento finale invia sempre il testo rimanente).- Il separatore deriva da
blockStreamingChunk.breakPreference(paragraph→\n\n,newline→\n,sentence→ spazio). - Sono disponibili override per canale tramite
*.blockStreamingCoalesce(incluse le configurazioni per account). - Il valore predefinito di coalescenza
minCharsviene portato a 1500 per Signal/Slack/Discord salvo override.
Ritmo umano tra i blocchi
Quando lo streaming a blocchi è abilitato, puoi aggiungere una pausa casuale tra le risposte a blocchi (dopo il primo blocco). Questo rende le risposte multi-bolla più naturali.- Configurazione:
agents.defaults.humanDelay(override per agente tramiteagents.list[].humanDelay). - Modalità:
off(predefinita),natural(800–2500ms),custom(minMs/maxMs). - Si applica solo alle risposte a blocchi, non alle risposte finali o ai riepiloghi degli strumenti.
”Trasmettere i chunk o tutto”
Questo corrisponde a:- Trasmettere i chunk:
blockStreamingDefault: "on"+blockStreamingBreak: "text_end"(emette man mano). I canali non Telegram richiedono anche*.blockStreaming: true. - Trasmettere tutto alla fine:
blockStreamingBreak: "message_end"(svuota una volta sola, eventualmente in più chunk se è molto lungo). - Nessuno streaming a blocchi:
blockStreamingDefault: "off"(solo risposta finale).
*.blockStreaming non sia esplicitamente impostato su true. I canali possono trasmettere una preview live
(channels.<channel>.streaming) senza risposte a blocchi.
Promemoria sulla posizione della configurazione: i valori predefiniti blockStreaming* si trovano in
agents.defaults, non nella configurazione root.
Modalità di preview streaming
Chiave canonica:channels.<channel>.streaming
Modalità:
off: disabilita il preview streaming.partial: singola anteprima che viene sostituita con il testo più recente.block: l’anteprima si aggiorna in passaggi suddivisi in chunk/aggiunti.progress: anteprima di avanzamento/stato durante la generazione, risposta finale al completamento.
Mappatura per canale
| Canale | off | partial | block | progress |
|---|---|---|---|---|
| Telegram | ✅ | ✅ | ✅ | corrisponde a partial |
| Discord | ✅ | ✅ | ✅ | corrisponde a partial |
| Slack | ✅ | ✅ | ✅ | ✅ |
channels.slack.nativeStreamingabilita/disabilita le chiamate API di streaming nativo di Slack quandostreaming=partial(predefinito:true).
- Telegram:
streamMode+ booleanostreamingvengono migrati automaticamente all’enumstreaming. - Discord:
streamMode+ booleanostreamingvengono migrati automaticamente all’enumstreaming. - Slack:
streamModeviene migrato automaticamente all’enumstreaming; il booleanostreamingviene migrato automaticamente anativeStreaming.
Comportamento a runtime
Telegram:- Usa gli aggiornamenti di anteprima
sendMessage+editMessageTexttra DM e gruppi/topic. - Il preview streaming viene saltato quando lo streaming a blocchi di Telegram è esplicitamente abilitato (per evitare doppio streaming).
/reasoning streampuò scrivere il ragionamento nell’anteprima.
- Usa messaggi di anteprima con invio + modifica.
- La modalità
blockusa il chunking delle bozze (draftChunk). - Il preview streaming viene saltato quando lo streaming a blocchi di Discord è esplicitamente abilitato.
partialpuò usare lo streaming nativo di Slack (chat.startStream/append/stop) quando disponibile.blockusa anteprime bozza in stile append.progressusa testo di anteprima dello stato, poi la risposta finale.