#23614: feat(routing): add sessionScope binding override for session key scoping
size: S
## Summary
By default, each group/channel/guild gets its own isolated session. This means the agent has no memory of DM conversations when talking in a group, and vice versa.
The new `overrideDmScope` option on agent bindings allows specific channels to reuse the agent's main session — the same session used for DMs. This is useful for "inner circle" groups where you want the agent to have full context of all prior conversations, behaving as a single continuous session across DMs and selected groups.
## Changes
- **`src/config/types.agents.ts`** — Added optional `overrideDmScope?: DmScope` field to `AgentBinding`
- **`src/routing/session-key.ts`** — `buildAgentPeerSessionKey` now accepts `overrideDmScope`; when set to `"main"`, short-circuits to `buildAgentMainSessionKey`
- **`src/routing/resolve-route.ts`** — `buildAgentSessionKey` and `resolveAgentRoute` extract `overrideDmScope` from the matched binding and pass it through
- **`src/routing/resolve-route.test.ts`** — 6 new tests covering Telegram, Discord, WhatsApp, Slack, default (no override), and non-matching binding
## Example config
```yaml
bindings:
# Shared session with DMs
- agentId: main
match:
channel: telegram
peer:
kind: group
id: "-1003691588332"
overrideDmScope: main # → agent:main:main
# Discord server — shared session
- agentId: main
match:
channel: discord
guildId: "123456789"
overrideDmScope: main
# Normal group — isolated (default behavior)
- agentId: main
match:
channel: telegram
peer:
kind: group
id: "-1009999999999"
# No overrideDmScope → agent:main:telegram:group:-1009999999999
```
## How it works
The `overrideDmScope` field on a binding overrides the default session key derivation for that binding's matched context. It reuses the existing `DmScope` type:
| Value | Session key behavior |
| -------------------------- | ------------------------------------------------------------- |
| `"main"` | Collapses to `agent:<id>:main` — same session as DMs |
| `"per-peer"` | Isolates by peer ID only |
| `"per-channel-peer"` | Isolates by channel + peer ID |
| `"per-account-channel-peer"` | Isolates by account + channel + peer ID |
| *(not set)* | Default behavior — isolated per channel/peer for groups |
## Test plan
- [x] All 40 existing + 6 new routing tests pass
- [x] Verify Telegram group binding with `overrideDmScope: main` shares session with DMs
- [ ] Verify Discord guild binding with `overrideDmScope: main` collapses session key
- [ ] Verify bindings without `overrideDmScope` retain isolated session keys
Most Similar PRs
#7868: Default DM sessions to per-channel scope (avoid webchat contention)
by Smile232323 · 2026-02-03
68.7%
#20078: feat(session): Add channelGroups config(optional config) for shared...
by demarlik01 · 2026-02-18
68.3%
#22486: feat: add /agent command for dynamic per-chat agent switching
by cesarfavero · 2026-02-21
67.3%
#9051: fix(sessions): respect dmScope config in CLI agent commands
by benleavett · 2026-02-04
67.1%
#13580: fix(telegram): skip updateLastRoute when dmScope isolates DM sessions
by lailoo · 2026-02-10
66.0%
#15663: fix(discord): normalize DM session keys for multi-agent setups 🤖
by james-wang-sage · 2026-02-13
64.8%
#14689: onboard: set per-channel DM scope by default for multi-channel setups
by constansino · 2026-02-12
64.6%
#13057: feat(matrix): add sessionScope=room to route sessions by roomId
by spengrah · 2026-02-10
64.3%
#16441: feat: add topicId matching to bindings for Telegram forum topics
by alextnetto · 2026-02-14
63.9%
#8879: fix(sessions-spawn): resolve target agent's bound accountId for sub...
by gianni-dalerta · 2026-02-04
63.9%