@llblab/pi-telegram 0.21.0 → 0.22.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.
- package/AGENTS.md +6 -4
- package/CHANGELOG.md +477 -447
- package/README.md +9 -7
- package/docs/architecture.md +26 -14
- package/docs/delivery.md +2 -1
- package/docs/locks.md +9 -5
- package/docs/multi-instance-bus.md +5 -5
- package/docs/public-api.md +2 -2
- package/index.ts +311 -633
- package/lib/bindings.ts +59 -21
- package/lib/bus-api.ts +12 -2
- package/lib/bus-follower.ts +327 -83
- package/lib/bus-leader.ts +201 -121
- package/lib/bus.ts +345 -37
- package/lib/config.ts +168 -28
- package/lib/delivery.ts +148 -61
- package/lib/lifecycle.ts +199 -8
- package/lib/locks.ts +569 -56
- package/lib/logs.ts +178 -19
- package/lib/media.ts +79 -24
- package/lib/model.ts +5 -10
- package/lib/ownership.ts +150 -6
- package/lib/polling.ts +156 -7
- package/lib/preview.ts +15 -3
- package/lib/queue.ts +167 -20
- package/lib/routing.ts +68 -12
- package/lib/sync.ts +105 -32
- package/lib/telegram-api.ts +86 -10
- package/lib/text-groups.ts +71 -15
- package/lib/thread-reconciler.ts +49 -36
- package/lib/threads.ts +505 -118
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -83,71 +83,47 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
83
83
|
const telegramBusAuthSecret = Bus.createTelegramBusAuthSecret();
|
|
84
84
|
let telegramActiveBusAuthSecret: string | undefined;
|
|
85
85
|
let telegramBusLifecycleOverridePhase:
|
|
86
|
-
|
|
87
|
-
| undefined;
|
|
88
|
-
let telegramBusRequestSequence = 0;
|
|
86
|
+
Status.TelegramBridgeBusLifecyclePhase | undefined;
|
|
89
87
|
const telegramBusFollowerRegistry = Bus.createTelegramBusFollowerRegistry();
|
|
90
88
|
const telegramBusFollowerRegistrationState =
|
|
91
89
|
BusFollower.createTelegramBusFollowerRegistrationState();
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
90
|
+
const telegramBusLeaderState =
|
|
91
|
+
Threads.createTelegramLeaderThreadStateRuntime();
|
|
92
|
+
const telegramThreadCapabilityState =
|
|
93
|
+
Polling.createTelegramThreadCapabilityStateRuntime();
|
|
94
|
+
const telegramProvisioningActivity =
|
|
95
|
+
Sync.createTelegramProvisioningActivityRuntime();
|
|
96
|
+
const messageOwnershipRuntime =
|
|
97
|
+
Ownership.createTelegramBusMessageOwnershipRuntime({
|
|
98
|
+
instanceId: telegramInstanceId,
|
|
99
|
+
getProfileKey() {
|
|
100
|
+
return getActiveTelegramThreadProfile() ?? "default";
|
|
101
|
+
},
|
|
102
|
+
listFollowers: telegramBusFollowerRegistry.list,
|
|
103
|
+
});
|
|
98
104
|
const { abort, lifecycle, queue, setup, typing } = bridgeRuntime;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
},
|
|
104
|
-
});
|
|
105
|
-
let getRuntimeLogProfileName = function (): string | undefined {
|
|
106
|
-
return undefined;
|
|
107
|
-
};
|
|
108
|
-
const runtimeJsonlLog = Logs.createTelegramRuntimeJsonlLog({
|
|
109
|
-
path: function () {
|
|
110
|
-
return Logs.getTelegramRuntimeLogPath(
|
|
111
|
-
undefined,
|
|
112
|
-
getRuntimeLogProfileName(),
|
|
113
|
-
);
|
|
114
|
-
},
|
|
115
|
-
previousPath: function () {
|
|
116
|
-
return Logs.getTelegramPreviousRuntimeLogPath(
|
|
117
|
-
undefined,
|
|
118
|
-
getRuntimeLogProfileName(),
|
|
119
|
-
);
|
|
120
|
-
},
|
|
121
|
-
});
|
|
122
|
-
runtimeJsonlLog.reset("extension-start", {
|
|
123
|
-
instanceId: telegramInstanceId,
|
|
124
|
-
pid: process.pid,
|
|
125
|
-
});
|
|
126
|
-
let scheduleRuntimeDiagnosticsSnapshotPersist = function () {};
|
|
127
|
-
const recordRuntimeEvent = function (
|
|
128
|
-
category: string,
|
|
129
|
-
error: unknown,
|
|
130
|
-
details?: Record<string, unknown>,
|
|
131
|
-
) {
|
|
132
|
-
runtimeEvents.record(category, error, details);
|
|
133
|
-
const latestEvent = runtimeEvents.getEvents().at(-1);
|
|
134
|
-
if (latestEvent) runtimeJsonlLog.record(latestEvent);
|
|
135
|
-
scheduleRuntimeDiagnosticsSnapshotPersist();
|
|
136
|
-
};
|
|
105
|
+
const runtimeDiagnostics =
|
|
106
|
+
Logs.createTelegramRuntimeDiagnosticsRuntime<Pi.ExtensionContext>();
|
|
107
|
+
const runtimeEvents = runtimeDiagnostics.events;
|
|
108
|
+
const recordRuntimeEvent = runtimeDiagnostics.recordRuntimeEvent;
|
|
137
109
|
const configStore = Config.createTelegramConfigStore({ recordRuntimeEvent });
|
|
138
|
-
configStoreForRedaction = configStore;
|
|
139
|
-
getRuntimeLogProfileName = configStore.getActiveProfileName;
|
|
140
110
|
const isTelegramBusConfigured = function (): boolean {
|
|
141
111
|
return true;
|
|
142
112
|
};
|
|
143
113
|
const isTelegramBusRuntimeEnabled = function (): boolean {
|
|
144
|
-
return
|
|
114
|
+
return (
|
|
115
|
+
isTelegramBusConfigured() &&
|
|
116
|
+
!telegramThreadCapabilityState.isTopicModeUnavailable()
|
|
117
|
+
);
|
|
145
118
|
};
|
|
146
119
|
Config.bindGlobalTelegramConfigRuntime(configStore);
|
|
147
120
|
const configControls = Config.createTelegramConfigControls(configStore);
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
121
|
+
const lockRuntime = Locks.createTelegramLockRuntime<Pi.ExtensionContext>({
|
|
122
|
+
key: Locks.createTelegramLockKeyResolver(configStore),
|
|
123
|
+
instanceId: telegramInstanceId,
|
|
124
|
+
busSecret: telegramBusAuthSecret,
|
|
125
|
+
staleHeartbeatMs: Locks.TELEGRAM_BUS_LEADER_STALE_HEARTBEAT_MS,
|
|
126
|
+
});
|
|
151
127
|
const threadStore = Threads.createTelegramTopicTargetStore({
|
|
152
128
|
path: function () {
|
|
153
129
|
return Threads.getTelegramTopicTargetsPath(
|
|
@@ -155,27 +131,24 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
155
131
|
configStore.getActiveProfileName(),
|
|
156
132
|
);
|
|
157
133
|
},
|
|
158
|
-
canPersist:
|
|
159
|
-
|
|
160
|
-
},
|
|
134
|
+
canPersist: lockRuntime.owns,
|
|
135
|
+
commitPersist: lockRuntime.commitIfOwned,
|
|
161
136
|
});
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
137
|
+
runtimeDiagnostics.bindStorage({
|
|
138
|
+
getBotToken: configStore.getBotToken,
|
|
139
|
+
getProfileName: configStore.getActiveProfileName,
|
|
140
|
+
canReset: lockRuntime.owns,
|
|
141
|
+
commitReset: lockRuntime.commitIfOwned,
|
|
167
142
|
});
|
|
168
|
-
canPersistThreadState = function (): boolean {
|
|
169
|
-
return lockRuntime.getState().kind === "active-here";
|
|
170
|
-
};
|
|
171
143
|
const lockOwnershipGuard =
|
|
172
144
|
Locks.createTelegramLockOwnershipGuard(lockRuntime);
|
|
173
|
-
const getCurrentLeaderEpoch =
|
|
174
|
-
const state = lockRuntime.getState();
|
|
175
|
-
return state.kind === "active-here" ? state.lock.leaderEpoch : undefined;
|
|
176
|
-
};
|
|
145
|
+
const getCurrentLeaderEpoch = lockRuntime.getOwnedLeaderEpoch;
|
|
177
146
|
const telegramSessionContextStore =
|
|
178
|
-
Lifecycle.createTelegramSessionContextStore<Pi.ExtensionContext>(
|
|
147
|
+
Lifecycle.createTelegramSessionContextStore<Pi.ExtensionContext>({
|
|
148
|
+
getIdentity(ctx) {
|
|
149
|
+
return ctx.sessionManager ?? ctx.cwd;
|
|
150
|
+
},
|
|
151
|
+
});
|
|
179
152
|
const ownsTelegramDirectDelivery =
|
|
180
153
|
Locks.createTelegramDirectDeliveryOwnershipChecker({
|
|
181
154
|
lock: lockRuntime,
|
|
@@ -193,7 +166,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
193
166
|
getAssignedTarget() {
|
|
194
167
|
return (
|
|
195
168
|
telegramBusFollowerRegistrationState.getTarget() ??
|
|
196
|
-
|
|
169
|
+
telegramBusLeaderState.getTarget()
|
|
197
170
|
);
|
|
198
171
|
},
|
|
199
172
|
getAllowedUserId: configStore.getAllowedUserId,
|
|
@@ -223,89 +196,83 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
223
196
|
TelegramApi.TelegramMessage,
|
|
224
197
|
Pi.ExtensionContext
|
|
225
198
|
>();
|
|
226
|
-
const
|
|
199
|
+
const rawTelegramQueueStore =
|
|
227
200
|
Queue.createTelegramQueueStore<Pi.ExtensionContext>();
|
|
201
|
+
const telegramTransportStampRuntime =
|
|
202
|
+
Queue.createTelegramTransportStampRuntime({
|
|
203
|
+
getProfileName: configStore.getActiveProfileName,
|
|
204
|
+
getBotToken: configStore.getBotToken,
|
|
205
|
+
});
|
|
206
|
+
const telegramQueueStore = Queue.createTelegramTransportStampedQueueStore(
|
|
207
|
+
rawTelegramQueueStore,
|
|
208
|
+
telegramTransportStampRuntime.getStamp,
|
|
209
|
+
);
|
|
228
210
|
const deferredQueueDispatchRuntime =
|
|
229
211
|
Queue.createTelegramDeferredQueueDispatchRuntime<Pi.ExtensionContext>({
|
|
230
212
|
delayMs: 50,
|
|
231
213
|
recordRuntimeEvent,
|
|
232
214
|
});
|
|
233
215
|
const pollingControllerState = Polling.createTelegramPollingControllerState();
|
|
234
|
-
|
|
216
|
+
const telegramSyncStateRuntime = Sync.createTelegramSyncStateRuntime();
|
|
235
217
|
const threadReconciliationRuntime =
|
|
236
218
|
ThreadReconciler.createThreadReconciliationRuntime({
|
|
237
219
|
recordRuntimeEvent,
|
|
238
|
-
scheduleSnapshotPersist
|
|
239
|
-
scheduleRuntimeDiagnosticsSnapshotPersist();
|
|
240
|
-
},
|
|
220
|
+
scheduleSnapshotPersist: runtimeDiagnostics.scheduleSnapshotPersist,
|
|
241
221
|
});
|
|
242
222
|
const recordThreadReconciliationPlan = threadReconciliationRuntime.recordPlan;
|
|
243
|
-
const markTelegramConfigSyncChange =
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
const persistTelegramConfigWithSync = async function () {
|
|
250
|
-
await configStore.persist();
|
|
223
|
+
const markTelegramConfigSyncChange =
|
|
224
|
+
telegramSyncStateRuntime.markConfigChange;
|
|
225
|
+
const persistTelegramConfigWithSync = async function (
|
|
226
|
+
nextConfig?: Config.TelegramConfig,
|
|
227
|
+
) {
|
|
228
|
+
await configStore.persist(nextConfig);
|
|
251
229
|
markTelegramConfigSyncChange("config-persist");
|
|
252
230
|
};
|
|
253
|
-
const
|
|
254
|
-
|
|
255
|
-
| undefined {
|
|
256
|
-
return Threads.findCurrentTelegramInstanceThreadRecord({
|
|
257
|
-
records: threadStore.list(),
|
|
231
|
+
const currentInstanceThreadRuntime =
|
|
232
|
+
Threads.createTelegramCurrentInstanceThreadRuntime({
|
|
258
233
|
instanceId: telegramInstanceId,
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
234
|
+
listRecords: threadStore.list,
|
|
235
|
+
getPreferredTarget() {
|
|
236
|
+
return (
|
|
237
|
+
activeTurnRuntime.getTarget() ??
|
|
238
|
+
telegramBusFollowerRegistrationState.getTarget() ??
|
|
239
|
+
telegramBusLeaderState.getTarget()
|
|
240
|
+
);
|
|
241
|
+
},
|
|
242
|
+
getFollower() {
|
|
243
|
+
const target = telegramBusFollowerRegistrationState.getTarget();
|
|
244
|
+
if (!target) return undefined;
|
|
245
|
+
return {
|
|
246
|
+
registered: telegramBusFollowerRegistrationState.isRegistered(),
|
|
247
|
+
target,
|
|
248
|
+
slot: telegramBusFollowerRegistrationState.getSlot(),
|
|
249
|
+
threadName: telegramBusFollowerRegistrationState.getThreadName(),
|
|
250
|
+
};
|
|
251
|
+
},
|
|
252
|
+
getLeader: telegramBusLeaderState.getIdentity,
|
|
263
253
|
});
|
|
264
|
-
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
preferredTarget: target,
|
|
286
|
-
})
|
|
287
|
-
: getCurrentThreadRecord();
|
|
288
|
-
return Threads.resolveTelegramInstanceThreadIdentity({
|
|
289
|
-
target,
|
|
290
|
-
follower:
|
|
291
|
-
telegramBusFollowerRegistrationState.isRegistered() && followerTarget
|
|
292
|
-
? {
|
|
293
|
-
target: followerTarget,
|
|
294
|
-
slot: telegramBusFollowerRegistrationState.getSlot(),
|
|
295
|
-
threadName:
|
|
296
|
-
telegramBusFollowerRegistrationState.getThreadName(),
|
|
297
|
-
}
|
|
298
|
-
: undefined,
|
|
299
|
-
leader: telegramBusLeaderTarget
|
|
300
|
-
? {
|
|
301
|
-
target: telegramBusLeaderTarget,
|
|
302
|
-
slot: telegramBusLeaderSlot,
|
|
303
|
-
threadName: telegramBusLeaderThreadName,
|
|
304
|
-
}
|
|
305
|
-
: undefined,
|
|
306
|
-
record,
|
|
254
|
+
const findCurrentThreadRecord = currentInstanceThreadRuntime.findRecord;
|
|
255
|
+
const getCurrentInstanceThreadIdentity =
|
|
256
|
+
currentInstanceThreadRuntime.getIdentity;
|
|
257
|
+
const threadStatusProjectionRuntime =
|
|
258
|
+
Threads.createTelegramThreadStatusProjectionRuntime({
|
|
259
|
+
getThreadMode: function () {
|
|
260
|
+
return threadStore.getBotState().threadMode;
|
|
261
|
+
},
|
|
262
|
+
isBusPollingStarted: telegramThreadCapabilityState.isBusPollingStarted,
|
|
263
|
+
isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
|
|
264
|
+
listFollowers: telegramBusFollowerRegistry.list,
|
|
265
|
+
listRecords: threadStore.list,
|
|
266
|
+
listReservations: threadStore.listReservations,
|
|
267
|
+
listSyncObservations: threadStore.listSyncObservations,
|
|
268
|
+
getLeaderSocketPath: getTelegramBusSocketPath,
|
|
269
|
+
getFollowerSocketPath: getTelegramBusFollowerSocketPath,
|
|
270
|
+
getTransportKind: BusTransport.getTelegramBusTransportKind,
|
|
271
|
+
getFollowerTarget: telegramBusFollowerRegistrationState.getTarget,
|
|
272
|
+
getFollowerSlot: telegramBusFollowerRegistrationState.getSlot,
|
|
273
|
+
getFollowerThreadName: telegramBusFollowerRegistrationState.getThreadName,
|
|
274
|
+
getCurrentIdentity: getCurrentInstanceThreadIdentity,
|
|
307
275
|
});
|
|
308
|
-
};
|
|
309
276
|
const statusRuntime = Status.createTelegramBridgeStatusRuntime<
|
|
310
277
|
Pi.ExtensionContext,
|
|
311
278
|
Queue.TelegramQueueItem<Pi.ExtensionContext>
|
|
@@ -326,108 +293,29 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
326
293
|
formatQueuedStatus: Queue.formatQueuedTelegramItemsStatus,
|
|
327
294
|
getRecentRuntimeEvents: runtimeEvents.getEvents,
|
|
328
295
|
getRuntimeLockState: lockRuntime.getStatusLabel,
|
|
329
|
-
|
|
330
|
-
if (threadStore.getBotState().threadMode === "disabled") return undefined;
|
|
331
|
-
if (pollingStartedWithTelegramBus) return "leader";
|
|
332
|
-
if (telegramBusFollowerRegistrationState.isRegistered())
|
|
333
|
-
return "follower";
|
|
334
|
-
return undefined;
|
|
335
|
-
},
|
|
296
|
+
...threadStatusProjectionRuntime,
|
|
336
297
|
getBusLifecyclePhase() {
|
|
337
298
|
return telegramBusLifecycleOverridePhase;
|
|
338
299
|
},
|
|
339
300
|
getBotThreadMode() {
|
|
340
301
|
return threadStore.getBotState();
|
|
341
302
|
},
|
|
342
|
-
|
|
343
|
-
return Threads.listTelegramThreadStatusFollowers({
|
|
344
|
-
followers: telegramBusFollowerRegistry.list(),
|
|
345
|
-
records: threadStore.list(),
|
|
346
|
-
});
|
|
347
|
-
},
|
|
348
|
-
getLocalBus() {
|
|
349
|
-
return {
|
|
350
|
-
leaderSocketPath: getTelegramBusSocketPath(),
|
|
351
|
-
leaderTransport: BusTransport.getTelegramBusTransportKind(
|
|
352
|
-
getTelegramBusSocketPath(),
|
|
353
|
-
),
|
|
354
|
-
followerSocketPath: getTelegramBusFollowerSocketPath(),
|
|
355
|
-
followerTransport: BusTransport.getTelegramBusTransportKind(
|
|
356
|
-
getTelegramBusFollowerSocketPath(),
|
|
357
|
-
),
|
|
358
|
-
followerRegistered: telegramBusFollowerRegistrationState.isRegistered(),
|
|
359
|
-
followerTarget: telegramBusFollowerRegistrationState.getTarget(),
|
|
360
|
-
followerSlot: telegramBusFollowerRegistrationState.getSlot(),
|
|
361
|
-
followerThreadName: telegramBusFollowerRegistrationState.getThreadName(),
|
|
362
|
-
};
|
|
363
|
-
},
|
|
364
|
-
getTopicTargets() {
|
|
365
|
-
return Threads.listTelegramThreadStatusTargets(threadStore.list());
|
|
366
|
-
},
|
|
367
|
-
getThreadReservations() {
|
|
368
|
-
return Threads.listTelegramThreadStatusReservations(
|
|
369
|
-
threadStore.listReservations(),
|
|
370
|
-
);
|
|
371
|
-
},
|
|
372
|
-
getTopicSyncObservations() {
|
|
373
|
-
return Threads.listTelegramThreadStatusObservations(
|
|
374
|
-
threadStore.listSyncObservations(),
|
|
375
|
-
);
|
|
376
|
-
},
|
|
377
|
-
getSyncState() {
|
|
378
|
-
return telegramSyncState;
|
|
379
|
-
},
|
|
303
|
+
getSyncState: telegramSyncStateRuntime.getState,
|
|
380
304
|
getThreadReconciliationState() {
|
|
381
305
|
return threadReconciliationRuntime.getState();
|
|
382
306
|
},
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
307
|
+
});
|
|
308
|
+
runtimeDiagnostics.bindStatus({
|
|
309
|
+
instanceId: telegramInstanceId,
|
|
310
|
+
updateStatus: statusRuntime.updateStatus,
|
|
311
|
+
getStatusState: statusRuntime.getStatusState,
|
|
312
|
+
async persistSnapshot(snapshot) {
|
|
313
|
+
threadStore.setStatusSnapshot(snapshot);
|
|
314
|
+
await threadStore.persist();
|
|
390
315
|
},
|
|
391
316
|
});
|
|
392
|
-
const
|
|
393
|
-
const
|
|
394
|
-
const scope = Status.createTelegramRuntimeLogScope({
|
|
395
|
-
state: statusRuntime.getStatusState(),
|
|
396
|
-
instanceId: telegramInstanceId,
|
|
397
|
-
});
|
|
398
|
-
const scopeKey = JSON.stringify(scope);
|
|
399
|
-
runtimeJsonlLog.resetIfScopeChanged(scopeKey, reason, scope);
|
|
400
|
-
};
|
|
401
|
-
const updateStatus = function (ctx: Pi.ExtensionContext) {
|
|
402
|
-
updateStatusLine(ctx);
|
|
403
|
-
updateRuntimeLogScope("status-scope-change");
|
|
404
|
-
};
|
|
405
|
-
const persistCurrentStatusSnapshot = function () {
|
|
406
|
-
threadStore.setStatusSnapshot(
|
|
407
|
-
Status.createTelegramStatusSnapshot(statusRuntime.getStatusState()),
|
|
408
|
-
);
|
|
409
|
-
return threadStore.persist();
|
|
410
|
-
};
|
|
411
|
-
scheduleRuntimeDiagnosticsSnapshotPersist =
|
|
412
|
-
Status.createTelegramRuntimeDiagnosticsSnapshotScheduler({
|
|
413
|
-
persistSnapshot: persistCurrentStatusSnapshot,
|
|
414
|
-
recordError(error) {
|
|
415
|
-
runtimeEvents.record("telegram", error, {
|
|
416
|
-
phase: "runtime-diagnostics-snapshot-persist",
|
|
417
|
-
});
|
|
418
|
-
},
|
|
419
|
-
});
|
|
420
|
-
const getStatusLines = function (
|
|
421
|
-
options?: Status.TelegramBridgeStatusLineOptions,
|
|
422
|
-
): string[] {
|
|
423
|
-
const state = statusRuntime.getStatusState();
|
|
424
|
-
void persistCurrentStatusSnapshot().catch(function (error) {
|
|
425
|
-
recordRuntimeEvent("telegram", error, {
|
|
426
|
-
phase: "status-snapshot-persist",
|
|
427
|
-
});
|
|
428
|
-
});
|
|
429
|
-
return Status.buildTelegramBridgeStatusLines(state, options);
|
|
430
|
-
};
|
|
317
|
+
const updateStatus = runtimeDiagnostics.updateStatus;
|
|
318
|
+
const getStatusLines = runtimeDiagnostics.getStatusLines;
|
|
431
319
|
const inboundHandlerRuntime = Inbound.createTelegramInboundHandlerRuntime({
|
|
432
320
|
getHandlers: configStore.getInboundHandlers,
|
|
433
321
|
execCommand: CommandTemplates.execCommandTemplate,
|
|
@@ -442,29 +330,32 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
442
330
|
getBotToken: configStore.getBotToken,
|
|
443
331
|
recordRuntimeEvent,
|
|
444
332
|
});
|
|
333
|
+
const telegramBusFollowerClients =
|
|
334
|
+
BusFollower.createTelegramBusFollowerClientRuntime<
|
|
335
|
+
Pi.ExtensionContext,
|
|
336
|
+
Updates.TelegramMessageReactionUpdated,
|
|
337
|
+
Routing.TelegramRoutedCallbackQuery,
|
|
338
|
+
Routing.TelegramRoutedMessage
|
|
339
|
+
>({
|
|
340
|
+
socketPath: getTelegramBusSocketPath,
|
|
341
|
+
instanceId: telegramInstanceId,
|
|
342
|
+
getApiAuthSecret() {
|
|
343
|
+
return telegramActiveBusAuthSecret;
|
|
344
|
+
},
|
|
345
|
+
getForwardingAuthSecret() {
|
|
346
|
+
return telegramBusAuthSecret;
|
|
347
|
+
},
|
|
348
|
+
getRegistrationGeneration:
|
|
349
|
+
telegramBusFollowerRegistrationState.getGeneration,
|
|
350
|
+
timeoutMs: 30_000,
|
|
351
|
+
});
|
|
445
352
|
const telegramApiRuntime = BusApi.createTelegramBusAwareApiRuntime({
|
|
446
353
|
directRuntime: directTelegramApiRuntime,
|
|
447
354
|
ownsDirect() {
|
|
448
|
-
return (
|
|
449
|
-
lockRuntime.owns() ||
|
|
450
|
-
!telegramBusFollowerRegistrationState.isRegistered()
|
|
451
|
-
);
|
|
355
|
+
return lockRuntime.owns();
|
|
452
356
|
},
|
|
453
357
|
getDefaultTarget: proactivePushTargetGetter,
|
|
454
|
-
callFollowerApi:
|
|
455
|
-
socketPath: getTelegramBusSocketPath,
|
|
456
|
-
instanceId: telegramInstanceId,
|
|
457
|
-
createRequestId() {
|
|
458
|
-
telegramBusRequestSequence += 1;
|
|
459
|
-
return Bus.createTelegramBusRequestId({
|
|
460
|
-
instanceId: telegramInstanceId,
|
|
461
|
-
sequence: telegramBusRequestSequence,
|
|
462
|
-
});
|
|
463
|
-
},
|
|
464
|
-
getAuthSecret() {
|
|
465
|
-
return telegramActiveBusAuthSecret;
|
|
466
|
-
},
|
|
467
|
-
}),
|
|
358
|
+
callFollowerApi: telegramBusFollowerClients.callApi,
|
|
468
359
|
});
|
|
469
360
|
const {
|
|
470
361
|
call: callTelegramApi,
|
|
@@ -518,14 +409,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
518
409
|
// --- Reply Runtime & Preview ---
|
|
519
410
|
|
|
520
411
|
const replyRuntime = Replies.createTelegramRenderedMessageDeliveryRuntime({
|
|
521
|
-
recordOwnership
|
|
522
|
-
messageOwnershipStore.record({
|
|
523
|
-
chatId: input.chatId,
|
|
524
|
-
messageId: input.messageId,
|
|
525
|
-
target: input.target,
|
|
526
|
-
instanceId: telegramInstanceId,
|
|
527
|
-
});
|
|
528
|
-
},
|
|
412
|
+
recordOwnership: messageOwnershipRuntime.recordLocal,
|
|
529
413
|
sendMessage,
|
|
530
414
|
sendRichMessage,
|
|
531
415
|
getAssistantRenderingMode: configControls.getAssistantRenderingMode,
|
|
@@ -533,37 +417,27 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
533
417
|
});
|
|
534
418
|
const { replyTransport, editInteractiveMessage, sendInteractiveMessage } =
|
|
535
419
|
replyRuntime;
|
|
536
|
-
const
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
return record.target;
|
|
548
|
-
}),
|
|
549
|
-
};
|
|
550
|
-
};
|
|
420
|
+
const deliveryTargetPolicyRuntime =
|
|
421
|
+
Delivery.createTelegramDeliveryTargetPolicyRuntime({
|
|
422
|
+
ownsDirect: lockRuntime.owns,
|
|
423
|
+
isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
|
|
424
|
+
getAllowedChatId: configStore.getAllowedUserId,
|
|
425
|
+
getFollowerTarget: telegramBusFollowerRegistrationState.getTarget,
|
|
426
|
+
getLeaderTarget: telegramBusLeaderState.getTarget,
|
|
427
|
+
listThreadRecords: threadStore.list,
|
|
428
|
+
getActiveTurnTarget: activeTurnRuntime.getTarget,
|
|
429
|
+
getActiveGuestQueryId: activeTurnRuntime.getGuestQueryId,
|
|
430
|
+
});
|
|
551
431
|
const deliveryGenerationSeed = `${telegramInstanceId}:${Date.now()}`;
|
|
552
432
|
const deliveryLifecycleRuntime =
|
|
553
433
|
Delivery.createTelegramBridgeDeliveryLifecycleHooks({
|
|
554
434
|
generationSeed: deliveryGenerationSeed,
|
|
555
|
-
getTargetPolicyView:
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
},
|
|
435
|
+
getTargetPolicyView: deliveryTargetPolicyRuntime.getTargetPolicyView,
|
|
436
|
+
getTransportStamp: telegramTransportStampRuntime.getStamp,
|
|
437
|
+
isTransportStampActive: telegramTransportStampRuntime.isActive,
|
|
438
|
+
getActiveTurnTarget: deliveryTargetPolicyRuntime.getActiveTurnTarget,
|
|
560
439
|
api: telegramApiRuntime,
|
|
561
|
-
recordOwnership
|
|
562
|
-
messageOwnershipStore.record({
|
|
563
|
-
...input,
|
|
564
|
-
instanceId: telegramInstanceId,
|
|
565
|
-
});
|
|
566
|
-
},
|
|
440
|
+
recordOwnership: messageOwnershipRuntime.recordLocal,
|
|
567
441
|
recordFailure(operation, error, target) {
|
|
568
442
|
recordRuntimeEvent("delivery", error, {
|
|
569
443
|
operation,
|
|
@@ -598,6 +472,9 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
598
472
|
isIdle,
|
|
599
473
|
hasPendingMessages,
|
|
600
474
|
hasDispatchContext: deferredQueueDispatchRuntime.isBound,
|
|
475
|
+
isQueueItemTransportActive(item) {
|
|
476
|
+
return telegramTransportStampRuntime.isActive(item.transportStamp);
|
|
477
|
+
},
|
|
601
478
|
updateStatus,
|
|
602
479
|
sendTextReply,
|
|
603
480
|
recordRuntimeEvent,
|
|
@@ -723,111 +600,55 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
723
600
|
// --- Polling ---
|
|
724
601
|
|
|
725
602
|
const foreignOwnedUpdateForwarder =
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
Updates.TelegramMessageReactionUpdated,
|
|
729
|
-
Routing.TelegramRoutedCallbackQuery,
|
|
730
|
-
Routing.TelegramRoutedMessage
|
|
731
|
-
>({
|
|
732
|
-
socketPath: getTelegramBusSocketPath,
|
|
733
|
-
createRequestId() {
|
|
734
|
-
telegramBusRequestSequence += 1;
|
|
735
|
-
return Bus.createTelegramBusRequestId({
|
|
736
|
-
instanceId: telegramInstanceId,
|
|
737
|
-
sequence: telegramBusRequestSequence,
|
|
738
|
-
});
|
|
739
|
-
},
|
|
740
|
-
getAuthSecret() {
|
|
741
|
-
return telegramBusAuthSecret;
|
|
742
|
-
},
|
|
743
|
-
timeoutMs: 30_000,
|
|
744
|
-
});
|
|
745
|
-
const followerTargetController =
|
|
746
|
-
Bus.createTelegramBusFollowerTargetController({
|
|
747
|
-
socketPath: getTelegramBusSocketPath,
|
|
748
|
-
createRequestId() {
|
|
749
|
-
telegramBusRequestSequence += 1;
|
|
750
|
-
return Bus.createTelegramBusRequestId({
|
|
751
|
-
instanceId: telegramInstanceId,
|
|
752
|
-
sequence: telegramBusRequestSequence,
|
|
753
|
-
});
|
|
754
|
-
},
|
|
755
|
-
getAuthSecret() {
|
|
756
|
-
return telegramBusAuthSecret;
|
|
757
|
-
},
|
|
758
|
-
timeoutMs: 30_000,
|
|
759
|
-
});
|
|
603
|
+
telegramBusFollowerClients.foreignOwnedUpdateForwarder;
|
|
604
|
+
const followerTargetController = telegramBusFollowerClients.targetController;
|
|
760
605
|
const restoreFollowerThreadTarget =
|
|
761
606
|
Bus.createTelegramBusFollowerThreadRestoreHandler({
|
|
762
607
|
followerRegistry: telegramBusFollowerRegistry,
|
|
763
608
|
followerTargetController,
|
|
764
609
|
onRestored() {
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
"
|
|
768
|
-
|
|
769
|
-
);
|
|
610
|
+
telegramSyncStateRuntime.markSliceFresh("target-bindings", {
|
|
611
|
+
nowMs: Date.now(),
|
|
612
|
+
action: "follower-thread-restore",
|
|
613
|
+
});
|
|
770
614
|
},
|
|
771
615
|
});
|
|
772
|
-
|
|
773
|
-
Pi.ExtensionContext
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
616
|
+
const observedThreadTargetBinding =
|
|
617
|
+
Polling.createTelegramThreadTargetObservationBinding<Pi.ExtensionContext>();
|
|
618
|
+
const topicLifecycleSync =
|
|
619
|
+
Sync.createTelegramObservedTopicLifecycleSyncHandler({
|
|
620
|
+
topicTargetStore: threadStore,
|
|
621
|
+
isBusEnabled: isTelegramBusRuntimeEnabled,
|
|
622
|
+
callApi: callTelegramApi,
|
|
623
|
+
isTopicProvisioningActive: telegramProvisioningActivity.isActive,
|
|
624
|
+
getCurrentLeaderEpoch,
|
|
625
|
+
getThreadReconciliationMachineState() {
|
|
626
|
+
return threadReconciliationRuntime.getState();
|
|
627
|
+
},
|
|
628
|
+
recordThreadReconciliationPlan,
|
|
629
|
+
getSyncState: telegramSyncStateRuntime.getState,
|
|
630
|
+
setSyncState: telegramSyncStateRuntime.setState,
|
|
631
|
+
recordEvent: recordRuntimeEvent,
|
|
632
|
+
});
|
|
633
|
+
const inboundBusProjectionRuntime =
|
|
634
|
+
Routing.createTelegramInboundBusProjectionRuntime({
|
|
635
|
+
instanceId: telegramInstanceId,
|
|
636
|
+
listFollowers: telegramBusFollowerRegistry.list,
|
|
637
|
+
listThreadRecords: threadStore.list,
|
|
638
|
+
getLeaderTarget: telegramBusLeaderState.getTarget,
|
|
639
|
+
isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
|
|
640
|
+
getFollowerTarget: telegramBusFollowerRegistrationState.getTarget,
|
|
641
|
+
getCurrentIdentity: getCurrentInstanceThreadIdentity,
|
|
642
|
+
});
|
|
795
643
|
const inboundRouteRuntime = Routing.createTelegramInboundRouteRuntime({
|
|
796
644
|
configStore,
|
|
797
645
|
callApi: callTelegramApi,
|
|
798
646
|
getCurrentInstanceId() {
|
|
799
647
|
return telegramInstanceId;
|
|
800
648
|
},
|
|
801
|
-
getMessageOwnership:
|
|
802
|
-
recordMessageOwnership
|
|
803
|
-
|
|
804
|
-
},
|
|
805
|
-
getTargetOwnership(target) {
|
|
806
|
-
return Bus.getTelegramFollowerTargetOwnership({
|
|
807
|
-
target,
|
|
808
|
-
followers: telegramBusFollowerRegistry.list(),
|
|
809
|
-
activeThreadRecords: threadStore.list(),
|
|
810
|
-
currentInstanceId: telegramInstanceId,
|
|
811
|
-
});
|
|
812
|
-
},
|
|
813
|
-
getLiveThreadTargets() {
|
|
814
|
-
return Bus.listTelegramBusLiveThreadTargets({
|
|
815
|
-
leaderTarget: telegramBusLeaderTarget,
|
|
816
|
-
followers: telegramBusFollowerRegistry.list(),
|
|
817
|
-
});
|
|
818
|
-
},
|
|
819
|
-
getLocalThreadLabelForTarget(target) {
|
|
820
|
-
const followerTarget = telegramBusFollowerRegistrationState.getTarget();
|
|
821
|
-
const isLocalFollowerTarget =
|
|
822
|
-
telegramBusFollowerRegistrationState.isRegistered() &&
|
|
823
|
-
followerTarget?.chatId === target.chatId &&
|
|
824
|
-
followerTarget.threadId === target.threadId;
|
|
825
|
-
const isLocalLeaderTarget =
|
|
826
|
-
telegramBusLeaderTarget?.chatId === target.chatId &&
|
|
827
|
-
telegramBusLeaderTarget.threadId === target.threadId;
|
|
828
|
-
if (!isLocalFollowerTarget && !isLocalLeaderTarget) return undefined;
|
|
829
|
-
return getCurrentInstanceThreadIdentity(target).threadName;
|
|
830
|
-
},
|
|
649
|
+
getMessageOwnership: messageOwnershipRuntime.store.get,
|
|
650
|
+
recordMessageOwnership: messageOwnershipRuntime.recordRouted,
|
|
651
|
+
...inboundBusProjectionRuntime,
|
|
831
652
|
getCurrentLeaderEpoch,
|
|
832
653
|
getThreadReconciliationMachineState() {
|
|
833
654
|
return threadReconciliationRuntime.getState();
|
|
@@ -835,7 +656,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
835
656
|
recordThreadReconciliationPlan,
|
|
836
657
|
handleTelegramTopicLifecycleUpdate: topicLifecycleSync,
|
|
837
658
|
handleTelegramThreadTargetObserved(_target, ctx) {
|
|
838
|
-
return
|
|
659
|
+
return observedThreadTargetBinding.handle(ctx);
|
|
839
660
|
},
|
|
840
661
|
foreignOwnedUpdateForwarder,
|
|
841
662
|
replaceFollowerThreadTarget: restoreFollowerThreadTarget,
|
|
@@ -893,11 +714,26 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
893
714
|
topicTargetStore: threadStore,
|
|
894
715
|
instanceId: telegramInstanceId,
|
|
895
716
|
getActiveProfileName: getActiveTelegramThreadProfile,
|
|
896
|
-
async startLeader(ctx): Promise<
|
|
897
|
-
await lockedPollingRuntime.start(ctx, {
|
|
717
|
+
async startLeader(ctx, election, onAcquired): Promise<boolean> {
|
|
718
|
+
const result = await lockedPollingRuntime.start(ctx, {
|
|
719
|
+
election,
|
|
720
|
+
onAcquired,
|
|
721
|
+
});
|
|
722
|
+
return result.ok;
|
|
898
723
|
},
|
|
899
724
|
recordRuntimeEvent,
|
|
900
725
|
});
|
|
726
|
+
const forwardedRouteHandlers =
|
|
727
|
+
BusFollower.createTelegramBusForwardedRouteHandlers<
|
|
728
|
+
Pi.ExtensionContext,
|
|
729
|
+
Updates.TelegramMessageReactionUpdated,
|
|
730
|
+
Routing.TelegramRoutedCallbackQuery,
|
|
731
|
+
Routing.TelegramRoutedMessage
|
|
732
|
+
>({
|
|
733
|
+
handleUpdate: inboundRouteRuntime.handleUpdate,
|
|
734
|
+
handleAuthorizedReactionUpdate:
|
|
735
|
+
inboundRouteRuntime.handleAuthorizedReactionUpdate,
|
|
736
|
+
});
|
|
901
737
|
const telegramBusFollowerAssembly: BusFollower.TelegramBusFollowerRuntimeAssembly<Pi.ExtensionContext> =
|
|
902
738
|
BusFollower.createTelegramBusFollowerRuntimeAssembly<
|
|
903
739
|
Pi.ExtensionContext,
|
|
@@ -914,27 +750,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
914
750
|
getAuthSecret() {
|
|
915
751
|
return telegramActiveBusAuthSecret;
|
|
916
752
|
},
|
|
917
|
-
|
|
918
|
-
return inboundRouteRuntime.handleUpdate({ callback_query: query }, ctx);
|
|
919
|
-
},
|
|
920
|
-
handleForwardedReaction(reactionUpdate, ctx) {
|
|
921
|
-
return inboundRouteRuntime.handleAuthorizedReactionUpdate(
|
|
922
|
-
reactionUpdate,
|
|
923
|
-
ctx,
|
|
924
|
-
);
|
|
925
|
-
},
|
|
926
|
-
handleForwardedMessage(message, ctx) {
|
|
927
|
-
return inboundRouteRuntime.handleUpdate(
|
|
928
|
-
{ message: message as never },
|
|
929
|
-
ctx,
|
|
930
|
-
);
|
|
931
|
-
},
|
|
932
|
-
async handleForwardedEditedMessage(message, ctx) {
|
|
933
|
-
return inboundRouteRuntime.handleUpdate(
|
|
934
|
-
{ edited_message: message as never },
|
|
935
|
-
ctx,
|
|
936
|
-
);
|
|
937
|
-
},
|
|
753
|
+
...forwardedRouteHandlers,
|
|
938
754
|
recordRuntimeEvent,
|
|
939
755
|
},
|
|
940
756
|
targetReplacement: {
|
|
@@ -943,12 +759,8 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
943
759
|
instanceId: telegramInstanceId,
|
|
944
760
|
getManualFollowerProfileKey: getTelegramManualFollowerProfileKey,
|
|
945
761
|
manualFollowerOwnerId: telegramManualFollowerOwnerId,
|
|
946
|
-
getSyncState
|
|
947
|
-
|
|
948
|
-
},
|
|
949
|
-
setSyncState(state) {
|
|
950
|
-
telegramSyncState = state;
|
|
951
|
-
},
|
|
762
|
+
getSyncState: telegramSyncStateRuntime.getState,
|
|
763
|
+
setSyncState: telegramSyncStateRuntime.setState,
|
|
952
764
|
updateStatus,
|
|
953
765
|
recordRuntimeEvent,
|
|
954
766
|
},
|
|
@@ -962,10 +774,9 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
962
774
|
},
|
|
963
775
|
updateStatus,
|
|
964
776
|
promoteToLeader: promoteTelegramBusFollowerToLeader,
|
|
965
|
-
|
|
966
|
-
return
|
|
777
|
+
getActiveContext() {
|
|
778
|
+
return telegramSessionContextStore.get();
|
|
967
779
|
},
|
|
968
|
-
promotionGraceMs: BusFollower.TELEGRAM_BUS_FOLLOWER_PROMOTION_GRACE_MS,
|
|
969
780
|
recordRuntimeEvent,
|
|
970
781
|
},
|
|
971
782
|
registration: {
|
|
@@ -973,13 +784,10 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
973
784
|
getFollowerBusSocketPath: getTelegramBusFollowerSocketPath,
|
|
974
785
|
getLeaderSocketPath: getTelegramBusSocketPath,
|
|
975
786
|
registrationState: telegramBusFollowerRegistrationState,
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
return Bus.createTelegramBusRequestId({
|
|
979
|
-
instanceId: telegramInstanceId,
|
|
980
|
-
sequence: telegramBusRequestSequence,
|
|
981
|
-
});
|
|
787
|
+
isContextActive(ctx) {
|
|
788
|
+
return telegramSessionContextStore.isCurrent(ctx);
|
|
982
789
|
},
|
|
790
|
+
createRequestId: telegramBusFollowerClients.createRequestId,
|
|
983
791
|
getLeaderAuthSecret(owner) {
|
|
984
792
|
return owner.busSecret;
|
|
985
793
|
},
|
|
@@ -1017,31 +825,28 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1017
825
|
) {
|
|
1018
826
|
return Sync.recoverStaleTelegramTopicApiError(apiBody, error, {
|
|
1019
827
|
topicTargetStore: threadStore,
|
|
1020
|
-
getSyncState
|
|
1021
|
-
|
|
1022
|
-
},
|
|
1023
|
-
setSyncState(state) {
|
|
1024
|
-
telegramSyncState = state;
|
|
1025
|
-
},
|
|
828
|
+
getSyncState: telegramSyncStateRuntime.getState,
|
|
829
|
+
setSyncState: telegramSyncStateRuntime.setState,
|
|
1026
830
|
recordEvent: recordRuntimeEvent,
|
|
1027
831
|
});
|
|
1028
832
|
};
|
|
833
|
+
const authorizeFollowerApiCall = Bus.createTelegramFollowerApiCallAuthorizer({
|
|
834
|
+
isMessageOwned: messageOwnershipRuntime.isOwnedByFollower,
|
|
835
|
+
});
|
|
1029
836
|
const telegramBusLeaderRuntime =
|
|
1030
837
|
BusLeader.createTelegramBusLeaderRuntimeAssembly<Pi.ExtensionContext>({
|
|
1031
838
|
runtime: {
|
|
1032
839
|
socketPath: getTelegramBusSocketPath,
|
|
840
|
+
commitEndpointPublication(commit) {
|
|
841
|
+
return lockRuntime.commitIfOwned(commit);
|
|
842
|
+
},
|
|
1033
843
|
followerRegistry: telegramBusFollowerRegistry,
|
|
1034
844
|
authSecret: telegramBusAuthSecret,
|
|
1035
845
|
startPolling: pollingRuntime.start,
|
|
1036
846
|
stopPolling: pollingRuntime.stop,
|
|
1037
|
-
authorizeFollowerApiCall
|
|
847
|
+
authorizeFollowerApiCall,
|
|
1038
848
|
recordFollowerMessageOwnership(record) {
|
|
1039
|
-
|
|
1040
|
-
chatId: record.chatId,
|
|
1041
|
-
messageId: record.messageId,
|
|
1042
|
-
target: record.target,
|
|
1043
|
-
instanceId: record.follower.instanceId,
|
|
1044
|
-
});
|
|
849
|
+
messageOwnershipRuntime.recordFollower(record);
|
|
1045
850
|
},
|
|
1046
851
|
},
|
|
1047
852
|
getAllowedUserId: configStore.getAllowedUserId,
|
|
@@ -1050,9 +855,8 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1050
855
|
return typeof ctx.cwd === "string" ? ctx.cwd : undefined;
|
|
1051
856
|
},
|
|
1052
857
|
getTelegramProfile: getActiveTelegramThreadProfile,
|
|
1053
|
-
shouldForceFreshUnnamed
|
|
1054
|
-
|
|
1055
|
-
},
|
|
858
|
+
shouldForceFreshUnnamed:
|
|
859
|
+
telegramThreadCapabilityState.shouldForceFreshLeaderThread,
|
|
1056
860
|
topicTargetStore: threadStore,
|
|
1057
861
|
callApi(method, body) {
|
|
1058
862
|
return directTelegramApiRuntime.call(method, body);
|
|
@@ -1065,158 +869,52 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1065
869
|
return threadReconciliationRuntime.getState();
|
|
1066
870
|
},
|
|
1067
871
|
recordThreadReconciliationPlan,
|
|
1068
|
-
getSyncState
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
},
|
|
1074
|
-
setLeaderTarget(input) {
|
|
1075
|
-
telegramBusLeaderTarget = input.target;
|
|
1076
|
-
telegramBusLeaderSlot = input.slot;
|
|
1077
|
-
telegramBusLeaderThreadName = input.threadName;
|
|
1078
|
-
},
|
|
1079
|
-
onProvisioningStart() {
|
|
1080
|
-
telegramTopicProvisioningCount += 1;
|
|
1081
|
-
},
|
|
1082
|
-
onProvisioningEnd() {
|
|
1083
|
-
telegramTopicProvisioningCount = Math.max(
|
|
1084
|
-
0,
|
|
1085
|
-
telegramTopicProvisioningCount - 1,
|
|
1086
|
-
);
|
|
1087
|
-
},
|
|
872
|
+
getSyncState: telegramSyncStateRuntime.getState,
|
|
873
|
+
setSyncState: telegramSyncStateRuntime.setState,
|
|
874
|
+
setLeaderTarget: telegramBusLeaderState.set,
|
|
875
|
+
onProvisioningStart: telegramProvisioningActivity.start,
|
|
876
|
+
onProvisioningEnd: telegramProvisioningActivity.end,
|
|
1088
877
|
recordRuntimeEvent,
|
|
1089
878
|
});
|
|
1090
|
-
let pollingStartedWithTelegramBus = false;
|
|
1091
|
-
let forceFreshLeaderThreadOnNextStart = false;
|
|
1092
879
|
const telegramLeaderHealthRuntime = Sync.createTelegramLeaderHealthRuntime({
|
|
1093
880
|
callGetMe() {
|
|
1094
881
|
return directTelegramApiRuntime.call("getMe", {});
|
|
1095
882
|
},
|
|
1096
|
-
getSyncState
|
|
1097
|
-
|
|
1098
|
-
},
|
|
1099
|
-
setSyncState(state) {
|
|
1100
|
-
telegramSyncState = state;
|
|
1101
|
-
},
|
|
883
|
+
getSyncState: telegramSyncStateRuntime.getState,
|
|
884
|
+
setSyncState: telegramSyncStateRuntime.setState,
|
|
1102
885
|
recordEvent: recordRuntimeEvent,
|
|
1103
886
|
});
|
|
1104
|
-
const
|
|
1105
|
-
Polling.
|
|
1106
|
-
getAllowedUserId: configStore.getAllowedUserId,
|
|
1107
|
-
callApi: callTelegramApi,
|
|
1108
|
-
topicTargetStore: threadStore,
|
|
1109
|
-
isBusConfigured: isTelegramBusConfigured,
|
|
1110
|
-
ownsLock(ctx) {
|
|
1111
|
-
return lockRuntime.owns(ctx);
|
|
1112
|
-
},
|
|
1113
|
-
getPollingStartedWithTelegramBus() {
|
|
1114
|
-
return pollingStartedWithTelegramBus;
|
|
1115
|
-
},
|
|
1116
|
-
setPollingStartedWithTelegramBus(started) {
|
|
1117
|
-
pollingStartedWithTelegramBus = started;
|
|
1118
|
-
},
|
|
1119
|
-
setTopicModeUnavailable(unavailable) {
|
|
1120
|
-
telegramTopicModeUnavailable = unavailable;
|
|
1121
|
-
},
|
|
1122
|
-
stopFollowerRegistration: telegramBusFollowerRegistration.stop,
|
|
1123
|
-
startClassicPolling(ctx) {
|
|
1124
|
-
return pollingRuntime.start(ctx);
|
|
1125
|
-
},
|
|
1126
|
-
stopClassicPolling() {
|
|
1127
|
-
return pollingRuntime.stop();
|
|
1128
|
-
},
|
|
1129
|
-
startBusPolling(ctx) {
|
|
1130
|
-
return telegramBusLeaderRuntime.startPolling(ctx);
|
|
1131
|
-
},
|
|
1132
|
-
stopBusPolling() {
|
|
1133
|
-
return telegramBusLeaderRuntime.stopPolling();
|
|
1134
|
-
},
|
|
1135
|
-
startLeaderHealth: telegramLeaderHealthRuntime.start,
|
|
1136
|
-
stopLeaderHealth: telegramLeaderHealthRuntime.stop,
|
|
1137
|
-
isTopicModeUnavailableError: Threads.isTelegramTopicModeUnavailableError,
|
|
1138
|
-
updateStatus,
|
|
1139
|
-
recordEvent: recordRuntimeEvent,
|
|
1140
|
-
});
|
|
1141
|
-
observeTelegramThreadTarget = Polling.createTelegramThreadTargetObservationHandler({
|
|
1142
|
-
getAllowedUserId: configStore.getAllowedUserId,
|
|
1143
|
-
callApi: callTelegramApi,
|
|
1144
|
-
topicTargetStore: threadStore,
|
|
1145
|
-
isBusConfigured: isTelegramBusConfigured,
|
|
1146
|
-
ownsLock(ctx) {
|
|
1147
|
-
return lockRuntime.owns(ctx);
|
|
1148
|
-
},
|
|
1149
|
-
getPollingStartedWithTelegramBus() {
|
|
1150
|
-
return pollingStartedWithTelegramBus;
|
|
1151
|
-
},
|
|
1152
|
-
setPollingStartedWithTelegramBus(started) {
|
|
1153
|
-
pollingStartedWithTelegramBus = started;
|
|
1154
|
-
},
|
|
1155
|
-
setTopicModeUnavailable(unavailable) {
|
|
1156
|
-
telegramTopicModeUnavailable = unavailable;
|
|
1157
|
-
},
|
|
1158
|
-
stopFollowerRegistration: telegramBusFollowerRegistration.stop,
|
|
1159
|
-
startClassicPolling(ctx) {
|
|
1160
|
-
return pollingRuntime.start(ctx);
|
|
1161
|
-
},
|
|
1162
|
-
stopClassicPolling() {
|
|
1163
|
-
return pollingRuntime.stop();
|
|
1164
|
-
},
|
|
1165
|
-
startBusPolling(ctx) {
|
|
1166
|
-
return telegramBusLeaderRuntime.startPolling(ctx);
|
|
1167
|
-
},
|
|
1168
|
-
stopBusPolling() {
|
|
1169
|
-
return telegramBusLeaderRuntime.stopPolling();
|
|
1170
|
-
},
|
|
1171
|
-
startLeaderHealth: telegramLeaderHealthRuntime.start,
|
|
1172
|
-
stopLeaderHealth: telegramLeaderHealthRuntime.stop,
|
|
1173
|
-
isTopicModeUnavailableError: Threads.isTelegramTopicModeUnavailableError,
|
|
1174
|
-
updateStatus,
|
|
1175
|
-
recordEvent: recordRuntimeEvent,
|
|
1176
|
-
});
|
|
1177
|
-
const threadAwarePollingPorts =
|
|
1178
|
-
Polling.createTelegramThreadAwarePollingPorts<
|
|
887
|
+
const telegramThreadCapabilityRuntime =
|
|
888
|
+
Polling.createTelegramThreadCapabilityOrchestration<
|
|
1179
889
|
Pi.ExtensionContext,
|
|
1180
890
|
Locks.TelegramLockEntry
|
|
1181
891
|
>({
|
|
892
|
+
state: telegramThreadCapabilityState,
|
|
1182
893
|
getAllowedUserId: configStore.getAllowedUserId,
|
|
1183
894
|
callApi: callTelegramApi,
|
|
1184
895
|
topicTargetStore: threadStore,
|
|
1185
896
|
isBusConfigured: isTelegramBusConfigured,
|
|
1186
897
|
isBusRuntimeEnabled: isTelegramBusRuntimeEnabled,
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
pollingStartedWithTelegramBus = started;
|
|
1193
|
-
},
|
|
1194
|
-
setForceFreshLeaderThreadOnNextStart(forceFresh) {
|
|
1195
|
-
forceFreshLeaderThreadOnNextStart = forceFresh;
|
|
1196
|
-
},
|
|
1197
|
-
setTopicModeUnavailable(unavailable) {
|
|
1198
|
-
telegramTopicModeUnavailable = unavailable;
|
|
1199
|
-
},
|
|
1200
|
-
startClassicPolling(ctx) {
|
|
1201
|
-
return pollingRuntime.start(ctx);
|
|
1202
|
-
},
|
|
1203
|
-
stopClassicPolling() {
|
|
1204
|
-
return pollingRuntime.stop();
|
|
1205
|
-
},
|
|
1206
|
-
startBusLeaderPolling(ctx) {
|
|
1207
|
-
return telegramBusLeaderRuntime.startPolling(ctx);
|
|
1208
|
-
},
|
|
1209
|
-
stopBusLeaderPolling() {
|
|
1210
|
-
return telegramBusLeaderRuntime.stopPolling();
|
|
1211
|
-
},
|
|
898
|
+
ownsLock: lockRuntime.owns,
|
|
899
|
+
startClassicPolling: pollingRuntime.start,
|
|
900
|
+
stopClassicPolling: pollingRuntime.stop,
|
|
901
|
+
startBusLeaderPolling: telegramBusLeaderRuntime.startPolling,
|
|
902
|
+
stopBusLeaderPolling: telegramBusLeaderRuntime.stopPolling,
|
|
1212
903
|
startLeaderHealth: telegramLeaderHealthRuntime.start,
|
|
1213
904
|
stopLeaderHealth: telegramLeaderHealthRuntime.stop,
|
|
1214
|
-
registerFollowerWithLeader
|
|
1215
|
-
|
|
1216
|
-
},
|
|
905
|
+
registerFollowerWithLeader:
|
|
906
|
+
telegramBusFollowerRegistration.registerWithLeader,
|
|
1217
907
|
stopFollowerRegistration: telegramBusFollowerRegistration.stop,
|
|
908
|
+
isTopicModeUnavailableError: Threads.isTelegramTopicModeUnavailableError,
|
|
909
|
+
updateStatus,
|
|
1218
910
|
recordEvent: recordRuntimeEvent,
|
|
1219
911
|
});
|
|
912
|
+
const telegramThreadCapabilityMonitor =
|
|
913
|
+
telegramThreadCapabilityRuntime.monitor;
|
|
914
|
+
observedThreadTargetBinding.set(
|
|
915
|
+
telegramThreadCapabilityRuntime.observeTarget,
|
|
916
|
+
);
|
|
917
|
+
const threadAwarePollingPorts = telegramThreadCapabilityRuntime.pollingPorts;
|
|
1220
918
|
const lockedPollingRuntime = Locks.createTelegramLockedPollingRuntime({
|
|
1221
919
|
lock: lockRuntime,
|
|
1222
920
|
hasBotToken: configStore.hasBotToken,
|
|
@@ -1224,7 +922,8 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1224
922
|
formatStartBlockedMessage: Pi.formatPollingStartBlockedByRunMode,
|
|
1225
923
|
startPolling: threadAwarePollingPorts.startPolling,
|
|
1226
924
|
stopPolling: threadAwarePollingPorts.stopPolling,
|
|
1227
|
-
registerFollowerWithOwner:
|
|
925
|
+
registerFollowerWithOwner:
|
|
926
|
+
threadAwarePollingPorts.registerFollowerWithOwner,
|
|
1228
927
|
stopFollowerRegistration: threadAwarePollingPorts.stopFollowerRegistration,
|
|
1229
928
|
updateStatus,
|
|
1230
929
|
recordRuntimeEvent,
|
|
@@ -1235,89 +934,61 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1235
934
|
getCurrentThreadRecord: findCurrentThreadRecord,
|
|
1236
935
|
topicTargetStore: threadStore,
|
|
1237
936
|
callApi: callTelegramApi,
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
telegramBusLeaderSlot = undefined;
|
|
1244
|
-
telegramBusLeaderThreadName = undefined;
|
|
1245
|
-
},
|
|
1246
|
-
getSyncState() {
|
|
1247
|
-
return telegramSyncState;
|
|
1248
|
-
},
|
|
1249
|
-
setSyncState(state) {
|
|
1250
|
-
telegramSyncState = state;
|
|
1251
|
-
},
|
|
937
|
+
getCurrentLeaderEpoch,
|
|
938
|
+
getLeaderTarget: telegramBusLeaderState.getTarget,
|
|
939
|
+
clearLeaderTarget: telegramBusLeaderState.clear,
|
|
940
|
+
getSyncState: telegramSyncStateRuntime.getState,
|
|
941
|
+
setSyncState: telegramSyncStateRuntime.setState,
|
|
1252
942
|
stopPolling: lockedPollingRuntime.stop,
|
|
1253
943
|
recordRuntimeEvent,
|
|
1254
944
|
});
|
|
1255
|
-
const
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
}),
|
|
1278
|
-
clearModelMenuState: modelMenuRuntime.clear,
|
|
1279
|
-
getActiveTurnChatId: activeTurnRuntime.getChatId,
|
|
1280
|
-
getActiveTurnTarget: activeTurnRuntime.getTarget,
|
|
1281
|
-
clearPreview: previewRuntime.clear,
|
|
1282
|
-
clearActiveTurn: activeTurnRuntime.clear,
|
|
1283
|
-
clearAbort: abort.clearHandler,
|
|
1284
|
-
stopPolling: suspendTelegramForSessionReplacement,
|
|
1285
|
-
recordRuntimeEvent,
|
|
1286
|
-
});
|
|
1287
|
-
const baseSessionLifecycleRuntime = Lifecycle.appendTelegramLifecycleHooks(
|
|
1288
|
-
queueSessionLifecycle,
|
|
1289
|
-
{
|
|
1290
|
-
async onSessionStart(event, ctx) {
|
|
1291
|
-
await deliveryLifecycleRuntime.onSessionStart();
|
|
1292
|
-
await lockedPollingRuntime.onSessionStart(event, ctx);
|
|
1293
|
-
telegramThreadCapabilityMonitor.start(ctx);
|
|
1294
|
-
queueDispatchWatchdogRuntime.start(ctx);
|
|
1295
|
-
},
|
|
1296
|
-
async onSessionShutdown() {
|
|
1297
|
-
await deliveryLifecycleRuntime.onSessionShutdown();
|
|
1298
|
-
queueDispatchWatchdogRuntime.stop();
|
|
1299
|
-
telegramThreadCapabilityMonitor.stop();
|
|
945
|
+
const sessionLifecycleRuntime =
|
|
946
|
+
Lifecycle.createTelegramBridgeSessionLifecycleAssembly({
|
|
947
|
+
contextStore: telegramSessionContextStore,
|
|
948
|
+
queue: {
|
|
949
|
+
getCurrentModel: getContextModel,
|
|
950
|
+
loadConfig: configStore.load,
|
|
951
|
+
setQueuedItems: telegramQueueStore.setQueuedItems,
|
|
952
|
+
setCurrentModel: currentModelRuntime.set,
|
|
953
|
+
setPendingModelSwitch: pendingModelSwitchStore.set,
|
|
954
|
+
syncCounters: queue.syncCounters,
|
|
955
|
+
syncFlags: lifecycle.syncFlags,
|
|
956
|
+
bindDeferredDispatchContext: deferredQueueDispatchRuntime.bind,
|
|
957
|
+
prepareTempDir,
|
|
958
|
+
updateStatus,
|
|
959
|
+
unbindDeferredDispatchContext: deferredQueueDispatchRuntime.unbind,
|
|
960
|
+
clearModelMenuState: modelMenuRuntime.clear,
|
|
961
|
+
getActiveTurnChatId: activeTurnRuntime.getChatId,
|
|
962
|
+
getActiveTurnTarget: activeTurnRuntime.getTarget,
|
|
963
|
+
clearPreview: previewRuntime.clear,
|
|
964
|
+
clearActiveTurn: activeTurnRuntime.clear,
|
|
965
|
+
clearAbort: abort.clearHandler,
|
|
966
|
+
recordRuntimeEvent,
|
|
1300
967
|
},
|
|
1301
|
-
|
|
1302
|
-
);
|
|
1303
|
-
const sessionLifecycleWithContext = Lifecycle.appendTelegramLifecycleHooks(
|
|
1304
|
-
baseSessionLifecycleRuntime,
|
|
1305
|
-
Lifecycle.createTelegramSessionContextTracker(telegramSessionContextStore),
|
|
1306
|
-
);
|
|
1307
|
-
const sessionLifecycleRuntime = Lifecycle.appendTelegramLifecycleHooks(
|
|
1308
|
-
sessionLifecycleWithContext,
|
|
1309
|
-
{
|
|
1310
|
-
onSessionStart: BusFollower.createTelegramBusFollowerSessionRefreshHook({
|
|
968
|
+
follower: {
|
|
1311
969
|
registrationState: telegramBusFollowerRegistrationState,
|
|
1312
970
|
registrationRuntime: telegramBusFollowerRegistration,
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
971
|
+
instanceId: telegramInstanceId,
|
|
972
|
+
suspendPolling: lockedPollingRuntime.suspend,
|
|
973
|
+
getLeaderState: lockRuntime.getState,
|
|
1316
974
|
updateStatus,
|
|
1317
975
|
recordRuntimeEvent,
|
|
1318
|
-
}
|
|
1319
|
-
|
|
1320
|
-
|
|
976
|
+
},
|
|
977
|
+
services: {
|
|
978
|
+
resumeGroupedInput(ctx) {
|
|
979
|
+
mediaGroupRuntime.resume(ctx);
|
|
980
|
+
textGroupRuntime.resume(ctx);
|
|
981
|
+
},
|
|
982
|
+
suspendGroupedInput: TextGroups.createTelegramGroupedInputClearer({
|
|
983
|
+
clearMediaGroups: mediaGroupRuntime.suspend,
|
|
984
|
+
clearTextGroups: textGroupRuntime.suspend,
|
|
985
|
+
}),
|
|
986
|
+
delivery: deliveryLifecycleRuntime,
|
|
987
|
+
polling: lockedPollingRuntime,
|
|
988
|
+
capabilityMonitor: telegramThreadCapabilityMonitor,
|
|
989
|
+
queueWatchdog: queueDispatchWatchdogRuntime,
|
|
990
|
+
},
|
|
991
|
+
});
|
|
1321
992
|
|
|
1322
993
|
// --- Extension API Bindings ---
|
|
1323
994
|
|
|
@@ -1329,6 +1000,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1329
1000
|
activeTurnRuntime,
|
|
1330
1001
|
lockedPollingRuntime,
|
|
1331
1002
|
stopPolling: disconnectTelegramAndDeleteCurrentThread,
|
|
1003
|
+
onTransportChanged: deliveryLifecycleRuntime.onSessionStart,
|
|
1332
1004
|
getStatusLines,
|
|
1333
1005
|
buttonActionStore,
|
|
1334
1006
|
sendMarkdownReply,
|
|
@@ -1391,6 +1063,12 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1391
1063
|
telegramBusFollowerRegistrationState.isRegistered()
|
|
1392
1064
|
);
|
|
1393
1065
|
},
|
|
1066
|
+
isSessionContextActive(ctx) {
|
|
1067
|
+
return telegramSessionContextStore.isCurrent(ctx);
|
|
1068
|
+
},
|
|
1069
|
+
isTurnTransportActive(turn) {
|
|
1070
|
+
return telegramTransportStampRuntime.isActive(turn.transportStamp);
|
|
1071
|
+
},
|
|
1394
1072
|
updateStatus,
|
|
1395
1073
|
recordRuntimeEvent,
|
|
1396
1074
|
});
|