From 8eeb049683fb2639d0485129b2c6de7fca3d0f37 Mon Sep 17 00:00:00 2001 From: Evgeny Zislis Date: Wed, 4 Mar 2026 02:21:37 +0200 Subject: [PATCH] fix(telegram): address PR review comments - Export pickFirstExistingAgentId and use it to validate topic agentId - Properly update mainSessionKey when overriding route agent - Fix docs example showing incorrect session key for topic 3 Fixes issue where non-existent agentId would create orphaned sessions. Fixes issue where DM topic replies would route to wrong agent. --- docs/channels/telegram.md | 2 +- src/routing/resolve-route.ts | 2 +- src/telegram/bot-message-context.ts | 17 ++++++++++++++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/docs/channels/telegram.md b/docs/channels/telegram.md index 912d8e77540..c70c89ff2fb 100644 --- a/docs/channels/telegram.md +++ b/docs/channels/telegram.md @@ -466,7 +466,7 @@ curl "https://api.telegram.org/bot/getUpdates" } ``` - Each topic then has its own session key: `agent:main:telegram:group:-1001234567890:topic:3` + Each topic then has its own session key: `agent:zu:telegram:group:-1001234567890:topic:3` Template context includes: diff --git a/src/routing/resolve-route.ts b/src/routing/resolve-route.ts index ef8d11209e6..b2310e20ae8 100644 --- a/src/routing/resolve-route.ts +++ b/src/routing/resolve-route.ts @@ -143,7 +143,7 @@ function resolveAgentLookupCache(cfg: OpenClawConfig): AgentLookupCache { return next; } -function pickFirstExistingAgentId(cfg: OpenClawConfig, agentId: string): string { +export function pickFirstExistingAgentId(cfg: OpenClawConfig, agentId: string): string { const lookup = resolveAgentLookupCache(cfg); const trimmed = (agentId ?? "").trim(); if (!trimmed) { diff --git a/src/telegram/bot-message-context.ts b/src/telegram/bot-message-context.ts index f5a2b858205..3e5d25002de 100644 --- a/src/telegram/bot-message-context.ts +++ b/src/telegram/bot-message-context.ts @@ -40,10 +40,15 @@ import { logVerbose, shouldLogVerbose } from "../globals.js"; import { recordChannelActivity } from "../infra/channel-activity.js"; import { buildAgentSessionKey, + pickFirstExistingAgentId, resolveAgentRoute, type ResolvedAgentRoute, } from "../routing/resolve-route.js"; -import { DEFAULT_ACCOUNT_ID, resolveThreadSessionKeys } from "../routing/session-key.js"; +import { + DEFAULT_ACCOUNT_ID, + buildAgentMainSessionKey, + resolveThreadSessionKeys, +} from "../routing/session-key.js"; import { resolvePinnedMainDmOwnerFromAllowlist } from "../security/dm-policy-shared.js"; import { withTelegramApiErrorLogging } from "./api-logging.js"; import { @@ -215,8 +220,10 @@ export const buildTelegramMessageContext = async ({ parentPeer, }); // Per-topic agentId override: re-derive session key under the topic's agent. - const topicAgentId = topicConfig?.agentId?.trim(); - if (topicAgentId) { + const rawTopicAgentId = topicConfig?.agentId?.trim(); + if (rawTopicAgentId) { + // Validate agentId against configured agents; falls back to default if not found. + const topicAgentId = pickFirstExistingAgentId(freshCfg, rawTopicAgentId); const overrideSessionKey = buildAgentSessionKey({ agentId: topicAgentId, channel: "telegram", @@ -225,10 +232,14 @@ export const buildTelegramMessageContext = async ({ dmScope: freshCfg.session?.dmScope, identityLinks: freshCfg.session?.identityLinks, }).toLowerCase(); + const overrideMainSessionKey = buildAgentMainSessionKey({ + agentId: topicAgentId, + }).toLowerCase(); route = { ...route, agentId: topicAgentId, sessionKey: overrideSessionKey, + mainSessionKey: overrideMainSessionKey, }; logVerbose( `telegram: per-topic agent override: topic=${resolvedThreadId ?? dmThreadId} agent=${topicAgentId} sessionKey=${overrideSessionKey}`,