Skip to content

fix(whatsapp): pass Baileys quoted reply text to the agent - #53228

Closed
herbalizer404 wants to merge 1 commit into
NousResearch:mainfrom
herbalizer404:fix/whatsapp-baileys-quoted-replies
Closed

fix(whatsapp): pass Baileys quoted reply text to the agent#53228
herbalizer404 wants to merge 1 commit into
NousResearch:mainfrom
herbalizer404:fix/whatsapp-baileys-quoted-replies

Conversation

@herbalizer404

Copy link
Copy Markdown
Contributor

Problem

The Baileys WhatsApp bridge already forwards reply metadata such as quotedMessageId, quotedParticipant, and hasQuotedMessage, and the Python adapter has logic that looks for a quotedText field.

However, scripts/whatsapp-bridge/bridge.js never populated quotedText from Baileys' contextInfo.quotedMessage. As a result, replies such as "approve", "ok", or "what about this?" reached the agent without the actual text of the quoted WhatsApp message. The model could see that the incoming message was a reply, but not what it was replying to.

This is the same user-visible class of issue addressed for WhatsApp Cloud in #52957, but on the Baileys/Web bridge path.

Root cause

Baileys exposes the quoted payload under contextInfo.quotedMessage, but the bridge event only serialized:

  • quotedMessageId
  • quotedParticipant
  • quotedRemoteJid
  • hasQuotedMessage

The downstream adapter therefore had no text to pass into the platform-neutral reply context fields.

Fix

This PR updates the Baileys bridge and adapter path to preserve quoted reply text using the existing MessageEvent reply-context mechanism:

  • scripts/whatsapp-bridge/bridge.js

    • adds extractTextFromMessageContent(...) for quoted Baileys payloads
    • extracts text/captions from common quoted message shapes: conversation, extended text, image/video/document captions, and button/list replies
    • includes quotedText in the bridge event
  • plugins/platforms/whatsapp/adapter.py

    • stops splicing [Replying to: ...] directly into body
    • populates MessageEvent.reply_to_message_id
    • populates MessageEvent.reply_to_text
    • populates MessageEvent.reply_to_is_own_message

This leaves gateway/run.py responsible for the standard reply-context injection path, which keeps the behavior aligned with other platform adapters and avoids duplicating reply-context formatting inside the WhatsApp adapter.

Tests

Added/extended coverage in tests/gateway/test_whatsapp_formatting.py for:

  • preserving quoted text in reply_to_text
  • preserving the quoted message id in reply_to_message_id
  • preserving the user's actual message body without mutating it
  • marking replies to the bot's own messages via reply_to_is_own_message
  • preserving only the quoted id when Baileys does not provide quoted text

Validation run on a clean worktree rebased on current origin/main:

PYTHONPATH=. /home/hermes/.hermes/hermes-agent/venv/bin/python -m pytest tests/gateway/test_whatsapp_formatting.py tests/gateway/test_whatsapp_group_gating.py -q

Result:

54 passed, 2 warnings in 5.14s

Additional checks:

node --check scripts/whatsapp-bridge/bridge.js
git diff --check origin/main..HEAD

Both passed.

Notes / limitations

If Baileys does not include contextInfo.quotedMessage for older messages or unsupported message types, Hermes will still preserve the quoted message id, but reply_to_text will remain unset. The extractor covers the common text/caption/button/list reply shapes and can be extended for additional WhatsApp message types later.

@alt-glitch alt-glitch added type/bug Something isn't working comp/plugins Plugin system and bundled plugins platform/whatsapp WhatsApp Business adapter P3 Low — cosmetic, nice to have labels Jun 26, 2026
@teknium1

teknium1 commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

This fix landed on main via PR #58865 (salvage of #58704), which made the same change — quoted-reply context moved from a pre-rendered [Replying to: ...] splice into structured reply_to_message_id / reply_to_text / reply_to_is_own_message fields so gateway/run.py's single injection path owns the rendering.

Your PR was submitted first and correctly diagnosed both the duplication and the reply_to_is_own_message bypass — crediting you here alongside @devatnull, whose broader WhatsApp-native PR carried the equivalent fix in the salvage. Sorry we couldn't land yours directly; the overlapping change had already been cherry-picked when the cluster was processed. Thanks for the clean diagnosis and fix!

@teknium1 teknium1 closed this Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have platform/whatsapp WhatsApp Business adapter type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants