← Back to PRs

#21953: feat(whatsapp): sender prefix on BodyForAgent + contactNames config

by mactsk open 2026-02-20 15:24 View on GitHub →
channel: whatsapp-web size: S
## Summary - In direct chats, prefix `BodyForAgent` with the sender name so the LLM sees who is speaking (e.g. `[Alice]: hello` instead of just `hello`) - Add `contactNames` config option (`Record<string, string>`) for overriding WhatsApp push-names with custom display names - Also populate `SenderName` context with the resolved name for consistency ### Name resolution priority 1. `contactNames` config mapping (E.164 → display name) 2. WhatsApp push-name (`senderName` / `pushName`) 3. Normalized phone number 4. `"contact"` fallback ### Why - In DMs, the LLM currently receives raw message text with no sender identity in `BodyForAgent`. The sender info is only in the envelope header (`[WhatsApp +1555...]`) and in `SenderName` context — but `SenderName` is not included in DM system prompt metadata (see `inbound-meta.ts` line 102: `isDirect ? undefined : {...}`) - WhatsApp push-names are user-controlled and can be ambiguous (e.g. two contacts both using "MG"). `contactNames` lets gateway operators map phone numbers to stable display names ### Config example ```json { "channels": { "whatsapp": { "contactNames": { "+15551234567": "Alice Smith", "+15559876543": "Bob Jones" } } } } ``` Per-account override: ```json { "channels": { "whatsapp": { "accounts": { "work": { "contactNames": { "+15551234567": "Alice (Work)" } } } } } } ``` ### What's NOT changed - Group messages (already have sender labels in the envelope body) - `CommandBody` / `RawBody` (unchanged — command parsing unaffected) - Backward compatible: without `contactNames` config, behavior is the same as before except DMs now show pushName prefix ## Test plan - [x] Unit tests for `resolveDmSenderName` (9 cases: group skip, contactNames match, pushName fallback, phone fallback, empty fallback, normalization, senderE164 priority, contactNames precedence, undefined contactNames) - [x] TypeScript type-check passes - [x] All existing web/auto-reply tests pass (222 tests, 31 files) - [ ] CI 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- greptile_comment --> <h3>Greptile Summary</h3> Added `contactNames` configuration to WhatsApp channels for mapping E.164 phone numbers to custom display names. In direct chats, `BodyForAgent` is now prefixed with the sender name (e.g., `[Alice]: hello`), resolving the issue where LLMs couldn't identify who was speaking in DM conversations. - Introduced `contactNames` config at both channel and account levels with account-level taking precedence - Created `resolveDmSenderName` utility with fallback chain: `contactNames` → push-name → phone number → "contact" - Updated `BodyForAgent` to include sender prefix for direct messages only (groups unchanged as they already include sender labels) - Populated `SenderName` context with resolved name for consistency - Comprehensive test coverage (9 test cases) validates name resolution priority and edge cases <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk - Well-designed feature with clear separation of concerns, comprehensive test coverage (9 test cases), backward compatible implementation, and consistent config resolution pattern. The change is isolated to WhatsApp direct messages and preserves existing group chat behavior. - No files require special attention <sub>Last reviewed commit: 8632ba0</sub> <!-- greptile_other_comments_section --> <sub>(4/5) You can add custom instructions or style guidelines for the agent [here](https://app.greptile.com/review/github)!</sub> <!-- /greptile_comment -->

Most Similar PRs