@llblab/pi-kit 0.6.0 → 0.7.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 (123) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +4 -4
  3. package/node_modules/@llblab/pi-actors/AGENTS.md +1 -1
  4. package/node_modules/@llblab/pi-actors/CHANGELOG.md +6 -0
  5. package/node_modules/@llblab/pi-actors/README.md +1 -1
  6. package/node_modules/@llblab/pi-actors/dist/lib/async-runs.d.ts +3 -0
  7. package/node_modules/@llblab/pi-actors/dist/lib/async-runs.js +14 -1
  8. package/node_modules/@llblab/pi-actors/dist/lib/command-templates.js +45 -3
  9. package/node_modules/@llblab/pi-actors/dist/lib/extension-runtime.js +1 -1
  10. package/node_modules/@llblab/pi-actors/dist/lib/observability.d.ts +16 -3
  11. package/node_modules/@llblab/pi-actors/dist/lib/observability.js +92 -7
  12. package/node_modules/@llblab/pi-actors/dist/lib/pi.d.ts +0 -1
  13. package/node_modules/@llblab/pi-actors/dist/lib/pi.js +15 -24
  14. package/node_modules/@llblab/pi-actors/dist/lib/run-delivery-lineage.d.ts +17 -0
  15. package/node_modules/@llblab/pi-actors/dist/lib/run-delivery-lineage.js +44 -0
  16. package/node_modules/@llblab/pi-actors/dist/lib/run-delivery.d.ts +4 -0
  17. package/node_modules/@llblab/pi-actors/dist/lib/run-delivery.js +102 -4
  18. package/node_modules/@llblab/pi-actors/dist/lib/run-ui-runtime.js +58 -39
  19. package/node_modules/@llblab/pi-actors/dist/lib/runtime.js +14 -6
  20. package/node_modules/@llblab/pi-actors/dist/skills/actors/SKILL.md +1 -1
  21. package/node_modules/@llblab/pi-actors/docs/async-runs.md +1 -1
  22. package/node_modules/@llblab/pi-actors/docs/coordinator-delivery.md +18 -23
  23. package/node_modules/@llblab/pi-actors/lib/async-runs.ts +18 -1
  24. package/node_modules/@llblab/pi-actors/lib/command-templates.ts +41 -3
  25. package/node_modules/@llblab/pi-actors/lib/extension-runtime.ts +1 -1
  26. package/node_modules/@llblab/pi-actors/lib/observability.ts +119 -5
  27. package/node_modules/@llblab/pi-actors/lib/pi.ts +15 -28
  28. package/node_modules/@llblab/pi-actors/lib/run-delivery-lineage.ts +68 -0
  29. package/node_modules/@llblab/pi-actors/lib/run-delivery.ts +120 -4
  30. package/node_modules/@llblab/pi-actors/lib/run-ui-runtime.ts +69 -44
  31. package/node_modules/@llblab/pi-actors/lib/runtime.ts +17 -6
  32. package/node_modules/@llblab/pi-actors/package.json +1 -1
  33. package/node_modules/@llblab/pi-actors/skills/actors/SKILL.md +1 -1
  34. package/node_modules/@llblab/pi-state-flow/AGENTS.md +33 -12
  35. package/node_modules/@llblab/pi-state-flow/BACKLOG.md +125 -2
  36. package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +87 -45
  37. package/node_modules/@llblab/pi-state-flow/README.md +203 -107
  38. package/node_modules/@llblab/pi-state-flow/docs/README.md +4 -0
  39. package/node_modules/@llblab/pi-state-flow/docs/architecture.md +188 -0
  40. package/node_modules/@llblab/pi-state-flow/docs/temporal-acceptance.md +42 -0
  41. package/node_modules/@llblab/pi-state-flow/index.ts +164 -2
  42. package/node_modules/@llblab/pi-state-flow/lib/acquisition.ts +138 -0
  43. package/node_modules/@llblab/pi-state-flow/lib/artifact.ts +273 -0
  44. package/node_modules/@llblab/pi-state-flow/lib/config.ts +48 -0
  45. package/node_modules/@llblab/pi-state-flow/lib/context.ts +18 -5
  46. package/node_modules/@llblab/pi-state-flow/lib/continuation.ts +268 -0
  47. package/node_modules/@llblab/pi-state-flow/lib/discovery.ts +117 -0
  48. package/node_modules/@llblab/pi-state-flow/lib/durable.ts +562 -0
  49. package/node_modules/@llblab/pi-state-flow/lib/episode.ts +24 -12
  50. package/node_modules/@llblab/pi-state-flow/lib/extension.ts +606 -70
  51. package/node_modules/@llblab/pi-state-flow/lib/git.ts +666 -0
  52. package/node_modules/@llblab/pi-state-flow/lib/history.ts +95 -0
  53. package/node_modules/@llblab/pi-state-flow/lib/json.ts +24 -0
  54. package/node_modules/@llblab/pi-state-flow/lib/maintenance.ts +141 -0
  55. package/node_modules/@llblab/pi-state-flow/lib/memory.ts +52 -0
  56. package/node_modules/@llblab/pi-state-flow/lib/migration.ts +88 -0
  57. package/node_modules/@llblab/pi-state-flow/lib/publication.ts +296 -0
  58. package/node_modules/@llblab/pi-state-flow/lib/recovery.ts +23 -7
  59. package/node_modules/@llblab/pi-state-flow/lib/rehydration.ts +79 -0
  60. package/node_modules/@llblab/pi-state-flow/lib/runtime.ts +264 -0
  61. package/node_modules/@llblab/pi-state-flow/lib/session.ts +6 -0
  62. package/node_modules/@llblab/pi-state-flow/lib/skills.ts +99 -7
  63. package/node_modules/@llblab/pi-state-flow/lib/snapshot.ts +305 -48
  64. package/node_modules/@llblab/pi-state-flow/lib/state.ts +74 -7
  65. package/node_modules/@llblab/pi-state-flow/lib/status.ts +125 -6
  66. package/node_modules/@llblab/pi-state-flow/lib/storage.ts +196 -0
  67. package/node_modules/@llblab/pi-state-flow/lib/temporal.ts +233 -0
  68. package/node_modules/@llblab/pi-state-flow/lib/terminal.ts +70 -24
  69. package/node_modules/@llblab/pi-state-flow/lib/transition.ts +254 -29
  70. package/node_modules/@llblab/pi-state-flow/package.json +8 -2
  71. package/node_modules/@llblab/pi-state-flow/skills/state-flow-memory/SKILL.md +128 -0
  72. package/node_modules/@llblab/pi-telegram/AGENTS.md +13 -8
  73. package/node_modules/@llblab/pi-telegram/BACKLOG.md +20 -3
  74. package/node_modules/@llblab/pi-telegram/CHANGELOG.md +13 -0
  75. package/node_modules/@llblab/pi-telegram/README.md +12 -8
  76. package/node_modules/@llblab/pi-telegram/docs/README.md +1 -0
  77. package/node_modules/@llblab/pi-telegram/docs/architecture.md +220 -18
  78. package/node_modules/@llblab/pi-telegram/docs/generative-apps.md +1 -1
  79. package/node_modules/@llblab/pi-telegram/docs/multi-instance-bus.md +70 -19
  80. package/node_modules/@llblab/pi-telegram/docs/outbound.md +6 -6
  81. package/node_modules/@llblab/pi-telegram/docs/public-api.md +12 -5
  82. package/node_modules/@llblab/pi-telegram/docs/ui-style.md +3 -1
  83. package/node_modules/@llblab/pi-telegram/index.ts +4 -1418
  84. package/node_modules/@llblab/pi-telegram/lib/agent-messages.ts +6 -3
  85. package/node_modules/@llblab/pi-telegram/lib/bindings.ts +28 -1
  86. package/node_modules/@llblab/pi-telegram/lib/bus-follower.ts +600 -135
  87. package/node_modules/@llblab/pi-telegram/lib/bus-leader.ts +962 -55
  88. package/node_modules/@llblab/pi-telegram/lib/bus.ts +350 -26
  89. package/node_modules/@llblab/pi-telegram/lib/channel-posts.ts +544 -0
  90. package/node_modules/@llblab/pi-telegram/lib/commands.ts +234 -11
  91. package/node_modules/@llblab/pi-telegram/lib/config.ts +177 -24
  92. package/node_modules/@llblab/pi-telegram/lib/extension.ts +1792 -0
  93. package/node_modules/@llblab/pi-telegram/lib/generative-apps.ts +20 -2
  94. package/node_modules/@llblab/pi-telegram/lib/journal.ts +2184 -126
  95. package/node_modules/@llblab/pi-telegram/lib/locks.ts +38 -1
  96. package/node_modules/@llblab/pi-telegram/lib/menu-settings.ts +152 -13
  97. package/node_modules/@llblab/pi-telegram/lib/outbound-attachments.ts +51 -10
  98. package/node_modules/@llblab/pi-telegram/lib/paths.ts +29 -0
  99. package/node_modules/@llblab/pi-telegram/lib/polling.ts +85 -17
  100. package/node_modules/@llblab/pi-telegram/lib/prompts.ts +5 -2
  101. package/node_modules/@llblab/pi-telegram/lib/queue.ts +52 -18
  102. package/node_modules/@llblab/pi-telegram/lib/replies.ts +2 -2
  103. package/node_modules/@llblab/pi-telegram/lib/routing.ts +305 -112
  104. package/node_modules/@llblab/pi-telegram/lib/status.ts +10 -0
  105. package/node_modules/@llblab/pi-telegram/lib/sync.ts +308 -39
  106. package/node_modules/@llblab/pi-telegram/lib/telegram-api.ts +279 -4
  107. package/node_modules/@llblab/pi-telegram/lib/thread-cleanup-manager.ts +664 -0
  108. package/node_modules/@llblab/pi-telegram/lib/thread-display.ts +226 -0
  109. package/node_modules/@llblab/pi-telegram/lib/thread-naming.ts +118 -0
  110. package/node_modules/@llblab/pi-telegram/lib/threads.ts +1686 -129
  111. package/node_modules/@llblab/pi-telegram/lib/updates.ts +1319 -97
  112. package/node_modules/@llblab/pi-telegram/lib/workspace-admission.ts +1643 -0
  113. package/node_modules/@llblab/pi-telegram/lib/workspace-retirement.ts +968 -0
  114. package/node_modules/@llblab/pi-telegram/lib/workspace-slots.ts +84 -0
  115. package/node_modules/@llblab/pi-telegram/package.json +1 -1
  116. package/node_modules/@llblab/pi-telegram/screenshot.png +0 -0
  117. package/node_modules/@llblab/pi-telegram/scripts/measure-bus.mjs +83 -0
  118. package/node_modules/@llblab/pi-telegram/scripts/measure-workspace.mjs +101 -0
  119. package/node_modules/@llblab/{skills → pi-telegram/skills}/show-me/SKILL.md +28 -6
  120. package/node_modules/@llblab/pi-telegram/skills/show-me/references/telegram-surfaces.md +43 -0
  121. package/node_modules/@llblab/pi-telegram/skills/telegram-bridge/references/delivery-and-threads.md +1 -1
  122. package/node_modules/@llblab/skills/package.json +2 -3
  123. package/package.json +6 -5
@@ -1,1421 +1,7 @@
1
1
  /**
2
- * Telegram bridge extension entrypoint and orchestration layer
3
- * Zones: telegram, pi agent, orchestration
4
- * Keeps the runtime wiring in one place while delegating reusable domain logic to /lib modules
2
+ * Telegram package entrypoint
3
+ * Zones: telegram, pi agent, public API
4
+ * Re-exports the extension composition root without owning runtime wiring.
5
5
  */
6
6
 
7
- import * as AgentMessages from "./lib/agent-messages.ts";
8
- import * as Bindings from "./lib/bindings.ts";
9
- import * as BusApi from "./lib/bus-api.ts";
10
- import * as BusFollower from "./lib/bus-follower.ts";
11
- import * as BusLeader from "./lib/bus-leader.ts";
12
- import * as BusTransport from "./lib/bus-transport.ts";
13
- import * as Bus from "./lib/bus.ts";
14
- import * as CommandTemplates from "./lib/command-templates.ts";
15
- import * as Commands from "./lib/commands.ts";
16
- import * as Config from "./lib/config.ts";
17
- import * as Delivery from "./lib/delivery.ts";
18
- import * as Inbound from "./lib/inbound.ts";
19
- import * as Journal from "./lib/journal.ts";
20
- import * as Lifecycle from "./lib/lifecycle.ts";
21
- import * as Locks from "./lib/locks.ts";
22
- import * as Logs from "./lib/logs.ts";
23
- import * as Media from "./lib/media.ts";
24
- import * as MenuQueue from "./lib/menu-queue.ts";
25
- import * as MenuSettings from "./lib/menu-settings.ts";
26
- import * as Menu from "./lib/menu.ts";
27
- import * as Model from "./lib/model.ts";
28
- import * as Outbound from "./lib/outbound.ts";
29
- import * as Ownership from "./lib/ownership.ts";
30
- import * as Paths from "./lib/paths.ts";
31
- import * as Pi from "./lib/pi.ts";
32
- import * as Polling from "./lib/polling.ts";
33
- import * as Preview from "./lib/preview.ts";
34
- import * as PromptTemplates from "./lib/prompt-templates.ts";
35
- import * as Prompts from "./lib/prompts.ts";
36
- import * as Queue from "./lib/queue.ts";
37
- import * as Recovery from "./lib/recovery.ts";
38
- import * as Replies from "./lib/replies.ts";
39
- import * as Routing from "./lib/routing.ts";
40
- import * as Runtime from "./lib/runtime.ts";
41
- import * as Sections from "./lib/sections.ts";
42
- import * as Skills from "./lib/skills.ts";
43
- import * as Status from "./lib/status.ts";
44
- import * as Sync from "./lib/sync.ts";
45
- import * as TelegramApi from "./lib/telegram-api.ts";
46
- import * as TextGroups from "./lib/text-groups.ts";
47
- import * as ThreadReconciler from "./lib/thread-reconciler.ts";
48
- import * as Threads from "./lib/threads.ts";
49
- import * as TimeInjection from "./lib/time-injection.ts";
50
- import * as Updates from "./lib/updates.ts";
51
- import * as Voice from "./lib/voice.ts";
52
-
53
- type ActivePiModel = NonNullable<Pi.ExtensionContext["model"]>;
54
-
55
- const telegramBusProtocolIdentity =
56
- Bus.createTelegramCurrentBusProtocolIdentity([
57
- Bus.TELEGRAM_BUS_CAPABILITY_DURABLE_FOLLOWER_ADMISSION,
58
- Bus.TELEGRAM_BUS_CAPABILITY_QUEUE_HANDOFF,
59
- ]);
60
-
61
- // --- Extension Runtime ---
62
-
63
- export default function (pi: Pi.ExtensionAPI) {
64
- Skills.registerTelegramSkillDiscovery(pi);
65
- const piRuntime = Pi.createExtensionApiRuntimePorts(pi);
66
- const {
67
- getActiveTools,
68
- getCommands,
69
- getThinkingLevel,
70
- sendUserMessage,
71
- setActiveTools,
72
- setModel,
73
- setThinkingLevel,
74
- } = piRuntime;
75
- const bridgeRuntime = Runtime.createTelegramBridgeRuntime();
76
- const runtimeDiagnostics =
77
- Logs.createTelegramRuntimeDiagnosticsRuntime<Pi.ExtensionContext>();
78
- const runtimeEvents = runtimeDiagnostics.events;
79
- const recordRuntimeEvent = runtimeDiagnostics.recordRuntimeEvent;
80
- const configStore = Config.createTelegramConfigStore({ recordRuntimeEvent });
81
- const busProcessRuntime = Bus.createCurrentTelegramBusProcessRuntime({
82
- getActiveProfileName: configStore.getActiveProfileName,
83
- });
84
- const {
85
- instanceId: telegramInstanceId,
86
- processId: telegramProcessId,
87
- processBirthId: telegramQueueProcessBirthId,
88
- manualFollowerOwnerId: telegramManualFollowerOwnerId,
89
- getLeaderSocketPath: getTelegramBusSocketPath,
90
- getFollowerSocketPath: getTelegramBusFollowerSocketPath,
91
- } = busProcessRuntime;
92
- const getTelegramBotId = Config.createTelegramConfigBotIdGetter(configStore);
93
- const getTelegramActiveProfileKey =
94
- Config.createTelegramActiveProfileKeyGetter(configStore);
95
- const getTelegramManualFollowerProfileKey =
96
- BusFollower.createTelegramManualFollowerProfileKeyResolver({
97
- getActiveProfileName: configStore.getActiveProfileName,
98
- manualFollowerOwnerId: telegramManualFollowerOwnerId,
99
- });
100
- const telegramBusAuthSecret = Bus.createTelegramBusAuthSecret();
101
- const telegramBusFollowerControlState =
102
- BusFollower.createTelegramBusFollowerControlState();
103
- const telegramBusFollowerRegistry = Bus.createTelegramBusFollowerRegistry();
104
- const modelContextAvailabilityBinding =
105
- Prompts.createTelegramModelContextAvailabilityBinding();
106
- const telegramBusFollowerRegistrationState =
107
- BusFollower.createTelegramBusFollowerRegistrationState({
108
- onAvailabilityChanged: modelContextAvailabilityBinding.reconcile,
109
- });
110
- const telegramBusLeaderState =
111
- Threads.createTelegramLeaderThreadStateRuntime();
112
- const telegramThreadCapabilityState =
113
- Polling.createTelegramThreadCapabilityStateRuntime();
114
- const telegramProvisioningActivity =
115
- Sync.createTelegramProvisioningActivityRuntime();
116
- const messageOwnershipRuntime =
117
- Ownership.createTelegramBusMessageOwnershipRuntime({
118
- instanceId: telegramInstanceId,
119
- getProfileKey: getTelegramActiveProfileKey,
120
- listFollowers: telegramBusFollowerRegistry.list,
121
- });
122
- const { abort, lifecycle, queue, setup, typing } = bridgeRuntime;
123
- const getTelegramUpdateAdmissionScope =
124
- Journal.createTelegramUpdateJournalReceiptScopeResolver({
125
- getProfileName: configStore.getActiveProfileName,
126
- getBotToken: configStore.getBotToken,
127
- getBotId: getTelegramBotId,
128
- });
129
- const telegramJournalBindingRuntime =
130
- Journal.createTelegramUpdateJournalBindingRuntime({
131
- base: {
132
- getProfileName: configStore.getActiveProfileName,
133
- getBotToken: configStore.getBotToken,
134
- getBotId: getTelegramBotId,
135
- onRecovery(event) {
136
- recordRuntimeEvent(
137
- "recovery",
138
- event.kind === "repaired"
139
- ? "Telegram update journal was repaired automatically."
140
- : "Telegram update journal was reset after its damaged files were quarantined.",
141
- {
142
- phase: "journal-auto-recovery",
143
- recoveryKind: event.kind,
144
- journalPath: event.path,
145
- revision: event.revision,
146
- quarantinePath: event.quarantinePath,
147
- reason: event.reason,
148
- },
149
- );
150
- },
151
- getQueueRuntimeIdentity() {
152
- return {
153
- instanceId: telegramInstanceId,
154
- processId: telegramProcessId,
155
- processBirthId: telegramQueueProcessBirthId,
156
- };
157
- },
158
- },
159
- getLeaderJournalPath: Paths.resolveTelegramUpdateJournalPath,
160
- getFollowerJournalPath(bindingKey, profileName) {
161
- return Paths.resolveTelegramFollowerJournalPath(
162
- bindingKey,
163
- undefined,
164
- profileName,
165
- );
166
- },
167
- getActiveFollowerBindingKey: getTelegramManualFollowerProfileKey,
168
- isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
169
- });
170
- const resolveTelegramUpdateJournalBinding =
171
- telegramJournalBindingRuntime.resolveLeader;
172
- const resolveTelegramFollowerJournalBinding =
173
- telegramJournalBindingRuntime.resolveFollower;
174
- const getTelegramQueueJournalBinding =
175
- telegramJournalBindingRuntime.getActiveRecoveryKey;
176
- const isTelegramBusRuntimeEnabled =
177
- telegramThreadCapabilityState.isBusRuntimeEnabled;
178
- Config.bindGlobalTelegramConfigRuntime(configStore);
179
- const configControls = Config.createTelegramConfigControls(configStore);
180
- const lockRuntime = Locks.createTelegramLockRuntime<Pi.ExtensionContext>({
181
- key: Locks.createTelegramLockKeyResolver(configStore),
182
- instanceId: telegramInstanceId,
183
- busSecret: telegramBusAuthSecret,
184
- staleHeartbeatMs: Locks.TELEGRAM_BUS_LEADER_STALE_HEARTBEAT_MS,
185
- });
186
- const threadStore = Threads.createTelegramTopicTargetStore({
187
- path: function () {
188
- return Threads.getTelegramTopicTargetsPath(
189
- undefined,
190
- configStore.getActiveProfileName(),
191
- );
192
- },
193
- canPersist: lockRuntime.owns,
194
- commitPersist: lockRuntime.commitIfOwned,
195
- });
196
- runtimeDiagnostics.bindStorage({
197
- getBotToken: configStore.getBotToken,
198
- getProfileName: configStore.getActiveProfileName,
199
- canReset: lockRuntime.owns,
200
- commitReset: lockRuntime.commitIfOwned,
201
- });
202
- const lockOwnershipGuard =
203
- Locks.createTelegramLockOwnershipGuard(lockRuntime);
204
- const getCurrentLeaderEpoch = lockRuntime.getOwnedLeaderEpoch;
205
- const telegramSessionContextStore =
206
- Lifecycle.createTelegramSessionContextStore<Pi.ExtensionContext>({
207
- getIdentity(ctx) {
208
- return ctx.sessionManager ?? ctx.cwd;
209
- },
210
- });
211
- const ownsTelegramDirectDelivery =
212
- Locks.createTelegramDirectDeliveryOwnershipChecker({
213
- lock: lockRuntime,
214
- contextStore: telegramSessionContextStore,
215
- });
216
- const modelContextAvailabilityRuntime =
217
- Prompts.createTelegramModelContextAvailabilityRuntime({
218
- getActiveTools,
219
- setActiveTools,
220
- isAvailable() {
221
- return (
222
- ownsTelegramDirectDelivery() ||
223
- telegramBusFollowerRegistrationState.isRegistered()
224
- );
225
- },
226
- canReconcile() {
227
- const ctx = telegramSessionContextStore.get();
228
- return !ctx || Pi.isExtensionContextIdle(ctx);
229
- },
230
- });
231
- modelContextAvailabilityBinding.bind(modelContextAvailabilityRuntime);
232
- const activeTurnRuntime = Queue.createTelegramActiveTurnStore();
233
- const proactivePushTargetGetter =
234
- Config.createTelegramProactivePushTargetGetter({
235
- getActiveTurnTarget: activeTurnRuntime.getTarget,
236
- getAssignedTarget() {
237
- return (
238
- telegramBusFollowerRegistrationState.getTarget() ??
239
- telegramBusLeaderState.getTarget()
240
- );
241
- },
242
- getAllowedUserId: configStore.getAllowedUserId,
243
- });
244
- const proactivePushChatIdGetter =
245
- Config.createTelegramProactivePushChatIdGetter(proactivePushTargetGetter);
246
- const buttonActionStore = Outbound.createTelegramButtonActionStore();
247
- const planGenerativeAppOutput =
248
- Outbound.createTelegramOutboundReplyPlanner(
249
- buttonActionStore,
250
- configControls.getAssistantRenderingMode,
251
- );
252
- const pendingModelSwitchStore =
253
- Model.createPendingModelSwitchStore<
254
- Model.ScopedTelegramModel<ActivePiModel>
255
- >();
256
- const modelMenuRuntime = Menu.createTelegramModelMenuRuntime<ActivePiModel>();
257
- const sectionRegistry = Sections.createAndBindTelegramSectionRegistry();
258
-
259
- const timeInjectionRuntime = TimeInjection.createTimeInjectionRuntime({
260
- getConfig: Config.createTelegramTimeConfigGetter(configStore),
261
- recordRuntimeEvent,
262
- });
263
- Outbound.bindTelegramRuntimeEventRecorder(recordRuntimeEvent);
264
- const getContextModel = Pi.getExtensionContextModel;
265
- const isIdle = Pi.isExtensionContextIdle;
266
- const hasPendingMessages = Pi.hasExtensionContextPendingMessages;
267
- const compact = Pi.compactExtensionContext;
268
- const mediaGroupRuntime = Media.createTelegramMediaGroupController<
269
- TelegramApi.TelegramMessage,
270
- Pi.ExtensionContext
271
- >();
272
- const textGroupRuntime = TextGroups.createTelegramTextGroupController<
273
- TelegramApi.TelegramMessage,
274
- Pi.ExtensionContext
275
- >();
276
- const rawTelegramQueueStore =
277
- Queue.createTelegramQueueStore<Pi.ExtensionContext>();
278
- const telegramTransportStampRuntime =
279
- Queue.createTelegramTransportStampRuntime({
280
- getProfileName: configStore.getActiveProfileName,
281
- getBotToken: configStore.getBotToken,
282
- });
283
- const telegramQueueStore = Queue.createTelegramTransportStampedQueueStore(
284
- rawTelegramQueueStore,
285
- telegramTransportStampRuntime.getStamp,
286
- );
287
- const updateAdmissionRuntimeBinding =
288
- Updates.createTelegramUpdateAdmissionRuntimeBinding<Pi.ExtensionContext>({
289
- isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
290
- });
291
- const deferredQueueDispatchRuntime =
292
- Queue.createTelegramDeferredQueueDispatchRuntime<Pi.ExtensionContext>({
293
- recordRuntimeEvent,
294
- });
295
- const pollingControllerState = Polling.createTelegramPollingControllerState();
296
- const telegramSyncStateRuntime = Sync.createTelegramSyncStateRuntime();
297
- const threadReconciliationRuntime =
298
- ThreadReconciler.createThreadReconciliationRuntime({
299
- recordRuntimeEvent,
300
- scheduleSnapshotPersist: runtimeDiagnostics.scheduleSnapshotPersist,
301
- });
302
- const recordThreadReconciliationPlan = threadReconciliationRuntime.recordPlan;
303
- const persistTelegramConfigWithSync =
304
- Sync.createTelegramConfigSyncPersister<Config.TelegramConfig>({
305
- persist: configStore.persist,
306
- markConfigChange: telegramSyncStateRuntime.markConfigChange,
307
- });
308
- const {
309
- current: currentInstanceThreadRuntime,
310
- status: threadStatusProjectionRuntime,
311
- } = Threads.createTelegramCurrentThreadAssembly({
312
- instanceId: telegramInstanceId,
313
- listRecords: threadStore.list,
314
- getActiveTurnTarget: activeTurnRuntime.getTarget,
315
- getFollowerTarget: telegramBusFollowerRegistrationState.getTarget,
316
- isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
317
- getFollowerSlot: telegramBusFollowerRegistrationState.getSlot,
318
- getFollowerThreadName: telegramBusFollowerRegistrationState.getThreadName,
319
- getLeaderIdentity: telegramBusLeaderState.getIdentity,
320
- getLeaderTarget: telegramBusLeaderState.getTarget,
321
- getLeaderProtocol: telegramBusFollowerRegistrationState.getLeaderProtocol,
322
- status: {
323
- getThreadMode: function () {
324
- return threadStore.getBotState().threadMode;
325
- },
326
- isBusPollingStarted: telegramThreadCapabilityState.isBusPollingStarted,
327
- listFollowers: telegramBusFollowerRegistry.list,
328
- listReservations: threadStore.listReservations,
329
- listSyncObservations: threadStore.listSyncObservations,
330
- getLeaderSocketPath: getTelegramBusSocketPath,
331
- getFollowerSocketPath: getTelegramBusFollowerSocketPath,
332
- getTransportKind: BusTransport.getTelegramBusTransportKind,
333
- },
334
- });
335
- const findCurrentThreadRecord = currentInstanceThreadRuntime.findRecord;
336
- const getCurrentInstanceThreadIdentity =
337
- currentInstanceThreadRuntime.getIdentity;
338
- const statusRuntime = Status.createTelegramBridgeStatusRuntime<
339
- Pi.ExtensionContext,
340
- Queue.TelegramQueueItem<Pi.ExtensionContext>
341
- >({
342
- getConfig: configStore.get,
343
- getActiveProfileName: configStore.getActiveProfileName,
344
- getDiagnosticPaths: Paths.getTelegramDiagnosticsDisplayPaths,
345
- isPollingActive: Polling.createTelegramPollingActivityReader(
346
- pollingControllerState,
347
- ),
348
- getPollingState: Polling.createTelegramPollingStateReader(
349
- pollingControllerState,
350
- ),
351
- getInboundWorkerState() {
352
- return updateAdmissionRuntimeBinding.getActive()?.getState();
353
- },
354
- getAcceptedThroughUpdateId() {
355
- return resolveTelegramUpdateJournalBinding()?.journal.read()
356
- .acceptedThroughUpdateId;
357
- },
358
- getActiveSourceMessageIds: activeTurnRuntime.getSourceMessageIds,
359
- hasActiveTurn: activeTurnRuntime.has,
360
- hasDispatchPending: lifecycle.hasDispatchPending,
361
- isCompactionInProgress: lifecycle.isCompactionInProgress,
362
- getActiveToolExecutions: lifecycle.getActiveToolExecutions,
363
- hasPendingModelSwitch: pendingModelSwitchStore.has,
364
- getQueuedItems: telegramQueueStore.getQueuedItems,
365
- getQueuedItemCount: Queue.countExecutableTelegramQueueItems,
366
- formatQueuedStatus: Queue.formatQueuedTelegramItemsStatus,
367
- getRecentRuntimeEvents: runtimeEvents.getEvents,
368
- getRuntimeLockState: lockRuntime.getStatusLabel,
369
- ...threadStatusProjectionRuntime,
370
- getBusProtocol() {
371
- return telegramBusProtocolIdentity;
372
- },
373
- getBusLifecyclePhase: telegramBusFollowerControlState.getLifecyclePhase,
374
- getBotThreadMode() {
375
- return threadStore.getBotState();
376
- },
377
- getSyncState: telegramSyncStateRuntime.getState,
378
- getThreadReconciliationState() {
379
- return threadReconciliationRuntime.getState();
380
- },
381
- });
382
- runtimeDiagnostics.bindStatus({
383
- instanceId: telegramInstanceId,
384
- updateStatus: statusRuntime.updateStatus,
385
- getStatusState: statusRuntime.getStatusState,
386
- async persistSnapshot(snapshot) {
387
- threadStore.setStatusSnapshot(snapshot);
388
- await threadStore.persist();
389
- },
390
- });
391
- const updateStatus = runtimeDiagnostics.updateStatus;
392
- const getStatusLines = runtimeDiagnostics.getStatusLines;
393
- const inboundHandlerRuntime = Inbound.createTelegramInboundHandlerRuntime({
394
- getHandlers: configStore.getInboundHandlers,
395
- execCommand: CommandTemplates.execCommandTemplate,
396
- getCwd: Pi.getExtensionContextCwd,
397
- recordRuntimeEvent,
398
- });
399
-
400
- // --- Telegram API ---
401
-
402
- const directTelegramApiRuntime =
403
- TelegramApi.createDefaultTelegramBridgeApiRuntime({
404
- getBotToken: configStore.getBotToken,
405
- recordRuntimeEvent,
406
- captureRequestErrorHandler(body) {
407
- return Sync.captureTelegramStaleTargetRequestRecovery(body, {
408
- ...staleTopicApiErrorRecoveryDeps,
409
- getCurrentLeaderEpoch,
410
- getSessionGeneration: telegramSessionContextStore.getGeneration,
411
- getProfileName: configStore.getActiveProfileName,
412
- onRecovered: runtimeDiagnostics.scheduleSnapshotPersist,
413
- });
414
- },
415
- });
416
- const telegramBusFollowerClients =
417
- BusFollower.createTelegramBusFollowerClientRuntime<
418
- Pi.ExtensionContext,
419
- Updates.TelegramMessageReactionUpdated,
420
- Routing.TelegramRoutedCallbackQuery,
421
- Routing.TelegramRoutedMessage
422
- >({
423
- socketPath: getTelegramBusSocketPath,
424
- instanceId: telegramInstanceId,
425
- getApiAuthSecret: telegramBusFollowerControlState.getActiveAuthSecret,
426
- getForwardingAuthSecret() {
427
- return telegramBusAuthSecret;
428
- },
429
- getRegistrationGeneration:
430
- telegramBusFollowerRegistrationState.getGeneration,
431
- waitForRegistrationGeneration:
432
- telegramBusFollowerRegistrationState.waitForGeneration,
433
- getForwardCommentBatchPosition:
434
- textGroupRuntime.getPreparedForwardingPosition,
435
- recordRuntimeEvent,
436
- });
437
- const telegramApiRuntime = BusApi.createTelegramBusAwareApiRuntime({
438
- directRuntime: directTelegramApiRuntime,
439
- ownsDirect() {
440
- return lockRuntime.owns();
441
- },
442
- getDefaultTarget: proactivePushTargetGetter,
443
- callFollowerApi: telegramBusFollowerClients.callApi,
444
- });
445
- const {
446
- call: callTelegramApi,
447
- callMultipart,
448
- deleteWebhook,
449
- getUpdates,
450
- setMyCommands,
451
- sendTypingAction,
452
- sendChatAction,
453
- sendRecordVoiceAction,
454
- sendMessageDraft,
455
- sendMessage,
456
- sendRichMessage,
457
- sendRichMessageDraft,
458
- downloadFile: downloadTelegramBridgeFile,
459
- editMessageText: editTelegramMessageText,
460
- editMessageReplyMarkup: editTelegramMessageReplyMarkup,
461
- answerCallbackQuery,
462
- answerGuestQuery,
463
- deleteMessage: deleteTelegramMessage,
464
- prepareTempDir,
465
- } = telegramApiRuntime;
466
-
467
- // --- Message Delivery ---
468
-
469
- const sendGuestReply = Replies.createGuestMarkdownReplySender({
470
- answerGuestQuery,
471
- });
472
-
473
- const promptDispatchRuntime = Runtime.createTelegramPromptDispatchRuntime({
474
- lifecycle,
475
- typing,
476
- getDefaultChatId: proactivePushChatIdGetter,
477
- sendTypingAction,
478
- sendAggregateTypingAction:
479
- BusApi.createTelegramAggregateTypingActionSender(telegramApiRuntime),
480
- updateStatus,
481
- isContextActive: telegramSessionContextStore.isCurrent,
482
- getTransportAuthority() {
483
- if (ownsTelegramDirectDelivery()) {
484
- const epoch = getCurrentLeaderEpoch();
485
- return epoch === undefined ? undefined : `direct:${epoch}`;
486
- }
487
- if (!telegramBusFollowerRegistrationState.isRegistered()) return undefined;
488
- const generation = telegramBusFollowerRegistrationState.getGeneration();
489
- return generation ? `follower:${generation}` : undefined;
490
- },
491
- recordRuntimeEvent,
492
- });
493
- const currentModelRuntime = Model.createCurrentModelRuntime({
494
- getContextModel,
495
- updateStatus,
496
- });
497
-
498
- // --- Reply Runtime & Preview ---
499
-
500
- const replyRuntime = Replies.createTelegramRenderedMessageDeliveryRuntime({
501
- recordOwnership: messageOwnershipRuntime.recordLocal,
502
- sendMessage,
503
- sendRichMessage,
504
- getAssistantRenderingMode: configControls.getAssistantRenderingMode,
505
- editMessage: editTelegramMessageText,
506
- });
507
- const { replyTransport, editInteractiveMessage, sendInteractiveMessage } =
508
- replyRuntime;
509
- const deliveryTargetPolicyRuntime =
510
- Delivery.createTelegramDeliveryTargetPolicyRuntime({
511
- ownsDirect: lockRuntime.owns,
512
- isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
513
- getAllowedChatId: configStore.getAllowedUserId,
514
- getFollowerTarget: telegramBusFollowerRegistrationState.getTarget,
515
- getLeaderTarget: telegramBusLeaderState.getTarget,
516
- listThreadRecords: threadStore.list,
517
- getActiveTurnTarget: activeTurnRuntime.getTarget,
518
- getActiveGuestQueryId: activeTurnRuntime.getGuestQueryId,
519
- });
520
- const deliveryGenerationSeed =
521
- Delivery.createTelegramDeliveryGenerationSeed(telegramInstanceId);
522
- const deliveryLifecycleRuntime =
523
- Delivery.createTelegramBridgeDeliveryLifecycleHooks({
524
- generationSeed: deliveryGenerationSeed,
525
- getTargetPolicyView: deliveryTargetPolicyRuntime.getTargetPolicyView,
526
- getTransportStamp: telegramTransportStampRuntime.getStamp,
527
- isTransportStampActive: telegramTransportStampRuntime.isActive,
528
- getActiveTurnTarget: deliveryTargetPolicyRuntime.getActiveTurnTarget,
529
- api: telegramApiRuntime,
530
- recordOwnership: messageOwnershipRuntime.recordLocal,
531
- recordFailure(operation, error, target) {
532
- recordRuntimeEvent("delivery", error, {
533
- operation,
534
- scope: target?.threadId === undefined ? "aggregate" : "thread",
535
- });
536
- },
537
- });
538
- const { sendTextReply, sendMarkdownReply } =
539
- Outbound.createTelegramOutboundTextReplyRuntime({
540
- sendTextReply: replyRuntime.sendTextReply,
541
- sendMarkdownReply: replyRuntime.sendMarkdownReply,
542
- execCommand: CommandTemplates.execCommandTemplate,
543
- getHandlers: configStore.getOutboundHandlers,
544
- recordRuntimeEvent,
545
- });
546
- const invokeGenerativeAppBoundButtonAction =
547
- Bindings.createTelegramGenerativeAppBoundButtonActionInvoker({
548
- agentDir: Paths.resolveAgentDir(),
549
- assertExecutionCurrent: Updates.assertTelegramUpdateExecutionCurrent,
550
- getExecutionFence: Updates.getTelegramUpdateExecutionFence,
551
- planOutput: planGenerativeAppOutput,
552
- sendMarkdownReply,
553
- editInteractiveMessage,
554
- recordRuntimeEvent,
555
- });
556
- const nativeMarkdownDraftSender =
557
- TelegramApi.createTelegramAssistantDraftSender({
558
- getAssistantRenderingMode: configControls.getAssistantRenderingMode,
559
- renderMarkdownToHtmlDraft: Replies.renderTelegramMarkdownToHtmlDraft,
560
- sendMessageDraft,
561
- sendRichMessageDraft,
562
- });
563
- const previewRuntime = Preview.createTelegramAssistantPreviewRuntime({
564
- getActiveTurn: activeTurnRuntime.get,
565
- isAssistantMessage: Replies.isAssistantAgentMessage,
566
- getMessageText: Replies.getAgentMessageText,
567
- getDefaultReplyToMessageId: activeTurnRuntime.getReplyToMessageId,
568
- sendDraft: nativeMarkdownDraftSender,
569
- canSend: configControls.areDraftPreviewsEnabled,
570
- sendMarkdownReply,
571
- recordRuntimeEvent,
572
- ...replyTransport,
573
- });
574
- const {
575
- activityRuntime,
576
- activityVerbosityRuntime,
577
- assistantOutputRuntime,
578
- publicationRuntime,
579
- } = Bindings.createTelegramActivityBindingRuntime({
580
- generation: deliveryGenerationSeed,
581
- assistantOutput: {
582
- prepareTelegramPreview: previewRuntime.preparePublication,
583
- authority: {
584
- getPreferredTarget: proactivePushTargetGetter,
585
- getFallbackChatId: proactivePushChatIdGetter,
586
- getTransportStamp: telegramTransportStampRuntime.getStamp,
587
- isTransportStampActive: telegramTransportStampRuntime.isActive,
588
- ownsDirect: lockRuntime.owns,
589
- getDirectEpoch: lockRuntime.getOwnedLeaderEpoch,
590
- isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
591
- getFollowerGeneration:
592
- telegramBusFollowerRegistrationState.getGeneration,
593
- },
594
- sender: {
595
- recordOwnership: messageOwnershipRuntime.recordLocal,
596
- sendMessage,
597
- sendRichMessage,
598
- editMessage: editTelegramMessageText,
599
- getAssistantRenderingMode: configControls.getAssistantRenderingMode,
600
- planButtonReply:
601
- Outbound.createTelegramButtonReplyPlanner(buttonActionStore),
602
- execCommand: CommandTemplates.execCommandTemplate,
603
- getHandlers: configStore.getOutboundHandlers,
604
- recordRuntimeEvent,
605
- },
606
- recordRuntimeEvent,
607
- },
608
- activityVerbosity: {
609
- getActivityMode: configControls.getActivityVerbosity,
610
- refreshActivityMode: configControls.refreshActivityVerbosity,
611
- resolveTarget(event) {
612
- return event.target ?? proactivePushTargetGetter();
613
- },
614
- sendMessage,
615
- sendRichMessage,
616
- editMessageText: editTelegramMessageText,
617
- },
618
- });
619
- const {
620
- mutation: queueMutationRuntime,
621
- dispatchNext: dispatchNextQueuedTelegramTurn,
622
- watchdog: queueDispatchWatchdogRuntime,
623
- } = Bindings.createTelegramQueueBindingRuntime({
624
- store: telegramQueueStore,
625
- queue,
626
- lifecycle,
627
- activeTurn: activeTurnRuntime,
628
- admission: updateAdmissionRuntimeBinding,
629
- transportStamp: telegramTransportStampRuntime,
630
- deferredDispatch: deferredQueueDispatchRuntime,
631
- promptDispatch: promptDispatchRuntime,
632
- isIdle,
633
- hasPendingMessages,
634
- updateStatus,
635
- sendTextReply,
636
- sendUserMessage,
637
- recordRuntimeEvent,
638
- });
639
- const { finalizeMarkdownPreview, preparePreviewDelivery } =
640
- Outbound.createTelegramOutboundTextPreviewRuntime({
641
- finalizeMarkdownPreview: previewRuntime.finalizeMarkdown,
642
- preparePreviewDelivery: previewRuntime.prepareDelivery,
643
- execCommand: CommandTemplates.execCommandTemplate,
644
- getHandlers: configStore.getOutboundHandlers,
645
- recordRuntimeEvent,
646
- });
647
-
648
- // --- Model And Menu Setup ---
649
-
650
- const modelSwitchController =
651
- Model.createTelegramModelSwitchControllerRuntime({
652
- isIdle,
653
- getPendingModelSwitch: pendingModelSwitchStore.get,
654
- setPendingModelSwitch: pendingModelSwitchStore.set,
655
- getActiveTurn: activeTurnRuntime.get,
656
- getAbortHandler: abort.getHandler,
657
- hasAbortHandler: abort.hasHandler,
658
- getActiveToolExecutions: lifecycle.getActiveToolExecutions,
659
- allocateItemOrder: queue.allocateItemOrder,
660
- allocateControlOrder: queue.allocateControlOrder,
661
- appendQueuedItem: queueMutationRuntime.append,
662
- updateStatus,
663
- });
664
- const getQueueItemCount =
665
- Queue.createTelegramQueueItemCountGetter(telegramQueueStore);
666
- const getPromptTemplateCommands =
667
- PromptTemplates.createTelegramPromptTemplateCommandGetter({
668
- getCommands,
669
- getReservedCommandNames: Commands.getTelegramReservedCommandNames,
670
- });
671
- const menuActions = Menu.createTelegramMenuActionRuntimeWithStateBuilder({
672
- runtime: modelMenuRuntime,
673
- createSettingsManager: Pi.createSettingsManager,
674
- getActiveModel: currentModelRuntime.get,
675
- getThinkingLevel,
676
- getQueueItemCount,
677
- buildStatusHtml: Commands.createTelegramAppMenuHtmlBuilder({
678
- buildStatusHtml: Status.createTelegramStatusHtmlBuilder({
679
- getActiveModel: currentModelRuntime.get,
680
- isCompactionInProgress: lifecycle.isCompactionInProgress,
681
- getBridgeStatusLineState: statusRuntime.getStatusState,
682
- }),
683
- getPromptTemplateCommands,
684
- }),
685
- storeModelMenuState: modelMenuRuntime.storeState,
686
- isIdle,
687
- canOfferInFlightModelSwitch: modelSwitchController.canOfferInFlightSwitch,
688
- sendTextReply,
689
- editInteractiveMessage,
690
- sendInteractiveMessage,
691
- sectionRegistry,
692
-
693
- // Menu/status UI uses this to reflect whether the active Telegram turn expects voice delivery.
694
- isVoiceReplyActive: function () {
695
- const turn = activeTurnRuntime.get();
696
- return Voice.isVoiceTurn(turn);
697
- },
698
- });
699
-
700
- // --- Queue And Settings Menus ---
701
-
702
- const getQueueMenuState = Menu.createTelegramModelMenuStateBuilder({
703
- runtime: modelMenuRuntime,
704
- createSettingsManager: Pi.createSettingsManager,
705
- getActiveModel: currentModelRuntime.get,
706
- });
707
- const queueMenuRuntime = MenuQueue.createTelegramQueueMenuRuntime({
708
- telegramQueueStore,
709
- queueMutationRuntime,
710
- sendInteractiveMessage,
711
- editInteractiveMessage,
712
- answerCallbackQuery,
713
- getModelMenuState: getQueueMenuState,
714
- getStoredModelMenuState: modelMenuRuntime.getState,
715
- storeModelMenuState: modelMenuRuntime.storeState,
716
- updateStatusMessage: menuActions.updateStatusMessage,
717
- updateStatus,
718
- });
719
- const settingsMenuRuntime = MenuSettings.createTelegramSettingsMenuRuntime(
720
- {
721
- reloadConfig: configStore.load,
722
- getModelMenuState: getQueueMenuState,
723
- getStoredModelMenuState: modelMenuRuntime.getState,
724
- storeModelMenuState: modelMenuRuntime.storeState,
725
- editInteractiveMessage,
726
- sendInteractiveMessage,
727
- answerCallbackQuery,
728
- ...configControls,
729
- },
730
- sectionRegistry,
731
- );
732
-
733
- // --- Polling ---
734
-
735
- const foreignOwnedUpdateForwarder =
736
- telegramBusFollowerClients.foreignOwnedUpdateForwarder;
737
- const followerTargetController = telegramBusFollowerClients.targetController;
738
- const restoreFollowerThreadTarget =
739
- Bus.createTelegramBusFollowerThreadRestoreHandler({
740
- followerRegistry: telegramBusFollowerRegistry,
741
- followerTargetController,
742
- onRestored() {
743
- telegramSyncStateRuntime.markSliceFresh(
744
- Sync.TELEGRAM_SYNC_SLICE_TARGET_BINDINGS,
745
- {
746
- nowMs: Date.now(),
747
- action: "follower-thread-restore",
748
- },
749
- );
750
- },
751
- });
752
- const observedThreadTargetBinding =
753
- Polling.createTelegramThreadTargetObservationBinding<Pi.ExtensionContext>();
754
- const topicLifecycleSync =
755
- Sync.createTelegramObservedTopicLifecycleSyncHandler({
756
- topicTargetStore: threadStore,
757
- isBusEnabled: isTelegramBusRuntimeEnabled,
758
- callApi: callTelegramApi,
759
- isTopicProvisioningActive: telegramProvisioningActivity.isActive,
760
- getCurrentLeaderEpoch,
761
- getThreadReconciliationMachineState: threadReconciliationRuntime.getState,
762
- recordThreadReconciliationPlan,
763
- assertExecutionCurrent(message) {
764
- Updates.assertTelegramUpdateExecutionCurrent(message);
765
- },
766
- getSyncState: telegramSyncStateRuntime.getState,
767
- setSyncState: telegramSyncStateRuntime.setState,
768
- recordEvent: recordRuntimeEvent,
769
- });
770
- const inboundBusProjectionRuntime =
771
- Routing.createTelegramInboundBusProjectionRuntime({
772
- instanceId: telegramInstanceId,
773
- listFollowers: telegramBusFollowerRegistry.list,
774
- listThreadRecords: threadStore.list,
775
- getLeaderTarget: telegramBusLeaderState.getTarget,
776
- isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
777
- getFollowerTarget: telegramBusFollowerRegistrationState.getTarget,
778
- getCurrentIdentity: getCurrentInstanceThreadIdentity,
779
- });
780
- const inboundRouteRuntime = Routing.createTelegramInboundRouteRuntime({
781
- configStore,
782
- callApi: callTelegramApi,
783
- getCurrentInstanceId() {
784
- return telegramInstanceId;
785
- },
786
- getAdmissionScope: getTelegramUpdateAdmissionScope,
787
- getAdmissionJournalBinding: getTelegramQueueJournalBinding,
788
- getMessageOwnership: messageOwnershipRuntime.store.get,
789
- recordMessageOwnership: messageOwnershipRuntime.recordRouted,
790
- ...inboundBusProjectionRuntime,
791
- getCurrentLeaderEpoch,
792
- setCurrentLeaderIdentity: telegramBusLeaderState.set,
793
- getThreadReconciliationMachineState: threadReconciliationRuntime.getState,
794
- recordThreadReconciliationPlan,
795
- handleTelegramTopicLifecycleUpdate: topicLifecycleSync,
796
- handleTelegramThreadTargetObserved(_target, ctx) {
797
- return observedThreadTargetBinding.handle(ctx);
798
- },
799
- foreignOwnedUpdateForwarder,
800
- replaceFollowerThreadTarget: restoreFollowerThreadTarget,
801
- bridgeRuntime,
802
- activeTurnRuntime,
803
- mediaGroupRuntime,
804
- textGroupRuntime,
805
- telegramQueueStore,
806
- queueMutationRuntime,
807
- modelMenuRuntime,
808
- currentModelRuntime,
809
- modelSwitchController,
810
- menuActions,
811
- updateSettingsMenuMessage: settingsMenuRuntime.updateSettingsMenuMessage,
812
- openQueueMenu: queueMenuRuntime.openQueueMenu,
813
- queueMenuCallbackHandler: queueMenuRuntime.handleCallbackQuery,
814
- openSettingsMenu: settingsMenuRuntime.openSettingsMenu,
815
- settingsMenuCallbackHandler: settingsMenuRuntime.handleCallbackQuery,
816
- sectionRegistry,
817
- buttonActionStore,
818
- invokeBoundButtonAction: invokeGenerativeAppBoundButtonAction,
819
- inboundHandlerRuntime,
820
- threadStore,
821
- updateStatus,
822
- isContextActive: telegramSessionContextStore.isCurrent,
823
- dispatchNextQueuedTelegramTurn,
824
- requestDeferredDispatchNextQueuedTelegramTurn:
825
- deferredQueueDispatchRuntime.request,
826
- hasDeferredDispatchContext: deferredQueueDispatchRuntime.isBound,
827
- startTypingLoop: promptDispatchRuntime.startTypingLoop,
828
- stopTypingLoop: typing.stop,
829
- answerCallbackQuery,
830
- editInteractiveMessage,
831
- editMessageReplyMarkup: editTelegramMessageReplyMarkup,
832
- sendInteractiveMessage,
833
- deleteMessage: deleteTelegramMessage,
834
- answerGuestQuery,
835
- sendTextReply,
836
- setMyCommands,
837
- getCommands,
838
- downloadFile: downloadTelegramBridgeFile,
839
- resolveTimeLine: timeInjectionRuntime.resolveLine,
840
- getThinkingLevel,
841
- setThinkingLevel,
842
- persistScopedModelPatterns: Pi.createScopedModelPatternPersister({
843
- createSettingsManager: Pi.createSettingsManager,
844
- clearCachedModelMenuInputs: modelMenuRuntime.clearCachedInputs,
845
- }),
846
- setModel,
847
- sendUserMessage,
848
- isIdle,
849
- hasPendingMessages,
850
- compact,
851
- recordRuntimeEvent,
852
- });
853
- const queueHandoffReconciliationBinding =
854
- Updates.createTelegramQueueHandoffReconciliationBinding<Pi.ExtensionContext>(
855
- function (error) {
856
- recordRuntimeEvent("inbound-worker", error, {
857
- phase: "queue-handoff-reconcile",
858
- });
859
- },
860
- );
861
- const staleTopicApiErrorRecoveryDeps = {
862
- topicTargetStore: threadStore,
863
- getSyncState: telegramSyncStateRuntime.getState,
864
- setSyncState: telegramSyncStateRuntime.setState,
865
- recordEvent: recordRuntimeEvent,
866
- };
867
- const recoverStaleTelegramTopicApiError =
868
- Sync.createTelegramStaleTopicApiErrorRecoveryRuntime(
869
- staleTopicApiErrorRecoveryDeps,
870
- );
871
- const {
872
- owner: updateWorkerOwnerRuntime,
873
- leader: updateAdmissionLifecycleRuntime,
874
- follower: followerAdmissionLifecycleRuntime,
875
- } = Updates.createTelegramUpdateAdmissionRuntimeAssembly<
876
- Parameters<typeof inboundRouteRuntime.handleUpdate>[0] &
877
- Journal.TelegramJournaledUpdate,
878
- Pi.ExtensionContext
879
- >({
880
- runtimeBinding: updateAdmissionRuntimeBinding,
881
- owner: {
882
- instanceId: telegramInstanceId,
883
- processId: telegramProcessId,
884
- processBirthId: telegramQueueProcessBirthId,
885
- getSessionGeneration: telegramSessionContextStore.getGeneration,
886
- isContextCurrent: telegramSessionContextStore.isCurrent,
887
- dispatchNext: dispatchNextQueuedTelegramTurn,
888
- requestQueueHandoffReconciliation:
889
- queueHandoffReconciliationBinding.request,
890
- },
891
- worker: {
892
- defaultHandle: inboundRouteRuntime.handleUpdate,
893
- onStateChange: runtimeDiagnostics.scheduleSnapshotPersist,
894
- settleTerminalExecutionFailure(error) {
895
- return Sync.settleStaleTelegramTopicExecutionFailure(
896
- error,
897
- staleTopicApiErrorRecoveryDeps,
898
- );
899
- },
900
- },
901
- leader: {
902
- resolveBinding: resolveTelegramUpdateJournalBinding,
903
- hasAuthority: lockRuntime.owns,
904
- },
905
- follower: {
906
- resolveBinding: resolveTelegramFollowerJournalBinding,
907
- isRegistered: telegramBusFollowerRegistrationState.isRegistered,
908
- getGeneration: telegramBusFollowerRegistrationState.getGeneration,
909
- prepareUpdateForExecution(update) {
910
- return BusFollower.prepareTelegramBusFollowerJournaledUpdateForExecution(
911
- update,
912
- textGroupRuntime.prepareForwardedMessage,
913
- );
914
- },
915
- },
916
- recordRuntimeEvent,
917
- });
918
- const queueHandoffStagingRuntime =
919
- Queue.createTelegramQueueHandoffStagingRuntime({
920
- liveStore: telegramQueueStore,
921
- createControlExecution:
922
- Updates.createTelegramQueueHandoffControlExecutionFactory({
923
- isContextCurrent: telegramSessionContextStore.isCurrent,
924
- showStatus: menuActions.sendStatusMessage,
925
- openModelMenu: menuActions.openModelMenu,
926
- }),
927
- });
928
- const acceptStagedQueueHandoff =
929
- Updates.createTelegramQueueHandoffRecipientRuntime({
930
- staging: queueHandoffStagingRuntime,
931
- getRecipientOwner: updateWorkerOwnerRuntime.getQueueOwnerIdentity,
932
- getLifecycleForBinding:
933
- updateAdmissionRuntimeBinding.getLifecycleForJournalBinding,
934
- isTransportStampActive: telegramTransportStampRuntime.isActive,
935
- dispatchNext: dispatchNextQueuedTelegramTurn,
936
- });
937
- const followerDurableAdmissionRuntime =
938
- BusFollower.createTelegramBusFollowerDurableAdmissionRuntime({
939
- journal: {
940
- appendBatch(updates) {
941
- return followerAdmissionLifecycleRuntime.appendBatch(updates);
942
- },
943
- },
944
- signalWorker() {
945
- followerAdmissionLifecycleRuntime.signal();
946
- },
947
- });
948
- const promoteTelegramBusFollowerToLeader: BusFollower.TelegramBusFollowerPromotionHandler<Pi.ExtensionContext> =
949
- BusFollower.createTelegramBusFollowerPromotionHandler<Pi.ExtensionContext>({
950
- topicTargetStore: threadStore,
951
- instanceId: telegramInstanceId,
952
- getActiveProfileName: configStore.getActiveProfileName,
953
- async startLeader(ctx, election, onAcquired): Promise<boolean> {
954
- const result = await lockedPollingRuntime.start(ctx, {
955
- election,
956
- onAcquired,
957
- });
958
- return result.ok;
959
- },
960
- recordRuntimeEvent,
961
- });
962
- const agentMessageRuntime = AgentMessages.createTelegramAgentMessageRuntime({
963
- instanceId: telegramInstanceId,
964
- getAllowedChatId: configStore.getAllowedUserId,
965
- getLeaderTarget: telegramBusLeaderState.getTarget,
966
- getLeaderThreadName() {
967
- return findCurrentThreadRecord()?.threadName;
968
- },
969
- followerRegistry: telegramBusFollowerRegistry,
970
- getContext: telegramSessionContextStore.get,
971
- handleUpdate: inboundRouteRuntime.handleUpdate,
972
- });
973
- const agentMessageToolRoutingRuntime =
974
- Bindings.createTelegramAgentMessageToolRoutingRuntime({
975
- ownsLeader: lockRuntime.owns,
976
- ownsDirectDelivery: ownsTelegramDirectDelivery,
977
- isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
978
- getSourceTarget: proactivePushTargetGetter,
979
- getSourceThreadName() {
980
- return findCurrentThreadRecord()?.threadName;
981
- },
982
- local: agentMessageRuntime,
983
- follower: telegramBusFollowerClients.agentMessages,
984
- });
985
- const telegramBusFollowerAssembly: BusFollower.TelegramBusFollowerRuntimeAssembly<Pi.ExtensionContext> =
986
- BusFollower.createTelegramBusFollowerRuntimeAssembly<Pi.ExtensionContext>({
987
- instanceId: telegramInstanceId,
988
- registrationState: telegramBusFollowerRegistrationState,
989
- recordRuntimeEvent,
990
- receiver: {
991
- socketPath: getTelegramBusFollowerSocketPath,
992
- getContext: telegramSessionContextStore.get,
993
- getAuthSecret: telegramBusFollowerControlState.getActiveAuthSecret,
994
- getRecipientBindingKey: getTelegramManualFollowerProfileKey,
995
- durableAdmission: followerDurableAdmissionRuntime,
996
- handleQueueHandoff: acceptStagedQueueHandoff,
997
- },
998
- targetReplacement: {
999
- topicTargetStore: threadStore,
1000
- getManualFollowerProfileKey: getTelegramManualFollowerProfileKey,
1001
- manualFollowerOwnerId: telegramManualFollowerOwnerId,
1002
- getSyncState: telegramSyncStateRuntime.getState,
1003
- setSyncState: telegramSyncStateRuntime.setState,
1004
- updateStatus,
1005
- },
1006
- recovery: {
1007
- getLeaderState: lockRuntime.getState,
1008
- setLifecyclePhase: telegramBusFollowerControlState.setLifecyclePhase,
1009
- updateStatus,
1010
- promoteToLeader: promoteTelegramBusFollowerToLeader,
1011
- getActiveContext: telegramSessionContextStore.get,
1012
- },
1013
- registration: {
1014
- protocolIdentity: telegramBusProtocolIdentity,
1015
- getFollowerBusSocketPath: getTelegramBusFollowerSocketPath,
1016
- getLeaderSocketPath: getTelegramBusSocketPath,
1017
- isContextActive: telegramSessionContextStore.isCurrent,
1018
- createRequestId: telegramBusFollowerClients.createRequestId,
1019
- setActiveAuthSecret:
1020
- telegramBusFollowerControlState.setActiveAuthSecret,
1021
- getProfileKey: getTelegramManualFollowerProfileKey,
1022
- getProcessBirthId() {
1023
- return telegramQueueProcessBirthId;
1024
- },
1025
- getSessionGeneration: telegramSessionContextStore.getGeneration,
1026
- async onRegistered(ctx) {
1027
- await followerAdmissionLifecycleRuntime.onTransportChanged(ctx);
1028
- queueHandoffReconciliationBinding.request(ctx);
1029
- },
1030
- },
1031
- });
1032
- const telegramBusFollowerRegistration =
1033
- telegramBusFollowerAssembly.registration;
1034
- const { admission: pollingAdmissionRuntime } =
1035
- Polling.createTelegramDurablePollingRuntimeAssembly<
1036
- TelegramApi.TelegramUpdate,
1037
- Pi.ExtensionContext
1038
- >({
1039
- state: pollingControllerState,
1040
- canStart(ctx) {
1041
- return telegramSessionContextStore.isCurrent(ctx) && lockRuntime.owns(ctx);
1042
- },
1043
- onPersistentConflict(ctx, count): Promise<void> {
1044
- return lockedPollingRuntime.onPersistentConflict(ctx, count);
1045
- },
1046
- getConfig: configStore.get,
1047
- hasBotToken: configStore.hasBotToken,
1048
- deleteWebhook,
1049
- getUpdates,
1050
- persistConfig: persistTelegramConfigWithSync,
1051
- prepareUpdateBatch: textGroupRuntime.prepareUpdateBatch,
1052
- journal: {
1053
- appendBatch(updates, acceptedThroughUpdateId) {
1054
- return updateAdmissionLifecycleRuntime.appendBatch(
1055
- updates as Journal.TelegramJournaledUpdate[],
1056
- acceptedThroughUpdateId,
1057
- );
1058
- },
1059
- getAcceptedThroughUpdateId() {
1060
- return resolveTelegramUpdateJournalBinding()?.journal.read()
1061
- .acceptedThroughUpdateId;
1062
- },
1063
- async prepareCursorCutover() {
1064
- const binding = resolveTelegramUpdateJournalBinding();
1065
- if (!binding) {
1066
- throw new Error("Telegram update journal binding is unavailable.");
1067
- }
1068
- await Polling.cutOverTelegramPollingCursor({
1069
- getLegacyCursor: configStore.getLegacyPollingCursor,
1070
- readJournal: binding.journal.read,
1071
- publishJournalCursor(acceptedThroughUpdateId) {
1072
- binding.journal.appendBatch([], acceptedThroughUpdateId);
1073
- },
1074
- async removeLegacyCursor() {
1075
- configStore.removeLegacyPollingCursor();
1076
- await persistTelegramConfigWithSync();
1077
- },
1078
- });
1079
- },
1080
- getEntryCount: updateAdmissionLifecycleRuntime.getJournalEntryCount,
1081
- signalWorker: updateAdmissionLifecycleRuntime.signal,
1082
- getBootstrapEntryCount() {
1083
- return (
1084
- resolveTelegramUpdateJournalBinding()?.journal.read().entries
1085
- .length ?? 0
1086
- );
1087
- },
1088
- onSessionStart: updateAdmissionLifecycleRuntime.onSessionStart,
1089
- },
1090
- stopTypingLoop: typing.stop,
1091
- updateStatus,
1092
- onPollingStateChange: runtimeDiagnostics.scheduleSnapshotPersist,
1093
- recordRuntimeEvent,
1094
- });
1095
- const authorizeFollowerApiCall = Bus.createTelegramFollowerApiCallAuthorizer({
1096
- isMessageOwned: messageOwnershipRuntime.isOwnedByFollower,
1097
- });
1098
- const telegramBusLeaderRuntime =
1099
- BusLeader.createTelegramBusLeaderRuntimeAssembly<Pi.ExtensionContext>({
1100
- runtime: {
1101
- socketPath: getTelegramBusSocketPath,
1102
- commitEndpointPublication(commit) {
1103
- return lockRuntime.commitIfOwned(commit);
1104
- },
1105
- followerRegistry: telegramBusFollowerRegistry,
1106
- authSecret: telegramBusAuthSecret,
1107
- protocolIdentity: telegramBusProtocolIdentity,
1108
- startPolling: pollingAdmissionRuntime.start,
1109
- stopPolling: pollingAdmissionRuntime.stop,
1110
- authorizeFollowerApiCall,
1111
- resolveAgentTarget(follower, selector) {
1112
- return agentMessageRuntime.resolveTarget(selector, follower.target);
1113
- },
1114
- routeAgentMessage(follower, message) {
1115
- return agentMessageRuntime.route({
1116
- sourceTarget: follower.target,
1117
- sourceThreadName: follower.threadName,
1118
- message,
1119
- });
1120
- },
1121
- isFollowerProcessAlive: Locks.isProcessAlive,
1122
- shouldCleanupConfirmedDeadFollower:
1123
- configControls.resolveAutomaticThreadCleanupEnabled,
1124
- recordFollowerMessageOwnership(record) {
1125
- messageOwnershipRuntime.recordFollower(record);
1126
- },
1127
- },
1128
- getAllowedUserId: configStore.getAllowedUserId,
1129
- instanceId: telegramInstanceId,
1130
- getCwd: Pi.getExtensionContextCwd,
1131
- getTelegramProfile: configStore.getActiveProfileName,
1132
- shouldForceFreshUnnamed:
1133
- telegramThreadCapabilityState.shouldForceFreshLeaderThread,
1134
- topicTargetStore: threadStore,
1135
- callApi(method, body) {
1136
- return directTelegramApiRuntime.call(method, body);
1137
- },
1138
- callMultipart: directTelegramApiRuntime.callMultipart,
1139
- downloadFile: directTelegramApiRuntime.downloadFile,
1140
- recoverStaleTargetError: recoverStaleTelegramTopicApiError,
1141
- getCurrentLeaderEpoch,
1142
- getThreadReconciliationMachineState: threadReconciliationRuntime.getState,
1143
- recordThreadReconciliationPlan,
1144
- getSyncState: telegramSyncStateRuntime.getState,
1145
- setSyncState: telegramSyncStateRuntime.setState,
1146
- setLeaderTarget: telegramBusLeaderState.set,
1147
- onProvisioningStart: telegramProvisioningActivity.start,
1148
- onProvisioningEnd: telegramProvisioningActivity.end,
1149
- recordRuntimeEvent,
1150
- });
1151
- queueHandoffReconciliationBinding.set(
1152
- Updates.createTelegramQueueHandoffReconciliationRuntimeAssembly({
1153
- ownsDirect: lockRuntime.owns,
1154
- isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
1155
- isBusEnabled: isTelegramBusRuntimeEnabled,
1156
- canHandoffWithLeader() {
1157
- return Bus.hasTelegramBusCapability(
1158
- telegramBusFollowerRegistrationState.getLeaderProtocol(),
1159
- Bus.TELEGRAM_BUS_CAPABILITY_QUEUE_HANDOFF,
1160
- );
1161
- },
1162
- listFollowers: telegramBusFollowerRegistry.list,
1163
- createRecipientJournalResolver:
1164
- telegramJournalBindingRuntime.createRecipientResolver,
1165
- queueStore: telegramQueueStore,
1166
- admission: updateAdmissionRuntimeBinding,
1167
- createHandoffToken: Journal.createTelegramUpdateQueueHandoffToken,
1168
- createRequestId: telegramBusFollowerClients.createRequestId,
1169
- donorInstanceId: telegramInstanceId,
1170
- authSecret: telegramBusAuthSecret,
1171
- stageThroughFollower: telegramBusFollowerClients.queueHandoff,
1172
- routeThroughLeader: telegramBusLeaderRuntime.routeQueueHandoff,
1173
- recordRuntimeEvent,
1174
- }),
1175
- );
1176
- const telegramLeaderHealthRuntime = Sync.createTelegramLeaderHealthRuntime({
1177
- callGetMe() {
1178
- return directTelegramApiRuntime.call("getMe", {});
1179
- },
1180
- getSyncState: telegramSyncStateRuntime.getState,
1181
- setSyncState: telegramSyncStateRuntime.setState,
1182
- recordEvent: recordRuntimeEvent,
1183
- });
1184
- const telegramThreadCapabilityRuntime =
1185
- Polling.createTelegramThreadCapabilityOrchestration<
1186
- Pi.ExtensionContext,
1187
- Locks.TelegramLockEntry
1188
- >({
1189
- state: telegramThreadCapabilityState,
1190
- getAllowedUserId: configStore.getAllowedUserId,
1191
- callApi: callTelegramApi,
1192
- topicTargetStore: threadStore,
1193
- isBusRuntimeEnabled: isTelegramBusRuntimeEnabled,
1194
- ownsLock: lockRuntime.owns,
1195
- isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
1196
- startClassicPolling: pollingAdmissionRuntime.start,
1197
- stopClassicPolling: pollingAdmissionRuntime.stop,
1198
- startBusLeaderPolling: telegramBusLeaderRuntime.startPolling,
1199
- stopBusLeaderPolling: telegramBusLeaderRuntime.stopPolling,
1200
- startLeaderHealth: telegramLeaderHealthRuntime.start,
1201
- stopLeaderHealth: telegramLeaderHealthRuntime.stop,
1202
- registerFollowerWithLeader:
1203
- telegramBusFollowerRegistration.registerWithLeader,
1204
- stopFollowerRegistration: telegramBusFollowerRegistration.stop,
1205
- isTopicModeUnavailableError: Threads.isTelegramTopicModeUnavailableError,
1206
- updateStatus,
1207
- recordEvent: recordRuntimeEvent,
1208
- });
1209
- const telegramThreadCapabilityMonitor =
1210
- telegramThreadCapabilityRuntime.monitor;
1211
- observedThreadTargetBinding.set(
1212
- telegramThreadCapabilityRuntime.observeTarget,
1213
- );
1214
- const threadAwarePollingPorts = telegramThreadCapabilityRuntime.pollingPorts;
1215
- const lockedPollingRuntime = Locks.createTelegramLockedPollingRuntime({
1216
- lock: lockRuntime,
1217
- transportMonitor: telegramThreadCapabilityMonitor,
1218
- hasBotToken: configStore.hasBotToken,
1219
- canStartPolling: Pi.canStartPollingInExtensionContext,
1220
- isContextCurrent: telegramSessionContextStore.isCurrent,
1221
- formatStartBlockedMessage: Pi.formatPollingStartBlockedByRunMode,
1222
- startPolling: threadAwarePollingPorts.startPolling,
1223
- stopPolling: threadAwarePollingPorts.stopPolling,
1224
- registerFollowerWithOwner:
1225
- threadAwarePollingPorts.registerFollowerWithOwner,
1226
- stopFollowerRegistration: threadAwarePollingPorts.stopFollowerRegistration,
1227
- onTransportAvailabilityChanged() {
1228
- modelContextAvailabilityRuntime.reconcile();
1229
- const ctx = telegramSessionContextStore.get();
1230
- if (ctx) queueHandoffReconciliationBinding.request(ctx);
1231
- },
1232
- updateStatus,
1233
- recordRuntimeEvent,
1234
- });
1235
- const {
1236
- disconnect: disconnectTelegramAndDeleteCurrentThread,
1237
- cleanupForSessionRestart: cleanupTelegramThreadForSessionRestart,
1238
- } = Sync.createTelegramThreadDisconnectAssembly({
1239
- instanceId: telegramInstanceId,
1240
- getCurrentThreadRecord: findCurrentThreadRecord,
1241
- topicTargetStore: threadStore,
1242
- callApi: callTelegramApi,
1243
- getCurrentLeaderEpoch,
1244
- getLeaderTarget: telegramBusLeaderState.getTarget,
1245
- clearLeaderTarget: telegramBusLeaderState.clear,
1246
- disconnectFollowerThread:
1247
- telegramBusFollowerRegistration.disconnectFromLeader,
1248
- getSyncState: telegramSyncStateRuntime.getState,
1249
- setSyncState: telegramSyncStateRuntime.setState,
1250
- stopPolling: lockedPollingRuntime.stop,
1251
- suspendPolling: lockedPollingRuntime.suspend,
1252
- recordRuntimeEvent,
1253
- });
1254
- const telegramBridgeSessionLifecycleDeps =
1255
- Lifecycle.createTelegramBridgeSessionLifecycleDeps({
1256
- contextStore: telegramSessionContextStore,
1257
- queue: {
1258
- getCurrentModel: getContextModel,
1259
- loadConfig: configStore.load,
1260
- setQueuedItems: telegramQueueStore.setQueuedItems,
1261
- setCurrentModel: currentModelRuntime.set,
1262
- setPendingModelSwitch: pendingModelSwitchStore.set,
1263
- syncCounters: queue.syncCounters,
1264
- syncFlags: lifecycle.syncFlags,
1265
- bindDeferredDispatchContext: deferredQueueDispatchRuntime.bind,
1266
- prepareTempDir,
1267
- updateStatus,
1268
- unbindDeferredDispatchContext: deferredQueueDispatchRuntime.unbind,
1269
- discardQueuedItems: queueMutationRuntime.clear,
1270
- clearModelMenuState: modelMenuRuntime.clear,
1271
- getActiveTurnChatId: activeTurnRuntime.getChatId,
1272
- getActiveTurnTarget: activeTurnRuntime.getTarget,
1273
- clearPreview: previewRuntime.clear,
1274
- clearActiveTurn: activeTurnRuntime.clear,
1275
- clearAbort: abort.clearHandler,
1276
- recordRuntimeEvent,
1277
- },
1278
- follower: {
1279
- registrationState: telegramBusFollowerRegistrationState,
1280
- registrationRuntime: telegramBusFollowerRegistration,
1281
- instanceId: telegramInstanceId,
1282
- suspendPolling: lockedPollingRuntime.suspend,
1283
- isLeader: lockRuntime.owns,
1284
- getLeaderBinding: currentInstanceThreadRuntime.getRestorationIdentity,
1285
- getActiveContext: telegramSessionContextStore.get,
1286
- getActiveProfileName: configStore.getActiveProfileName,
1287
- getLeaderState: lockRuntime.getState,
1288
- updateStatus,
1289
- recordRuntimeEvent,
1290
- },
1291
- services: {
1292
- mediaGroup: {
1293
- resume: mediaGroupRuntime.resume,
1294
- suspend: mediaGroupRuntime.suspend,
1295
- },
1296
- textGroup: {
1297
- resume: textGroupRuntime.resume,
1298
- suspend: textGroupRuntime.suspend,
1299
- },
1300
- delivery: deliveryLifecycleRuntime,
1301
- polling: lockedPollingRuntime,
1302
- inboundWorker: {
1303
- onSessionShutdown: updateAdmissionRuntimeBinding.onSessionShutdown,
1304
- },
1305
- capabilityMonitor: telegramThreadCapabilityMonitor,
1306
- queueWatchdog: queueDispatchWatchdogRuntime,
1307
- },
1308
- });
1309
- const sessionLifecycleRuntime =
1310
- Lifecycle.createTelegramBridgeSessionLifecycleAssembly(
1311
- telegramBridgeSessionLifecycleDeps,
1312
- );
1313
-
1314
- // --- Extension API Bindings ---
1315
-
1316
- Bindings.registerTelegramCommandsAndTools({
1317
- pi,
1318
- agentDir: Paths.resolveAgentDir(),
1319
- configStore,
1320
- persistConfig: persistTelegramConfigWithSync,
1321
- setup,
1322
- activeTurnRuntime,
1323
- lockedPollingRuntime,
1324
- stopPolling: disconnectTelegramAndDeleteCurrentThread,
1325
- recoverPollingStart: Recovery.createTelegramPollingStartRecoveryHandler({
1326
- getOwnersPath: Paths.resolveTelegramOwnersPath,
1327
- getStatePaths() {
1328
- return [
1329
- Threads.getTelegramTopicTargetsPath(
1330
- undefined,
1331
- configStore.getActiveProfileName(),
1332
- ),
1333
- ];
1334
- },
1335
- suspendPolling: lockedPollingRuntime.suspend,
1336
- releaseOwnership: lockRuntime.release,
1337
- recordRuntimeEvent,
1338
- }),
1339
- getDisconnectThreadName() {
1340
- const record = findCurrentThreadRecord();
1341
- if (!record?.target.threadId) return undefined;
1342
- return record.threadName ?? "current Telegram thread";
1343
- },
1344
- onTransportChanged() {
1345
- deliveryLifecycleRuntime.onSessionStart();
1346
- activityVerbosityRuntime.reset();
1347
- modelContextAvailabilityRuntime.reconcile();
1348
- },
1349
- getStatusLines,
1350
- buttonActionStore,
1351
- sendMarkdownReply,
1352
- callMultipart,
1353
- getDefaultChatId: proactivePushChatIdGetter,
1354
- getDefaultTarget: proactivePushTargetGetter,
1355
- ...agentMessageToolRoutingRuntime,
1356
- updateStatus,
1357
- recordRuntimeEvent,
1358
- });
1359
-
1360
- // --- Lifecycle Hooks ---
1361
-
1362
- Bindings.registerTelegramLifecycleRuntimeHooks({
1363
- pi,
1364
- sessionLifecycleRuntime: {
1365
- ...sessionLifecycleRuntime,
1366
- onModelSelect: currentModelRuntime.onModelSelect,
1367
- },
1368
- activityRuntime,
1369
- activityVerbosityRuntime,
1370
- assistantOutputRuntime,
1371
- publicationRuntime,
1372
- configStore,
1373
- abort,
1374
- typing,
1375
- lifecycle,
1376
- activeTurnRuntime,
1377
- telegramQueueStore,
1378
- modelSwitchController,
1379
- previewRuntime,
1380
- promptDispatchRuntime,
1381
- deferredQueueDispatchRuntime,
1382
- modelContextAvailabilityRuntime,
1383
- disconnectOnQuit: cleanupTelegramThreadForSessionRestart,
1384
- resolveAutomaticThreadCleanupEnabled:
1385
- configControls.resolveAutomaticThreadCleanupEnabled,
1386
- buttonActionStore,
1387
- callMultipart,
1388
- sendChatAction,
1389
- sendRecordVoiceAction,
1390
- sendMarkdownReply,
1391
- sendTextReply,
1392
- dispatchNextQueuedTelegramTurn,
1393
- onPromptHandedOff(turn, ctx) {
1394
- updateAdmissionRuntimeBinding
1395
- .getSettlement()
1396
- ?.onPromptHandedOff(turn, ctx);
1397
- },
1398
- answerGuestQuery,
1399
- deleteMessage: deleteTelegramMessage,
1400
- sendGuestReply,
1401
- finalizeMarkdownPreview,
1402
- preparePreviewDelivery,
1403
- proactivePushTargetGetter,
1404
- getAssistantRenderingMode: configControls.getAssistantRenderingMode,
1405
- recordMessageOwnership: messageOwnershipRuntime.recordLocal,
1406
- canSendAgentActivity(ctx) {
1407
- return (
1408
- lockOwnershipGuard.ownsContext(ctx) ||
1409
- telegramBusFollowerRegistrationState.isRegistered()
1410
- );
1411
- },
1412
- isSessionContextActive(ctx) {
1413
- return telegramSessionContextStore.isCurrent(ctx);
1414
- },
1415
- isTurnTransportActive(turn) {
1416
- return telegramTransportStampRuntime.isActive(turn.transportStamp);
1417
- },
1418
- updateStatus,
1419
- recordRuntimeEvent,
1420
- });
1421
- }
7
+ export { default } from "./lib/extension.ts";