← Back to PRs

#13580: fix(telegram): skip updateLastRoute when dmScope isolates DM sessions

by lailoo open 2026-02-10 18:41 View on GitHub →
channel: telegram stale size: S trusted-contributor
## Summary Fixes #13559 ## Problem When `dmScope` is set to `per-channel-peer` (or `per-peer`/`per-account-channel-peer`), Telegram DMs get their own isolated session key (e.g. `agent:main:telegram:direct:12345`). However, `recordInboundSession` still unconditionally calls `updateLastRoute` targeting `route.mainSessionKey` (`agent:main:main`), overwriting the webchat session's `deliveryContext` with Telegram routing info. This causes webchat responses to be routed to Telegram. ## Fix Gate `updateLastRoute` on `baseSessionKey === route.mainSessionKey` — only update the main session's delivery context when the DM session actually IS the main session (i.e. `dmScope: "main"`). **Before:** ```typescript updateLastRoute: !isGroup ? { sessionKey: route.mainSessionKey, ... } : undefined, ``` **After:** ```typescript updateLastRoute: !isGroup && baseSessionKey === route.mainSessionKey ? { sessionKey: route.mainSessionKey, ... } : undefined, ``` ## Reproduction & Verification ### Before fix (main branch) — Bug reproduced with real function calls: ``` Scenario 2: dmScope = 'per-channel-peer' sessionKey: agent:main:telegram:direct:12345 mainSessionKey: agent:main:main same? false updateLastRoute would write to: agent:main:main BUG CONFIRMED: DM has its own session but updateLastRoute still overwrites mainSessionKey's deliveryContext! ``` ### After fix — Verified with real function calls: ``` Test 1: dmScope='main' DM — updateLastRoute fires PASS Test 2: dmScope='per-channel-peer' DM — skipped PASS Test 3: dmScope='per-peer' DM — skipped PASS Test 4: group message — skipped PASS Test 5: dmScope='per-account-channel-peer' DM — skipped PASS --- Result: ALL PASSED (9/9) --- ``` ## Effect on User Experience **Before fix:** With `dmScope: "per-channel-peer"`, every Telegram DM overwrites the webchat session's `deliveryContext`, causing webchat responses and heartbeats to be routed to Telegram instead of back to the browser. **After fix:** Telegram DMs with isolated sessions no longer corrupt the main session. Webchat responses are correctly routed back to the browser. Default behavior (`dmScope: "main"`) is unchanged. ## Testing - 4 tests pass (3 existing + 1 new regression test) - Lint passes <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR prevents Telegram DM traffic from overwriting the main/webchat session’s `deliveryContext` when `session.dmScope` isolates DM sessions. The change gates the `recordInboundSession({ updateLastRoute: ... })` call in `src/telegram/bot-message-context.ts` so `updateLastRoute` only runs when the DM’s `baseSessionKey` equals `route.mainSessionKey` (i.e., `dmScope: "main"`). A regression test was added to cover the isolated-session case, and a changelog entry documents the fix. <h3>Confidence Score: 4/5</h3> - Mostly safe to merge, with one test correctness issue to address. - The production change is small and clearly targeted (gating `updateLastRoute` on main-session equality) and aligns with `recordInboundSession`’s behavior. The main concern is the new regression test: it mocks `loadConfig()` but still passes `cfg: baseConfig` into `buildTelegramMessageContext`, so it may not actually exercise the isolated `dmScope` route depending on how config is consumed. Fixing the test to ensure it truly covers the bug would make this PR low-risk. - src/telegram/bot-message-context.dm-topic-threadid.test.ts <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs