fix(session): tighten direct-session webchat routing matching#37867
fix(session): tighten direct-session webchat routing matching#37867vincentkoc merged 2 commits intomainfrom
Conversation
Greptile SummaryThis PR hardens the WebChat routing override in Key changes:
Confidence Score: 4/5
Last reviewed commit: 02e7525 |
| it.each([ | ||
| "agent:main:direct:user-1", | ||
| "agent:main:telegram:direct:123456", | ||
| "agent:main:telegram:account-a:direct:123456", | ||
| "agent:main:telegram:dm:123456", | ||
| "agent:main:telegram:direct:123456:thread:99", | ||
| "agent:main:telegram:account-a:direct:123456:topic:ops", | ||
| ])("lets webchat override persisted routes for strict direct key %s", (sessionKey) => { |
There was a problem hiding this comment.
The positive-case matrix includes "agent:main:direct:user-1" (short direct: form without a channel prefix), but doesn't include the analogous short dm: form — e.g. "agent:main:dm:user-1". The implementation at line 66 of session-delivery.ts hits DIRECT_SESSION_MARKERS.has(parts[0]) for both "direct" and "dm", so the short dm form is fully supported; it is just absent from the test matrix.
Given the PR description explicitly states "test coverage includes... legacy :dm: keys", adding this case would make the legacy coverage exhaustive.
| it.each([ | |
| "agent:main:direct:user-1", | |
| "agent:main:telegram:direct:123456", | |
| "agent:main:telegram:account-a:direct:123456", | |
| "agent:main:telegram:dm:123456", | |
| "agent:main:telegram:direct:123456:thread:99", | |
| "agent:main:telegram:account-a:direct:123456:topic:ops", | |
| ])("lets webchat override persisted routes for strict direct key %s", (sessionKey) => { | |
| it.each([ | |
| "agent:main:direct:user-1", | |
| "agent:main:dm:user-1", | |
| "agent:main:telegram:direct:123456", | |
| "agent:main:telegram:account-a:direct:123456", | |
| "agent:main:telegram:dm:123456", | |
| "agent:main:telegram:direct:123456:thread:99", | |
| "agent:main:telegram:account-a:direct:123456:topic:ops", | |
| ])("lets webchat override persisted routes for strict direct key %s", (sessionKey) => { |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/auto-reply/reply/session-delivery.test.ts
Line: 5-12
Comment:
The positive-case matrix includes `"agent:main:direct:user-1"` (short `direct:` form without a channel prefix), but doesn't include the analogous short `dm:` form — e.g. `"agent:main:dm:user-1"`. The implementation at line 66 of `session-delivery.ts` hits `DIRECT_SESSION_MARKERS.has(parts[0])` for both `"direct"` and `"dm"`, so the short `dm` form is fully supported; it is just absent from the test matrix.
Given the PR description explicitly states "test coverage includes... legacy `:dm:` keys", adding this case would make the legacy coverage exhaustive.
```suggestion
it.each([
"agent:main:direct:user-1",
"agent:main:dm:user-1",
"agent:main:telegram:direct:123456",
"agent:main:telegram:account-a:direct:123456",
"agent:main:telegram:dm:123456",
"agent:main:telegram:direct:123456:thread:99",
"agent:main:telegram:account-a:direct:123456:topic:ops",
])("lets webchat override persisted routes for strict direct key %s", (sessionKey) => {
```
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: 02e7525d04
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return false; | ||
| } | ||
| const scoped = parseAgentSessionKey(raw)?.rest ?? raw; | ||
| const parts = scoped.split(":").filter(Boolean); |
There was a problem hiding this comment.
Handle direct-session peer IDs that include colons
The new strict parser assumes : only separates structural tokens, but valid Matrix DM session keys embed MXIDs like @alice:example.org as the peer ID (extensions/matrix/src/matrix/monitor/handler.ts passes senderId into route key generation, and extensions/matrix/src/matrix/monitor/index.ts treats @...:... as a Matrix user ID). With const parts = scoped.split(":"), a key such as agent:main:matrix:direct:@alice:example.org is split so hasStrictDirectSessionTail sees an extra tail token and returns false, meaning resolveLastChannelRaw/resolveLastToRaw stop applying the WebChat direct-session override and can keep stale external routing for legitimate Matrix direct sessions.
Useful? React with 👍 / 👎.
…aw#37867) * fix(session): require strict direct key routing shapes * test(session): cover direct route poisoning cases
…aw#37867) * fix(session): require strict direct key routing shapes * test(session): cover direct route poisoning cases
* main: Mattermost: harden interaction callback binding (openclaw#38057) WhatsApp: honor outbound mediaMaxMb (openclaw#38097) openai-image-gen: validate --background and --style options (openclaw#36762) Docs: align BlueBubbles media cap wording Telegram/Discord: honor outbound mediaMaxMb uploads (openclaw#38065) CI: run changed-scope on main pushes Skills/nano-banana-pro: clarify MEDIA token comment (openclaw#38063) nano-banana-pro: respect explicit --resolution when editing images (openclaw#36880) CI: drop unused install-smoke bootstrap fix(nano-banana-pro): remove space after MEDIA: token in generate_image.py (openclaw#18706) docs: context engine docs(config): list the context engine plugin slot docs(plugins): add context-engine manifest kind example docs(plugins): document context engine slots and registration docs(protocol): document slash-delimited schema lookup plugin ids docs(tools): document slash-delimited config schema lookup paths fix(session): tighten direct-session webchat routing matching (openclaw#37867) feature(context): extend plugin system to support custom context management (openclaw#22201) Gateway: allow slash-delimited schema lookup paths
…aw#37867) * fix(session): require strict direct key routing shapes * test(session): cover direct route poisoning cases
…aw#37867) * fix(session): require strict direct key routing shapes * test(session): cover direct route poisoning cases
…aw#37867) * fix(session): require strict direct key routing shapes * test(session): cover direct route poisoning cases
…aw#37867) * fix(session): require strict direct key routing shapes * test(session): cover direct route poisoning cases
…aw#37867) * fix(session): require strict direct key routing shapes * test(session): cover direct route poisoning cases
Summary
session-delivery.tstreated any session key containing:direct:or:dm:as eligible for WebChat route override, even when the key shape was malformed.lastChannel/lastTorouting state during internal WebChat turns.:dm:keys and direct thread/topic descendants.deriveSessionChatType()remains best-effort for broader classification; this PR only hardens the routing-affecting override path.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
User-visible / Behavior Changes
WebChat route overrides now apply only to canonical direct-session keys instead of any key that happens to contain a
direct/dmtoken.Security Impact (required)
Yes/No) NoYes/No) NoYes/No) NoYes/No) NoYes/No) NoYes, explain risk + mitigation:Repro + Verification
Environment
dmScopecoverage via testsSteps
lastChannel/lastTofor a session.agent:main:cron:job-1:dmoragent:main:main:direct.agent:main:telegram:direct:123456and confirm WebChat still overrides routing.Expected
Actual
Evidence
Human Verification (required)
What you personally verified (not just CI), and how:
:dm:keys, per-account direct keys, direct thread/topic keys, and malformed direct-like keys.main,cron,subagent, missing peer ids, and unsupported suffixes no longer qualify for WebChat override.Compatibility / Migration
Yes/No) YesYes/No) NoYes/No) NoFailure Recovery (if this breaks)
src/auto-reply/reply/session-delivery.tsRisks and Mitigations