Skip to content

RFC: [slack].streaming toggle to disable live streaming (send-once mode) #1114

@dogzzdogzz

Description

@dogzzdogzz

Proposal

Problem

The Slack adapter always streams replies live — native streaming
(chat.startStream + assistant.threads.setStatus) when assistant_mode is on,
or a post+edit placeholder otherwise. This is great UX for a single bot, but in
multi-agent threads (several openab bots, or openab alongside other Slack bots in
one channel) it has a sharp edge.

Consider a thread with two bots:

  1. user → bot A
  2. bot A → bot B (bot A's reply @-mentions bot B)
  3. bot B → bot A

At step 2, no other bot has posted in the thread yet, so bot A still treats it
as a single-bot thread and streams its reply via post+edit. Each edit emits a
message_changed event → bot B's app_mention re-fires once per edit, so bot B
responds to intermediate/partial states instead of bot A's single final message.

The existing other_bot_present gate only disables streaming after another bot
has posted — it cannot help on the kickoff message that first mentions bot B. There
is no way for an operator to deterministically opt a deployment into send-once
behaviour.

[gateway] already exposes a streaming switch (defaults false). Slack has no
equivalent.

Proposed shape

Add one optional boolean to [slack], default true (preserves current behaviour):

[slack]
streaming = true     # default — live streaming, as today
# streaming = false  # always post a single final message (send-once)

When streaming = false:

  • No native streaming (no chat.startStream / streamed assistant.threads.setStatus).
  • No post+edit placeholder.
  • The adapter posts exactly one final chat.postMessage per turn.
  • Independent of assistant_mode — the assistant status API (reaction / set-status)
    is unaffected; only the message streaming path is gated.

Mirrors [gateway].streaming in concept; the default deliberately differs (true
for Slack to preserve the current streaming UX, vs false for gateway).

Key behaviour

  • Gating points: use_streaming() and uses_native_streaming() both AND-in the new flag.
  • assistant_mode status / reactions are unaffected by the switch.
  • Default truezero behaviour change for existing deployments.

Open questions

  1. Naming: streaming (mirrors gateway) vs something more explicit like
    live_streaming / send_once?
  2. Scope: Slack-only for now, or land the same toggle on Discord for symmetry?
    (Discord has no post+edit streaming, so the multi-agent concern is Slack-specific.)
  3. Default: keep true (current behaviour) — confirming that's the preferred default.

I have a working implementation + tests for the Slack side and am happy to open a
PR if the shape looks good.


Update (2026-06-18)

Beyond the streaming toggle, PR #1115 also introduces send-once narration trimming — only the final answer block (text after the last tool call) is delivered, dropping inter-tool narration. Per maintainer discussion this is controlled by a dedicated narration_display flag (default false), decoupled from streaming, and implemented in the shared adapter layer so it applies to any send-once turn (not just Slack). Supersedes the per-backend filters in #1030 / #1032.

Metadata

Metadata

Assignees

No one assigned

    Labels

    p2Medium — planned workrfcslack

    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