Description
resolve_mentions() currently replaces <@UID> with @DisplayName, discarding the UID. Change it to emit <@UID|DisplayName> instead, so the LLM sees a human-readable name while the UID is preserved for mention-back in replies.
Inbound (Discord → ACP): resolve other-user mentions to <@UID|DisplayName>:
// current (line 491-495)
let display = format!("@{}", label);
// proposed
let display = format!("<@{}|{}>", user.id, label);
Outbound (ACP → Discord): strip the |Name suffix before sending to Discord, since Discord does not support Slack-style <@UID|Name> syntax — it only renders <@UID>:
// before sending reply to Discord
let out = regex::Regex::new(r"<@(\d+)\|[^>]+>")
.unwrap()
.replace_all(&reply, "<@$1>");
|
fn resolve_mentions(content: &str, bot_id: UserId, mentions: &[User]) -> String { |
|
// 1. Strip the bot's own trigger mention |
|
let mut out = content |
|
.replace(&format!("<@{}>", bot_id), "") |
|
.replace(&format!("<@!{}>", bot_id), ""); |
|
// 2. Resolve known user mentions to @DisplayName |
|
for user in mentions { |
|
if user.id == bot_id { |
|
continue; |
|
} |
|
let label = user.global_name.as_deref().unwrap_or(&user.name); |
|
let display = format!("@{}", label); |
|
out = out |
|
.replace(&format!("<@{}>", user.id), &display) |
|
.replace(&format!("<@!{}>", user.id), &display); |
|
} |
|
// 3. Fallback: replace any remaining unresolved mentions |
|
let out = ROLE_MENTION_RE.replace_all(&out, "@(role)"); |
|
let out = USER_MENTION_RE.replace_all(&out, "@(user)").to_string(); |
|
out.trim().to_string() |
|
} |
Investigation: How Other Projects Handle This
We investigated how OpenClaw and Hermes handle Discord mentions:
|
Bot own mention |
Other user mentions |
| OpenAB (current) |
Stripped |
<@UID> → @DisplayName (UID lost) |
| Hermes (NousResearch/hermes-agent) |
Stripped |
Passed through as raw <@UID> — LLM sees Discord syntax but no human-readable name |
| OpenClaw (openclaw/openclaw) |
Stripped via stripPatterns: ["<@!?\\d+>"] |
All mentions stripped — LLM sees neither UID nor name |
- Hermes (
gateway/platforms/discord.py line ~2992): only strips the bot own mention, leaves other <@UID> raw in message.content passed to the agent.
- OpenClaw (
extensions/discord/src/channel.ts): declares stripPatterns: () => ["<@!?\\d+>"] which removes all user mentions before the message reaches the LLM. Outbound mentions are reconstructed via a directory lookup (mentions.ts → formatMention()).
Neither project preserves both UID and display name for the agent. The <@UID|DisplayName> format (borrowed from Slack native syntax) gives the LLM human-readable context while keeping the UID available for mention-back.
Use Case
When a user mentions another user (e.g. @AgentDealer) in a message to the bot, the agent receives @AgentDealer but has no way to mention that user back in its reply because the UID is lost. Preserving both UID and display name enables the agent to reference users in responses that Discord can render as proper mentions.
The outbound regex cleanup ensures Discord renders <@UID> as a clickable mention rather than showing the raw <@UID|Name> as literal text.
Description
resolve_mentions()currently replaces<@UID>with@DisplayName, discarding the UID. Change it to emit<@UID|DisplayName>instead, so the LLM sees a human-readable name while the UID is preserved for mention-back in replies.Inbound (Discord → ACP): resolve other-user mentions to
<@UID|DisplayName>:Outbound (ACP → Discord): strip the
|Namesuffix before sending to Discord, since Discord does not support Slack-style<@UID|Name>syntax — it only renders<@UID>:openab/src/discord.rs
Lines 481 to 501 in 6887db6
Investigation: How Other Projects Handle This
We investigated how OpenClaw and Hermes handle Discord mentions:
<@UID>→@DisplayName(UID lost)<@UID>— LLM sees Discord syntax but no human-readable namestripPatterns: ["<@!?\\d+>"]gateway/platforms/discord.pyline ~2992): only strips the bot own mention, leaves other<@UID>raw inmessage.contentpassed to the agent.extensions/discord/src/channel.ts): declaresstripPatterns: () => ["<@!?\\d+>"]which removes all user mentions before the message reaches the LLM. Outbound mentions are reconstructed via a directory lookup (mentions.ts→formatMention()).Neither project preserves both UID and display name for the agent. The
<@UID|DisplayName>format (borrowed from Slack native syntax) gives the LLM human-readable context while keeping the UID available for mention-back.Use Case
When a user mentions another user (e.g.
@AgentDealer) in a message to the bot, the agent receives@AgentDealerbut has no way to mention that user back in its reply because the UID is lost. Preserving both UID and display name enables the agent to reference users in responses that Discord can render as proper mentions.The outbound regex cleanup ensures Discord renders
<@UID>as a clickable mention rather than showing the raw<@UID|Name>as literal text.