fix(routing): include accountId in group/channel session keys#27750
fix(routing): include accountId in group/channel session keys#27750scz2011 wants to merge 1 commit into
Conversation
Fixes openclaw#27731 When using multiple Discord bot accounts with agent bindings, all messages were routed to the main agent regardless of binding configuration. The root cause was that session keys for group/channel messages did not include the accountId, causing messages from different accounts to the same channel to share the same session key. This led to routing conflicts where whichever agent was last matched would capture all subsequent messages to that channel, regardless of which Discord account received the message. Changes: - Modified buildAgentPeerSessionKey() to include accountId in group/channel session key format - New format: agent:{agentId}:{channel}:{accountId}:{peerKind}:{peerId} - Added tests to verify accountId inclusion and multi-account isolation Impact: - Each Discord account now gets its own session namespace per channel - Agent bindings with accountId matching now work correctly - Messages route to the correct agent based on both channel and account
Greptile SummaryAdds Key changes:
Compatibility:
Confidence Score: 4/5
Last reviewed commit: fa21e62 |
Additional Comments (1)
Prompt To Fix With AIThis is a comment left during a code review.
Path: src/agents/tools/cron-tool.ts
Line: 176-177
Comment:
Update comment to reflect new session key format with `accountId`
```suggestion
// - <channel>:<accountId>:group:<peerId>
// - <channel>:<accountId>:channel:<peerId>
```
How can I resolve this? If you propose a fix, please make it concise. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fa21e6296c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const peerId = ((params.peerId ?? "").trim() || "unknown").toLowerCase(); | ||
| return `agent:${normalizeAgentId(params.agentId)}:${channel}:${peerKind}:${peerId}`; | ||
| const accountId = normalizeAccountId(params.accountId); | ||
| return `agent:${normalizeAgentId(params.agentId)}:${channel}:${accountId}:${peerKind}:${peerId}`; |
There was a problem hiding this comment.
Preserve Discord channel key compatibility
Including accountId in every group/channel key changes the shape to agent:<agent>:<channel>:<accountId>:<kind>:<id>, but Discord exec approvals still extract channel IDs with /discord:(?:channel|group):(\d+)/ (src/discord/monitor/exec-approvals.ts), which no longer matches these new keys. In handleApprovalRequested, channel-targeted approvals then cannot resolve channelId and silently fall back to DM-only behavior or miss channel delivery, so channel approval workflows break for routed sessions created with the new format.
Useful? React with 👍 / 👎.
| const peerId = ((params.peerId ?? "").trim() || "unknown").toLowerCase(); | ||
| return `agent:${normalizeAgentId(params.agentId)}:${channel}:${peerKind}:${peerId}`; | ||
| const accountId = normalizeAccountId(params.accountId); | ||
| return `agent:${normalizeAgentId(params.agentId)}:${channel}:${accountId}:${peerKind}:${peerId}`; |
There was a problem hiding this comment.
Keep send-policy channel matching for new session keys
This new key layout also breaks channel derivation in resolveSendPolicy: deriveChannelFromKey expects stripped keys like <channel>:<group|channel>:... (src/sessions/send-policy.ts), so agent:...:discord:<accountId>:channel:... now yields no channel. Gateway paths such as src/gateway/server-methods/agent.ts call resolveSendPolicy with channel: entry?.channel, and on first-use sessions entry can be absent, causing channel-scoped deny rules to be skipped for these group/channel keys.
Useful? React with 👍 / 👎.
|
The account-scoped session-key change makes sense, but this PR is currently red across node/bun/windows tests with many session-key expectation mismatches. Example from node test log:
I also see related failures in |
…ord exec approvals PR openclaw#27750 changed session key format for group/channel keys to include accountId: - Old: agent:<agentId>:<channel>:<peerKind>:<peerId> - New: agent:<agentId>:<channel>:<accountId>:<peerKind>:<peerId> This broke two critical features: 1. deriveChannelFromKey in send-policy.ts expected parts[1] to be peerKind, but it's now accountId. This caused channel-scoped deny rules to be skipped for group/channel keys, especially on first-use sessions. 2. extractDiscordChannelId regex /discord:(?:channel|group):(\d+)/ no longer matched the new format discord:<accountId>:channel:<id>. This broke channel-targeted approval workflows. Fixes: - Updated deriveChannelFromKey to check both parts[1] and parts[2] for peerKind, supporting both old and new formats - Updated extractDiscordChannelId regex to optionally match accountId segment - Added comprehensive tests for both old and new session key formats
|
This pull request has been automatically marked as stale due to inactivity. |
|
This pull request has been automatically marked as stale due to inactivity. |
|
Closing due to inactivity. |
Fixes #27731
When using multiple Discord bot accounts with agent bindings, all messages were routed to the main agent regardless of binding configuration. The root cause was that session keys for group/channel messages did not include the
accountId, causing messages from different accounts to the same channel to share the same session key.This led to routing conflicts where whichever agent was last matched would capture all subsequent messages to that channel, regardless of which Discord account received the message.
Root Cause
The
buildAgentPeerSessionKey()function insrc/routing/session-key.tswas generating session keys for group/channel messages without including theaccountId:Old format:
agent:{agentId}:{channel}:{peerKind}:{peerId}This meant messages from different Discord accounts (e.g.,
designer,erp) to the same channel would get identical session keys, causing routing conflicts.Changes
buildAgentPeerSessionKey()to includeaccountIdin group/channel session key formatagent:{agentId}:{channel}:{accountId}:{peerKind}:{peerId}Impact
accountIdmatching now work correctlyTesting
All existing tests pass, plus new tests added:
This fix applies to all channels (Discord, Telegram, WhatsApp, etc.) that use group/channel routing with multiple accounts.