diff --git a/CHANGELOG.md b/CHANGELOG.md index 9771d4c8710..31ade777576 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ Docs: https://docs.openclaw.ai - Matrix/crypto persistence: capture and write the IndexedDB snapshot while holding the snapshot file lock so concurrent gateway and CLI persists cannot overwrite newer crypto state. (#59851) Thanks @al3mart. - Telegram/media: keep inbound image attachments readable on upgraded installs where legacy state roots still differ from the managed config-dir media cache. (#59971) Thanks @neeravmakwana. - Telegram/local Bot API: thread `channels.telegram.apiRoot` through buffered reply-media and album downloads so self-hosted Bot API file paths stop falling back to `api.telegram.org` and 404ing. (#59544) Thanks @SARAMALI15792. +- Telegram/replies: preserve explicit topic targets when `replyTo` is present while still inheriting the current topic for same-chat replies without an explicit topic. (#59634) Thanks @dashhuang. ## 2026.4.2 diff --git a/extensions/telegram/src/action-threading.test.ts b/extensions/telegram/src/action-threading.test.ts index 8ced153eb74..2670b6ac11a 100644 --- a/extensions/telegram/src/action-threading.test.ts +++ b/extensions/telegram/src/action-threading.test.ts @@ -17,7 +17,7 @@ describe("resolveTelegramAutoThreadId", () => { it("matches chats across Telegram target formats", () => { expect( resolveTelegramAutoThreadId({ - to: "telegram:group:-100123:topic:77", + to: "telegram:group:-100123", toolContext: createToolContext(), }), ).toBe("thread-1"); @@ -36,4 +36,13 @@ describe("resolveTelegramAutoThreadId", () => { }), ).toBeUndefined(); }); + + it("does not override an explicit target topic", () => { + expect( + resolveTelegramAutoThreadId({ + to: "telegram:group:-100123:topic:77", + toolContext: createToolContext(), + }), + ).toBeUndefined(); + }); }); diff --git a/extensions/telegram/src/action-threading.ts b/extensions/telegram/src/action-threading.ts index 0c878eeab91..4765e16d298 100644 --- a/extensions/telegram/src/action-threading.ts +++ b/extensions/telegram/src/action-threading.ts @@ -9,6 +9,9 @@ export function resolveTelegramAutoThreadId(params: { return undefined; } const parsedTo = parseTelegramTarget(params.to); + if (parsedTo.messageThreadId != null) { + return undefined; + } const parsedChannel = parseTelegramTarget(context.currentChannelId); if (parsedTo.chatId.toLowerCase() !== parsedChannel.chatId.toLowerCase()) { return undefined; diff --git a/extensions/telegram/src/channel.test.ts b/extensions/telegram/src/channel.test.ts index 56fa6949774..7aac2e3ced5 100644 --- a/extensions/telegram/src/channel.test.ts +++ b/extensions/telegram/src/channel.test.ts @@ -268,6 +268,20 @@ describe("telegramPlugin threading", () => { expect(resolved).toBe("533274"); }); + + it("does not override an explicit target topic when replyToId is present", () => { + const resolved = telegramPlugin.threading?.resolveAutoThreadId?.({ + cfg: createCfg(), + to: "telegram:-1001:topic:99", + replyToId: "4103", + toolContext: { + currentChannelId: "telegram:-1001:topic:77", + currentThreadTs: "77", + }, + }); + + expect(resolved).toBeUndefined(); + }); }); describe("telegramPlugin bindings", () => {