feat(whatsapp): WhatsApp @mention tagging support - #81208
Open
dhruvkej9 wants to merge 5 commits into
Open
Conversation
…ssion keys SessionStore._generate_session_key and the run.py fallback/write paths read group_sessions_per_user / thread_sessions_per_user only from the global gateway config, while the adapters' text-batching keys resolve per-platform extra.* overrides. This divergence means a WhatsApp group with extra.group_sessions_per_user: false still gets per-user session keys on the main dispatch path, so each member carries a separate context even though batching keys say they share one. Resolve the per-platform extra overrides in the same three places the session key is built so dispatch, fallback, and shared-session attribution never diverge from the adapter's batching key.
The shared-key loop in load_gateway_config() only bridged known top-level keys (dm_policy, group_policy, require_mention, ...) into the platform extra and silently dropped the platform's own nested ``extra:`` dict. So ``whatsapp.extra.group_sessions_per_user: false`` never reached PlatformConfig.extra, and the session-key paths (which honor per-platform extra) fell back to the global default - every group member kept a separate context even though the config asked for a shared group session. Preserve the nested ``extra:`` dict before applying bridged keys so top-level bridged keys keep precedence. Adds a regression test that fails on main (nested extra dropped) and passes with this fix.
Two halves of the same feature: INBOUND — the bridge already extracts contextInfo.mentionedJid into the event's mentionedIds, but the adapter dropped it. Surface it as whatsapp_mentioned_ids in MessageEvent metadata so the agent can see who a group message @mentions. OUTBOUND — the bridge send path had no mention support at all. Add: - buildTextSendPayload accepts mentions and emits content.mentions (Baileys native @tag) - /send accepts a mentions array and forwards it - adapter.send() accepts mentions and passes them through - Auto-tag: when replying to a message in a group, the replied-to author is @mentioned automatically (WhatsApp @ behavior), so the user knows the reply is addressed to them. DM replies (no key.participant) and replies to the bot's own messages are skipped. Tests: bridge.native.test.mjs covers DM/own-message no-mention, explicit mentions, and auto-tag merge. All 17 native + 20 whatsapp pytest pass.
Builds on the mention pass-through with the missing half: the model
could tag a member only if it already knew their JID. Now it doesn't
need to.
- Bridge keeps a pushName cache (jid -> display name) fed from inbound
messages; /chat/:id returns participants as [{id, name}] (name falls
back to the @username handle, then the bare number).
- /send resolves "@name" tokens in the text against the cached group
roster (5-min TTL) into Baileys mentions, so the model can write
"@ankit" and Ankit gets a real tag. Case-insensitive substring match;
unknown names are left as literal text.
- Adapter prepends a compact "[Group members: ...]" line to group
messages (cached 10 min) so the model always knows who is in the
group, and surfaces inbound mentionedIds as whatsapp_mentioned_ids.
- No auto-tag on reply: WhatsApp already notifies the replied-to user,
so tagging stays the model's explicit choice.
Tests: bridge.native.test.mjs covers roster building, @name resolution
(case-insensitive, unknown ignored), and mention pass-through. All 18
native + 20 whatsapp pytest pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
WhatsApp @mention tagging is missing in Hermes, and the model has no idea who is in a group:
contextInfo.mentionedJidinto the event'smentionedIds, but the adapter silently dropped it — the agent never learns who a group message @mentions.Fix
Mention pass-through
buildTextSendPayloadacceptsmentionsand emits Baileys-nativecontent.mentions/sendaccepts amentionsarray and forwards itadapter.send()acceptsmentionsand passes them throughmentionedIdsaswhatsapp_mentioned_idsinMessageEventmetadataGroup roster + @name resolution
pushNamecache (jid → display name) fed from inbound messages;/chat/:idreturns participants as[{id, name}](falls back to the @username handle, then the bare number)/sendresolves@Nametokens in the text against the cached group roster (5-min TTL) into Baileys mentions — the model writes@Ankit, Ankit gets a real tag. Case-insensitive substring match; unknown names stay literal.[Group members: ...]line to group messages (cached 10 min) so the model always knows who is in the groupNo auto-tag on reply — WhatsApp already notifies the replied-to user, so tagging stays the model's explicit choice.
Tests
bridge.native.test.mjs: roster building (pushName → username → number fallback), @name resolution (case-insensitive, unknown ignored), mention pass-through. All 18 native bridge tests + 20 whatsapp pytest pass.