@llblab/pi-telegram 0.51.6 → 0.52.1

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 (178) hide show
  1. package/AGENTS.md +15 -12
  2. package/BACKLOG.md +16 -9
  3. package/CHANGELOG.md +19 -0
  4. package/LICENSE +21 -0
  5. package/README.md +17 -6
  6. package/dist/lib/activity-verbosity.d.ts +1 -5
  7. package/dist/lib/activity-verbosity.js +5 -7
  8. package/dist/lib/bindings.d.ts +5 -1
  9. package/dist/lib/bindings.js +7 -1
  10. package/dist/lib/bus-api.js +8 -5
  11. package/dist/lib/bus-follower.d.ts +54 -56
  12. package/dist/lib/bus-follower.js +206 -139
  13. package/dist/lib/bus-leader.d.ts +21 -2
  14. package/dist/lib/bus-leader.js +181 -25
  15. package/dist/lib/bus-transport.d.ts +4 -1
  16. package/dist/lib/bus-transport.js +28 -4
  17. package/dist/lib/bus.d.ts +52 -56
  18. package/dist/lib/bus.js +78 -246
  19. package/dist/lib/channel-posts.d.ts +1 -3
  20. package/dist/lib/channel-posts.js +23 -26
  21. package/dist/lib/command-templates.d.ts +0 -5
  22. package/dist/lib/command-templates.js +5 -5
  23. package/dist/lib/commands.d.ts +0 -23
  24. package/dist/lib/commands.js +15 -15
  25. package/dist/lib/config.d.ts +0 -17
  26. package/dist/lib/config.js +12 -14
  27. package/dist/lib/delivery.d.ts +0 -4
  28. package/dist/lib/delivery.js +2 -5
  29. package/dist/lib/extension.js +258 -61
  30. package/dist/lib/generative-apps.d.ts +0 -19
  31. package/dist/lib/inbound.d.ts +0 -2
  32. package/dist/lib/inbound.js +2 -2
  33. package/dist/lib/journal.d.ts +183 -16
  34. package/dist/lib/journal.js +1175 -248
  35. package/dist/lib/keyboard.d.ts +0 -2
  36. package/dist/lib/keyboard.js +2 -2
  37. package/dist/lib/lifecycle.js +1 -1
  38. package/dist/lib/locks.d.ts +100 -12
  39. package/dist/lib/locks.js +380 -14
  40. package/dist/lib/logging.d.ts +30 -12
  41. package/dist/lib/logging.js +129 -72
  42. package/dist/lib/media.d.ts +28 -5
  43. package/dist/lib/media.js +26 -8
  44. package/dist/lib/menu-model.d.ts +0 -11
  45. package/dist/lib/menu-model.js +8 -8
  46. package/dist/lib/menu-settings.d.ts +0 -18
  47. package/dist/lib/menu-settings.js +18 -18
  48. package/dist/lib/menu-status.d.ts +4 -4
  49. package/dist/lib/menu-status.js +12 -7
  50. package/dist/lib/menu-thinking.d.ts +1 -1
  51. package/dist/lib/menu-thinking.js +1 -1
  52. package/dist/lib/menu.d.ts +1 -0
  53. package/dist/lib/menu.js +4 -3
  54. package/dist/lib/outbound-attachments.d.ts +0 -1
  55. package/dist/lib/outbound-attachments.js +1 -1
  56. package/dist/lib/outbound-buttons.js +1 -8
  57. package/dist/lib/outbound-markup.d.ts +1 -6
  58. package/dist/lib/outbound-markup.js +4 -21
  59. package/dist/lib/outbound.d.ts +0 -8
  60. package/dist/lib/outbound.js +5 -5
  61. package/dist/lib/paths.d.ts +50 -7
  62. package/dist/lib/paths.js +155 -17
  63. package/dist/lib/pi.d.ts +1 -0
  64. package/dist/lib/pi.js +2 -1
  65. package/dist/lib/polling.d.ts +0 -5
  66. package/dist/lib/polling.js +5 -5
  67. package/dist/lib/preview.d.ts +0 -3
  68. package/dist/lib/preview.js +3 -3
  69. package/dist/lib/prompt-templates.d.ts +0 -1
  70. package/dist/lib/prompt-templates.js +1 -1
  71. package/dist/lib/queue.d.ts +5 -15
  72. package/dist/lib/queue.js +94 -11
  73. package/dist/lib/recovery.d.ts +29 -9
  74. package/dist/lib/recovery.js +104 -33
  75. package/dist/lib/replies.d.ts +0 -4
  76. package/dist/lib/replies.js +1 -1
  77. package/dist/lib/routing.d.ts +74 -8
  78. package/dist/lib/routing.js +2280 -307
  79. package/dist/lib/sections.d.ts +0 -2
  80. package/dist/lib/sections.js +1 -1
  81. package/dist/lib/status.d.ts +44 -9
  82. package/dist/lib/status.js +149 -27
  83. package/dist/lib/sync.d.ts +0 -5
  84. package/dist/lib/sync.js +5 -4
  85. package/dist/lib/telegram-api.d.ts +13 -3
  86. package/dist/lib/telegram-api.js +38 -23
  87. package/dist/lib/thread-cleanup-manager.d.ts +1 -0
  88. package/dist/lib/thread-cleanup-manager.js +18 -21
  89. package/dist/lib/thread-naming.d.ts +32 -5
  90. package/dist/lib/thread-naming.js +191 -7
  91. package/dist/lib/thread-reconciler.d.ts +2 -0
  92. package/dist/lib/thread-reconciler.js +1 -1
  93. package/dist/lib/threads.d.ts +293 -59
  94. package/dist/lib/threads.js +1689 -369
  95. package/dist/lib/turns.d.ts +0 -1
  96. package/dist/lib/turns.js +1 -1
  97. package/dist/lib/updates.d.ts +191 -28
  98. package/dist/lib/updates.js +1048 -114
  99. package/dist/lib/wire.d.ts +12 -0
  100. package/dist/lib/wire.js +21 -0
  101. package/dist/lib/workspace-admission.d.ts +25 -17
  102. package/dist/lib/workspace-admission.js +95 -20
  103. package/dist/lib/workspace-identity.d.ts +20 -0
  104. package/dist/lib/workspace-identity.js +103 -0
  105. package/dist/lib/workspace-retirement.d.ts +43 -8
  106. package/dist/lib/workspace-retirement.js +148 -52
  107. package/dist/package.json +6 -6
  108. package/dist/skills/generated-control-surface/SKILL.md +3 -3
  109. package/dist/skills/telegram-bridge/references/diagnosis.md +3 -3
  110. package/docs/README.md +1 -1
  111. package/docs/activity.md +1 -1
  112. package/docs/architecture.md +156 -36
  113. package/docs/callback-namespaces.md +1 -1
  114. package/docs/delivery.md +1 -1
  115. package/docs/generative-apps.md +2 -2
  116. package/docs/inbound.md +1 -1
  117. package/docs/multi-instance-bus.md +125 -19
  118. package/docs/public-api.md +3 -1
  119. package/docs/ui-style.md +23 -9
  120. package/docs/updates.md +1 -1
  121. package/lib/activity-verbosity.ts +5 -9
  122. package/lib/bindings.ts +7 -0
  123. package/lib/bus-api.ts +9 -4
  124. package/lib/bus-follower.ts +243 -224
  125. package/lib/bus-leader.ts +178 -31
  126. package/lib/bus-transport.ts +30 -8
  127. package/lib/bus.ts +110 -334
  128. package/lib/channel-posts.ts +29 -29
  129. package/lib/command-templates.ts +5 -5
  130. package/lib/commands.ts +15 -15
  131. package/lib/config.ts +12 -17
  132. package/lib/delivery.ts +2 -8
  133. package/lib/extension.ts +261 -72
  134. package/lib/generative-apps.ts +0 -22
  135. package/lib/inbound.ts +2 -2
  136. package/lib/journal.ts +1250 -325
  137. package/lib/keyboard.ts +2 -2
  138. package/lib/lifecycle.ts +1 -1
  139. package/lib/locks.ts +402 -23
  140. package/lib/logging.ts +151 -101
  141. package/lib/media.ts +51 -9
  142. package/lib/menu-model.ts +8 -8
  143. package/lib/menu-settings.ts +18 -18
  144. package/lib/menu-status.ts +11 -0
  145. package/lib/menu-thinking.ts +2 -2
  146. package/lib/menu.ts +5 -1
  147. package/lib/outbound-attachments.ts +1 -1
  148. package/lib/outbound-buttons.ts +1 -10
  149. package/lib/outbound-markup.ts +5 -24
  150. package/lib/outbound.ts +5 -5
  151. package/lib/paths.ts +177 -17
  152. package/lib/pi.ts +5 -2
  153. package/lib/polling.ts +5 -5
  154. package/lib/preview.ts +3 -3
  155. package/lib/prompt-templates.ts +1 -1
  156. package/lib/queue.ts +93 -12
  157. package/lib/recovery.ts +104 -44
  158. package/lib/replies.ts +1 -1
  159. package/lib/routing.ts +2010 -375
  160. package/lib/sections.ts +1 -1
  161. package/lib/status.ts +156 -36
  162. package/lib/sync.ts +4 -4
  163. package/lib/telegram-api.ts +53 -33
  164. package/lib/thread-cleanup-manager.ts +24 -21
  165. package/lib/thread-naming.ts +267 -9
  166. package/lib/thread-reconciler.ts +3 -1
  167. package/lib/threads.ts +1736 -488
  168. package/lib/turns.ts +1 -1
  169. package/lib/updates.ts +1094 -151
  170. package/lib/wire.ts +28 -0
  171. package/lib/workspace-admission.ts +97 -47
  172. package/lib/workspace-identity.ts +147 -0
  173. package/lib/workspace-retirement.ts +188 -89
  174. package/package.json +6 -6
  175. package/scripts/audit-exports.mjs +100 -0
  176. package/scripts/check-downgrade.mjs +80 -43
  177. package/skills/generated-control-surface/SKILL.md +3 -3
  178. package/skills/telegram-bridge/references/diagnosis.md +3 -3
package/docs/updates.md CHANGED
@@ -156,7 +156,7 @@ This means:
156
156
 
157
157
  ## Ownership semantics
158
158
 
159
- The handler registry is ownership-agnostic and does not interact with the extension-local transport owner slots documented in [Architecture](./architecture.md#configuration-and-ownership). When the polling runtime loses its `owners.json` slot and stops `getUpdates`, handlers stop receiving updates because no updates are being fetched; they are not unregistered.
159
+ The handler registry is ownership-agnostic and does not interact with the extension-local transport owner slots documented in [Architecture](./architecture.md#configuration-and-ownership). When the polling runtime loses its transport ownership and stops `getUpdates`, handlers stop receiving updates because no updates are being fetched; they are not unregistered.
160
160
 
161
161
  If a layered extension needs to react to ownership changes, it should observe `pi-telegram` lifecycle events through the standard pi extension hooks rather than through the handler registry.
162
162
 
@@ -17,16 +17,16 @@ import type {
17
17
  TelegramSendRichMessageBody,
18
18
  TelegramSentMessage,
19
19
  } from "./telegram-api.ts";
20
- import type { TelegramTarget } from "./target.ts";
20
+ import { areTelegramTargetsEqual as targetEquals, type TelegramTarget } from "./target.ts";
21
21
 
22
- export const TELEGRAM_ACTIVITY_DETAIL_MAX_CHARS = 1_200;
23
- export const TELEGRAM_ACTIVITY_MESSAGE_MAX_CHARS = 3_900;
22
+ const TELEGRAM_ACTIVITY_DETAIL_MAX_CHARS = 1_200;
23
+ const TELEGRAM_ACTIVITY_MESSAGE_MAX_CHARS = 3_900;
24
24
  export const TELEGRAM_ACTIVITY_MESSAGE_MAX_TOOLS = 6;
25
- export const TELEGRAM_REASONING_MESSAGE_MAX_FRAMES = 24;
25
+ const TELEGRAM_REASONING_MESSAGE_MAX_FRAMES = 24;
26
26
  export const TELEGRAM_REASONING_BUFFER_MAX_CHARS = 1_200;
27
27
  // Match native answer drafts: accumulate the opening frame for one full
28
28
  // interval, then publish at most one updated frame per interval.
29
- export const TELEGRAM_REASONING_MIN_INTERVAL_MS = 2_000;
29
+ const TELEGRAM_REASONING_MIN_INTERVAL_MS = 2_000;
30
30
  export const TELEGRAM_TOOL_UPDATE_MAX_ENTRIES = 4;
31
31
 
32
32
  interface ToolActivity {
@@ -52,10 +52,6 @@ interface ReasoningMessage {
52
52
  target: TelegramTarget;
53
53
  }
54
54
 
55
- function targetEquals(left: TelegramTarget, right: TelegramTarget): boolean {
56
- return left.chatId === right.chatId && left.threadId === right.threadId;
57
- }
58
-
59
55
  function redactActivityText(text: string): string {
60
56
  return text
61
57
  .replace(/\b\d{8,12}:[A-Za-z0-9_-]{30,}\b/g, "[REDACTED_BOT_TOKEN]")
package/lib/bindings.ts CHANGED
@@ -116,6 +116,7 @@ export function createTelegramQueueBindingRuntime<TContext>(deps: {
116
116
  };
117
117
  const mutation = Queue.createTelegramQueueMutationController({
118
118
  ...deps.store,
119
+ hasPendingDispatch: deps.lifecycle.hasDispatchPending,
119
120
  allocateLaneOrder: deps.queue.allocateItemOrder,
120
121
  onItemsDiscarded(items, ctx) {
121
122
  if (!settleDiscardedItems(items, ctx)) {
@@ -835,6 +836,7 @@ interface TelegramLifecycleBindingDeps {
835
836
  publicationRuntime: TelegramBridgePublicationRuntime;
836
837
  activityRuntime: Activity.TelegramActivityRuntime;
837
838
  activityVerbosityRuntime?: ActivityVerbosity.TelegramActivityVerbosityRuntime;
839
+ diagnostics?: { onSessionStart(): void; onSessionShutdown(): Promise<void> };
838
840
  assistantOutputRuntime: Pick<
839
841
  Activity.TelegramAssistantOutputRuntime,
840
842
  "start" | "beginTurn" | "hasAdmittedTelegramIntermediate" | "waitForIdle" | "stop"
@@ -941,6 +943,7 @@ export function registerTelegramLifecycleRuntimeHooks({
941
943
  publicationRuntime,
942
944
  activityRuntime,
943
945
  activityVerbosityRuntime,
946
+ diagnostics,
944
947
  assistantOutputRuntime,
945
948
  sessionLifecycleRuntime,
946
949
  configStore,
@@ -1278,6 +1281,7 @@ export function registerTelegramLifecycleRuntimeHooks({
1278
1281
  activityRuntime.recordInputSource(event.source ?? "unknown");
1279
1282
  },
1280
1283
  async onSessionStart(event, ctx) {
1284
+ diagnostics?.onSessionStart();
1281
1285
  cancelPendingFinalPublication();
1282
1286
  previewRuntime.invalidate();
1283
1287
  assistantOutputRuntime.start();
@@ -1289,6 +1293,7 @@ export function registerTelegramLifecycleRuntimeHooks({
1289
1293
  },
1290
1294
  async onSessionShutdown(event, ctx) {
1291
1295
  if (!isSessionContextActive(ctx)) return;
1296
+ const diagnosticsStopped = diagnostics?.onSessionShutdown();
1292
1297
  shutdownGenerativeAppLiveSurfaces?.();
1293
1298
  agentLifecycleHooks.clearRetainedAgentEnd();
1294
1299
  activityRuntime.onSessionShutdown();
@@ -1299,6 +1304,8 @@ export function registerTelegramLifecycleRuntimeHooks({
1299
1304
  cancelPendingFinalPublication();
1300
1305
  uiPromptActive = false;
1301
1306
  compactionObserver.onSessionShutdown();
1307
+ await diagnosticsStopped;
1308
+ if (!isSessionContextActive(ctx)) return;
1302
1309
  if (event.reason === "quit" && disconnectOnQuit) {
1303
1310
  try {
1304
1311
  const automaticCleanupEnabled =
package/lib/bus-api.ts CHANGED
@@ -10,8 +10,10 @@ import {
10
10
  } from "./bus.ts";
11
11
  import {
12
12
  buildTelegramAnswerGuestQueryBody,
13
+ formatTelegramCallbackAnswerText,
13
14
  isTelegramMessageNotModifiedError,
14
15
  } from "./telegram-api.ts";
16
+ import type { TelegramAttachmentSource } from "./media.ts";
15
17
  import type {
16
18
  TelegramAnswerGuestQueryOptions,
17
19
  TelegramApiCallOptions,
@@ -125,12 +127,14 @@ export function createTelegramBusAwareApiRuntime(
125
127
  options,
126
128
  ]) as Promise<TResponse>);
127
129
  },
128
- downloadFile(fileId: string, suggestedName: string): Promise<string> {
130
+ downloadFile(fileId: string, suggestedName: string, source?: TelegramAttachmentSource): Promise<string> {
131
+ // The source names the file (kind-scope-message); dropping it falls back to the bare generated name.
129
132
  return deps.ownsDirect()
130
- ? deps.directRuntime.downloadFile(fileId, suggestedName)
133
+ ? deps.directRuntime.downloadFile(fileId, suggestedName, source)
131
134
  : (deps.callFollowerApi("downloadFile", [
132
135
  fileId,
133
136
  suggestedName,
137
+ ...(source ? [source] : []),
134
138
  ]) as Promise<string>);
135
139
  },
136
140
  deleteWebhook(signal?: AbortSignal): Promise<boolean> {
@@ -318,15 +322,16 @@ export function createTelegramBusAwareApiRuntime(
318
322
  callbackQueryId: string,
319
323
  text?: string,
320
324
  ): Promise<void> {
325
+ const answer = formatTelegramCallbackAnswerText(text);
321
326
  if (deps.ownsDirect()) {
322
- await deps.directRuntime.answerCallbackQuery(callbackQueryId, text);
327
+ await deps.directRuntime.answerCallbackQuery(callbackQueryId, answer);
323
328
  return;
324
329
  }
325
330
  await deps.callFollowerApi("call", [
326
331
  "answerCallbackQuery",
327
332
  {
328
333
  callback_query_id: callbackQueryId,
329
- ...(text !== undefined ? { text } : {}),
334
+ ...(answer !== undefined ? { text: answer } : {}),
330
335
  },
331
336
  ]);
332
337
  },