Skip to content

fix(discord): send_message for streaming replies with bot mentions - #1112

Merged
thepagent merged 4 commits into
mainfrom
fix/streaming-mention-create-not-edit
Jun 15, 2026
Merged

fix(discord): send_message for streaming replies with bot mentions#1112
thepagent merged 4 commits into
mainfrom
fix/streaming-mention-create-not-edit

Conversation

@chaodu-agent

@chaodu-agent chaodu-agent commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

When a streaming response contains <@UID> bot mentions, the current code edits the placeholder message (MESSAGE_UPDATE). Discord does not send mention notifications for edited messages, so the mentioned bot never receives the gateway event.

Root Cause

┌─────────────────────────────────────────────────────────────────────┐
│                    BEFORE (Bug)                                      │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  Bot A (streaming)         Discord                    Bot B         │
│  ─────────────────         ───────                    ─────         │
│        │                      │                         │           │
│        ├─── send_message ────►│  (placeholder "…")      │           │
│        │    MESSAGE_CREATE    │                         │           │
│        │                      │                         │           │
│        │   ... streaming ...  │                         │           │
│        │                      │                         │           │
│        ├─── edit_message ────►│  (final: "<@BotB> hi") │           │
│        │    MESSAGE_UPDATE    │                         │           │
│        │                      │──── ❌ NO event ────────┤           │
│        │                      │  (edits dont notify)    │           │
│        │                      │                         │           │
│        ▼                      ▼                         ▼           │
│                    Bot B never responds                              │
└─────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────┐
│                    AFTER (Fix)                                       │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  Bot A (streaming)         Discord                    Bot B         │
│  ─────────────────         ───────                    ─────         │
│        │                      │                         │           │
│        ├─── send_message ────►│  (placeholder "…")      │           │
│        │    MESSAGE_CREATE    │                         │           │
│        │                      │                         │           │
│        │   ... streaming ...  │                         │           │
│        │                      │                         │           │
│        ├─── send_message ────►│  (final: "<@BotB> hi") │           │
│        │    MESSAGE_CREATE    │                         │           │
│        │                      │──── ✅ EVENT ──────────►│           │
│        │                      │  (mention triggered!)   │           │
│        ├─── delete_message ──►│  (remove placeholder)   │           │
│        │                      │                         │           │
│        ▼                      ▼                         ▼           │
│                    Bot B receives & responds                         │
└─────────────────────────────────────────────────────────────────────┘

Fix

In the streaming finalization path, detect if the final content contains Discord mentions (<@UID>, <@!UID>, or <@&ROLE_ID>). If so:

  1. Send the response as a new message (MESSAGE_CREATE)
  2. Delete the streaming placeholder

This ensures Discord triggers the mention notification and the mentioned bot receives the gateway event.

Scope

  • Discord only — gated by adapter.platform() == "discord"; Slack and other adapters are unaffected
  • Streaming mode only — non-streaming (send-once) path already uses send_message and works correctly
  • Covers user mentions (<@123>), nickname mentions (<@!123>), and role mentions (<@&123>)

What Was Tested

  • Confirmed via curl that POST /channels/{thread_id}/messages with <@bot_id> triggers the mentioned bot ✅
  • Confirmed that edit_message with the same mention does not trigger the mentioned bot ❌
  • Unit tests cover all mention formats and negative cases
  • CI check passed ✅

Fixes #1110

When a streaming response contains <@uid> mentions, Discord's
MESSAGE_UPDATE (edit) does not trigger mention notifications for the
mentioned bot. Switch to delete placeholder + send_message (MESSAGE_CREATE)
so the mentioned bot receives the gateway event and can respond.

Fixes #1110
@chaodu-agent
chaodu-agent requested a review from thepagent as a code owner June 14, 2026 23:47
超渡法師 added 3 commits June 14, 2026 23:51
- Support nickname-style mentions (<@!UID>) in contains_bot_mention()
- Add platform == "discord" check so the delete+send path only applies
  to Discord, not Slack or other adapters
- Fix misleading comment about '!' being for role mentions
Role mentions (e.g. <@&1496247626675257384>) should also trigger
MESSAGE_CREATE so all bots with that role receive the gateway event.
Covers user mentions (<@uid>), nickname mentions (<@!UID>),
role mentions (<@&ROLE_ID>), and negative cases.
@thepagent
thepagent merged commit 53dbb25 into main Jun 15, 2026
27 checks passed
tomcatzh added a commit to tomcatzh/openab that referenced this pull request Jun 30, 2026
…openabdev#1198 bd16546)

Re-implemented (not merged) from upstream openab onto the 0.8.4 patch branch,
kept consistent with upstream shapes/names for future convergence. All in the
handoff-critical adapter path the local fork already owns.

openabdev#1153 mention propagation across split chunks: a >2000-char reply mentioning a
peer is split, but only chunk 1 carries the mention, so a receiver gated on
mentions (allowBotMessages="off" + trustedBotIds, accept only when mentioned)
rejects chunks 2+ and silently truncates the handoff. extract_mentions() +
propagate_mentions_to_chunks() now append every mention to each chunk
(pre-deducting the footer from the split limit so it never busts 2000),
Discord-only, at the single split site that feeds every send path.

openabdev#1112 auto MESSAGE_CREATE on bot-mention: the streaming path edits the reply
into the placeholder (MESSAGE_UPDATE), which Discord emits no mention
notification for (openabdev#1110), so a mentioned peer never wakes. Now if the content
mentions a bot and there is no [[reply_to]] directive, delete the placeholder
and send as new message(s). contains_bot_mention() + a new streaming branch.

openabdev#1198 EOF without final response: the recv-loop broke silently to
"_(no response)_" when the agent stdout closed without an id-bearing
session/prompt response (a bridged agent crashing on backend HTTP 500 / quota
exhaustion exits without an ACP error). Now sets response_error =
"Agent process exited unexpectedly".

bd16546 silent empty turn: stopReason="end_turn" with 0 output tokens is a
silent provider/auth failure. Added TurnResult / parse_turn_result /
is_silent_failure (protocol.rs, exported via mod.rs); the result branch
surfaces a diagnostic instead of "_(no response)_".

Tests: +21 unit tests; cargo test = 521 passed, 0 failed.
Rollback: tag pre-upstream-ports-2026-06-30.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

update native agent OPENAB_AGENT_AUTH_COMMAND

2 participants