Skip to content

Mattermost: multi-turn responses batch all messages at end when edit-in-place streaming is active #43020

@teconomix

Description

@teconomix

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 dropped

Meanwhile, 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

  1. Configure Mattermost with blockStreaming enabled (default when bot has baseUrl + botToken)
  2. Send a request that triggers multiple tool calls (e.g., code analysis requiring file reads)
  3. Observe: one message appears and is edited in-place, but content changes between tool call boundaries
  4. When the model finishes: all messages appear at once

Expected Behavior

Each text segment between tool calls should:

  1. Stream via edit-in-place in its own Mattermost post
  2. Be finalized (posted) when the tool call starts
  3. Next segment starts a fresh streaming post

Environment

  • OpenClaw with Mattermost extension
  • blockStreaming enabled (edit-in-place via onPartialReply)
  • Agent making multi-turn tool-call responses

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions