@s0nderlabs/anima-plugin-telegram 0.19.17 → 0.19.18

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@s0nderlabs/anima-plugin-telegram",
3
- "version": "0.19.17",
3
+ "version": "0.19.18",
4
4
  "type": "module",
5
5
  "description": "Telegram gateway plugin for anima — long-poll bot, debounced dispatch, reactions, allowlist",
6
6
  "license": "MIT",
@@ -28,7 +28,7 @@
28
28
  "test": "bun test"
29
29
  },
30
30
  "dependencies": {
31
- "@s0nderlabs/anima-core": "0.19.17",
31
+ "@s0nderlabs/anima-core": "0.19.18",
32
32
  "grammy": "^1.42.0",
33
33
  "zod": "^3.23.8"
34
34
  }
package/src/index.ts CHANGED
@@ -27,7 +27,7 @@ export type {
27
27
  TelegramToolEvent,
28
28
  } from './types'
29
29
  export { ProgressTracker, PROGRESS_EDIT_INTERVAL } from './progress'
30
- export { TelegramListener, capForTelegram } from './listener'
30
+ export { TelegramListener, TELEGRAM_ALLOWED_UPDATES, capForTelegram } from './listener'
31
31
  export { buildSessionKey, sanitizeAgentName } from './session-key'
32
32
  export { formatTelegramChannel, formatInboundPreview } from './format'
33
33
  export { RateLimiter } from './limits'
@@ -0,0 +1,25 @@
1
+ import { describe, expect, it } from 'bun:test'
2
+ import { TELEGRAM_ALLOWED_UPDATES } from './listener'
3
+
4
+ /**
5
+ * Regression test for v0.19.18 callback_query polling fix.
6
+ *
7
+ * v0.18.0 introduced inline-keyboard approvals but only subscribed to
8
+ * `'message'` updates in `bot.start({ allowed_updates })`. v0.19.10 fixed
9
+ * the handler-registration path but left the polling spec narrow, so every
10
+ * keyboard tap was silently filtered out by Telegram before grammY ever
11
+ * saw it. Operators saw the modal "do nothing" — the harness saw zero
12
+ * resolution events. This test pins both kinds in the polling spec so a
13
+ * future refactor cannot quietly drop the second one again.
14
+ */
15
+ describe('TELEGRAM_ALLOWED_UPDATES', () => {
16
+ it('subscribes to both message and callback_query updates', () => {
17
+ expect(TELEGRAM_ALLOWED_UPDATES).toContain('message')
18
+ expect(TELEGRAM_ALLOWED_UPDATES).toContain('callback_query')
19
+ })
20
+
21
+ it('does not over-subscribe to update kinds we have no handler for', () => {
22
+ // Keep the wire payload minimal. Add new kinds only when a handler exists.
23
+ expect([...TELEGRAM_ALLOWED_UPDATES].sort()).toEqual(['callback_query', 'message'])
24
+ })
25
+ })
package/src/listener.ts CHANGED
@@ -38,6 +38,23 @@ import { startTypingLoop } from './typing'
38
38
  const RETRY_INTERVAL_MS = 30_000
39
39
  const MAX_LOCK_RETRY_ATTEMPTS = 12
40
40
 
41
+ /**
42
+ * Update kinds we ask Telegram to deliver via long-poll.
43
+ *
44
+ * `'message'` covers inbound DMs we dispatch to the brain. `'callback_query'`
45
+ * covers inline-keyboard taps (the [Allow Once / Session / Always / Deny]
46
+ * buttons rendered for tool approvals). Without `'callback_query'` here,
47
+ * Telegram silently filters the click events out of `getUpdates`, the
48
+ * `bot.on('callback_query:data', ...)` handler never fires, and operator
49
+ * taps register on the device but never reach the harness — the modal
50
+ * appears stuck and the brain's tool call hangs until timeout.
51
+ *
52
+ * Latent bug from v0.18.0 (the introduction of inline-keyboard approvals);
53
+ * v0.19.10 fixed handler registration but not the polling spec, which is
54
+ * why no live drive caught it before v0.19.18.
55
+ */
56
+ export const TELEGRAM_ALLOWED_UPDATES = ['message', 'callback_query'] as const
57
+
41
58
  export interface TelegramListenerOpts extends TelegramRuntimeContext {
42
59
  /** Optional override of the Telegram Bot API root. Used by the mock-bot test. */
43
60
  apiRoot?: string
@@ -182,7 +199,7 @@ export class TelegramListener {
182
199
  .start({
183
200
  onStart: info => console.log(`[telegram] listener active @${info.username}`),
184
201
  drop_pending_updates: true,
185
- allowed_updates: ['message'],
202
+ allowed_updates: [...TELEGRAM_ALLOWED_UPDATES],
186
203
  })
187
204
  .catch(err => {
188
205
  const verdict = classifyStartFailure(err)