Streaming + fragmentação
O OpenClaw tem duas camadas separadas de “streaming”:- Streaming em blocos (canais): emite blocos concluídos conforme o assistente escreve. São mensagens normais do canal (não deltas de tokens).
- Streaming tipo token (apenas Telegram): atualiza uma bolha de rascunho com texto parcial enquanto gera; a mensagem final é enviada ao final.
Streaming em blocos (mensagens do canal)
O streaming em blocos envia a saída do assistente em chunks grosseiros conforme ficam disponíveis.text_delta/events: eventos de stream do modelo (podem ser esparsos para modelos sem streaming).chunker:EmbeddedBlockChunkeraplicando limites mínimo/máximo + preferência de quebra.channel send: mensagens de saída reais (respostas em blocos).
agents.defaults.blockStreamingDefault:"on"/"off"(desativado por padrão).- Substituições por canal:
*.blockStreaming(e variantes por conta) para forçar"on"/"off"por canal. agents.defaults.blockStreamingBreak:"text_end"ou"message_end".agents.defaults.blockStreamingChunk:{ minChars, maxChars, breakPreference? }.agents.defaults.blockStreamingCoalesce:{ minChars?, maxChars?, idleMs? }(mesclar blocos transmitidos antes do envio).- Limite rígido do canal:
*.textChunkLimit(por exemplo,channels.whatsapp.textChunkLimit). - Modo de chunking do canal:
*.chunkMode(lengthpadrão,newlinedivide em linhas em branco (limites de parágrafo) antes do chunking por comprimento). - Limite flexível do Discord:
channels.discord.maxLinesPerMessage(padrão 17) divide respostas altas para evitar recorte na UI.
text_end: transmite blocos assim que o chunker emite; descarrega a cadatext_end.message_end: aguarda até a mensagem do assistente terminar e então descarrega a saída em buffer.
message_end ainda usa o chunker se o texto em buffer exceder maxChars, então pode emitir múltiplos chunks ao final.
Algoritmo de chunking (limites baixo/alto)
O chunking de blocos é implementado porEmbeddedBlockChunker:
- Limite baixo: não emitir até o buffer >=
minChars(a menos que forçado). - Limite alto: preferir quebras antes de
maxChars; se forçado, dividir emmaxChars. - Preferência de quebra:
paragraph→newline→sentence→whitespace→ quebra rígida. - Cercas de código: nunca dividir dentro de cercas; quando forçado em
maxChars, fechar + reabrir a cerca para manter o Markdown válido.
maxChars é limitado ao textChunkLimit do canal, então você não pode exceder os limites por canal.
Coalescência (mesclar blocos transmitidos)
Quando o streaming em blocos está ativado, o OpenClaw pode mesclar chunks de blocos consecutivos antes de enviá-los. Isso reduz “spam de linha única” enquanto ainda fornece saída progressiva.- A coalescência aguarda intervalos ociosos (
idleMs) antes de descarregar. - Os buffers são limitados por
maxCharse serão descarregados se excederem isso. minCharsimpede o envio de fragmentos minúsculos até que texto suficiente se acumule (a descarga final sempre envia o texto restante).- O conector é derivado de
blockStreamingChunk.breakPreference(paragraph→\n\n,newline→\n,sentence→ espaço). - Substituições por canal estão disponíveis via
*.blockStreamingCoalesce(incluindo configurações por conta). - O
minCharsde coalescência padrão é aumentado para 1500 para Signal/Slack/Discord, a menos que seja substituído.
Ritmo humano entre blocos
Quando o streaming em blocos está ativado, você pode adicionar uma pausa aleatória entre respostas em bloco (após o primeiro bloco). Isso faz respostas com múltiplas bolhas parecerem mais naturais.- Configuração:
agents.defaults.humanDelay(substituir por agente viaagents.list[].humanDelay). - Modos:
off(padrão),natural(800–2500ms),custom(minMs/maxMs). - Aplica-se apenas a respostas em bloco, não a respostas finais ou resumos de ferramentas.
“Transmitir chunks ou tudo”
Isso mapeia para:- Transmitir chunks:
blockStreamingDefault: "on"+blockStreamingBreak: "text_end"(emitir conforme avança). Canais não Telegram também precisam de*.blockStreaming: true. - Transmitir tudo no final:
blockStreamingBreak: "message_end"(descarregar uma vez, possivelmente em múltiplos chunks se for muito longo). - Sem streaming em blocos:
blockStreamingDefault: "off"(apenas resposta final).
*.blockStreaming seja explicitamente definido como true. O Telegram pode transmitir rascunhos
(channels.telegram.streamMode) sem respostas em bloco.
Lembrete de local da configuração: os padrões de blockStreaming* ficam em
agents.defaults, não na configuração raiz.
Streaming de rascunho do Telegram (tipo token)
O Telegram é o único canal com streaming de rascunho:- Usa a Bot API
sendMessage(primeira atualização) +editMessageText(atualizações subsequentes). channels.telegram.streamMode: "partial" | "block" | "off".partial: atualizações do rascunho com o texto de stream mais recente.block: atualizações do rascunho em blocos chunked (mesmas regras do chunker).off: sem streaming de rascunho.
- Configuração de chunk do rascunho (apenas para
streamMode: "block"):channels.telegram.draftChunk(padrões:minChars: 200,maxChars: 800). - A transmissão de preview é separada da transmissão de blocos.
- Quando o streaming de rascunho está ativo, o OpenClaw desativa o streaming em blocos para aquela resposta para evitar streaming duplo.
- Finais apenas em texto são aplicados editando a mensagem de preview no próprio local.
- Finais não textuais/complexos recorrem ao envio normal da mensagem final.
/reasoning streamgrava o raciocínio na bolha de rascunho (apenas Telegram).
preview message: mensagem temporária do Telegram atualizada durante a geração.final edit: edição no próprio local na mesma mensagem de preview (apenas texto).