@llblab/pi-kit 0.29.1 → 0.30.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 (222) hide show
  1. package/BACKLOG.md +3 -1
  2. package/CHANGELOG.md +10 -0
  3. package/README.md +4 -4
  4. package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +12 -0
  5. package/node_modules/@llblab/pi-state-flow/README.md +2 -2
  6. package/node_modules/@llblab/pi-state-flow/dist/lib/context.d.ts +2 -2
  7. package/node_modules/@llblab/pi-state-flow/dist/lib/context.js +17 -8
  8. package/node_modules/@llblab/pi-state-flow/dist/lib/extension.js +7 -3
  9. package/node_modules/@llblab/pi-state-flow/dist/lib/protocol.d.ts +2 -1
  10. package/node_modules/@llblab/pi-state-flow/dist/lib/protocol.js +3 -2
  11. package/node_modules/@llblab/pi-state-flow/dist/package.json +1 -1
  12. package/node_modules/@llblab/pi-state-flow/docs/architecture.md +3 -3
  13. package/node_modules/@llblab/pi-state-flow/docs/usage.md +3 -2
  14. package/node_modules/@llblab/pi-state-flow/lib/context.ts +17 -8
  15. package/node_modules/@llblab/pi-state-flow/lib/extension.ts +6 -3
  16. package/node_modules/@llblab/pi-state-flow/lib/protocol.ts +4 -2
  17. package/node_modules/@llblab/pi-state-flow/package.json +1 -1
  18. package/node_modules/@llblab/pi-telegram/AGENTS.md +13 -10
  19. package/node_modules/@llblab/pi-telegram/BACKLOG.md +1 -1
  20. package/node_modules/@llblab/pi-telegram/CHANGELOG.md +23 -0
  21. package/node_modules/@llblab/pi-telegram/README.md +10 -11
  22. package/node_modules/@llblab/pi-telegram/api/commands.ts +3 -0
  23. package/node_modules/@llblab/pi-telegram/dist/api/commands.d.ts +1 -1
  24. package/node_modules/@llblab/pi-telegram/dist/lib/activity-verbosity.d.ts +1 -5
  25. package/node_modules/@llblab/pi-telegram/dist/lib/activity-verbosity.js +15 -42
  26. package/node_modules/@llblab/pi-telegram/dist/lib/activity.d.ts +9 -0
  27. package/node_modules/@llblab/pi-telegram/dist/lib/activity.js +39 -10
  28. package/node_modules/@llblab/pi-telegram/dist/lib/agent-messages.js +7 -3
  29. package/node_modules/@llblab/pi-telegram/dist/lib/bindings.d.ts +43 -5
  30. package/node_modules/@llblab/pi-telegram/dist/lib/bindings.js +164 -20
  31. package/node_modules/@llblab/pi-telegram/dist/lib/bus-api.d.ts +12 -0
  32. package/node_modules/@llblab/pi-telegram/dist/lib/bus-api.js +181 -77
  33. package/node_modules/@llblab/pi-telegram/dist/lib/bus-follower.d.ts +111 -31
  34. package/node_modules/@llblab/pi-telegram/dist/lib/bus-follower.js +1324 -359
  35. package/node_modules/@llblab/pi-telegram/dist/lib/bus-leader.d.ts +41 -91
  36. package/node_modules/@llblab/pi-telegram/dist/lib/bus-leader.js +969 -637
  37. package/node_modules/@llblab/pi-telegram/dist/lib/bus-transport.js +16 -9
  38. package/node_modules/@llblab/pi-telegram/dist/lib/bus.d.ts +215 -18
  39. package/node_modules/@llblab/pi-telegram/dist/lib/bus.js +1048 -327
  40. package/node_modules/@llblab/pi-telegram/dist/lib/channel-posts.d.ts +5 -0
  41. package/node_modules/@llblab/pi-telegram/dist/lib/channel-posts.js +434 -261
  42. package/node_modules/@llblab/pi-telegram/dist/lib/command-templates.d.ts +26 -5
  43. package/node_modules/@llblab/pi-telegram/dist/lib/command-templates.js +92 -176
  44. package/node_modules/@llblab/pi-telegram/dist/lib/commands.d.ts +168 -82
  45. package/node_modules/@llblab/pi-telegram/dist/lib/commands.js +1409 -291
  46. package/node_modules/@llblab/pi-telegram/dist/lib/config.d.ts +1 -8
  47. package/node_modules/@llblab/pi-telegram/dist/lib/config.js +34 -76
  48. package/node_modules/@llblab/pi-telegram/dist/lib/delivery.d.ts +2 -2
  49. package/node_modules/@llblab/pi-telegram/dist/lib/delivery.js +16 -16
  50. package/node_modules/@llblab/pi-telegram/dist/lib/extension.js +642 -170
  51. package/node_modules/@llblab/pi-telegram/dist/lib/generative-app-worker.mjs +19 -7
  52. package/node_modules/@llblab/pi-telegram/dist/lib/generative-apps.d.ts +0 -5
  53. package/node_modules/@llblab/pi-telegram/dist/lib/generative-apps.js +61 -49
  54. package/node_modules/@llblab/pi-telegram/dist/lib/inbound.d.ts +5 -0
  55. package/node_modules/@llblab/pi-telegram/dist/lib/inbound.js +35 -59
  56. package/node_modules/@llblab/pi-telegram/dist/lib/journal.d.ts +40 -4
  57. package/node_modules/@llblab/pi-telegram/dist/lib/journal.js +2102 -760
  58. package/node_modules/@llblab/pi-telegram/dist/lib/lifecycle.d.ts +2 -6
  59. package/node_modules/@llblab/pi-telegram/dist/lib/lifecycle.js +75 -58
  60. package/node_modules/@llblab/pi-telegram/dist/lib/locks.d.ts +34 -3
  61. package/node_modules/@llblab/pi-telegram/dist/lib/locks.js +318 -119
  62. package/node_modules/@llblab/pi-telegram/dist/lib/logging.js +50 -14
  63. package/node_modules/@llblab/pi-telegram/dist/lib/media.d.ts +22 -1
  64. package/node_modules/@llblab/pi-telegram/dist/lib/media.js +46 -28
  65. package/node_modules/@llblab/pi-telegram/dist/lib/menu-model.d.ts +19 -5
  66. package/node_modules/@llblab/pi-telegram/dist/lib/menu-model.js +53 -11
  67. package/node_modules/@llblab/pi-telegram/dist/lib/menu-queue.d.ts +5 -4
  68. package/node_modules/@llblab/pi-telegram/dist/lib/menu-queue.js +45 -63
  69. package/node_modules/@llblab/pi-telegram/dist/lib/menu-settings.d.ts +5 -4
  70. package/node_modules/@llblab/pi-telegram/dist/lib/menu-settings.js +114 -78
  71. package/node_modules/@llblab/pi-telegram/dist/lib/menu-status.d.ts +1 -1
  72. package/node_modules/@llblab/pi-telegram/dist/lib/menu-status.js +8 -25
  73. package/node_modules/@llblab/pi-telegram/dist/lib/menu-thinking.d.ts +6 -1
  74. package/node_modules/@llblab/pi-telegram/dist/lib/menu-thinking.js +14 -21
  75. package/node_modules/@llblab/pi-telegram/dist/lib/menu.d.ts +8 -61
  76. package/node_modules/@llblab/pi-telegram/dist/lib/menu.js +92 -164
  77. package/node_modules/@llblab/pi-telegram/dist/lib/model.d.ts +1 -1
  78. package/node_modules/@llblab/pi-telegram/dist/lib/model.js +2 -16
  79. package/node_modules/@llblab/pi-telegram/dist/lib/outbound-attachments.d.ts +6 -27
  80. package/node_modules/@llblab/pi-telegram/dist/lib/outbound-attachments.js +45 -38
  81. package/node_modules/@llblab/pi-telegram/dist/lib/outbound-buttons.js +22 -16
  82. package/node_modules/@llblab/pi-telegram/dist/lib/outbound-markup.d.ts +0 -2
  83. package/node_modules/@llblab/pi-telegram/dist/lib/outbound-markup.js +51 -64
  84. package/node_modules/@llblab/pi-telegram/dist/lib/outbound-voice.js +6 -3
  85. package/node_modules/@llblab/pi-telegram/dist/lib/outbound.d.ts +6 -6
  86. package/node_modules/@llblab/pi-telegram/dist/lib/outbound.js +61 -51
  87. package/node_modules/@llblab/pi-telegram/dist/lib/ownership.js +6 -2
  88. package/node_modules/@llblab/pi-telegram/dist/lib/paths.d.ts +5 -0
  89. package/node_modules/@llblab/pi-telegram/dist/lib/paths.js +37 -21
  90. package/node_modules/@llblab/pi-telegram/dist/lib/pi.d.ts +2 -0
  91. package/node_modules/@llblab/pi-telegram/dist/lib/pi.js +8 -1
  92. package/node_modules/@llblab/pi-telegram/dist/lib/polling.d.ts +23 -37
  93. package/node_modules/@llblab/pi-telegram/dist/lib/polling.js +71 -52
  94. package/node_modules/@llblab/pi-telegram/dist/lib/preview.js +39 -19
  95. package/node_modules/@llblab/pi-telegram/dist/lib/process-identity.d.ts +24 -0
  96. package/node_modules/@llblab/pi-telegram/dist/lib/process-identity.js +133 -0
  97. package/node_modules/@llblab/pi-telegram/dist/lib/prompts.js +2 -7
  98. package/node_modules/@llblab/pi-telegram/dist/lib/queue.d.ts +16 -16
  99. package/node_modules/@llblab/pi-telegram/dist/lib/queue.js +261 -116
  100. package/node_modules/@llblab/pi-telegram/dist/lib/recovery.d.ts +2 -83
  101. package/node_modules/@llblab/pi-telegram/dist/lib/recovery.js +20 -274
  102. package/node_modules/@llblab/pi-telegram/dist/lib/replies.d.ts +16 -24
  103. package/node_modules/@llblab/pi-telegram/dist/lib/replies.js +99 -116
  104. package/node_modules/@llblab/pi-telegram/dist/lib/routing.d.ts +121 -7
  105. package/node_modules/@llblab/pi-telegram/dist/lib/routing.js +4750 -1161
  106. package/node_modules/@llblab/pi-telegram/dist/lib/runtime.d.ts +1 -11
  107. package/node_modules/@llblab/pi-telegram/dist/lib/sections.d.ts +4 -29
  108. package/node_modules/@llblab/pi-telegram/dist/lib/sections.js +7 -20
  109. package/node_modules/@llblab/pi-telegram/dist/lib/skills.js +4 -3
  110. package/node_modules/@llblab/pi-telegram/dist/lib/status.js +86 -57
  111. package/node_modules/@llblab/pi-telegram/dist/lib/sync.d.ts +6 -3
  112. package/node_modules/@llblab/pi-telegram/dist/lib/sync.js +112 -45
  113. package/node_modules/@llblab/pi-telegram/dist/lib/target.d.ts +4 -0
  114. package/node_modules/@llblab/pi-telegram/dist/lib/target.js +18 -0
  115. package/node_modules/@llblab/pi-telegram/dist/lib/telegram-api.d.ts +18 -11
  116. package/node_modules/@llblab/pi-telegram/dist/lib/telegram-api.js +165 -49
  117. package/node_modules/@llblab/pi-telegram/dist/lib/text-groups.js +4 -39
  118. package/node_modules/@llblab/pi-telegram/dist/lib/thread-cleanup-manager.d.ts +6 -27
  119. package/node_modules/@llblab/pi-telegram/dist/lib/thread-cleanup-manager.js +369 -186
  120. package/node_modules/@llblab/pi-telegram/dist/lib/thread-display.d.ts +1 -2
  121. package/node_modules/@llblab/pi-telegram/dist/lib/thread-display.js +58 -38
  122. package/node_modules/@llblab/pi-telegram/dist/lib/thread-naming.d.ts +28 -8
  123. package/node_modules/@llblab/pi-telegram/dist/lib/thread-naming.js +175 -66
  124. package/node_modules/@llblab/pi-telegram/dist/lib/thread-reconciler.d.ts +42 -16
  125. package/node_modules/@llblab/pi-telegram/dist/lib/thread-reconciler.js +90 -50
  126. package/node_modules/@llblab/pi-telegram/dist/lib/threads.d.ts +88 -24
  127. package/node_modules/@llblab/pi-telegram/dist/lib/threads.js +2276 -842
  128. package/node_modules/@llblab/pi-telegram/dist/lib/time-injection.js +1 -2
  129. package/node_modules/@llblab/pi-telegram/dist/lib/turns.js +1 -19
  130. package/node_modules/@llblab/pi-telegram/dist/lib/updates.d.ts +178 -82
  131. package/node_modules/@llblab/pi-telegram/dist/lib/updates.js +2438 -645
  132. package/node_modules/@llblab/pi-telegram/dist/lib/voice.d.ts +7 -22
  133. package/node_modules/@llblab/pi-telegram/dist/lib/voice.js +7 -22
  134. package/node_modules/@llblab/pi-telegram/dist/lib/wire.js +1 -1
  135. package/node_modules/@llblab/pi-telegram/dist/lib/workspace-admission.d.ts +3 -1
  136. package/node_modules/@llblab/pi-telegram/dist/lib/workspace-admission.js +425 -211
  137. package/node_modules/@llblab/pi-telegram/dist/lib/workspace-identity.js +8 -13
  138. package/node_modules/@llblab/pi-telegram/dist/lib/workspace-retirement.d.ts +1 -1
  139. package/node_modules/@llblab/pi-telegram/dist/lib/workspace-retirement.js +328 -140
  140. package/node_modules/@llblab/pi-telegram/dist/lib/workspace-slots.js +8 -4
  141. package/node_modules/@llblab/pi-telegram/dist/package.json +1 -1
  142. package/node_modules/@llblab/pi-telegram/docs/architecture.md +43 -35
  143. package/node_modules/@llblab/pi-telegram/docs/inbound.md +1 -1
  144. package/node_modules/@llblab/pi-telegram/docs/multi-instance-bus.md +15 -3
  145. package/node_modules/@llblab/pi-telegram/docs/outbound.md +1 -1
  146. package/node_modules/@llblab/pi-telegram/docs/public-api.md +29 -1
  147. package/node_modules/@llblab/pi-telegram/docs/ui-style.md +25 -8
  148. package/node_modules/@llblab/pi-telegram/lib/activity-verbosity.ts +59 -82
  149. package/node_modules/@llblab/pi-telegram/lib/activity.ts +146 -102
  150. package/node_modules/@llblab/pi-telegram/lib/agent-messages.ts +12 -5
  151. package/node_modules/@llblab/pi-telegram/lib/bindings.ts +390 -82
  152. package/node_modules/@llblab/pi-telegram/lib/bus-api.ts +262 -99
  153. package/node_modules/@llblab/pi-telegram/lib/bus-follower.ts +2440 -601
  154. package/node_modules/@llblab/pi-telegram/lib/bus-leader.ts +2209 -1290
  155. package/node_modules/@llblab/pi-telegram/lib/bus-transport.ts +46 -12
  156. package/node_modules/@llblab/pi-telegram/lib/bus.ts +1673 -444
  157. package/node_modules/@llblab/pi-telegram/lib/channel-posts.ts +848 -327
  158. package/node_modules/@llblab/pi-telegram/lib/command-templates.ts +152 -265
  159. package/node_modules/@llblab/pi-telegram/lib/commands.ts +2398 -555
  160. package/node_modules/@llblab/pi-telegram/lib/config.ts +177 -170
  161. package/node_modules/@llblab/pi-telegram/lib/delivery.ts +41 -29
  162. package/node_modules/@llblab/pi-telegram/lib/extension.ts +1209 -431
  163. package/node_modules/@llblab/pi-telegram/lib/generative-app-worker.mjs +19 -7
  164. package/node_modules/@llblab/pi-telegram/lib/generative-apps.ts +324 -211
  165. package/node_modules/@llblab/pi-telegram/lib/inbound.ts +95 -97
  166. package/node_modules/@llblab/pi-telegram/lib/journal.ts +5329 -1712
  167. package/node_modules/@llblab/pi-telegram/lib/keyboard.ts +1 -3
  168. package/node_modules/@llblab/pi-telegram/lib/lifecycle.ts +128 -78
  169. package/node_modules/@llblab/pi-telegram/lib/locks.ts +703 -212
  170. package/node_modules/@llblab/pi-telegram/lib/logging.ts +147 -58
  171. package/node_modules/@llblab/pi-telegram/lib/media.ts +82 -43
  172. package/node_modules/@llblab/pi-telegram/lib/menu-model.ts +85 -18
  173. package/node_modules/@llblab/pi-telegram/lib/menu-queue.ts +88 -129
  174. package/node_modules/@llblab/pi-telegram/lib/menu-settings.ts +260 -155
  175. package/node_modules/@llblab/pi-telegram/lib/menu-status.ts +20 -60
  176. package/node_modules/@llblab/pi-telegram/lib/menu-thinking.ts +41 -56
  177. package/node_modules/@llblab/pi-telegram/lib/menu.ts +112 -285
  178. package/node_modules/@llblab/pi-telegram/lib/model.ts +8 -22
  179. package/node_modules/@llblab/pi-telegram/lib/outbound-attachments.ts +156 -125
  180. package/node_modules/@llblab/pi-telegram/lib/outbound-buttons.ts +76 -49
  181. package/node_modules/@llblab/pi-telegram/lib/outbound-markup.ts +96 -94
  182. package/node_modules/@llblab/pi-telegram/lib/outbound-voice.ts +33 -27
  183. package/node_modules/@llblab/pi-telegram/lib/outbound.ts +125 -125
  184. package/node_modules/@llblab/pi-telegram/lib/ownership.ts +19 -10
  185. package/node_modules/@llblab/pi-telegram/lib/paths.ts +148 -49
  186. package/node_modules/@llblab/pi-telegram/lib/pi.ts +35 -15
  187. package/node_modules/@llblab/pi-telegram/lib/polling.ts +165 -149
  188. package/node_modules/@llblab/pi-telegram/lib/preview.ts +93 -40
  189. package/node_modules/@llblab/pi-telegram/lib/process-identity.ts +164 -0
  190. package/node_modules/@llblab/pi-telegram/lib/prompts.ts +4 -11
  191. package/node_modules/@llblab/pi-telegram/lib/queue.ts +523 -289
  192. package/node_modules/@llblab/pi-telegram/lib/recovery.ts +50 -454
  193. package/node_modules/@llblab/pi-telegram/lib/rendering.ts +1 -3
  194. package/node_modules/@llblab/pi-telegram/lib/replies.ts +248 -209
  195. package/node_modules/@llblab/pi-telegram/lib/routing.ts +8527 -2149
  196. package/node_modules/@llblab/pi-telegram/lib/runtime.ts +1 -12
  197. package/node_modules/@llblab/pi-telegram/lib/sections.ts +24 -89
  198. package/node_modules/@llblab/pi-telegram/lib/setup.ts +1 -3
  199. package/node_modules/@llblab/pi-telegram/lib/skills.ts +9 -4
  200. package/node_modules/@llblab/pi-telegram/lib/status.ts +215 -110
  201. package/node_modules/@llblab/pi-telegram/lib/sync.ts +488 -359
  202. package/node_modules/@llblab/pi-telegram/lib/target.ts +22 -3
  203. package/node_modules/@llblab/pi-telegram/lib/telegram-api.ts +322 -122
  204. package/node_modules/@llblab/pi-telegram/lib/text-groups.ts +5 -39
  205. package/node_modules/@llblab/pi-telegram/lib/thread-cleanup-manager.ts +833 -331
  206. package/node_modules/@llblab/pi-telegram/lib/thread-display.ts +213 -97
  207. package/node_modules/@llblab/pi-telegram/lib/thread-naming.ts +232 -87
  208. package/node_modules/@llblab/pi-telegram/lib/thread-reconciler.ts +155 -72
  209. package/node_modules/@llblab/pi-telegram/lib/threads.ts +5329 -1817
  210. package/node_modules/@llblab/pi-telegram/lib/time-injection.ts +1 -4
  211. package/node_modules/@llblab/pi-telegram/lib/turns.ts +15 -28
  212. package/node_modules/@llblab/pi-telegram/lib/updates.ts +5194 -1600
  213. package/node_modules/@llblab/pi-telegram/lib/voice.ts +7 -35
  214. package/node_modules/@llblab/pi-telegram/lib/wire.ts +1 -1
  215. package/node_modules/@llblab/pi-telegram/lib/workspace-admission.ts +996 -416
  216. package/node_modules/@llblab/pi-telegram/lib/workspace-identity.ts +14 -17
  217. package/node_modules/@llblab/pi-telegram/lib/workspace-retirement.ts +878 -376
  218. package/node_modules/@llblab/pi-telegram/lib/workspace-slots.ts +22 -13
  219. package/node_modules/@llblab/pi-telegram/package.json +1 -1
  220. package/package.json +3 -3
  221. package/node_modules/@llblab/pi-telegram/scripts/check-downgrade.mjs +0 -472
  222. package/node_modules/@llblab/pi-telegram/scripts/measure-workspace.mjs +0 -108
@@ -20,10 +20,7 @@ import {
20
20
  const TELEGRAM_ACTIVITY_REGISTRY_KEY = "__piTelegramActivityRegistry__";
21
21
 
22
22
  export type TelegramActivitySource =
23
- | "telegram"
24
- | "local"
25
- | "autonomous"
26
- | "unknown";
23
+ "telegram" | "local" | "autonomous" | "unknown";
27
24
 
28
25
  export type TelegramActivityTarget = Readonly<TelegramDeliveryTarget>;
29
26
 
@@ -38,61 +35,61 @@ export interface TelegramActivityEnvelope {
38
35
 
39
36
  export type TelegramActivityPayload =
40
37
  | { type: "agent-start" }
41
- | {
42
- type: "assistant-text-delta";
43
- contentIndex: number;
44
- delta: string;
45
- }
46
- | {
47
- type: "assistant-segment";
48
- contentIndex: number;
49
- text: string;
50
- placement: "intermediate" | "final" | "terminal-partial";
51
- }
52
- | {
53
- type: "reasoning-delta";
54
- contentIndex: number;
55
- delta: string;
56
- }
57
- | {
58
- type: "reasoning-end";
59
- contentIndex: number;
60
- text: string;
61
- }
62
- | {
63
- type: "tool-start";
64
- toolCallId: string;
65
- toolName: string;
66
- args: unknown;
67
- }
68
- | {
69
- type: "tool-update";
70
- toolCallId: string;
71
- toolName: string;
72
- update: unknown;
73
- }
74
- | {
75
- type: "tool-end";
76
- toolCallId: string;
77
- toolName: string;
78
- result: unknown;
79
- isError: boolean;
80
- }
81
- | {
82
- type: "compaction-start";
83
- reason: "manual" | "threshold" | "overflow" | "unknown";
84
- }
85
- | {
86
- type: "compaction-end";
87
- reason: "manual" | "threshold" | "overflow" | "unknown";
88
- }
89
- | {
90
- type: "ui-prompt-start";
91
- kind: "select" | "confirm" | "input" | "editor" | "custom";
92
- title?: string;
93
- }
94
- | { type: "ui-prompt-end" }
95
- | { type: "agent-end" }
38
+ | {
39
+ type: "assistant-text-delta";
40
+ contentIndex: number;
41
+ delta: string;
42
+ }
43
+ | {
44
+ type: "assistant-segment";
45
+ contentIndex: number;
46
+ text: string;
47
+ placement: "intermediate" | "final" | "terminal-partial";
48
+ }
49
+ | {
50
+ type: "reasoning-delta";
51
+ contentIndex: number;
52
+ delta: string;
53
+ }
54
+ | {
55
+ type: "reasoning-end";
56
+ contentIndex: number;
57
+ text: string;
58
+ }
59
+ | {
60
+ type: "tool-start";
61
+ toolCallId: string;
62
+ toolName: string;
63
+ args: unknown;
64
+ }
65
+ | {
66
+ type: "tool-update";
67
+ toolCallId: string;
68
+ toolName: string;
69
+ update: unknown;
70
+ }
71
+ | {
72
+ type: "tool-end";
73
+ toolCallId: string;
74
+ toolName: string;
75
+ result: unknown;
76
+ isError: boolean;
77
+ }
78
+ | {
79
+ type: "compaction-start";
80
+ reason: "manual" | "threshold" | "overflow" | "unknown";
81
+ }
82
+ | {
83
+ type: "compaction-end";
84
+ reason: "manual" | "threshold" | "overflow" | "unknown";
85
+ }
86
+ | {
87
+ type: "ui-prompt-start";
88
+ kind: "select" | "confirm" | "input" | "editor" | "custom";
89
+ title?: string;
90
+ }
91
+ | { type: "ui-prompt-end" }
92
+ | { type: "agent-end" }
96
93
  | { type: "agent-settled" };
97
94
 
98
95
  export type TelegramActivityEvent = TelegramActivityEnvelope &
@@ -135,8 +132,7 @@ export interface TelegramActivityHandlerRegistration {
135
132
  ) => void | Promise<void>;
136
133
  }
137
134
 
138
- interface RegisteredTelegramActivityHandler
139
- extends TelegramActivityHandlerRegistration {
135
+ interface RegisteredTelegramActivityHandler extends TelegramActivityHandlerRegistration {
140
136
  id: string;
141
137
  order: number;
142
138
  }
@@ -257,10 +253,7 @@ function canCoalesceActivityEvents(
257
253
  previous: TelegramActivityEvent,
258
254
  next: TelegramActivityEvent,
259
255
  ): boolean {
260
- if (
261
- previous.activityId !== next.activityId ||
262
- previous.type !== next.type
263
- ) {
256
+ if (previous.activityId !== next.activityId || previous.type !== next.type) {
264
257
  return false;
265
258
  }
266
259
  if (
@@ -269,10 +262,7 @@ function canCoalesceActivityEvents(
269
262
  ) {
270
263
  return previous.contentIndex === next.contentIndex;
271
264
  }
272
- if (
273
- previous.type === "reasoning-delta" &&
274
- next.type === "reasoning-delta"
275
- ) {
265
+ if (previous.type === "reasoning-delta" && next.type === "reasoning-delta") {
276
266
  return previous.contentIndex === next.contentIndex;
277
267
  }
278
268
  if (previous.type === "tool-update" && next.type === "tool-update") {
@@ -291,10 +281,7 @@ function coalesceActivityEvents(
291
281
  ) {
292
282
  return { ...next, delta: previous.delta + next.delta };
293
283
  }
294
- if (
295
- previous.type === "reasoning-delta" &&
296
- next.type === "reasoning-delta"
297
- ) {
284
+ if (previous.type === "reasoning-delta" && next.type === "reasoning-delta") {
298
285
  return { ...next, delta: previous.delta + next.delta };
299
286
  }
300
287
  return next;
@@ -302,18 +289,21 @@ function coalesceActivityEvents(
302
289
 
303
290
  /** @internal */
304
291
  export interface TelegramActivityDispatcher {
292
+ hasPending?: () => boolean;
305
293
  dispatch: (event: TelegramActivityEvent) => void;
306
294
  stop: () => void;
307
295
  }
308
296
 
309
297
  /** @internal */
310
- export function createTelegramActivityDispatcher(deps: {
311
- recordFailure?: (
312
- handlerId: string,
313
- event: TelegramActivityEvent,
314
- error: unknown,
315
- ) => void;
316
- } = {}): TelegramActivityDispatcher {
298
+ export function createTelegramActivityDispatcher(
299
+ deps: {
300
+ recordFailure?: (
301
+ handlerId: string,
302
+ event: TelegramActivityEvent,
303
+ error: unknown,
304
+ ) => void;
305
+ } = {},
306
+ ): TelegramActivityDispatcher {
317
307
  const queues = new Map<string, TelegramActivityHandlerQueue>();
318
308
  let stopped = false;
319
309
  const drain = async (queue: TelegramActivityHandlerQueue): Promise<void> => {
@@ -335,12 +325,14 @@ export function createTelegramActivityDispatcher(deps: {
335
325
  try {
336
326
  await queue.registration.handle(
337
327
  event,
338
- createTelegramActivityContext(event, () =>
339
- queue.active &&
340
- !stopped &&
341
- getOrCreateTelegramActivityRegistry().handlers.get(
342
- queue.registration.id,
343
- ) === queue.registration,
328
+ createTelegramActivityContext(
329
+ event,
330
+ () =>
331
+ queue.active &&
332
+ !stopped &&
333
+ getOrCreateTelegramActivityRegistry().handlers.get(
334
+ queue.registration.id,
335
+ ) === queue.registration,
344
336
  ),
345
337
  );
346
338
  } catch (error) {
@@ -352,6 +344,10 @@ export function createTelegramActivityDispatcher(deps: {
352
344
  }
353
345
  };
354
346
  return {
347
+ hasPending: () =>
348
+ Array.from(queues.values()).some(
349
+ (queue) => queue.active && (queue.running || queue.events.length > 0),
350
+ ),
355
351
  dispatch(event) {
356
352
  if (stopped) return;
357
353
  for (const registration of getTelegramActivityHandlers()) {
@@ -405,6 +401,7 @@ export function createTelegramActivityBridgeRuntime(deps: {
405
401
  let runtime: TelegramActivityRuntime | undefined;
406
402
  const getRuntime = (): TelegramActivityRuntime | undefined => runtime;
407
403
  return {
404
+ hasPending: () => getRuntime()?.hasPending?.(),
408
405
  onSessionStart() {
409
406
  runtime?.onSessionShutdown();
410
407
  runtime = createTelegramActivityRuntime({
@@ -470,10 +467,7 @@ export function createTelegramActivityBridgeRuntime(deps: {
470
467
  }
471
468
 
472
469
  export type TelegramActivityInputSource =
473
- | "interactive"
474
- | "rpc"
475
- | "extension"
476
- | "unknown";
470
+ "interactive" | "rpc" | "extension" | "unknown";
477
471
 
478
472
  export type TelegramAssistantStreamEvent =
479
473
  | { type: "start" }
@@ -491,9 +485,13 @@ export type TelegramAssistantStreamEvent =
491
485
 
492
486
  /** @internal */
493
487
  export interface TelegramActivityRuntime {
488
+ hasPending?: () => boolean | undefined;
494
489
  onSessionStart?: () => void;
495
490
  recordInputSource: (source: TelegramActivityInputSource) => void;
496
- onAgentStart: (activeTelegramTarget?: TelegramActivityTarget, replyToMessageId?: number) => void;
491
+ onAgentStart: (
492
+ activeTelegramTarget?: TelegramActivityTarget,
493
+ replyToMessageId?: number,
494
+ ) => void;
497
495
  onAssistantEvent: (event: TelegramAssistantStreamEvent) => void;
498
496
  onAssistantMessageEnd: (stopReason?: string) => void;
499
497
  onToolStart: (event: {
@@ -586,7 +584,9 @@ export function createTelegramActivityRuntime(deps: {
586
584
  sequence,
587
585
  source: activitySource,
588
586
  ...(activityTarget ? { target: activityTarget } : {}),
589
- ...(activityReplyToMessageId !== undefined ? { replyToMessageId: activityReplyToMessageId } : {}),
587
+ ...(activityReplyToMessageId !== undefined
588
+ ? { replyToMessageId: activityReplyToMessageId }
589
+ : {}),
590
590
  timestamp: now(),
591
591
  } as TelegramActivityEvent;
592
592
  try {
@@ -628,13 +628,15 @@ export function createTelegramActivityRuntime(deps: {
628
628
  if (shouldClearActivity) clearActivity();
629
629
  };
630
630
  return {
631
+ hasPending: () => deps.dispatcher.hasPending?.(),
631
632
  recordInputSource(source) {
632
633
  pendingInputSource = source;
633
634
  },
634
635
  onAgentStart(activeTelegramTarget, replyToMessageId) {
635
636
  abandonCompaction();
636
637
  ensureActivity(activeTelegramTarget);
637
- activityReplyToMessageId = activitySource === "telegram" ? replyToMessageId : undefined;
638
+ activityReplyToMessageId =
639
+ activitySource === "telegram" ? replyToMessageId : undefined;
638
640
  emit({ type: "agent-start" });
639
641
  },
640
642
  onAssistantEvent(event) {
@@ -750,21 +752,33 @@ export interface TelegramActivityPublicationReservation {
750
752
  cancel: () => void;
751
753
  }
752
754
 
755
+ export interface TelegramActivityPublicationWork {
756
+ settle(outcome: "settled" | "unconfirmed"): void;
757
+ }
758
+
753
759
  export interface TelegramActivityPublicationRuntime {
754
760
  enqueue: (task: () => Promise<void>) => Promise<void>;
755
761
  reserve: () => TelegramActivityPublicationReservation;
762
+ hasPending: () => boolean;
763
+ /** Observation only; detached work never occupies the ordered publication tail. */
764
+ beginWork: () => TelegramActivityPublicationWork;
765
+ hasUnconfirmed: () => boolean;
756
766
  reset: () => void;
757
767
  }
758
768
 
759
769
  export function createTelegramActivityPublicationRuntime(): TelegramActivityPublicationRuntime {
760
770
  let generation = 0;
761
771
  let tail = Promise.resolve();
772
+ let outstanding = 0,
773
+ unconfirmed = false;
762
774
  const pending = new Set<() => void>();
763
775
  const reserve = (): TelegramActivityPublicationReservation => {
764
776
  const admittedGeneration = generation;
765
777
  let state: "pending" | "published" | "cancelled" = "pending";
766
778
  let resolve!: (task: (() => Promise<void>) | undefined) => void;
767
- const ready = new Promise<(() => Promise<void>) | undefined>((accept) => { resolve = accept; });
779
+ const ready = new Promise<(() => Promise<void>) | undefined>((accept) => {
780
+ resolve = accept;
781
+ });
768
782
  const cancel = () => {
769
783
  if (state !== "pending") return;
770
784
  state = "cancelled";
@@ -772,15 +786,23 @@ export function createTelegramActivityPublicationRuntime(): TelegramActivityPubl
772
786
  resolve(undefined);
773
787
  };
774
788
  pending.add(cancel);
775
- const result = tail.then(async () => {
776
- const task = await ready;
777
- if (admittedGeneration === generation && task) await task();
778
- });
789
+ outstanding += 1;
790
+ const result = tail
791
+ .then(async () => {
792
+ const task = await ready;
793
+ if (admittedGeneration === generation && task) await task();
794
+ })
795
+ .finally(() => {
796
+ outstanding -= 1;
797
+ });
779
798
  tail = result.catch(() => {});
780
799
  return {
781
800
  publish(task) {
782
801
  if (state === "cancelled") return result;
783
- if (state === "published") return Promise.reject(new Error("Publication reservation already published."));
802
+ if (state === "published")
803
+ return Promise.reject(
804
+ new Error("Publication reservation already published."),
805
+ );
784
806
  state = "published";
785
807
  pending.delete(cancel);
786
808
  resolve(task);
@@ -792,8 +814,25 @@ export function createTelegramActivityPublicationRuntime(): TelegramActivityPubl
792
814
  return {
793
815
  reserve,
794
816
  enqueue: (task) => reserve().publish(task),
817
+ hasPending: () => outstanding > 0,
818
+ hasUnconfirmed: () => unconfirmed,
819
+ beginWork() {
820
+ const admittedGeneration = generation;
821
+ let settled = false;
822
+ outstanding += 1;
823
+ return {
824
+ settle(outcome) {
825
+ if (settled) return;
826
+ settled = true;
827
+ outstanding -= 1;
828
+ if (outcome === "unconfirmed" && admittedGeneration === generation)
829
+ unconfirmed = true;
830
+ },
831
+ };
832
+ },
795
833
  reset() {
796
834
  generation += 1;
835
+ unconfirmed = false;
797
836
  for (const cancel of pending) cancel();
798
837
  tail = Promise.resolve();
799
838
  },
@@ -816,8 +855,12 @@ export interface TelegramAssistantOutputPreparation {
816
855
  settle: () => void;
817
856
  }
818
857
 
819
- export function createTelegramAssistantOutputRuntime<TAuthority = undefined>(deps: {
820
- prepareSend?: (event: TelegramAssistantSegmentEvent) => TelegramAssistantOutputPreparation | undefined;
858
+ export function createTelegramAssistantOutputRuntime<
859
+ TAuthority = undefined,
860
+ >(deps: {
861
+ prepareSend?: (
862
+ event: TelegramAssistantSegmentEvent,
863
+ ) => TelegramAssistantOutputPreparation | undefined;
821
864
  enqueue?: TelegramActivityPublicationRuntime["enqueue"];
822
865
  captureAuthority?: () => TAuthority;
823
866
  isAuthorityActive?: (authority: TAuthority) => boolean;
@@ -865,7 +908,8 @@ export function createTelegramAssistantOutputRuntime<TAuthority = undefined>(dep
865
908
  const admittedGeneration = generation;
866
909
  const admittedAuthority = deps.captureAuthority?.();
867
910
  const preparation = deps.prepareSend?.(event);
868
- const enqueue = deps.enqueue ?? ((task: () => Promise<void>) => tail.then(task));
911
+ const enqueue =
912
+ deps.enqueue ?? ((task: () => Promise<void>) => tail.then(task));
869
913
  tail = enqueue(async () => {
870
914
  const isAdmittedAuthorityActive = () =>
871
915
  running &&
@@ -39,8 +39,12 @@ export function createTelegramAgentMessageRuntime<TContext, TUpdate>(
39
39
  const leaderTarget = deps.getLeaderTarget();
40
40
  if (leaderTarget?.threadId) {
41
41
  targets.push({
42
- target: { chatId: leaderTarget.chatId, threadId: leaderTarget.threadId },
43
- threadName: deps.getDisplayTitle?.(leaderTarget) ?? deps.getLeaderThreadName(),
42
+ target: {
43
+ chatId: leaderTarget.chatId,
44
+ threadId: leaderTarget.threadId,
45
+ },
46
+ threadName:
47
+ deps.getDisplayTitle?.(leaderTarget) ?? deps.getLeaderThreadName(),
44
48
  });
45
49
  }
46
50
  for (const follower of deps.followerRegistry.list()) {
@@ -50,7 +54,8 @@ export function createTelegramAgentMessageRuntime<TContext, TUpdate>(
50
54
  chatId: follower.target.chatId,
51
55
  threadId: follower.target.threadId,
52
56
  },
53
- threadName: deps.getDisplayTitle?.(follower.target) ?? follower.threadName,
57
+ threadName:
58
+ deps.getDisplayTitle?.(follower.target) ?? follower.threadName,
54
59
  });
55
60
  }
56
61
  return targets;
@@ -99,8 +104,10 @@ export function createTelegramAgentMessageRuntime<TContext, TUpdate>(
99
104
  if (allowedChatId === undefined || !ctx) {
100
105
  throw new Error("Telegram agent turn routing is unavailable.");
101
106
  }
102
- const sourceTitle = (input.sourceTarget ? deps.getDisplayTitle?.(input.sourceTarget) : undefined)
103
- ?? input.sourceThreadName;
107
+ const sourceTitle =
108
+ (input.sourceTarget
109
+ ? deps.getDisplayTitle?.(input.sourceTarget)
110
+ : undefined) ?? input.sourceThreadName;
104
111
  const sourceLabel =
105
112
  sourceTitle
106
113
  ?.replace(/[\r\n\[\]]+/g, " ")