Skip to content

feat: add WhatsApp quote and status primitives#21977

Open
aldoeliacim wants to merge 2 commits into
NousResearch:mainfrom
aldoeliacim:feat/whatsapp-status-reply-primitives
Open

feat: add WhatsApp quote and status primitives#21977
aldoeliacim wants to merge 2 commits into
NousResearch:mainfrom
aldoeliacim:feat/whatsapp-status-reply-primitives

Conversation

@aldoeliacim

@aldoeliacim aldoeliacim commented May 8, 2026

Copy link
Copy Markdown

What does this PR do?

Adds WhatsApp quote/reaction/status primitives that Baileys supports natively but Hermes was paving over with plain-text follow-ups.

  • Adds a bounded WhatsApp bridge WAMessage cache so Baileys can send native quoted replies instead of plain-text follow-ups.
  • Propagates incoming quote metadata (quotedMessageId, quotedText, quotedRemoteJid) into Hermes MessageEvent reply context.
  • Wires media replies through /send-media and adds bridge primitives for message reactions, private status replies, status reactions, and explicit-recipient text status posts.
  • Keeps status ingestion disabled by default; statuses are only admitted when platforms.whatsapp.extra.statuses.enabled: true and ingest: true.
  • Adds whatsapp_action, a WhatsApp-specific messaging tool for owner/user-requested advanced actions: react_message, status_reply, status_react, and post_text_status.
  • Adds Node bridge tests and Python tool/adapter tests.

Design notes

  • The advanced status/reaction primitives live behind bridge/adapter methods and a WhatsApp-specific tool rather than broadening generic send_message; this keeps WhatsApp-specific semantics explicit.
  • whatsapp_action includes dry_run=true so agents can inspect the exact bridge endpoint/payload before performing external side effects.
  • Status posting requires a non-empty explicit status_jid_list; there is intentionally no "all contacts" fallback.
  • Native quotes degrade gracefully: if replyTo is not in the bridge cache, the bridge sends the message without a quote and reports quoted: false.
  • Bridge imports are now side-effect-light so node:test can import helper functions without starting an HTTP server or socket.

Operational follow-up after merge

  • Real-device smoke test for status replies/reactions; Baileys status support is known to be flaky upstream and should be validated against an actual WhatsApp session before enabling any automation.

Related Issue

No related issue — surfaced from production WhatsApp use where plain-text "@reply" fallbacks felt wrong vs the platform's native quote/reaction UX.

Fixes #

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • scripts/whatsapp-bridge/bridge.js — WAMessage cache; new /send-media-reply, /react, /status-reply, /status-react, /post-text-status endpoints; side-effect-light import surface for tests.
  • scripts/whatsapp-bridge/bridge.test.mjs — Node test suite for the new primitives.
  • gateway/platforms/whatsapp.py — quote metadata propagation; adapter methods for reactions/status/replies.
  • tools/whatsapp_action_tool.py — new whatsapp_action tool: react_message, status_reply, status_react, post_text_status, with dry_run.
  • tests/tools/test_whatsapp_action_tool.py, tests/gateway/test_whatsapp_*.py — coverage for tool + adapter wiring.

How to Test

  1. ./venv/bin/python -m pytest tests/tools/test_whatsapp_action_tool.py tests/gateway/test_whatsapp_*.py tests/gateway/test_platform_base.py -q
    — 188 passing on current rebase.
  2. cd scripts/whatsapp-bridge && npm test -- --test-reporter=spec for the Node bridge primitives.
  3. node --check scripts/whatsapp-bridge/bridge.js and ./venv/bin/python -m py_compile tools/whatsapp_action_tool.py gateway/platforms/whatsapp.py for syntax sanity.
  4. Real-device smoke test (post-merge): use the whatsapp_action tool with dry_run=true first to inspect the bridge payload, then run with dry_run=false against a paired WhatsApp session.

Checklist

  • Tests added/updated and passing locally (188 pass)
  • Rebased on origin/main (2026-05-25; one trivial conflict in whatsapp.py was an additive merge — kept upstream's new pre-flight pairing check plus this PR's bridge-found log line)
  • Follows existing code conventions for gateway/platforms/* adapters and tools/* modules
  • Documentation updated where needed (design notes inline + tool docstrings)
  • Conventional commit messages

Notes for reviewers

  • The breaking-change risk is contained to the WhatsApp surface; whatsapp_action is a new tool, whatsapp.py additions are backward compatible (existing callers see the same methods plus new optional ones).
  • Status ingest stays off by default. The opt-in lives behind two flags (enabled + ingest) precisely because Baileys status support is fragile and shouldn't fail-open into surprise behavior.

@aldoeliacim aldoeliacim marked this pull request as ready for review May 8, 2026 17:13
Copilot AI review requested due to automatic review settings May 8, 2026 17:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@alt-glitch alt-glitch added type/feature New feature or request P2 Medium — degraded but workaround exists platform/whatsapp WhatsApp Business adapter comp/gateway Gateway runner, session dispatch, delivery labels May 11, 2026
@aldoeliacim aldoeliacim force-pushed the feat/whatsapp-status-reply-primitives branch from 828e39d to 16cfe6e Compare May 15, 2026 15:09
@aldoeliacim aldoeliacim requested a review from a team May 15, 2026 15:09

@austinpickett austinpickett left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix merge conflicts and use .github/PULL_REQUEST_TEMPLATE.md

@aldoeliacim

Copy link
Copy Markdown
Author

@austinpickett — rebased on current origin/main, body now uses the PR template. Ready for re-review.

@aldoeliacim aldoeliacim requested a review from austinpickett May 25, 2026 09:38
@aldoeliacim aldoeliacim force-pushed the feat/whatsapp-status-reply-primitives branch from 88322e2 to f59a700 Compare May 28, 2026 23:41
@aldoeliacim

Copy link
Copy Markdown
Author

@austinpickett — rebased onto current origin/main (force-push). Now 313 commits forward of the last rebase; clean rebase, no upstream conflicts on either commit.

Same 2-commit scope as before:

  • feat: add WhatsApp quote and status primitives
  • feat: expose WhatsApp action tool

Locally validated on the rebased tip:
tests/gateway/test_whatsapp_formatting.py, tests/gateway/test_whatsapp_group_gating.py, tests/tools/test_whatsapp_action_tool.py — 60 passed, 0 failed. The new bridge.test.mjs is wired into the bridge package and runs clean.

Ready for re-review whenever you have a moment. Happy to address anything else.

@aldoeliacim

Copy link
Copy Markdown
Author

Rebased onto current origin/main (force-push). Same 2-commit scope as
before — brings the branch up to date so it merges cleanly. The only
conflict was in gateway/platforms/whatsapp.py: upstream landed its own
inbound text-batching implementation (_enqueue_text_event /
_flush_text_batch / _pending_text_batches), which this branch's base
predated. Resolved by keeping upstream's batching block verbatim and
layering the quote/status primitives on top — the replyTo quoted-reply
send option, the statuses ingest config gate, and the
reply_to_status / react_to_status / post_text_status methods.

Locally tested: tests/gateway/test_whatsapp_formatting.py,
test_whatsapp_group_gating.py, tests/tools/test_whatsapp_action_tool.py
— 60 passed, 0 failed; scripts/whatsapp-bridge/bridge.test.mjs
(node --test) — 6 passed, 0 failed.

The earlier review feedback (merge-conflict fix + PR template) has been
addressed. Ready for another look whenever you have a moment — happy to
adjust anything.

@aldoeliacim aldoeliacim force-pushed the feat/whatsapp-status-reply-primitives branch 2 times, most recently from 234cc04 to 28a2131 Compare June 2, 2026 15:08
@aldoeliacim

Copy link
Copy Markdown
Author

Rebased onto current origin/main (force-push). Same two-commit scope as before — just brings the branch up to date so it merges cleanly. Clean rebase, no behavioral changes vs the prior tip.

Locally tested: tests/gateway/test_whatsapp_formatting.py, tests/gateway/test_whatsapp_group_gating.py, tests/tools/test_whatsapp_action_tool.py — 60 passed, 0 failed.

@aldoeliacim

Copy link
Copy Markdown
Author

@austinpickett both points from your review should be addressed now:

  1. Merge conflicts — resolved. The branch is freshly rebased onto current origin/main (force-pushed above) and now merges cleanly with zero conflicts. Locally tested: 60 passed across the WhatsApp formatting/gating/action-tool suites.
  2. PR template — the description already follows .github/PULL_REQUEST_TEMPLATE.md (What/Related Issue/Type/Changes Made/How to Test/Checklist sections are all filled in).

Would appreciate a re-review when you have a moment. Thanks!

@aldoeliacim

Copy link
Copy Markdown
Author

Rebased onto current origin/main (force-push). Same two-commit scope as
before — brings the branch up to date so it merges cleanly. No behavioral
changes vs the prior tip. The earlier review feedback (merge-conflict fix +
PR template) remains addressed.

Locally tested:

  • tests/gateway/test_whatsapp_formatting.py,
    tests/gateway/test_whatsapp_group_gating.py,
    tests/tools/test_whatsapp_action_tool.py — 60 passed, 0 failed.
  • scripts/whatsapp-bridge/bridge.test.mjs — 6 passed, 0 failed.

@aldoeliacim aldoeliacim force-pushed the feat/whatsapp-status-reply-primitives branch 2 times, most recently from 50425a9 to 1a4a4aa Compare June 11, 2026 04:04
@aldoeliacim

Copy link
Copy Markdown
Author

Rebased onto current origin/main — conflicts cleared (now MERGEABLE), and the PR body follows .github/PULL_REQUEST_TEMPLATE.md. Targeted Python suite (60 tests across the tool + adapter + formatting/gating) and the Node bridge tests pass on the rebased head. Ready for re-review.

@aldoeliacim

Copy link
Copy Markdown
Author

Rebased onto current origin/main (force-push). Was 13 commits behind.

Same scope as before — no behavioral changes vs the prior tip. Clean
rerere-assisted replay, zero manual conflicts. PR body is already
template-compliant; this just brings the branch up to date so it merges
cleanly.

Locally tested: whatsapp-formatting + whatsapp-group-gating +
whatsapp_action_tool suites (60 Python) and the bridge test suite (6 Node) —
all pass. Ready for re-review.

@aldoeliacim aldoeliacim force-pushed the feat/whatsapp-status-reply-primitives branch from 1a4a4aa to 9255371 Compare June 11, 2026 06:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/whatsapp WhatsApp Business adapter type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants