Streaming y Chunking
Streaming + chunking
Sección titulada «Streaming + chunking»OpenClaw tiene dos capas de streaming separadas:
- Block streaming (canales): emite bloques completados a medida que el asistente escribe. Estos son mensajes de canal normales (no deltas de tokens).
- Preview streaming (Telegram/Discord/Slack): actualiza un mensaje de vista previa temporal mientras se genera.
Actualmente no hay un verdadero streaming de deltas de tokens hacia los mensajes del canal. El streaming de vista previa se basa en mensajes (enviar + ediciones/adiciones).
Block streaming (mensajes de canal)
Sección titulada «Block streaming (mensajes de canal)»Block streaming envía la salida del asistente en fragmentos gruesos a medida que está disponible.
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)Leyenda:
text_delta/events: eventos de streaming del modelo (pueden ser dispersos para modelos no-streaming).chunker:EmbeddedBlockChunkeraplicando límites min/máx + preferencia de corte.channel send: mensajes salientes reales (respuestas de bloque).
Controles:
agents.defaults.blockStreamingDefault:"on"/"off"(desactivado por defecto).- anulaciones de canal:
*.blockStreaming(y variantes por cuenta) para forzar"on"/"off"por canal. agents.defaults.blockStreamingBreak:"text_end"o"message_end".agents.defaults.blockStreamingChunk:{ minChars, maxChars, breakPreference? }.agents.defaults.blockStreamingCoalesce:{ minChars?, maxChars?, idleMs? }(fusionar bloques transmitidos antes del envío).- Límite estricto del canal:
*.textChunkLimit(por ejemplo,channels.whatsapp.textChunkLimit). - Modo de fragmentación del canal:
*.chunkMode(lengthpor defecto,newlinedivide en líneas en blanco (límites de párrafo) antes de la fragmentación por longitud). - Límite suave de Discord:
channels.discord.maxLinesPerMessage(por defecto 17) divide las respuestas largas para evitar el recorte de la interfaz de usuario.
Semántica de límites:
text_end: transmite bloques tan pronto como el fragmentador los emite; vacía en cadatext_end.message_end: espera a que finalice el mensaje del asistente y luego vacía el resultado almacenado en el búfer.
message_end todavía utiliza el fragmentador si el texto en el búfer supera maxChars, por lo que puede emitir múltiples fragmentos al final.
Algoritmo de fragmentación (límites bajo/alto)
Sección titulada «Algoritmo de fragmentación (límites bajo/alto)»La fragmentación de bloques está implementada por EmbeddedBlockChunker:
- Límite bajo: no emitir hasta que el búfer >=
minChars(a menos que se fuerce). - Límite alto: prefiere divisiones antes de
maxChars; si se fuerza, dividir enmaxChars. - Preferencia de ruptura:
paragraph→newline→sentence→whitespace→ ruptura forzada. - Cercas de código (code fences): nunca dividir dentro de las cercas; cuando se fuerza en
maxChars, cerrar + reabrir la cerca para mantener el Markdown válido.
maxChars está limitado al límite del canal textChunkLimit, por lo que no puedes exceder los límites por canal.
Fusión (combinar bloques transmitidos)
Sección titulada «Fusión (combinar bloques transmitidos)»Cuando la transmisión de bloques está habilitada, OpenClaw puede combinar fragmentos de bloques consecutivos antes de enviarlos. Esto reduce el “spam de líneas individuales” mientras aún proporciona un resultado progresivo.
- La fusión espera brechas de inactividad (
idleMs) antes de vaciar. - Los búferes tienen un límite de
maxCharsy se vaciarán si lo superan. minCharsevita que se envíen fragmentos diminutos hasta que se acumule suficiente texto (el vaciado final siempre envía el texto restante).- El unidor se deriva de
blockStreamingChunk.breakPreference(paragraph→\n\n,newline→\n,sentence→ espacio). - Las anulaciones de canal están disponibles a través de
*.blockStreamingCoalesce(incluyendo configuraciones por cuenta). - La fusión predeterminada
minCharsse aumenta a 1500 para Signal/Slack/Discord a menos que se anule.
Ritmo similar al humano entre bloques
Sección titulada «Ritmo similar al humano entre bloques»Cuando la transmisión de bloques está habilitada, puedes agregar una pausa aleatoria entre las respuestas de bloques (después del primer bloque). Esto hace que las respuestas de múltiples burbujas se sientan más naturales.
- Configuración:
agents.defaults.humanDelay(anular por agente a través deagents.list[].humanDelay). - Modos:
off(predeterminado),natural(800–2500ms),custom(minMs/maxMs). - Se aplica solo a las respuestas de bloques, no a las respuestas finales ni a los resúmenes de herramientas.
”Transmitir fragmentos o todo”
Sección titulada «”Transmitir fragmentos o todo”»Esto se asigna a:
- Transmitir fragmentos:
blockStreamingDefault: "on"+blockStreamingBreak: "text_end"(emitir sobre la marcha). Los canales que no sean Telegram también necesitan*.blockStreaming: true. - Transmitir todo al final:
blockStreamingBreak: "message_end"(vaciar una vez, posiblemente múltiples fragmentos si es muy largo). - Sin transmisión de bloques:
blockStreamingDefault: "off"(solo respuesta final).
Nota del canal: La transmisión de bloques está desactivada a menos que
*.blockStreaming esté establecido explícitamente en true. Los canales pueden transmitir una vista previa en vivo
(channels.<channel>.streaming) sin respuestas de bloques.
Recordatorio de ubicación de configuración: los valores predeterminados blockStreaming* se encuentran en
agents.defaults, no en la configuración raíz.
Modos de transmisión de vista previa
Sección titulada «Modos de transmisión de vista previa»Clave canónica: channels.<channel>.streaming
Modos:
off: desactivar la transmisión de vista previa.partial: vista previa única que se reemplaza con el texto más reciente.block: actualizaciones de vista previa en pasos fragmentados/agregados.progress: vista previa de progreso/estado durante la generación, respuesta final al completar.
Asignación de canales
Sección titulada «Asignación de canales»| Canal | off | partial | block | progress |
|---|---|---|---|---|
| Telegram | ✅ | ✅ | ✅ | se asigna a partial |
| Discord | ✅ | ✅ | ✅ | se asigna a partial |
| Slack | ✅ | ✅ | ✅ | ✅ |
Solo para Slack:
channels.slack.nativeStreamingalterna las llamadas a la API de transmisión nativa de Slack cuandostreaming=partial(predeterminado:true).
Migración de clave heredada:
- Telegram:
streamMode+ booleanostreamingmigran automáticamente al enumstreaming. - Discord:
streamMode+ booleanstreamingse migra automáticamente al enumstreaming. - Slack:
streamModese migra automáticamente al enumstreaming; el booleanstreamingse migra automáticamente anativeStreaming.
Comportamiento en tiempo de ejecución
Sección titulada «Comportamiento en tiempo de ejecución»Telegram:
- Usa
sendMessage+editMessageTextactualizaciones de vista previa en MDs y grupos/temas. - La transmisión de vista previa se omite cuando la transmisión de bloques de Telegram está explícitamente habilitada (para evitar la doble transmisión).
/reasoning streampuede escribir el razonamiento en la vista previa.
Discord:
- Usa mensajes de vista previa de envío y edición.
- El modo
blockusa fragmentación de borradores (draftChunk). - La transmisión de vista previa se omite cuando la transmisión de bloques de Discord está explícitamente habilitada.
Slack:
partialpuede usar la transmisión nativa de Slack (chat.startStream/append/stop) cuando esté disponible.blockusa vistas previas de borrador de estilo anexar.progressusa texto de vista previa de estado, luego la respuesta final.