-
-
Notifications
You must be signed in to change notification settings - Fork 69.4k
Mattermost: multi-turn responses batch all messages at end when edit-in-place streaming is active #43020
Description
Summary
When a Mattermost agent responds with multiple messages (multi-turn tool-call responses), and edit-in-place streaming is active (blockStreaming enabled, introduced in #33506), the user sees unexpected behavior:
Expected: Each message streams independently (edit-in-place), gets posted when complete, then the next message starts streaming.
Observed: A single streaming message appears and keeps getting overwritten with each turn's text. When the model run completes, all messages appear at once.
Root Cause
The Mattermost extension sets disableBlockStreaming: true when it handles streaming via onPartialReply (to prevent the core from sending duplicate block messages). However, this flag also prevents createBlockReplyDeliveryHandler from delivering block replies at message_end boundaries (between tool calls):
// In createBlockReplyDeliveryHandler:
if (params.blockStreamingEnabled && params.blockReplyPipeline)
params.blockReplyPipeline.enqueue(blockPayload); // ← skipped
else if (params.blockStreamingEnabled)
await params.onBlockReply(blockPayload); // ← also skipped
// When blockStreamingEnabled=false → block is silently droppedMeanwhile, onPartialReply receives the current turn's text (resets between tool calls), so the single streaming post keeps changing content as new turns start. Only when the model finishes does getReplyFromConfig return all accumulated assistantTexts[] as final replies, causing them to appear all at once.
Steps to Reproduce
- Configure Mattermost with
blockStreamingenabled (default when bot has baseUrl + botToken) - Send a request that triggers multiple tool calls (e.g., code analysis requiring file reads)
- Observe: one message appears and is edited in-place, but content changes between tool call boundaries
- When the model finishes: all messages appear at once
Expected Behavior
Each text segment between tool calls should:
- Stream via edit-in-place in its own Mattermost post
- Be finalized (posted) when the tool call starts
- Next segment starts a fresh streaming post
Environment
- OpenClaw with Mattermost extension
blockStreamingenabled (edit-in-place viaonPartialReply)- Agent making multi-turn tool-call responses
Related
- feat(mattermost): block streaming edit-in-place (rebased) #33506 — Mattermost edit-in-place streaming (introduces
disableBlockStreaming: true) - feat(mattermost): chunk text before final streaming edit to respect post size limits #39491 — Stream text when response includes media