@spinabot/brigade 1.0.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/convex/channels.d.ts +5 -5
  2. package/convex/schema.d.ts +2 -2
  3. package/dist/agents/agent-loop.d.ts.map +1 -1
  4. package/dist/agents/agent-loop.js +27 -4
  5. package/dist/agents/agent-loop.js.map +1 -1
  6. package/dist/agents/channels/approval-callback-codec.d.ts +107 -0
  7. package/dist/agents/channels/approval-callback-codec.d.ts.map +1 -0
  8. package/dist/agents/channels/approval-callback-codec.js +173 -0
  9. package/dist/agents/channels/approval-callback-codec.js.map +1 -0
  10. package/dist/agents/channels/approval-router.d.ts +77 -20
  11. package/dist/agents/channels/approval-router.d.ts.map +1 -1
  12. package/dist/agents/channels/approval-router.js +163 -37
  13. package/dist/agents/channels/approval-router.js.map +1 -1
  14. package/dist/agents/channels/backoff.d.ts +55 -0
  15. package/dist/agents/channels/backoff.d.ts.map +1 -0
  16. package/dist/agents/channels/backoff.js +47 -0
  17. package/dist/agents/channels/backoff.js.map +1 -0
  18. package/dist/agents/channels/channel-secrets.d.ts +45 -0
  19. package/dist/agents/channels/channel-secrets.d.ts.map +1 -0
  20. package/dist/agents/channels/channel-secrets.js +69 -0
  21. package/dist/agents/channels/channel-secrets.js.map +1 -0
  22. package/dist/agents/channels/inbound-pipeline.d.ts.map +1 -1
  23. package/dist/agents/channels/inbound-pipeline.js +67 -3
  24. package/dist/agents/channels/inbound-pipeline.js.map +1 -1
  25. package/dist/agents/channels/last-sent-message.d.ts +46 -0
  26. package/dist/agents/channels/last-sent-message.d.ts.map +1 -0
  27. package/dist/agents/channels/last-sent-message.js +55 -0
  28. package/dist/agents/channels/last-sent-message.js.map +1 -0
  29. package/dist/agents/channels/manager.d.ts +52 -0
  30. package/dist/agents/channels/manager.d.ts.map +1 -1
  31. package/dist/agents/channels/manager.js +141 -31
  32. package/dist/agents/channels/manager.js.map +1 -1
  33. package/dist/agents/channels/plugin-channel-manager-facade.d.ts +13 -2
  34. package/dist/agents/channels/plugin-channel-manager-facade.d.ts.map +1 -1
  35. package/dist/agents/channels/plugin-channel-manager-facade.js +21 -0
  36. package/dist/agents/channels/plugin-channel-manager-facade.js.map +1 -1
  37. package/dist/agents/channels/sdk.d.ts +426 -0
  38. package/dist/agents/channels/sdk.d.ts.map +1 -0
  39. package/dist/agents/channels/sdk.js +274 -0
  40. package/dist/agents/channels/sdk.js.map +1 -0
  41. package/dist/agents/channels/telegram/account-config.d.ts +92 -0
  42. package/dist/agents/channels/telegram/account-config.d.ts.map +1 -0
  43. package/dist/agents/channels/telegram/account-config.js +192 -0
  44. package/dist/agents/channels/telegram/account-config.js.map +1 -0
  45. package/dist/agents/channels/telegram/adapter.d.ts +79 -0
  46. package/dist/agents/channels/telegram/adapter.d.ts.map +1 -0
  47. package/dist/agents/channels/telegram/adapter.js +475 -0
  48. package/dist/agents/channels/telegram/adapter.js.map +1 -0
  49. package/dist/agents/channels/telegram/allowed-updates.d.ts +44 -0
  50. package/dist/agents/channels/telegram/allowed-updates.d.ts.map +1 -0
  51. package/dist/agents/channels/telegram/allowed-updates.js +52 -0
  52. package/dist/agents/channels/telegram/allowed-updates.js.map +1 -0
  53. package/dist/agents/channels/telegram/approval-authorize.d.ts +41 -0
  54. package/dist/agents/channels/telegram/approval-authorize.d.ts.map +1 -0
  55. package/dist/agents/channels/telegram/approval-authorize.js +69 -0
  56. package/dist/agents/channels/telegram/approval-authorize.js.map +1 -0
  57. package/dist/agents/channels/telegram/approval-native.d.ts +68 -0
  58. package/dist/agents/channels/telegram/approval-native.d.ts.map +1 -0
  59. package/dist/agents/channels/telegram/approval-native.js +94 -0
  60. package/dist/agents/channels/telegram/approval-native.js.map +1 -0
  61. package/dist/agents/channels/telegram/command-menu.d.ts +35 -0
  62. package/dist/agents/channels/telegram/command-menu.d.ts.map +1 -0
  63. package/dist/agents/channels/telegram/command-menu.js +59 -0
  64. package/dist/agents/channels/telegram/command-menu.js.map +1 -0
  65. package/dist/agents/channels/telegram/connection.d.ts +359 -0
  66. package/dist/agents/channels/telegram/connection.d.ts.map +1 -0
  67. package/dist/agents/channels/telegram/connection.js +865 -0
  68. package/dist/agents/channels/telegram/connection.js.map +1 -0
  69. package/dist/agents/channels/telegram/format.d.ts +48 -0
  70. package/dist/agents/channels/telegram/format.d.ts.map +1 -0
  71. package/dist/agents/channels/telegram/format.js +256 -0
  72. package/dist/agents/channels/telegram/format.js.map +1 -0
  73. package/dist/agents/channels/telegram/inbound-extras.d.ts +73 -0
  74. package/dist/agents/channels/telegram/inbound-extras.d.ts.map +1 -0
  75. package/dist/agents/channels/telegram/inbound-extras.js +231 -0
  76. package/dist/agents/channels/telegram/inbound-extras.js.map +1 -0
  77. package/dist/agents/channels/telegram/index.d.ts +14 -0
  78. package/dist/agents/channels/telegram/index.d.ts.map +1 -0
  79. package/dist/agents/channels/telegram/index.js +14 -0
  80. package/dist/agents/channels/telegram/index.js.map +1 -0
  81. package/dist/agents/channels/telegram/media.d.ts +68 -0
  82. package/dist/agents/channels/telegram/media.d.ts.map +1 -0
  83. package/dist/agents/channels/telegram/media.js +143 -0
  84. package/dist/agents/channels/telegram/media.js.map +1 -0
  85. package/dist/agents/channels/telegram/module.d.ts +15 -0
  86. package/dist/agents/channels/telegram/module.d.ts.map +1 -0
  87. package/dist/agents/channels/telegram/module.js +36 -0
  88. package/dist/agents/channels/telegram/module.js.map +1 -0
  89. package/dist/agents/channels/telegram/plugin.d.ts +76 -0
  90. package/dist/agents/channels/telegram/plugin.d.ts.map +1 -0
  91. package/dist/agents/channels/telegram/plugin.js +314 -0
  92. package/dist/agents/channels/telegram/plugin.js.map +1 -0
  93. package/dist/agents/channels/telegram/probe.d.ts +54 -0
  94. package/dist/agents/channels/telegram/probe.d.ts.map +1 -0
  95. package/dist/agents/channels/telegram/probe.js +95 -0
  96. package/dist/agents/channels/telegram/probe.js.map +1 -0
  97. package/dist/agents/channels/telegram/webhook.d.ts +55 -0
  98. package/dist/agents/channels/telegram/webhook.d.ts.map +1 -0
  99. package/dist/agents/channels/telegram/webhook.js +141 -0
  100. package/dist/agents/channels/telegram/webhook.js.map +1 -0
  101. package/dist/agents/extensions/modules/index.d.ts.map +1 -1
  102. package/dist/agents/extensions/modules/index.js +4 -0
  103. package/dist/agents/extensions/modules/index.js.map +1 -1
  104. package/dist/agents/extensions/types.d.ts +72 -2
  105. package/dist/agents/extensions/types.d.ts.map +1 -1
  106. package/dist/agents/extensions/types.js.map +1 -1
  107. package/dist/agents/tools/connect-channel-tool.d.ts +86 -0
  108. package/dist/agents/tools/connect-channel-tool.d.ts.map +1 -0
  109. package/dist/agents/tools/connect-channel-tool.js +398 -0
  110. package/dist/agents/tools/connect-channel-tool.js.map +1 -0
  111. package/dist/agents/tools/message-action-tool.d.ts +67 -0
  112. package/dist/agents/tools/message-action-tool.d.ts.map +1 -0
  113. package/dist/agents/tools/message-action-tool.js +216 -0
  114. package/dist/agents/tools/message-action-tool.js.map +1 -0
  115. package/dist/agents/tools/registry.d.ts.map +1 -1
  116. package/dist/agents/tools/registry.js +19 -0
  117. package/dist/agents/tools/registry.js.map +1 -1
  118. package/dist/buildstamp.json +1 -1
  119. package/dist/cli/commands/channels.d.ts.map +1 -1
  120. package/dist/cli/commands/channels.js +27 -2
  121. package/dist/cli/commands/channels.js.map +1 -1
  122. package/dist/cli/commands/convex-cmd.d.ts +27 -0
  123. package/dist/cli/commands/convex-cmd.d.ts.map +1 -0
  124. package/dist/cli/commands/convex-cmd.js +162 -0
  125. package/dist/cli/commands/convex-cmd.js.map +1 -0
  126. package/dist/cli/program/build-program.d.ts.map +1 -1
  127. package/dist/cli/program/build-program.js +64 -0
  128. package/dist/cli/program/build-program.js.map +1 -1
  129. package/dist/config/paths.d.ts +3 -0
  130. package/dist/config/paths.d.ts.map +1 -1
  131. package/dist/config/paths.js +39 -0
  132. package/dist/config/paths.js.map +1 -1
  133. package/dist/core/server.d.ts.map +1 -1
  134. package/dist/core/server.js +77 -27
  135. package/dist/core/server.js.map +1 -1
  136. package/dist/cron/service/state.d.ts +10 -0
  137. package/dist/cron/service/state.d.ts.map +1 -1
  138. package/dist/cron/service/state.js.map +1 -1
  139. package/dist/cron/service/timer.d.ts.map +1 -1
  140. package/dist/cron/service/timer.js +43 -14
  141. package/dist/cron/service/timer.js.map +1 -1
  142. package/dist/cron/session-reaper.d.ts +27 -0
  143. package/dist/cron/session-reaper.d.ts.map +1 -1
  144. package/dist/cron/session-reaper.js +81 -0
  145. package/dist/cron/session-reaper.js.map +1 -1
  146. package/dist/system-prompt/assembler.d.ts +14 -0
  147. package/dist/system-prompt/assembler.d.ts.map +1 -1
  148. package/dist/system-prompt/assembler.js +36 -14
  149. package/dist/system-prompt/assembler.js.map +1 -1
  150. package/package.json +16 -3
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Telegram `ChannelPlugin` — the multi-account contract surface.
3
+ *
4
+ * Mirrors `whatsapp/plugin.ts`: wraps `createTelegramAdapter()` (the
5
+ * per-connection implementation) with the lifecycle adapters the
6
+ * `ChannelPluginManager` consumes, so an operator can run MORE THAN ONE
7
+ * Telegram bot at once via:
8
+ *
9
+ * channels.telegram = {
10
+ * enabled: true,
11
+ * accounts: [
12
+ * { id: "main", botToken: "111:AAA" },
13
+ * { id: "ops", botToken: "222:BBB" },
14
+ * ],
15
+ * }
16
+ *
17
+ * - `config.listAccountIds` / `resolveAccount` → multi-account discovery
18
+ * - `gateway.startAccount` / `stopAccount` → per-account bot lifecycle
19
+ * - `outbound.sendText` / `sendMedia` → routes by `target.accountId`
20
+ * - per-account approval-dispatcher registration → an exec-gate prompt raised
21
+ * by a turn on (telegram, ops) replies on (telegram, ops), not the default
22
+ *
23
+ * Per-account state lives in a `Map<accountId, AccountRuntime>` held in this
24
+ * closure — one bot per account, partitioned token resolution per
25
+ * `channels.telegram.accounts[].botToken`. Inbound dispatch reuses the shared
26
+ * `runChannelInboundPipeline` so the multi-account path carries the identical
27
+ * ACL + debounce + abort + approval-reply + approval-callback surface as the
28
+ * legacy single-adapter manager.
29
+ *
30
+ * The legacy single-account `createTelegramAdapter` (started by the legacy
31
+ * `startChannels` manager) STEPS ASIDE when >1 account is configured — its
32
+ * `isConfigured` returns false for the default account in that case (mirrors
33
+ * WhatsApp), so the two paths never double-start a bot.
34
+ */
35
+ import type { BrigadeConfig } from "../../../config/types.js";
36
+ import { type ChannelAdapter, type ChannelOutboundTarget, type ChannelPlugin, type StartChannelsArgs } from "../sdk.js";
37
+ import { type ResolvedTelegramAccount } from "./account-config.js";
38
+ import { type TelegramProbeResult } from "./probe.js";
39
+ /** Dependencies the gateway hands the plugin to drive turns + replies. */
40
+ export interface TelegramPluginDeps {
41
+ /** Boot-time default agent for routing fallbacks. */
42
+ defaultAgentId: string;
43
+ /** Active gateway config — re-read fresh per inbound for live policy. */
44
+ loadConfig: () => BrigadeConfig;
45
+ /** Run one agent turn (the gateway's serialised turn executor). */
46
+ runTurn: StartChannelsArgs["runTurn"];
47
+ /**
48
+ * Optional adapter factory — tests inject a fake; production uses
49
+ * `createTelegramAdapter`. Receives the per-account scope + the resolved
50
+ * command menu + auto-label flag the plugin threads in.
51
+ */
52
+ adapterFactory?: (args: {
53
+ accountId: string;
54
+ commandMenu: Array<{
55
+ command: string;
56
+ description: string;
57
+ }>;
58
+ autoLabelTopics: boolean;
59
+ }) => ChannelAdapter;
60
+ }
61
+ /** Operator-grade view of a per-account bot — exposed via attached helpers. */
62
+ export interface TelegramPluginRuntimeView {
63
+ /** Currently-running account ids. */
64
+ startedAccountIds(): string[];
65
+ /** Look up the per-account adapter (or undefined when the account isn't started). */
66
+ getAdapter(accountId: string): ChannelAdapter | undefined;
67
+ /** Run a `getMe` probe for an account (for status / doctor). */
68
+ probeAccount(accountId: string, cfg: BrigadeConfig): Promise<TelegramProbeResult>;
69
+ }
70
+ /** Plugin handle with the extra per-account introspection surface attached. */
71
+ export type TelegramPluginHandle = ChannelPlugin<ResolvedTelegramAccount> & TelegramPluginRuntimeView;
72
+ /** Construct the plugin instance, capturing per-account runtime state in closure. */
73
+ export declare function createTelegramPlugin(deps: TelegramPluginDeps): TelegramPluginHandle;
74
+ /** Outbound dispatch helper for callers reaching the plugin directly. */
75
+ export type TelegramOutboundTarget = ChannelOutboundTarget;
76
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../../src/agents/channels/telegram/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAO9D,OAAO,EAON,KAAK,cAAc,EAQnB,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAKlB,KAAK,iBAAiB,EACtB,MAAM,WAAW,CAAC;AACnB,OAAO,EAON,KAAK,uBAAuB,EAC5B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAiB,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAsBrE,0EAA0E;AAC1E,MAAM,WAAW,kBAAkB;IAClC,qDAAqD;IACrD,cAAc,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,UAAU,EAAE,MAAM,aAAa,CAAC;IAChC,mEAAmE;IACnE,OAAO,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACtC;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE;QACvB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,KAAK,CAAC;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC7D,eAAe,EAAE,OAAO,CAAC;KACzB,KAAK,cAAc,CAAC;CACrB;AAED,+EAA+E;AAC/E,MAAM,WAAW,yBAAyB;IACzC,qCAAqC;IACrC,iBAAiB,IAAI,MAAM,EAAE,CAAC;IAC9B,qFAAqF;IACrF,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC;IAC1D,gEAAgE;IAChE,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;CAClF;AAED,+EAA+E;AAC/E,MAAM,MAAM,oBAAoB,GAAG,aAAa,CAAC,uBAAuB,CAAC,GAAG,yBAAyB,CAAC;AAqBtG,qFAAqF;AACrF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,kBAAkB,GAAG,oBAAoB,CAmOnF;AAeD,yEAAyE;AACzE,MAAM,MAAM,sBAAsB,GAAG,qBAAqB,CAAC"}
@@ -0,0 +1,314 @@
1
+ /**
2
+ * Telegram `ChannelPlugin` — the multi-account contract surface.
3
+ *
4
+ * Mirrors `whatsapp/plugin.ts`: wraps `createTelegramAdapter()` (the
5
+ * per-connection implementation) with the lifecycle adapters the
6
+ * `ChannelPluginManager` consumes, so an operator can run MORE THAN ONE
7
+ * Telegram bot at once via:
8
+ *
9
+ * channels.telegram = {
10
+ * enabled: true,
11
+ * accounts: [
12
+ * { id: "main", botToken: "111:AAA" },
13
+ * { id: "ops", botToken: "222:BBB" },
14
+ * ],
15
+ * }
16
+ *
17
+ * - `config.listAccountIds` / `resolveAccount` → multi-account discovery
18
+ * - `gateway.startAccount` / `stopAccount` → per-account bot lifecycle
19
+ * - `outbound.sendText` / `sendMedia` → routes by `target.accountId`
20
+ * - per-account approval-dispatcher registration → an exec-gate prompt raised
21
+ * by a turn on (telegram, ops) replies on (telegram, ops), not the default
22
+ *
23
+ * Per-account state lives in a `Map<accountId, AccountRuntime>` held in this
24
+ * closure — one bot per account, partitioned token resolution per
25
+ * `channels.telegram.accounts[].botToken`. Inbound dispatch reuses the shared
26
+ * `runChannelInboundPipeline` so the multi-account path carries the identical
27
+ * ACL + debounce + abort + approval-reply + approval-callback surface as the
28
+ * legacy single-adapter manager.
29
+ *
30
+ * The legacy single-account `createTelegramAdapter` (started by the legacy
31
+ * `startChannels` manager) STEPS ASIDE when >1 account is configured — its
32
+ * `isConfigured` returns false for the default account in that case (mirrors
33
+ * WhatsApp), so the two paths never double-start a bot.
34
+ */
35
+ // Channel SDK barrel — the SINGLE import surface for the multi-account
36
+ // `ChannelPlugin` contract + every sub-adapter type + the shared inbound
37
+ // pipeline + the approval router + the gateway boot args. A multi-account
38
+ // channel authors entirely from here; nothing reaches past `../sdk.js` into
39
+ // `../types.*`, `../inbound-pipeline`, `../approval-router`, `../manager`, or
40
+ // `../../extensions/`.
41
+ import { buildBundledCommands, createInboundPipelineContext, createSubsystemLogger, registerChannelApprovalDispatcher, removeChannelApprovalDispatcher, runChannelInboundPipeline, } from "../sdk.js";
42
+ import { listTelegramAccountIds, resolveTelegramAccount, resolveTelegramBotToken, telegramAutoLabelTopics, TELEGRAM_CHANNEL_ID, TELEGRAM_DEFAULT_ACCOUNT_ID, } from "./account-config.js";
43
+ import { createTelegramAdapter, TELEGRAM_CAPABILITIES } from "./adapter.js";
44
+ import { buildTelegramCommandMenu } from "./command-menu.js";
45
+ import { probeTelegram } from "./probe.js";
46
+ const log = createSubsystemLogger("channels/telegram/plugin");
47
+ const TELEGRAM_META = {
48
+ id: TELEGRAM_CHANNEL_ID,
49
+ label: "Telegram",
50
+ selectionLabel: "Telegram",
51
+ docsPath: "channels/telegram",
52
+ blurb: "Paste a @BotFather token, DM/group chat over a Telegram bot.",
53
+ order: 20,
54
+ exposure: "public",
55
+ markdownCapable: true,
56
+ };
57
+ /** Build the per-account approval capability — the native button prompt + approver gate. */
58
+ function buildApprovalCapability(adapter, accountId) {
59
+ return {
60
+ async sendApprovalPrompt(params) {
61
+ // Delegate to the adapter's own native prompt (inline buttons). The
62
+ // adapter throws when the approval id can't fit the button budget, so
63
+ // the router falls back to its text prompt — mirror that here.
64
+ const cap = adapter.approvalCapability?.sendApprovalPrompt;
65
+ if (!cap)
66
+ throw new Error("telegram adapter has no approval prompt");
67
+ await cap({ ...params, accountId });
68
+ },
69
+ authorizeApprover(p) {
70
+ const cap = adapter.approvalCapability?.authorizeApprover;
71
+ if (!cap)
72
+ return { authorized: true };
73
+ return cap(p);
74
+ },
75
+ };
76
+ }
77
+ /** Construct the plugin instance, capturing per-account runtime state in closure. */
78
+ export function createTelegramPlugin(deps) {
79
+ const accountRuntimes = new Map();
80
+ const startAccount = async (ctx) => {
81
+ const accountId = ctx.accountId || TELEGRAM_DEFAULT_ACCOUNT_ID;
82
+ // Re-entrant start (the plugin-manager's restart loop) — stop the prior
83
+ // adapter, then build fresh.
84
+ const existing = accountRuntimes.get(accountId);
85
+ if (existing) {
86
+ try {
87
+ await existing.adapter.stop();
88
+ }
89
+ catch {
90
+ /* best-effort */
91
+ }
92
+ try {
93
+ existing.abort.abort("restart");
94
+ }
95
+ catch {
96
+ /* best-effort */
97
+ }
98
+ removeChannelApprovalDispatcher(TELEGRAM_CHANNEL_ID, accountId);
99
+ accountRuntimes.delete(accountId);
100
+ }
101
+ const cfg = deps.loadConfig();
102
+ const autoLabel = telegramAutoLabelTopics(cfg);
103
+ // Build the adapter first WITHOUT a command menu, then derive the menu from
104
+ // its bundled commands and rebuild — the command set depends on the adapter
105
+ // (its selfId etc.), so we materialise the bundled commands, map them to the
106
+ // Telegram menu shape, and hand them to the real adapter we start.
107
+ const factory = deps.adapterFactory ?? defaultTelegramAdapterFactory;
108
+ const probeAdapter = factory({ accountId, commandMenu: [], autoLabelTopics: autoLabel });
109
+ const commandMenu = buildTelegramCommandMenu(buildBundledCommands(probeAdapter));
110
+ const adapter = factory({ accountId, commandMenu, autoLabelTopics: autoLabel });
111
+ // Per-account abort derived from the gateway's parent abort.
112
+ const accountAbort = new AbortController();
113
+ const parent = ctx.signal;
114
+ if (parent) {
115
+ if (parent.aborted)
116
+ accountAbort.abort();
117
+ else
118
+ parent.addEventListener("abort", () => accountAbort.abort(), { once: true });
119
+ }
120
+ const pipelineRunTurn = (turn) => deps.runTurn(turn);
121
+ // Bundled channel commands so `/help` etc. work on the multi-account path.
122
+ const commandMap = new Map();
123
+ for (const c of buildBundledCommands(adapter)) {
124
+ commandMap.set(c.name.toLowerCase(), c);
125
+ }
126
+ const pipeline = createInboundPipelineContext({
127
+ adapter,
128
+ config: cfg,
129
+ agentId: deps.defaultAgentId,
130
+ runTurn: pipelineRunTurn,
131
+ commandMap,
132
+ parentAbort: accountAbort.signal,
133
+ });
134
+ const startCtx = {
135
+ signal: accountAbort.signal,
136
+ log: (msg, meta) => log.info(`[${accountId}] ${msg}`, meta),
137
+ onInbound: async (msg) => {
138
+ // Re-read the active config per inbound so policy edits land without
139
+ // restarting the bot. Stamp the accountId so the shared pipeline keys
140
+ // ACL + approval-route per account.
141
+ pipeline.config = deps.loadConfig();
142
+ const stamped = msg.accountId ? msg : { ...msg, accountId };
143
+ await runChannelInboundPipeline(pipeline, stamped);
144
+ },
145
+ };
146
+ try {
147
+ await adapter.start(startCtx);
148
+ accountRuntimes.set(accountId, { adapter, pipeline, abort: accountAbort });
149
+ // Per-account approval dispatcher — native inline-button prompt + per-
150
+ // account routing. Without this an exec-gate prompt from a turn on
151
+ // (telegram, ops) would fall through to the channel default.
152
+ registerChannelApprovalDispatcher(TELEGRAM_CHANNEL_ID, accountId, {
153
+ sendText: (conversationId, text, opts) => adapter.sendText(conversationId, text, { ...(opts ?? {}), accountId }),
154
+ prettyName: "Telegram",
155
+ approvalCapability: buildApprovalCapability(adapter, accountId),
156
+ getApprovalContext: () => ({ runtime: ctx.runtime, cfg: deps.loadConfig() }),
157
+ });
158
+ log.info("telegram account started", { accountId });
159
+ }
160
+ catch (err) {
161
+ log.warn("telegram account failed to start", {
162
+ accountId,
163
+ error: err instanceof Error ? err.message : String(err),
164
+ });
165
+ throw err;
166
+ }
167
+ };
168
+ const stopAccount = async (ctx) => {
169
+ const runtime = accountRuntimes.get(ctx.accountId);
170
+ if (!runtime)
171
+ return;
172
+ accountRuntimes.delete(ctx.accountId);
173
+ // Drop the per-account dispatcher BEFORE adapter.stop() so a late in-flight
174
+ // bridge can't ask a torn-down bot to send.
175
+ removeChannelApprovalDispatcher(TELEGRAM_CHANNEL_ID, ctx.accountId);
176
+ try {
177
+ runtime.abort.abort("stop-requested");
178
+ }
179
+ catch {
180
+ /* best-effort */
181
+ }
182
+ // Clear pending debounce slots so a flush can't fire after stop.
183
+ for (const slot of runtime.pipeline.pendingDispatches.values())
184
+ clearTimeout(slot.timer);
185
+ runtime.pipeline.pendingDispatches.clear();
186
+ try {
187
+ await runtime.adapter.stop();
188
+ }
189
+ catch (err) {
190
+ log.warn("telegram account stop threw", {
191
+ accountId: ctx.accountId,
192
+ error: err instanceof Error ? err.message : String(err),
193
+ });
194
+ }
195
+ };
196
+ const logoutAccount = async (ctx) => {
197
+ try {
198
+ await stopAccount(ctx);
199
+ return { ok: true };
200
+ }
201
+ catch (err) {
202
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
203
+ }
204
+ };
205
+ return {
206
+ id: TELEGRAM_CHANNEL_ID,
207
+ meta: TELEGRAM_META,
208
+ capabilities: TELEGRAM_CAPABILITIES,
209
+ startedAccountIds: () => [...accountRuntimes.keys()],
210
+ getAdapter: (accountId) => accountRuntimes.get(accountId)?.adapter,
211
+ probeAccount: async (accountId, cfg) => {
212
+ const token = resolveTelegramBotToken(cfg, accountId);
213
+ return probeTelegram({ token });
214
+ },
215
+ config: {
216
+ listAccountIds: (cfg) => listTelegramAccountIds(cfg),
217
+ resolveAccount: (cfg, accountId) => resolveTelegramAccount(cfg, accountId ?? undefined),
218
+ defaultAccountId: () => TELEGRAM_DEFAULT_ACCOUNT_ID,
219
+ isEnabled: (account) => account.enabled,
220
+ },
221
+ gateway: {
222
+ startAccount,
223
+ stopAccount,
224
+ logoutAccount,
225
+ },
226
+ outbound: {
227
+ sendText: async (params) => {
228
+ const accountId = params.target.accountId || TELEGRAM_DEFAULT_ACCOUNT_ID;
229
+ const runtime = accountRuntimes.get(accountId);
230
+ if (!runtime) {
231
+ return { ok: false, error: `telegram account "${accountId}" is not running` };
232
+ }
233
+ try {
234
+ const sent = await runtime.adapter.sendText(params.target.to, params.text, {
235
+ accountId,
236
+ ...(params.target.threadId !== undefined ? { threadId: params.target.threadId } : {}),
237
+ });
238
+ return {
239
+ ok: true,
240
+ ...(sent && typeof sent === "object" && sent.messageId !== undefined
241
+ ? { messageId: sent.messageId }
242
+ : {}),
243
+ };
244
+ }
245
+ catch (err) {
246
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
247
+ }
248
+ },
249
+ sendMedia: async (params) => {
250
+ const accountId = params.target.accountId || TELEGRAM_DEFAULT_ACCOUNT_ID;
251
+ const runtime = accountRuntimes.get(accountId);
252
+ if (!runtime || !runtime.adapter.sendMedia) {
253
+ return { ok: false, error: `telegram account "${accountId}" cannot send media right now` };
254
+ }
255
+ try {
256
+ await runtime.adapter.sendMedia(params.target.to, {
257
+ kind: params.mediaType ?? "document",
258
+ path: params.mediaUrl,
259
+ ...(params.caption !== undefined ? { caption: params.caption } : {}),
260
+ });
261
+ return { ok: true };
262
+ }
263
+ catch (err) {
264
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
265
+ }
266
+ },
267
+ sendReaction: async (params) => {
268
+ const accountId = params.target.accountId || TELEGRAM_DEFAULT_ACCOUNT_ID;
269
+ const runtime = accountRuntimes.get(accountId);
270
+ if (!runtime || !runtime.adapter.react) {
271
+ return { ok: false, error: `telegram account "${accountId}" cannot react right now` };
272
+ }
273
+ try {
274
+ await runtime.adapter.react(params.target.to, params.messageId, params.emoji);
275
+ return { ok: true };
276
+ }
277
+ catch (err) {
278
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
279
+ }
280
+ },
281
+ },
282
+ actions: {
283
+ handleAction: async (params) => {
284
+ const accountId = params.accountId || params.target.accountId || TELEGRAM_DEFAULT_ACCOUNT_ID;
285
+ const runtime = accountRuntimes.get(accountId);
286
+ if (!runtime || !runtime.adapter.handleAction) {
287
+ return { ok: false, error: `telegram account "${accountId}" cannot perform message actions` };
288
+ }
289
+ return runtime.adapter.handleAction({
290
+ conversationId: params.target.to,
291
+ action: params.action,
292
+ accountId,
293
+ ...(params.signal ? { signal: params.signal } : {}),
294
+ });
295
+ },
296
+ },
297
+ secrets: {
298
+ secretTargetRegistryEntries: [
299
+ { path: "channels.telegram.botToken", description: "Telegram bot token (single-account)" },
300
+ { path: "channels.telegram.accounts.*.botToken", description: "Telegram bot token (per account)" },
301
+ { path: "channels.telegram.webhook.secretToken", description: "Telegram webhook secret token" },
302
+ ],
303
+ },
304
+ };
305
+ }
306
+ /** Default adapter factory — threads the per-account command menu + auto-label flag. */
307
+ function defaultTelegramAdapterFactory(args) {
308
+ return createTelegramAdapter({
309
+ accountId: args.accountId,
310
+ ...(args.commandMenu.length > 0 ? { commandMenu: args.commandMenu } : {}),
311
+ autoLabelTopics: args.autoLabelTopics,
312
+ });
313
+ }
314
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../../src/agents/channels/telegram/plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Telegram status / doctor probe — a lightweight `getMe` reachability check.
3
+ *
4
+ * Telegram is token-based and stateless on disk: unlike WhatsApp (which leaves
5
+ * Baileys creds the status command can stat), there's no local artifact to
6
+ * inspect, so "is this channel actually working?" can only be answered by
7
+ * asking Telegram. This probe does the cheapest possible call — a single
8
+ * `getMe` over plain HTTPS (no grammY, no polling, no runner) — and reports the
9
+ * bot's identity + group/inline capability flags so `brigade channels status`
10
+ * and `brigade doctor` can show real Telegram health.
11
+ *
12
+ * It deliberately does NOT import grammY: a status check must stay fast +
13
+ * dependency-light, and `getMe` is a trivial GET. The bot token is never
14
+ * logged; the URL it's embedded in is built locally and discarded.
15
+ *
16
+ * Returns a structured result the caller renders; never throws — a network
17
+ * failure / invalid token surfaces as `{ ok: false, error }` so the status
18
+ * command degrades gracefully instead of crashing.
19
+ */
20
+ /** The bot identity fields surfaced by the probe (from `getMe`). */
21
+ export interface TelegramProbeIdentity {
22
+ id?: number;
23
+ username?: string;
24
+ firstName?: string;
25
+ canJoinGroups?: boolean;
26
+ canReadAllGroupMessages?: boolean;
27
+ supportsInlineQueries?: boolean;
28
+ }
29
+ /** Structured probe result. `ok` true ⇒ token valid + bot reachable. */
30
+ export interface TelegramProbeResult {
31
+ ok: boolean;
32
+ /** HTTP status of the `getMe` call, when one came back. */
33
+ status?: number;
34
+ /** Operator-facing error line when `ok` is false. */
35
+ error?: string;
36
+ /** Round-trip time in ms. */
37
+ elapsedMs: number;
38
+ /** Bot identity (populated on success). */
39
+ bot?: TelegramProbeIdentity;
40
+ }
41
+ export interface TelegramProbeArgs {
42
+ /** The resolved Bot API token. NEVER logged. */
43
+ token: string;
44
+ /** Injectable fetch (defaults to global fetch) — lets tests stub the call. */
45
+ fetchImpl?: typeof fetch;
46
+ /** Probe timeout in ms (default 8s). */
47
+ timeoutMs?: number;
48
+ }
49
+ /**
50
+ * Run a `getMe` probe. Resolves to a structured result describing whether the
51
+ * token is valid + the bot is reachable, plus its identity. Never rejects.
52
+ */
53
+ export declare function probeTelegram(args: TelegramProbeArgs): Promise<TelegramProbeResult>;
54
+ //# sourceMappingURL=probe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probe.d.ts","sourceRoot":"","sources":["../../../../src/agents/channels/telegram/probe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,oEAAoE;AACpE,MAAM,WAAW,qBAAqB;IACrC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,wEAAwE;AACxE,MAAM,WAAW,mBAAmB;IACnC,EAAE,EAAE,OAAO,CAAC;IACZ,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,GAAG,CAAC,EAAE,qBAAqB,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IACjC,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAkEzF"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Telegram status / doctor probe — a lightweight `getMe` reachability check.
3
+ *
4
+ * Telegram is token-based and stateless on disk: unlike WhatsApp (which leaves
5
+ * Baileys creds the status command can stat), there's no local artifact to
6
+ * inspect, so "is this channel actually working?" can only be answered by
7
+ * asking Telegram. This probe does the cheapest possible call — a single
8
+ * `getMe` over plain HTTPS (no grammY, no polling, no runner) — and reports the
9
+ * bot's identity + group/inline capability flags so `brigade channels status`
10
+ * and `brigade doctor` can show real Telegram health.
11
+ *
12
+ * It deliberately does NOT import grammY: a status check must stay fast +
13
+ * dependency-light, and `getMe` is a trivial GET. The bot token is never
14
+ * logged; the URL it's embedded in is built locally and discarded.
15
+ *
16
+ * Returns a structured result the caller renders; never throws — a network
17
+ * failure / invalid token surfaces as `{ ok: false, error }` so the status
18
+ * command degrades gracefully instead of crashing.
19
+ */
20
+ const TELEGRAM_API_BASE = "https://api.telegram.org";
21
+ const DEFAULT_PROBE_TIMEOUT_MS = 8_000;
22
+ /**
23
+ * Run a `getMe` probe. Resolves to a structured result describing whether the
24
+ * token is valid + the bot is reachable, plus its identity. Never rejects.
25
+ */
26
+ export async function probeTelegram(args) {
27
+ const started = Date.now();
28
+ const token = (args.token ?? "").trim();
29
+ if (!token) {
30
+ return { ok: false, error: "no Telegram bot token configured", elapsedMs: 0 };
31
+ }
32
+ const doFetch = args.fetchImpl ?? fetch;
33
+ const timeoutMs = args.timeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
34
+ const controller = new AbortController();
35
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
36
+ if (typeof timer.unref === "function")
37
+ timer.unref();
38
+ try {
39
+ const res = await doFetch(`${TELEGRAM_API_BASE}/bot${token}/getMe`, { signal: controller.signal });
40
+ const elapsedMs = Date.now() - started;
41
+ let body = null;
42
+ try {
43
+ body = (await res.json());
44
+ }
45
+ catch {
46
+ body = null;
47
+ }
48
+ if (!res.ok || !body?.ok || !body.result) {
49
+ return {
50
+ ok: false,
51
+ status: res.status,
52
+ error: body?.description ??
53
+ (res.status === 401
54
+ ? "Telegram rejected the bot token (401) — paste a fresh @BotFather token."
55
+ : `Telegram getMe failed (HTTP ${res.status}).`),
56
+ elapsedMs,
57
+ };
58
+ }
59
+ const r = body.result;
60
+ return {
61
+ ok: true,
62
+ status: res.status,
63
+ elapsedMs,
64
+ bot: {
65
+ ...(typeof r.id === "number" ? { id: r.id } : {}),
66
+ ...(typeof r.username === "string" ? { username: r.username } : {}),
67
+ ...(typeof r.first_name === "string" ? { firstName: r.first_name } : {}),
68
+ ...(typeof r.can_join_groups === "boolean" ? { canJoinGroups: r.can_join_groups } : {}),
69
+ ...(typeof r.can_read_all_group_messages === "boolean"
70
+ ? { canReadAllGroupMessages: r.can_read_all_group_messages }
71
+ : {}),
72
+ ...(typeof r.supports_inline_queries === "boolean"
73
+ ? { supportsInlineQueries: r.supports_inline_queries }
74
+ : {}),
75
+ },
76
+ };
77
+ }
78
+ catch (err) {
79
+ const elapsedMs = Date.now() - started;
80
+ const aborted = controller.signal.aborted;
81
+ return {
82
+ ok: false,
83
+ error: aborted
84
+ ? `Telegram getMe timed out after ${timeoutMs}ms`
85
+ : err instanceof Error
86
+ ? err.message
87
+ : String(err),
88
+ elapsedMs,
89
+ };
90
+ }
91
+ finally {
92
+ clearTimeout(timer);
93
+ }
94
+ }
95
+ //# sourceMappingURL=probe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probe.js","sourceRoot":"","sources":["../../../../src/agents/channels/telegram/probe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Telegram webhook gateway route.
3
+ *
4
+ * In webhook transport mode (`channels.telegram.mode: "webhook"`) Telegram POSTs
5
+ * each update to a public URL instead of Brigade polling `getUpdates`. This
6
+ * module builds the Brigade `HttpRoute` that receives those POSTs:
7
+ *
8
+ * 1. Verify the `X-Telegram-Bot-Api-Secret-Token` header against the
9
+ * configured secret (constant-time compare). A mismatch → 401, BEFORE the
10
+ * body is parsed, so a forged update can't reach the agent.
11
+ * 2. Parse the JSON body as a Telegram `Update`.
12
+ * 3. Hand it to the started Telegram adapter's `feedWebhookUpdate`, which runs
13
+ * it through the SAME normalize + dedupe + dispatch path as polling.
14
+ * 4. Reply `200 {"ok":true}` so Telegram marks the update delivered.
15
+ *
16
+ * The route is registered with `auth: "none"` because Telegram authenticates via
17
+ * the secret-token header, not Brigade's operator-auth (Telegram can't present
18
+ * an operator credential). The secret-token check IS the auth.
19
+ *
20
+ * Polling mode never registers this route — it's added by the module only when
21
+ * webhook mode is configured, so the default local-first install exposes no
22
+ * inbound HTTP surface.
23
+ */
24
+ import type { HttpRoute } from "../sdk.js";
25
+ /** The header Telegram sends carrying the configured secret token. */
26
+ export declare const TELEGRAM_WEBHOOK_SECRET_HEADER = "x-telegram-bot-api-secret-token";
27
+ /** Constant-time string compare — avoids leaking the secret via timing. */
28
+ export declare function safeEqualSecret(a: string, b: string): boolean;
29
+ /**
30
+ * Verify the inbound secret-token header. When no secret is configured the check
31
+ * passes (the operator opted out of header verification) — but configuring a
32
+ * secret is strongly recommended and the setWebhook call always sends one.
33
+ */
34
+ export declare function hasValidTelegramWebhookSecret(headerValue: string | undefined, expected: string): boolean;
35
+ /** The minimal adapter surface the webhook route drives. */
36
+ export interface TelegramWebhookSink {
37
+ /** Feed a parsed Telegram update into the inbound path. */
38
+ feedWebhookUpdate(update: unknown): void;
39
+ }
40
+ export interface BuildTelegramWebhookRouteArgs {
41
+ /** The gateway route path (e.g. `/telegram/webhook`). */
42
+ path: string;
43
+ /** The configured secret token (`""` → no header check). */
44
+ secretToken: string;
45
+ /** Resolve the started adapter to feed updates into (null when not started). */
46
+ resolveSink: () => TelegramWebhookSink | null;
47
+ /** Logger (token-redacted upstream). */
48
+ log?: (msg: string, meta?: Record<string, unknown>) => void;
49
+ }
50
+ /**
51
+ * Build the Brigade `HttpRoute` for the Telegram webhook. Register it via
52
+ * `b.httpRoute(...)` from the module when webhook mode is active.
53
+ */
54
+ export declare function buildTelegramWebhookRoute(args: BuildTelegramWebhookRouteArgs): HttpRoute;
55
+ //# sourceMappingURL=webhook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../../../src/agents/channels/telegram/webhook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,sEAAsE;AACtE,eAAO,MAAM,8BAA8B,oCAAoC,CAAC;AAKhF,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAK7D;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAIxG;AA0BD,4DAA4D;AAC5D,MAAM,WAAW,mBAAmB;IACnC,2DAA2D;IAC3D,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,6BAA6B;IAC7C,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,WAAW,EAAE,MAAM,mBAAmB,GAAG,IAAI,CAAC;IAC9C,wCAAwC;IACxC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CAC5D;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,6BAA6B,GAAG,SAAS,CA6DxF"}