Skip to content

Slack adapter strips receiving bot's own mention, breaking multi-bot @-mention routing (mutual-deferral silence) #1401

Description

@howie

Summary

The Slack adapter strips the receiving bot's own <@UID> from the message
body before handing it to the agent (resolve_slack_mentions,
crates/openab-core/src/slack.rs:1553-1584, called at :1258). This is
correct on its own — it lets the LLM @-mention other users in its reply.
But in a multi-agent deployment it removes the only per-recipient signal
each bot has to tell whether it was explicitly mentioned, which breaks any
"should I respond or defer?" logic when one message @-mentions two or more
bots.

Environment

  • openab version: 0.9.0
  • Adapter: Slack (Socket Mode). The stripping is in shared
    openab_core::slack, so it affects every agent backend
    (claude-agent-acp, codex-acp, agy/Antigravity, hermes-acp) equally.
  • Deployment: 4 team bots in one Slack workspace, each in each other's
    trustedBotIds.

Repro (minimal)

  1. Run two OpenAB bots (say @bot-a = <@UAAA>, @bot-b = <@UBBB>) in the
    same Slack channel.
  2. A human posts one message mentioning both:
    <@UAAA>, <@UBBB> please tell me X.
  3. Inspect the trigger body each bot actually receives (agent session
    transcript):
    • bot-a receives , <@UBBB> please tell me X ← its own <@UAAA> stripped
    • bot-b receives <@UAAA>, please tell me X ← its own <@UBBB> stripped

Each bot's body now contains only the other bot's UID. Any agent
instruction of the form "respond iff the trigger contains your own UID" is
structurally unsatisfiable, and the natural failure mode is mutual
deferral
: each bot sees the other's mention, concludes "the other one is the
target", and both stay silent — so a message that explicitly addressed both
gets no answer.

We hit exactly this in production (both bots silent to a direct two-bot
question; separately, one bot leaked its "should I stay silent?" deliberation
as the visible reply, and that leak re-quoted the other bot's raw <@UID>,
re-triggering it). We've worked around it in our steering docs by telling the
bots not to gate on their own UID, but that's a heuristic — the bot can no
longer reliably know it was addressed.

Why the body alone can't be worked around cleanly

sender_context (schema openab.sender.v1) exposes channel, channel_id,
sender_id, receiver_id, thread_ts, etc., but no field says whether the
receiving bot was explicitly @-mentioned
vs woken by the
multibot-mentions "involved" fallback. receiver_id is always the bot
itself, so it can't distinguish the two. The stripped body was the only
mention signal, and it's gone by the time the agent sees it.

Requested fix (either is sufficient)

  1. Preferred: add a reliable per-recipient signal to sender_context,
    e.g. "mentioned": true|false (was this bot's own UID present in the
    original body before stripping), and optionally "mentioned_bots": ["UAAA", "UBBB"] (all bot UIDs the human addressed). Then multi-agent steering can
    decide correctly without depending on the mutated body.
  2. Alternative: keep the stripped body for readability, but stop stripping
    (or re-surface) the self-mention when the message addresses 2+ known bots,
    so each recipient can still see it was among those addressed.

Happy to send a PR for option 1 (small addition to the sender-context builder
around slack.rs:1258) if the maintainers agree on the field shape.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    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