Messages and delivery
Streaming e fragmentação
OpenClaw tem duas camadas de streaming separadas:
- Streaming em blocos (canais): emite blocos concluídos enquanto o assistente escreve. Essas são mensagens normais de canal (não deltas de tokens).
- Streaming de prévia (Telegram/Discord/Slack): atualiza uma mensagem de prévia temporária durante a geração.
Hoje não há streaming real de deltas de tokens para mensagens de canal. O streaming de prévia é baseado em mensagens (envio + edições/acréscimos).
Streaming em blocos (mensagens de canal)
O streaming em blocos envia a saída do assistente em partes maiores conforme ela fica disponível.
Model output └─ text_delta/events ├─ (blockStreamingBreak=text_end) │ └─ chunker emits blocks as buffer grows └─ (blockStreamingBreak=message_end) └─ chunker flushes at message_end └─ channel send (block replies)Legenda:
text_delta/events: eventos de stream do modelo (podem ser esparsos para modelos sem streaming).chunker:EmbeddedBlockChunkeraplicando limites mínimos/máximos + preferência de quebra.channel send: mensagens de saída reais (respostas em blocos).
Controles:
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? }(mescla blocos transmitidos antes do envio).- Limite rígido do canal:
*.textChunkLimit(por exemplo,channels.whatsapp.textChunkLimit). - Modo de divisão do canal:
*.chunkMode(lengthpor padrão,newlinedivide em linhas em branco (limites de parágrafo) antes da divisão por tamanho). - Limite suave do Discord:
channels.discord.maxLinesPerMessage(padrão 17) divide respostas altas para evitar corte na UI.
Semântica de limite:
text_end: transmite blocos assim que o chunker emite; descarrega em cadatext_end.message_end: espera até a mensagem do assistente terminar e então descarrega a saída armazenada.
message_end ainda usa o chunker se o texto armazenado exceder maxChars, então pode emitir vários blocos no final.
Entrega de mídia com streaming em blocos
Mídia em streaming deve usar campos estruturados de payload, como mediaUrl ou
mediaUrls; texto transmitido não é interpretado como comando de anexo. Quando o
streaming em blocos envia mídia antecipadamente, o OpenClaw lembra essa entrega
no turno. Se o payload final do assistente repetir a mesma URL de mídia, a entrega
final remove a mídia duplicada em vez de enviar o anexo novamente.
Payloads finais exatamente duplicados são suprimidos. Se o payload final adicionar texto distinto ao redor da mídia que já foi transmitida, o OpenClaw ainda envia o novo texto mantendo a mídia em entrega única. Isso evita notas de voz ou arquivos duplicados em canais como Telegram.
Algoritmo de divisão (limites baixo/alto)
A divisão em blocos é implementada por EmbeddedBlockChunker:
- Limite baixo: não emite até o buffer >=
minChars(a menos que seja forçado). - Limite alto: prefere divisões antes de
maxChars; se forçado, divide emmaxChars. - Preferência de quebra:
paragraph→newline→sentence→whitespace→ quebra rígida. - Cercas de código: nunca divide dentro de cercas; quando forçado em
maxChars, fecha + reabre 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 partes de blocos consecutivas antes de enviá-las. Isso reduz "spam de linha única" enquanto ainda fornece saída progressiva.
- A coalescência aguarda intervalos de inatividade (
idleMs) antes de descarregar. - Buffers são limitados por
maxCharse serão descarregados se excederem esse limite. minCharsimpede que fragmentos muito pequenos sejam enviados até que texto suficiente se acumule (a descarga final sempre envia o texto restante).- O juntador é 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
minCharspadrão de coalescência é aumentado para 1500 para Signal/Slack/Discord, a menos que seja sobrescrito.
Ritmo semelhante ao humano entre blocos
Quando o streaming em blocos está ativado, você pode adicionar uma pausa aleatória entre respostas em blocos (após o primeiro bloco). Isso faz respostas com várias bolhas parecerem mais naturais.
- Configuração:
agents.defaults.humanDelay(sobrescreva por agente viaagents.list[].humanDelay). - Modos:
off(padrão),natural(800-2500ms),custom(minMs/maxMs). - Aplica-se apenas a respostas em blocos, não a respostas finais ou resumos de ferramentas.
"Transmitir blocos ou tudo"
Isso corresponde a:
- Transmitir blocos:
blockStreamingDefault: "on"+blockStreamingBreak: "text_end"(emite conforme avança). Canais que não sejam Telegram também precisam de*.blockStreaming: true. - Transmitir tudo no final:
blockStreamingBreak: "message_end"(descarrega uma vez, possivelmente em vários blocos se for muito longo). - Sem streaming em blocos:
blockStreamingDefault: "off"(apenas resposta final).
Observação sobre canais: O streaming em blocos fica desativado a menos que
*.blockStreaming seja definido explicitamente como true. Canais podem transmitir uma prévia ao vivo
(channels.<channel>.streaming) sem respostas em blocos.
Lembrete de localização da configuração: os padrões blockStreaming* ficam em
agents.defaults, não na configuração raiz.
Modos de streaming de prévia
Chave canônica: channels.<channel>.streaming
Modos:
off: desativa o streaming de prévia.partial: prévia única que é substituída pelo texto mais recente.block: prévia atualizada em etapas divididas/anexadas.progress: prévia de progresso/status durante a geração, resposta final na conclusão.
streaming.mode: "block" é um modo de streaming de prévia para canais com capacidade
de edição, como Discord e Telegram. Ele não habilita a entrega de blocos no canal ali.
Use streaming.block.enabled ou a chave de canal legada blockStreaming quando
quiser respostas normais em blocos. Microsoft Teams é a exceção: ele não tem
transporte de bloco de prévia em rascunho, então streaming.mode: "block" mapeia para entrega
em blocos do Teams em vez de streaming parcial/de progresso nativo.
Mapeamento de canais
| Canal | off |
partial |
block |
progress |
|---|---|---|---|---|
| Telegram | ✅ | ✅ | ✅ | rascunho de progresso editável |
| Discord | ✅ | ✅ | ✅ | rascunho de progresso editável |
| Slack | ✅ | ✅ | ✅ | ✅ |
| Mattermost | ✅ | ✅ | ✅ | ✅ |
| MS Teams | ✅ | ✅ | ✅ | stream de progresso nativo |
Somente Slack:
channels.slack.streaming.nativeTransportalterna chamadas da API de streaming nativa do Slack quandochannels.slack.streaming.mode="partial"(padrão:true).- O streaming nativo do Slack e o status de thread do assistente do Slack exigem um destino de thread de resposta. DMs de nível superior não mostram essa prévia em estilo de thread, mas ainda podem usar posts de prévia em rascunho e edições do Slack.
Migração de chaves legadas:
- Telegram: valores legados
streamModee valores escalares/booleanos destreamingsão detectados e migrados pelos caminhos de compatibilidade de doctor/config parastreaming.mode. - Discord:
streamMode+ booleanostreamingcontinuam como aliases de runtime para o enumstreaming; executeopenclaw doctor --fixpara reescrever a configuração persistida. - Slack:
streamModecontinua como alias de runtime parastreaming.mode; booleanostreamingcontinua como alias de runtime parastreaming.modemaisstreaming.nativeTransport;nativeStreaminglegado continua como alias de runtime parastreaming.nativeTransport. Executeopenclaw doctor --fixpara reescrever a configuração persistida.
Comportamento em runtime
Telegram:
- Usa atualizações de prévia
sendMessage+editMessageTextem DMs e grupos/tópicos. - Prévias iniciais curtas ainda recebem debounce para melhorar a UX de notificações push, mas o Telegram agora as materializa após um atraso limitado para que execuções ativas não fiquem visualmente silenciosas.
- O texto final edita a prévia ativa no lugar; finais longos reutilizam essa mensagem para o primeiro bloco e enviam apenas os blocos restantes.
- O modo
blockrotaciona a prévia para uma nova mensagem emstreaming.preview.chunk.maxChars(padrão 800, limitado ao limite de edição de 4096 do Telegram); outros modos aumentam uma prévia até 4096 caracteres. - O modo
progressmantém o progresso de ferramentas em um rascunho de status editável, materializa o rótulo de status quando o streaming da resposta está ativo mas nenhuma linha de ferramenta está disponível ainda, limpa esse rascunho na conclusão e envia a resposta final pela entrega normal. - Se a edição final falhar antes que o texto concluído seja confirmado, o OpenClaw usa a entrega final normal e limpa a prévia obsoleta.
- O streaming de prévia é ignorado quando o streaming em blocos do Telegram está explicitamente ativado (para evitar streaming duplo).
/reasoning streampode escrever o raciocínio em uma prévia transitória que é excluída após a entrega final.
Discord:
- Usa envio + edição de mensagens de prévia.
- O modo
blockusa divisão de rascunho (draftChunk). - O streaming de prévia é ignorado quando o streaming em blocos do Discord está explicitamente ativado.
- Payloads finais de mídia, erro e resposta explícita cancelam prévias pendentes sem descarregar um novo rascunho, depois usam a entrega normal.
Slack:
partialpode usar streaming nativo do Slack (chat.startStream/append/stop) quando disponível.blockusa prévias de rascunho em estilo de acréscimo.progressusa texto de prévia de status e depois a resposta final.- DMs de nível superior sem uma thread de resposta usam posts de prévia em rascunho e edições em vez de streaming nativo do Slack.
- Streaming de prévia nativo e em rascunho suprime respostas em blocos para esse turno, então uma resposta do Slack é transmitida por apenas um caminho de entrega.
- Payloads finais de mídia/erro e finais de progresso não criam mensagens de rascunho descartáveis; apenas finais de texto/bloco que podem editar a prévia descarregam texto de rascunho pendente.
Mattermost:
- Transmite raciocínio, atividade de ferramentas e texto parcial de resposta para um único post de prévia em rascunho que é finalizado no lugar quando a resposta final é segura para enviar.
- Recorre ao envio de um novo post final se o post de prévia foi excluído ou está indisponível no momento da finalização.
- Payloads finais de mídia/erro cancelam atualizações de prévia pendentes antes da entrega normal em vez de descarregar um post de prévia temporário.
Matrix:
- Prévias em rascunho são finalizadas no lugar quando o texto final pode reutilizar o evento de prévia.
- Finais somente de mídia, de erro e com incompatibilidade de destino de resposta cancelam atualizações de prévia pendentes antes da entrega normal; uma prévia obsoleta já visível é redigida.
Atualizações de prévia de progresso de ferramentas
O streaming de prévia também pode incluir atualizações de progresso de ferramentas - linhas curtas de status como "pesquisando na web", "lendo arquivo" ou "chamando ferramenta" - que aparecem na mesma mensagem de prévia enquanto as ferramentas estão em execução, antes da resposta final. No modo app-server do Codex, mensagens de preâmbulo/comentário do Codex usam esse mesmo caminho de prévia, então notas curtas de progresso como "Estou verificando..." podem ser transmitidas para o rascunho editável sem se tornarem parte da resposta final. Isso mantém turnos de ferramentas em várias etapas visualmente ativos, em vez de silenciosos entre a primeira prévia de raciocínio e a resposta final.
Ferramentas de longa duração podem emitir progresso tipado antes de retornarem. Por exemplo,
web_fetch arma um temporizador de cinco segundos ao iniciar: se a busca ainda estiver
pendente, a prévia pode mostrar Fetching page content...; se a busca terminar
ou for cancelada antes disso, nenhuma linha de progresso é emitida. O resultado final posterior da ferramenta
ainda é entregue normalmente ao modelo.
Superfícies compatíveis:
- Discord, Slack, Telegram e Matrix transmitem o progresso de ferramentas e atualizações de preâmbulo do Codex para a edição de prévia ao vivo por padrão quando o streaming de prévia está ativo. Microsoft Teams usa seu stream de progresso nativo em conversas pessoais.
- Telegram é distribuído com atualizações de prévia de progresso de ferramentas habilitadas desde
v2026.4.22; mantê-las habilitadas preserva esse comportamento lançado. - Mattermost já incorpora a atividade de ferramentas em sua única publicação de prévia de rascunho (veja acima).
- Edições de progresso de ferramentas seguem o modo de streaming de prévia ativo; elas são ignoradas quando o streaming de prévia está
offou quando o streaming em blocos assumiu a mensagem. No Telegram,streaming.mode: "off"é somente final: conversas genéricas de progresso também são suprimidas em vez de serem entregues como mensagens de status avulsas, enquanto solicitações de aprovação, payloads de mídia e erros ainda são roteados normalmente. - Para manter o streaming de prévia, mas ocultar linhas de progresso de ferramentas, defina
streaming.preview.toolProgresscomofalsepara esse canal. Para manter linhas de progresso de ferramentas visíveis enquanto oculta texto de comando/execução, definastreaming.preview.commandTextcomo"status"oustreaming.progress.commandTextcomo"status"; o padrão é"raw"para preservar o comportamento lançado. Essa política é compartilhada por canais de rascunho/progresso que usam o renderizador compacto de progresso do OpenClaw, incluindo Discord, Matrix, Microsoft Teams, Mattermost, prévias de rascunho do Slack e Telegram. Para desabilitar completamente as edições de prévia, definastreaming.modecomooff. - Respostas a citações selecionadas do Telegram são uma exceção: quando
replyToModenão é"off"e há texto de citação selecionado, o OpenClaw ignora o stream de prévia da resposta para esse turno, de modo que as linhas de prévia de progresso de ferramentas não possam ser renderizadas. Respostas à mensagem atual sem texto de citação selecionado ainda mantêm o streaming de prévia. Consulte a documentação do canal Telegram para detalhes.
Faixa de progresso de comentário
Além do progresso de ferramentas, o renderizador compacto de progresso pode exibir mais uma faixa no rascunho:
streaming.progress.commentary— renderiza o comentário pré-ferramenta do modelo (💬) — narração curta do tipo "Vou verificar… então…" — intercalado com linhas de ferramentas no rascunho de progresso.
{ "channels": { "discord": { "streaming": { "mode": "progress", "progress": { "commentary": true } } } }}Mantenha as linhas de progresso visíveis, mas oculte o texto bruto de comando/execução:
{ "channels": { "telegram": { "streaming": { "mode": "partial", "preview": { "toolProgress": true, "commandText": "status" } } } }}Use a mesma forma sob outra chave de canal de progresso compacto, por exemplo channels.discord, channels.matrix, channels.msteams, channels.mattermost ou prévias de rascunho do Slack. Para o modo de rascunho de progresso, coloque a mesma política sob streaming.progress:
{ "channels": { "telegram": { "streaming": { "mode": "progress", "progress": { "toolProgress": true, "commandText": "status" } } } }}Relacionados
- Refatoração do ciclo de vida de mensagens - design compartilhado alvo de prévia, edição, stream e finalização
- Rascunhos de progresso - mensagens visíveis de trabalho em andamento que são atualizadas durante turnos longos
- Mensagens - ciclo de vida e entrega de mensagens
- Nova tentativa - comportamento de nova tentativa em falha de entrega
- Canais - suporte a streaming por canal