← Back to PRs

#22919: WhatsApp: add lifecycle status reactions

by tristanmanchester open 2026-02-21 20:30 View on GitHub →
docs channel: whatsapp-web size: L
## Summary Describe the problem and fix in 2–5 bullets: - Problem: WhatsApp only sent a one-shot ack reaction and did not reflect run lifecycle state. - Why it matters: Users could not see queued/thinking/tool/done/error progression like Telegram/Discord, and broadcast runs could race reaction updates. - What changed: Added lifecycle status reactions for WhatsApp behind `messages.statusReactions.enabled`, reused shared status reaction controller, introduced deterministic single-owner lifecycle updates for broadcast groups, and added dedicated tests/docs/help updates. - What did NOT change (scope boundary): No Slack lifecycle implementation changes, no new config keys, and default behavior remains unchanged unless lifecycle mode is enabled. ## Change Type (select all) - [ ] Bug fix - [x] Feature - [ ] Refactor - [x] Docs - [ ] Security hardening - [ ] Chore/infra ## Scope (select all touched areas) - [x] Gateway / orchestration - [ ] Skills / tool execution - [ ] Auth / tokens - [ ] Memory / storage - [x] Integrations - [x] API / contracts - [ ] UI / DX - [ ] CI/CD / infra ## Linked Issue/PR - Closes: None - Related: #21893 - Related: #6790 - Related: #22190 - Related: #23288 ## User-visible / Behavior Changes - WhatsApp now supports lifecycle auto-updating reactions (`queued -> thinking -> tool -> done/error`) when `messages.statusReactions.enabled=true`. - One-shot ack reaction is skipped in lifecycle mode to avoid duplicate writes. - In broadcast groups, lifecycle reactions are emitted by only the deterministic owner agent (first valid configured broadcast agent). - Final lifecycle reaction is kept on WhatsApp (no post-reply cleanup). ## Security Impact (required) - New permissions/capabilities? (`No`) - Secrets/tokens handling changed? (`No`) - New/changed network calls? (`No`) - Command/tool execution surface changed? (`No`) - Data access scope changed? (`No`) - If any `Yes`, explain risk + mitigation: ## Repro + Verification ### Environment - OS: macOS - Runtime/container: Node 22+, pnpm - Model/provider: N/A - Integration/channel (if any): WhatsApp (web monitor path) - Relevant config (redacted): `channels.whatsapp.ackReaction.*`, `messages.statusReactions.enabled` ### Steps 1. Enable `channels.whatsapp.ackReaction` and set `messages.statusReactions.enabled=true`. 2. Send inbound WhatsApp message and trigger response flow (including reasoning/tool activity). 3. Observe reaction progression and broadcast behavior with multiple agents configured. ### Expected - Lifecycle reaction transitions on a single trigger message; non-owner broadcast agents do not emit lifecycle updates. ### Actual - Matches expected in unit tests and targeted monitor/broadcast test suites. ## Evidence Attach at least one: - [x] Failing test/log before + passing after - [ ] Trace/log snippets - [ ] Screenshot/recording - [ ] Perf numbers (if relevant) ## Human Verification (required) What you personally verified (not just CI), and how: - Verified scenarios: lifecycle queued/thinking/tool/done path, dispatch error path, final delivery error path, silent/no-final terminalization, one-shot ack suppression in lifecycle mode, broadcast owner-only lifecycle updates. - Edge cases checked: missing message id in ack decision resolver; mention bypass via group activation; deterministic owner selection when first configured agent is invalid. - What you did **not** verify: live WhatsApp device run in this PR flow. ## Compatibility / Migration - Backward compatible? (`Yes`) - Config/env changes? (`No`) - Migration needed? (`No`) - If yes, exact upgrade steps: ## Failure Recovery (if this breaks) - How to disable/revert this change quickly: set `messages.statusReactions.enabled=false`. - Files/config to restore: WhatsApp monitor reaction paths under `src/web/auto-reply/monitor/*` and help/docs updates. - Known bad symptoms reviewers should watch for: duplicate initial reactions, non-owner reaction updates in broadcast groups, missing terminal reaction state. ## Risks and Mitigations List only real risks for this PR. Add/remove entries as needed. If none, write `None`. - Risk: Merge conflicts with active WhatsApp monitor PRs touching `process-message.ts` / ack logic. - Mitigation: Isolated ack decision helper, explicit lifecycle gating, and targeted tests around lifecycle and broadcast ownership. <!-- greptile_comment --> <h3>Greptile Summary</h3> Added lifecycle status reactions for WhatsApp that reuse the shared status reaction controller. The implementation introduces deterministic single-owner lifecycle updates for broadcast groups where only the first valid configured broadcast agent emits reactions. - Refactored `maybeSendAckReaction` to extract decision logic into `resolveWhatsAppAckReactionDecision` for reuse - One-shot ack reaction is now skipped when lifecycle mode is enabled to avoid duplicate initial reactions - Broadcast groups pass `lifecycleOwnerAgentId` through the call chain, and non-owner agents suppress all lifecycle reactions - Final lifecycle reaction is kept on WhatsApp (no post-reply cleanup like some other channels) - Tests cover lifecycle progression, error handling, broadcast ownership, and silent terminalization scenarios <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk - The implementation follows established patterns from Telegram/Discord, reuses the shared status reaction controller without modifications, includes comprehensive tests covering edge cases (broadcast ownership, error paths, silent terminalization), and maintains backward compatibility with proper feature gating - No files require special attention <sub>Last reviewed commit: 44f36ac</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs