@s0nderlabs/anima-plugin-telegram 0.24.17 → 0.25.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 (2) hide show
  1. package/package.json +2 -2
  2. package/src/listener.ts +12 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@s0nderlabs/anima-plugin-telegram",
3
- "version": "0.24.17",
3
+ "version": "0.25.0",
4
4
  "type": "module",
5
5
  "description": "Telegram gateway plugin for anima — long-poll bot, debounced dispatch, reactions, allowlist",
6
6
  "license": "MIT",
@@ -39,7 +39,7 @@
39
39
  "test": "bun test"
40
40
  },
41
41
  "dependencies": {
42
- "@s0nderlabs/anima-core": "0.24.17",
42
+ "@s0nderlabs/anima-core": "0.25.0",
43
43
  "grammy": "^1.42.0",
44
44
  "zod": "^3.23.8"
45
45
  }
package/src/listener.ts CHANGED
@@ -64,7 +64,7 @@ export function formatApprovalResolution(choice: ApprovalChoice, byUserId: numbe
64
64
  * buttons rendered for tool approvals). Without `'callback_query'` here,
65
65
  * Telegram silently filters the click events out of `getUpdates`, the
66
66
  * `bot.on('callback_query:data', ...)` handler never fires, and operator
67
- * taps register on the device but never reach the harness the modal
67
+ * taps register on the device but never reach the harness, the modal
68
68
  * appears stuck and the brain's tool call hangs until timeout.
69
69
  *
70
70
  * Latent bug from v0.18.0 (the introduction of inline-keyboard approvals);
@@ -172,7 +172,7 @@ export class TelegramListener {
172
172
  // Resolve the modal visually: append the choice + drop the inline
173
173
  // keyboard. Without this, every clicked approval message stays on
174
174
  // screen with all four buttons, leaving operators unsure whether
175
- // their tap registered. Best-effort if the edit fails (rate
175
+ // their tap registered. Best-effort, if the edit fails (rate
176
176
  // limit, message age, deleted), the underlying approval is still
177
177
  // resolved at the runtime level, so we swallow the error.
178
178
  const originalText =
@@ -185,7 +185,7 @@ export class TelegramListener {
185
185
  await ctx.editMessageReplyMarkup({ reply_markup: undefined })
186
186
  }
187
187
  } catch {
188
- /* ignore modal was clicked, runtime already resolved; keyboard cleanup is cosmetic */
188
+ /* ignore, modal was clicked, runtime already resolved; keyboard cleanup is cosmetic */
189
189
  }
190
190
  }
191
191
 
@@ -514,11 +514,15 @@ export class TelegramListener {
514
514
  const stack = err instanceof Error && err.stack ? `\n${err.stack}` : ''
515
515
  console.error(`[telegram] dispatch failed: ${msg.slice(0, 500)}${stack}`)
516
516
  void reactError(this.bot, chatId, messageId)
517
- // Translate LedgerInsufficientError into an actionable topup hint
518
- // instead of the generic "something went wrong" reply. Detect by
519
- // name (avoids requiring the plugin to import core's typed class).
520
- const isLedger = err instanceof Error && err.name === 'LedgerInsufficientError'
521
- const replyText = isLedger
517
+ // Translate a credit/ledger-exhaustion error into an actionable topup
518
+ // hint instead of the generic "something went wrong" reply. Detect by
519
+ // name (avoids importing core's typed classes): Direct throws
520
+ // LedgerInsufficientError ("anima topup --compute"), Router throws
521
+ // RouterCreditError ("anima topup --router"), both carry the actionable
522
+ // message, so surface it verbatim.
523
+ const errName = err instanceof Error ? err.name : ''
524
+ const isTopupHint = errName === 'LedgerInsufficientError' || errName === 'RouterCreditError'
525
+ const replyText = isTopupHint
522
526
  ? `⚠️ I need a top-up to keep working.\n\n${msg}`
523
527
  : 'sorry, something went wrong on my side. try again in a moment.'
524
528
  try {