From 5ce3eb3ff3e462cf366f12522da10a73faee892a Mon Sep 17 00:00:00 2001 From: Gustavo Madeira Santana Date: Tue, 17 Mar 2026 23:55:05 +0000 Subject: [PATCH] Telegram: dedupe message action discovery state --- extensions/telegram/src/channel-actions.ts | 93 +++++++++++----------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/extensions/telegram/src/channel-actions.ts b/extensions/telegram/src/channel-actions.ts index c81b7e1aec6..5358c1d4dec 100644 --- a/extensions/telegram/src/channel-actions.ts +++ b/extensions/telegram/src/channel-actions.ts @@ -16,6 +16,7 @@ import { import type { ChannelMessageActionAdapter, ChannelMessageActionName, + ChannelMessageToolSchemaContribution, } from "openclaw/plugin-sdk/channel-runtime"; import type { TelegramActionConfig } from "openclaw/plugin-sdk/config-runtime"; import { resolveTelegramPollVisibility } from "openclaw/plugin-sdk/telegram"; @@ -34,6 +35,35 @@ export const telegramMessageActionRuntime = { handleTelegramAction, }; +function resolveTelegramActionDiscovery(cfg: Parameters[0]) { + const accounts = listTokenSourcedAccounts(listEnabledTelegramAccounts(cfg)); + if (accounts.length === 0) { + return null; + } + const unionGate = createUnionActionGate(accounts, (account) => + createTelegramActionGate({ + cfg, + accountId: account.accountId, + }), + ); + const pollEnabled = accounts.some((account) => { + const accountGate = createTelegramActionGate({ + cfg, + accountId: account.accountId, + }); + return resolveTelegramPollActionGateState(accountGate).enabled; + }); + const buttonsEnabled = accounts.some((account) => + isTelegramInlineButtonsEnabled({ cfg, accountId: account.accountId }), + ); + return { + isEnabled: (key: keyof TelegramActionConfig, defaultValue = true) => + unionGate(key, defaultValue), + pollEnabled, + buttonsEnabled, + }; +} + function readTelegramSendParams(params: Record) { const to = readStringParam(params, "to", { required: true }); const mediaUrl = readStringParam(params, "media", { trim: false }); @@ -89,85 +119,56 @@ function readTelegramMessageIdParam(params: Record): number { export const telegramMessageActions: ChannelMessageActionAdapter = { listActions: ({ cfg }) => { - const accounts = listTokenSourcedAccounts(listEnabledTelegramAccounts(cfg)); - if (accounts.length === 0) { + const discovery = resolveTelegramActionDiscovery(cfg); + if (!discovery) { return []; } - // Union of all accounts' action gates (any account enabling an action makes it available) - const gate = createUnionActionGate(accounts, (account) => - createTelegramActionGate({ - cfg, - accountId: account.accountId, - }), - ); - const isEnabled = (key: keyof TelegramActionConfig, defaultValue = true) => - gate(key, defaultValue); const actions = new Set(["send"]); - const pollEnabledForAnyAccount = accounts.some((account) => { - const accountGate = createTelegramActionGate({ - cfg, - accountId: account.accountId, - }); - return resolveTelegramPollActionGateState(accountGate).enabled; - }); - if (pollEnabledForAnyAccount) { + if (discovery.pollEnabled) { actions.add("poll"); } - if (isEnabled("reactions")) { + if (discovery.isEnabled("reactions")) { actions.add("react"); } - if (isEnabled("deleteMessage")) { + if (discovery.isEnabled("deleteMessage")) { actions.add("delete"); } - if (isEnabled("editMessage")) { + if (discovery.isEnabled("editMessage")) { actions.add("edit"); } - if (isEnabled("sticker", false)) { + if (discovery.isEnabled("sticker", false)) { actions.add("sticker"); actions.add("sticker-search"); } - if (isEnabled("createForumTopic")) { + if (discovery.isEnabled("createForumTopic")) { actions.add("topic-create"); } - if (isEnabled("editForumTopic")) { + if (discovery.isEnabled("editForumTopic")) { actions.add("topic-edit"); } return Array.from(actions); }, getCapabilities: ({ cfg }) => { - const accounts = listTokenSourcedAccounts(listEnabledTelegramAccounts(cfg)); - if (accounts.length === 0) { + const discovery = resolveTelegramActionDiscovery(cfg); + if (!discovery) { return []; } - const buttonsEnabled = accounts.some((account) => - isTelegramInlineButtonsEnabled({ cfg, accountId: account.accountId }), - ); - return buttonsEnabled ? (["interactive", "buttons"] as const) : []; + return discovery.buttonsEnabled ? (["interactive", "buttons"] as const) : []; }, getToolSchema: ({ cfg }) => { - const accounts = listTokenSourcedAccounts(listEnabledTelegramAccounts(cfg)); - if (accounts.length === 0) { + const discovery = resolveTelegramActionDiscovery(cfg); + if (!discovery) { return null; } - const buttonsEnabled = accounts.some((account) => - isTelegramInlineButtonsEnabled({ cfg, accountId: account.accountId }), - ); - const pollEnabledForAnyAccount = accounts.some((account) => { - const accountGate = createTelegramActionGate({ - cfg, - accountId: account.accountId, - }); - return resolveTelegramPollActionGateState(accountGate).enabled; - }); - const entries = []; - if (buttonsEnabled) { + const entries: ChannelMessageToolSchemaContribution[] = []; + if (discovery.buttonsEnabled) { entries.push({ properties: { buttons: createMessageToolButtonsSchema(), }, }); } - if (pollEnabledForAnyAccount) { + if (discovery.pollEnabled) { entries.push({ properties: createTelegramPollExtraToolSchemas(), visibility: "all-configured" as const,