CoderClaw has two separate βstreamingβ layers:
There is no true token-delta streaming to channel messages today. Telegram preview streaming is the only partial-stream surface.
Block streaming sends assistant output in coarse chunks as it becomes available.
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)
Legend:
text_delta/events: model stream events (may be sparse for non-streaming models).chunker: EmbeddedBlockChunker applying min/max bounds + break preference.channel send: actual outbound messages (block replies).Controls:
agents.defaults.blockStreamingDefault: "on"/"off" (default off).*.blockStreaming (and per-account variants) to force "on"/"off" per channel.agents.defaults.blockStreamingBreak: "text_end" or "message_end".agents.defaults.blockStreamingChunk: { minChars, maxChars, breakPreference? }.agents.defaults.blockStreamingCoalesce: { minChars?, maxChars?, idleMs? } (merge streamed blocks before send).*.textChunkLimit (e.g., channels.whatsapp.textChunkLimit).*.chunkMode (length default, newline splits on blank lines (paragraph boundaries) before length chunking).channels.discord.maxLinesPerMessage (default 17) splits tall replies to avoid UI clipping.Boundary semantics:
text_end: stream blocks as soon as chunker emits; flush on each text_end.message_end: wait until assistant message finishes, then flush buffered output.message_end still uses the chunker if the buffered text exceeds maxChars, so it can emit multiple chunks at the end.
Block chunking is implemented by EmbeddedBlockChunker:
minChars (unless forced).maxChars; if forced, split at maxChars.paragraph β newline β sentence β whitespace β hard break.maxChars, close + reopen the fence to keep Markdown valid.maxChars is clamped to the channel textChunkLimit, so you canβt exceed per-channel caps.
When block streaming is enabled, CoderClaw can merge consecutive block chunks before sending them out. This reduces βsingle-line spamβ while still providing progressive output.
idleMs) before flushing.maxChars and will flush if they exceed it.minChars prevents tiny fragments from sending until enough text accumulates
(final flush always sends remaining text).blockStreamingChunk.breakPreference
(paragraph β \n\n, newline β \n, sentence β space).*.blockStreamingCoalesce (including per-account configs).minChars is bumped to 1500 for Signal/Slack/Discord unless overridden.When block streaming is enabled, you can add a randomized pause between block replies (after the first block). This makes multi-bubble responses feel more natural.
agents.defaults.humanDelay (override per agent via agents.list[].humanDelay).off (default), natural (800β2500ms), custom (minMs/maxMs).This maps to:
blockStreamingDefault: "on" + blockStreamingBreak: "text_end" (emit as you go). Non-Telegram channels also need *.blockStreaming: true.blockStreamingBreak: "message_end" (flush once, possibly multiple chunks if very long).blockStreamingDefault: "off" (only final reply).Channel note: For non-Telegram channels, block streaming is off unless
*.blockStreaming is explicitly set to true. Telegram can stream a live preview
(channels.telegram.streamMode) without block replies.
Config location reminder: the blockStreaming* defaults live under
agents.defaults, not the root config.
Telegram is the only channel with live preview streaming:
sendMessage (first update) + editMessageText (subsequent updates).channels.telegram.streamMode: "partial" | "block" | "off".
partial: preview updates with latest stream text.block: preview updates in chunked blocks (same chunker rules).off: no preview streaming.streamMode: "block"): channels.telegram.draftChunk (defaults: minChars: 200, maxChars: 800)./reasoning stream writes reasoning into the live preview (Telegram only).Telegram
ββ sendMessage (temporary preview message)
ββ streamMode=partial β edit latest text
ββ streamMode=block β chunker + edit updates
ββ final text-only reply β final edit on same message
ββ fallback: cleanup preview + normal final delivery (media/complex)
Legend:
preview message: temporary Telegram message updated during generation.final edit: in-place edit on the same preview message (text-only).