fix(whatsapp): use per-channel-peer dmScope for inbound direct messages#76314
fix(whatsapp): use per-channel-peer dmScope for inbound direct messages#76314chinar-amrutkar wants to merge 3 commits into
Conversation
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Close as superseded: the same WhatsApp direct-message isolation work is now covered by the open account-aware fix at #76730, and that branch addresses the account-id gap in this PR. Canonical path: Close this branch and continue review of the account-aware fix at #76730; close the linked issue only after that fix lands. So I’m closing this here and keeping the remaining discussion on #76730. Review detailsBest possible solution: Close this branch and continue review of the account-aware fix at #76730; close the linked issue only after that fix lands. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection on current main shows WhatsApp direct inbound messages pass a peer to resolveAgentRoute, the resolver falls back to dmScope "main", and direct peer session-key generation returns the agent main key under that scope. Is this the best way to solve the issue? No. This PR uses per-channel-peer, which fixes separate contacts on one WhatsApp account but omits accountId; the account-aware per-account-channel-peer approach in the canonical PR is the safer fix. Security review: Security review needs attention: The branch narrows the existing context leak but leaves an account-crossing WhatsApp DM isolation gap because the chosen scope omits accountId.
What I checked:
Likely related people:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 333f65fc8a12. |
46e453f to
7181de4
Compare
7181de4 to
e736116
Compare
Distinct WhatsApp contacts were colliding on the same :main session key,
causing shared .jsonl files and interleaved model context.
- Added dmScopeOverride to ResolveAgentRouteInput so callers can force a
specific dmScope regardless of the global config setting
- WhatsApp now passes dmScopeOverride: "per-channel-peer" when resolving
inbound routes, producing session keys of the form
agent:{agentId}:whatsapp:direct:{peerId}
- Added regression test verifying distinct peerId values produce distinct
route.sessionKey values
Closes openclaw#76263
e736116 to
b4e160e
Compare
When using per-channel-peer dmScope, updateWhatsAppMainLastRoute now records the last-route against the per-contact sessionKey instead of skipping it. This ensures deliveryContext metadata is persisted for later session deliveries. Added test: "records last-route for per-contact session when using scoped dmScope"
… guard The pin guard (pinnedMainDmRecipient) applies only to main session updates. Per-contact sessions should always record their last-route since they are independent of the main session pin state. Updated test to use pinnedMainDmRecipient that differs from dmRouteTarget to verify the per-contact session is updated even when not the pinned owner.
Summary
Describe the problem and fix in 2–5 bullets:
agent:${agentId}:mainsession key regardless of contact, causing distinct chats to share session/.jsonl files and model context.dmScopeOverridetoResolveAgentRouteInputso callers can force per-chat session scoping; WhatsApp now passesdmScopeOverride: "per-channel-peer"when resolving inbound routes.resolveWhatsAppGroupSessionRoutewith proper group scoping.Change Type
Scope
Linked Issue/PR
Root Cause
resolveAgentRouteusescfg.session?.dmScope ?? "main". With"main", all direct chats collapse toagent:${agentId}:mainregardless of peer. WhatsApp passed a correct peer object but the global dmScope was the bottleneck.dmScope: "per-account-channel-peer"and works correctly. WhatsApp had no analogous override.Regression Test Plan
extensions/whatsapp/src/auto-reply/monitor/on-message.ts— add integration test verifying distinctpeerIdvalues produce distinctroute.sessionKeyvaluessessionKeyvalues differ and contain the peer IDsrc/routing/session-key.tstests fordmScope: "per-channel-peer"exist but no WhatsApp-specific seam testUser-Visible / Behavior Changes
agent:${agentId}:whatsapp:direct:${peerId}instead ofagent:${agentId}:mainmainsession continues independently