Skip to content

fix(slack): bot-to-bot communication broken by placeholder message and concurrent dispatch #419

@dogzzdogzz

Description

@dogzzdogzz

Description

Two related bugs that break bot-to-bot communication in Slack (and Discord), triggered when allow_bot_messages is set to mentions or all:

Bug 1: Same-thread race condition (src/slack.rs)

tokio::spawn dispatches messages with no per-thread ordering. Two messages arriving in the same thread can prompt the same ACP session concurrently, producing incoherent context:

Thread: @BotA please summarize
Thread: @BotA also check the logs    ← arrives 200ms later, same thread

Both spawn concurrently → ACP session receives both prompts simultaneously
→ context is scrambled

Bug 2: "..." placeholder + streaming edit (src/adapter.rs)

OpenAB immediately sends "..." then edits it every 1.5s as the ACP response streams in. This UX pattern was intentional for human users, but breaks bot-to-bot in two different ways depending on mode:

t=0s  BotA sends "..."          → new message event
t=1s  BotA edits "..." → chunk1 → message_changed event → BotB filters (skip_subtype)
t=2s  BotA edits → chunk2       → message_changed event → BotB filters
t=5s  BotA edits → final @BotB  → message_changed event → BotB filters
  • allow_bot_messages = "mentions": BotA's final reply contains @BotB, but it arrives as message_changed which BotB filters via skip_subtype. BotB never sees the @mention and never responds — even though it was explicitly called.
  • allow_bot_messages = "all": BotB sees the initial "..." as a message event and responds to it, before BotA has produced any real content.

The "..." placeholder was intentional for human UX (immediate visual feedback). But with bot-to-bot introduced, message_changed filtering — which is itself correct behavior — makes the streaming edit pattern fundamentally incompatible.

Prior art — OpenClaw and Hermes both use send-initial + chat.update streaming, but avoid the issue by dropping all bot messages by default. OpenAB is the only framework with configurable bot-to-bot, making this fix necessary.

Bug 3: Agent replies to channel root instead of thread (src/slack.rs, src/adapter.rs)

When an agent calls a Slack MCP tool directly to send a message, it has no access to thread_ts and posts to channel root instead of the active thread.

Steps to Reproduce

Bug 2 with mentions:

  1. Configure two OpenAB instances (BotA, BotB) in the same Slack channel
  2. Set allow_bot_messages = "mentions" on BotB
  3. Send a message to BotA asking it to pass results to @botb
  4. BotA's final response mentions @botb — but BotB never responds (mention arrives via message_changed, which is filtered)

Bug 2 with all:

  1. Same setup, set allow_bot_messages = "all" on BotB
  2. Send a message to BotA
  3. BotB immediately responds to "..." instead of BotA's actual response

Bug 3:

  1. Configure an agent with a Slack MCP tool
  2. Send a message in a Slack thread
  3. Agent replies via MCP tool — message appears in channel root, not in thread

Expected Behavior

  1. Bug 1: Same-thread messages execute sequentially (FIFO), different threads run concurrently
  2. Bug 2: BotB receives BotA's complete response as a single message event (not message_changed), regardless of allow_bot_messages mode
  3. Bug 3: Agent has access to thread_ts via sender_context.thread_id and replies in the correct thread

Environment

  • Affects: Slack adapter (allow_bot_messages = "mentions" or "all"), Discord adapter (send-once applies to both)
  • Source: src/adapter.rs, src/slack.rs
  • Reproducible on any OpenAB version with bot-to-bot enabled

Screenshots / Logs

# Bug 2 (mentions mode) — BotB never triggered despite @mention in BotA's response
# BotA's final edit contains "@BotB" but arrives as message_changed → silently dropped

# Bug 2 (all mode) — BotB logs showing response to "..."
[INFO] message event received text="..." channel=C0123 is_bot=true
[INFO] processing message
[INFO] session/prompt sent content="..."

Discord thread

https://discord.com/channels/1491295327620169908/1493496229168939130/1494352889563320430

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions