@llblab/pi-telegram 0.51.6 → 0.52.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +15 -12
- package/BACKLOG.md +16 -9
- package/CHANGELOG.md +19 -0
- package/LICENSE +21 -0
- package/README.md +17 -6
- package/dist/lib/activity-verbosity.d.ts +1 -5
- package/dist/lib/activity-verbosity.js +5 -7
- package/dist/lib/bindings.d.ts +5 -1
- package/dist/lib/bindings.js +7 -1
- package/dist/lib/bus-api.js +8 -5
- package/dist/lib/bus-follower.d.ts +54 -56
- package/dist/lib/bus-follower.js +206 -139
- package/dist/lib/bus-leader.d.ts +21 -2
- package/dist/lib/bus-leader.js +181 -25
- package/dist/lib/bus-transport.d.ts +4 -1
- package/dist/lib/bus-transport.js +28 -4
- package/dist/lib/bus.d.ts +52 -56
- package/dist/lib/bus.js +78 -246
- package/dist/lib/channel-posts.d.ts +1 -3
- package/dist/lib/channel-posts.js +23 -26
- package/dist/lib/command-templates.d.ts +0 -5
- package/dist/lib/command-templates.js +5 -5
- package/dist/lib/commands.d.ts +0 -23
- package/dist/lib/commands.js +15 -15
- package/dist/lib/config.d.ts +0 -17
- package/dist/lib/config.js +12 -14
- package/dist/lib/delivery.d.ts +0 -4
- package/dist/lib/delivery.js +2 -5
- package/dist/lib/extension.js +258 -61
- package/dist/lib/generative-apps.d.ts +0 -19
- package/dist/lib/inbound.d.ts +0 -2
- package/dist/lib/inbound.js +2 -2
- package/dist/lib/journal.d.ts +183 -16
- package/dist/lib/journal.js +1175 -248
- package/dist/lib/keyboard.d.ts +0 -2
- package/dist/lib/keyboard.js +2 -2
- package/dist/lib/lifecycle.js +1 -1
- package/dist/lib/locks.d.ts +100 -12
- package/dist/lib/locks.js +380 -14
- package/dist/lib/logging.d.ts +30 -12
- package/dist/lib/logging.js +129 -72
- package/dist/lib/media.d.ts +28 -5
- package/dist/lib/media.js +26 -8
- package/dist/lib/menu-model.d.ts +0 -11
- package/dist/lib/menu-model.js +8 -8
- package/dist/lib/menu-settings.d.ts +0 -18
- package/dist/lib/menu-settings.js +18 -18
- package/dist/lib/menu-status.d.ts +4 -4
- package/dist/lib/menu-status.js +12 -7
- package/dist/lib/menu-thinking.d.ts +1 -1
- package/dist/lib/menu-thinking.js +1 -1
- package/dist/lib/menu.d.ts +1 -0
- package/dist/lib/menu.js +4 -3
- package/dist/lib/outbound-attachments.d.ts +0 -1
- package/dist/lib/outbound-attachments.js +1 -1
- package/dist/lib/outbound-buttons.js +1 -8
- package/dist/lib/outbound-markup.d.ts +1 -6
- package/dist/lib/outbound-markup.js +4 -21
- package/dist/lib/outbound.d.ts +0 -8
- package/dist/lib/outbound.js +5 -5
- package/dist/lib/paths.d.ts +50 -7
- package/dist/lib/paths.js +155 -17
- package/dist/lib/pi.d.ts +1 -0
- package/dist/lib/pi.js +2 -1
- package/dist/lib/polling.d.ts +0 -5
- package/dist/lib/polling.js +5 -5
- package/dist/lib/preview.d.ts +0 -3
- package/dist/lib/preview.js +3 -3
- package/dist/lib/prompt-templates.d.ts +0 -1
- package/dist/lib/prompt-templates.js +1 -1
- package/dist/lib/queue.d.ts +5 -15
- package/dist/lib/queue.js +94 -11
- package/dist/lib/recovery.d.ts +29 -9
- package/dist/lib/recovery.js +104 -33
- package/dist/lib/replies.d.ts +0 -4
- package/dist/lib/replies.js +1 -1
- package/dist/lib/routing.d.ts +74 -8
- package/dist/lib/routing.js +2280 -307
- package/dist/lib/sections.d.ts +0 -2
- package/dist/lib/sections.js +1 -1
- package/dist/lib/status.d.ts +44 -9
- package/dist/lib/status.js +149 -27
- package/dist/lib/sync.d.ts +0 -5
- package/dist/lib/sync.js +5 -4
- package/dist/lib/telegram-api.d.ts +13 -3
- package/dist/lib/telegram-api.js +38 -23
- package/dist/lib/thread-cleanup-manager.d.ts +1 -0
- package/dist/lib/thread-cleanup-manager.js +18 -21
- package/dist/lib/thread-naming.d.ts +32 -5
- package/dist/lib/thread-naming.js +191 -7
- package/dist/lib/thread-reconciler.d.ts +2 -0
- package/dist/lib/thread-reconciler.js +1 -1
- package/dist/lib/threads.d.ts +293 -59
- package/dist/lib/threads.js +1689 -369
- package/dist/lib/turns.d.ts +0 -1
- package/dist/lib/turns.js +1 -1
- package/dist/lib/updates.d.ts +191 -28
- package/dist/lib/updates.js +1048 -114
- package/dist/lib/wire.d.ts +12 -0
- package/dist/lib/wire.js +21 -0
- package/dist/lib/workspace-admission.d.ts +25 -17
- package/dist/lib/workspace-admission.js +95 -20
- package/dist/lib/workspace-identity.d.ts +20 -0
- package/dist/lib/workspace-identity.js +103 -0
- package/dist/lib/workspace-retirement.d.ts +43 -8
- package/dist/lib/workspace-retirement.js +148 -52
- package/dist/package.json +6 -6
- package/dist/skills/generated-control-surface/SKILL.md +3 -3
- package/dist/skills/telegram-bridge/references/diagnosis.md +3 -3
- package/docs/README.md +1 -1
- package/docs/activity.md +1 -1
- package/docs/architecture.md +156 -36
- package/docs/callback-namespaces.md +1 -1
- package/docs/delivery.md +1 -1
- package/docs/generative-apps.md +2 -2
- package/docs/inbound.md +1 -1
- package/docs/multi-instance-bus.md +125 -19
- package/docs/public-api.md +3 -1
- package/docs/ui-style.md +23 -9
- package/docs/updates.md +1 -1
- package/lib/activity-verbosity.ts +5 -9
- package/lib/bindings.ts +7 -0
- package/lib/bus-api.ts +9 -4
- package/lib/bus-follower.ts +243 -224
- package/lib/bus-leader.ts +178 -31
- package/lib/bus-transport.ts +30 -8
- package/lib/bus.ts +110 -334
- package/lib/channel-posts.ts +29 -29
- package/lib/command-templates.ts +5 -5
- package/lib/commands.ts +15 -15
- package/lib/config.ts +12 -17
- package/lib/delivery.ts +2 -8
- package/lib/extension.ts +261 -72
- package/lib/generative-apps.ts +0 -22
- package/lib/inbound.ts +2 -2
- package/lib/journal.ts +1250 -325
- package/lib/keyboard.ts +2 -2
- package/lib/lifecycle.ts +1 -1
- package/lib/locks.ts +402 -23
- package/lib/logging.ts +151 -101
- package/lib/media.ts +51 -9
- package/lib/menu-model.ts +8 -8
- package/lib/menu-settings.ts +18 -18
- package/lib/menu-status.ts +11 -0
- package/lib/menu-thinking.ts +2 -2
- package/lib/menu.ts +5 -1
- package/lib/outbound-attachments.ts +1 -1
- package/lib/outbound-buttons.ts +1 -10
- package/lib/outbound-markup.ts +5 -24
- package/lib/outbound.ts +5 -5
- package/lib/paths.ts +177 -17
- package/lib/pi.ts +5 -2
- package/lib/polling.ts +5 -5
- package/lib/preview.ts +3 -3
- package/lib/prompt-templates.ts +1 -1
- package/lib/queue.ts +93 -12
- package/lib/recovery.ts +104 -44
- package/lib/replies.ts +1 -1
- package/lib/routing.ts +2010 -375
- package/lib/sections.ts +1 -1
- package/lib/status.ts +156 -36
- package/lib/sync.ts +4 -4
- package/lib/telegram-api.ts +53 -33
- package/lib/thread-cleanup-manager.ts +24 -21
- package/lib/thread-naming.ts +267 -9
- package/lib/thread-reconciler.ts +3 -1
- package/lib/threads.ts +1736 -488
- package/lib/turns.ts +1 -1
- package/lib/updates.ts +1094 -151
- package/lib/wire.ts +28 -0
- package/lib/workspace-admission.ts +97 -47
- package/lib/workspace-identity.ts +147 -0
- package/lib/workspace-retirement.ts +188 -89
- package/package.json +6 -6
- package/scripts/audit-exports.mjs +100 -0
- package/scripts/check-downgrade.mjs +80 -43
- package/skills/generated-control-surface/SKILL.md +3 -3
- package/skills/telegram-bridge/references/diagnosis.md +3 -3
package/lib/extension.ts
CHANGED
|
@@ -47,7 +47,9 @@ import * as Sync from "./sync.ts";
|
|
|
47
47
|
import * as TelegramApi from "./telegram-api.ts";
|
|
48
48
|
import * as TextGroups from "./text-groups.ts";
|
|
49
49
|
import * as ThreadReconciler from "./thread-reconciler.ts";
|
|
50
|
+
import * as Targets from "./target.ts";
|
|
50
51
|
import * as ThreadDisplay from "./thread-display.ts";
|
|
52
|
+
import * as ThreadNaming from "./thread-naming.ts";
|
|
51
53
|
import * as Threads from "./threads.ts";
|
|
52
54
|
import * as TimeInjection from "./time-injection.ts";
|
|
53
55
|
import * as Updates from "./updates.ts";
|
|
@@ -66,6 +68,7 @@ const telegramBusProtocolIdentity =
|
|
|
66
68
|
Bus.TELEGRAM_BUS_CAPABILITY_THREAD_DISPLAY_MODE,
|
|
67
69
|
Bus.TELEGRAM_BUS_CAPABILITY_DIRECTORY_DISPLAY_FORMAT,
|
|
68
70
|
Bus.TELEGRAM_BUS_CAPABILITY_SESSION_REPLACEMENT_INTENT,
|
|
71
|
+
Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE,
|
|
69
72
|
]);
|
|
70
73
|
|
|
71
74
|
// --- Extension Runtime ---
|
|
@@ -85,12 +88,13 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
85
88
|
} = piRuntime;
|
|
86
89
|
const bridgeRuntime = Runtime.createTelegramBridgeRuntime();
|
|
87
90
|
const runtimeDiagnostics =
|
|
88
|
-
Logging.createTelegramRuntimeDiagnosticsRuntime<Pi.ExtensionContext>();
|
|
91
|
+
Logging.createTelegramRuntimeDiagnosticsRuntime<Pi.ExtensionContext>({ sharedFile: true });
|
|
89
92
|
const runtimeEvents = runtimeDiagnostics.events;
|
|
90
93
|
const recordRuntimeEvent = runtimeDiagnostics.recordRuntimeEvent;
|
|
91
94
|
const configStore = Config.createTelegramConfigStore({ recordRuntimeEvent });
|
|
92
95
|
const busProcessRuntime = Bus.createCurrentTelegramBusProcessRuntime({
|
|
93
96
|
getActiveProfileName: configStore.getActiveProfileName,
|
|
97
|
+
endpointLayout: "consolidated",
|
|
94
98
|
});
|
|
95
99
|
const {
|
|
96
100
|
instanceId: telegramInstanceId,
|
|
@@ -105,7 +109,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
105
109
|
WorkspaceAdmission.createTelegramWorkspaceAdmissionRuntimeBinding({
|
|
106
110
|
getProfileName: configStore.getActiveProfileName,
|
|
107
111
|
getBotToken: configStore.getBotToken,
|
|
108
|
-
|
|
112
|
+
getStatePath: Paths.resolveTelegramStatePath,
|
|
109
113
|
owner: {
|
|
110
114
|
processId: telegramProcessId,
|
|
111
115
|
processBirthId: telegramQueueProcessBirthId,
|
|
@@ -157,24 +161,30 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
157
161
|
getBotToken: configStore.getBotToken,
|
|
158
162
|
getBotId: getTelegramBotId,
|
|
159
163
|
});
|
|
164
|
+
const telegramLeaderJournalPath = Locks.createTelegramLeaderJournalPathResolver({
|
|
165
|
+
getNamedJournalPath() { return lockRuntime.getJournalPath(); },
|
|
166
|
+
getSessionId() { return Pi.getExtensionContextSessionId(telegramSessionContextStore.get()); },
|
|
167
|
+
getProfileName: configStore.getActiveProfileName,
|
|
168
|
+
});
|
|
160
169
|
const telegramJournalBindingRuntime =
|
|
161
170
|
Journal.createTelegramUpdateJournalBindingRuntime({
|
|
162
171
|
base: {
|
|
163
172
|
getProfileName: configStore.getActiveProfileName,
|
|
164
173
|
getBotToken: configStore.getBotToken,
|
|
165
174
|
getBotId: getTelegramBotId,
|
|
175
|
+
withSourceSerialization: configStore.withSourceSerialization,
|
|
166
176
|
onRecovery(event) {
|
|
167
177
|
recordRuntimeEvent(
|
|
168
178
|
"recovery",
|
|
169
179
|
event.kind === "repaired"
|
|
170
180
|
? "Telegram update journal was repaired automatically."
|
|
171
|
-
: "Telegram update journal was reset after its damaged files were
|
|
181
|
+
: "Telegram update journal was reset after its damaged files were deleted.",
|
|
172
182
|
{
|
|
173
183
|
phase: "journal-auto-recovery",
|
|
174
184
|
recoveryKind: event.kind,
|
|
175
185
|
journalPath: event.path,
|
|
176
186
|
revision: event.revision,
|
|
177
|
-
|
|
187
|
+
deletedPaths: event.deletedPaths,
|
|
178
188
|
reason: event.reason,
|
|
179
189
|
},
|
|
180
190
|
);
|
|
@@ -188,8 +198,12 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
188
198
|
},
|
|
189
199
|
getWorkspaceAdmission: workspaceAdmissionRuntime.resolve,
|
|
190
200
|
},
|
|
191
|
-
getLeaderJournalPath:
|
|
192
|
-
|
|
201
|
+
getLeaderJournalPath: telegramLeaderJournalPath.resolve,
|
|
202
|
+
getRuntimeDir: Paths.resolveTelegramTempDir,
|
|
203
|
+
getFollowerJournalPath(bindingKey, profileName, sessionId) {
|
|
204
|
+
if (sessionId !== undefined) return Paths.resolveTelegramSessionJournalPath(
|
|
205
|
+
sessionId, bindingKey, undefined, profileName,
|
|
206
|
+
);
|
|
193
207
|
return Paths.resolveTelegramFollowerJournalPath(
|
|
194
208
|
bindingKey,
|
|
195
209
|
undefined,
|
|
@@ -197,6 +211,11 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
197
211
|
);
|
|
198
212
|
},
|
|
199
213
|
getActiveFollowerBindingKey: getTelegramManualFollowerProfileKey,
|
|
214
|
+
getActiveFollowerSessionId() {
|
|
215
|
+
return telegramBusFollowerRegistrationState.getSessionId(
|
|
216
|
+
Pi.getExtensionContextSessionId(telegramSessionContextStore.get()),
|
|
217
|
+
);
|
|
218
|
+
},
|
|
200
219
|
isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
|
|
201
220
|
});
|
|
202
221
|
const telegramJournalReferenceRegistry =
|
|
@@ -213,31 +232,46 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
213
232
|
const configControls = Config.createTelegramConfigControls(configStore);
|
|
214
233
|
const lockRuntime = Locks.createTelegramLockRuntime<Pi.ExtensionContext>({
|
|
215
234
|
key: Locks.createTelegramLockKeyResolver(configStore),
|
|
235
|
+
statePath: Paths.resolveTelegramStatePath(),
|
|
216
236
|
instanceId: telegramInstanceId,
|
|
217
237
|
busSecret: telegramBusAuthSecret,
|
|
218
238
|
staleHeartbeatMs: Locks.TELEGRAM_BUS_LEADER_STALE_HEARTBEAT_MS,
|
|
239
|
+
legacyLocksPath: Paths.resolveLegacyTelegramOwnersPath(),
|
|
240
|
+
createJournalPath() { return telegramLeaderJournalPath.createJournalPath(); },
|
|
219
241
|
});
|
|
242
|
+
const telegramSessionContextStore =
|
|
243
|
+
Lifecycle.createTelegramSessionContextStore<Pi.ExtensionContext>({
|
|
244
|
+
getIdentity(ctx) {
|
|
245
|
+
return ctx.sessionManager ?? ctx.cwd;
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
const captureTelegramStateAuthority = Locks.createTelegramOwnedStateAuthorityCapture(
|
|
249
|
+
lockRuntime, telegramSessionContextStore);
|
|
220
250
|
const threadStore = Threads.createTelegramTopicTargetStore({
|
|
221
|
-
path:
|
|
222
|
-
return Threads.getTelegramTopicTargetsPath(
|
|
223
|
-
undefined,
|
|
224
|
-
configStore.getActiveProfileName(),
|
|
225
|
-
);
|
|
226
|
-
},
|
|
251
|
+
path: Paths.resolveTelegramStatePath,
|
|
227
252
|
telegramProfile: function () {
|
|
228
253
|
return configStore.getActiveProfileName();
|
|
229
254
|
},
|
|
230
255
|
canPersist: lockRuntime.owns,
|
|
231
|
-
|
|
256
|
+
consolidated: {
|
|
257
|
+
captureAuthority: captureTelegramStateAuthority,
|
|
258
|
+
publishIfOwned: lockRuntime.publishStateSectionIfOwned!,
|
|
259
|
+
},
|
|
232
260
|
getExternalReservedSlots: function () {
|
|
233
261
|
return workspaceAdmissionRuntime.resolve()?.listReservedSlots() ?? [];
|
|
234
262
|
},
|
|
235
263
|
});
|
|
264
|
+
const resolveWorkspaceRestoreStore = Threads.createTelegramWorkspaceRestoreResolver({
|
|
265
|
+
getProfileName: configStore.getActiveProfileName,
|
|
266
|
+
getBotToken: configStore.getBotToken,
|
|
267
|
+
threadStore,
|
|
268
|
+
});
|
|
236
269
|
runtimeDiagnostics.bindStorage({
|
|
237
270
|
getBotToken: configStore.getBotToken,
|
|
238
271
|
getProfileName: configStore.getActiveProfileName,
|
|
239
272
|
canReset: lockRuntime.owns,
|
|
240
273
|
commitReset: lockRuntime.commitIfOwned,
|
|
274
|
+
captureAuthority: captureTelegramStateAuthority,
|
|
241
275
|
});
|
|
242
276
|
const sessionActionAssembly = Commands.createTelegramSessionActionAssembly({
|
|
243
277
|
registerCommand,
|
|
@@ -276,12 +310,6 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
276
310
|
const lockOwnershipGuard =
|
|
277
311
|
Locks.createTelegramLockOwnershipGuard(lockRuntime);
|
|
278
312
|
const getCurrentLeaderEpoch = lockRuntime.getOwnedLeaderEpoch;
|
|
279
|
-
const telegramSessionContextStore =
|
|
280
|
-
Lifecycle.createTelegramSessionContextStore<Pi.ExtensionContext>({
|
|
281
|
-
getIdentity(ctx) {
|
|
282
|
-
return ctx.sessionManager ?? ctx.cwd;
|
|
283
|
-
},
|
|
284
|
-
});
|
|
285
313
|
const ownsTelegramDirectDelivery =
|
|
286
314
|
Locks.createTelegramDirectDeliveryOwnershipChecker({
|
|
287
315
|
lock: lockRuntime,
|
|
@@ -360,13 +388,15 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
360
388
|
);
|
|
361
389
|
const telegramApiTargetActivityRuntime =
|
|
362
390
|
TelegramApi.createTelegramApiTargetActivityRuntime();
|
|
363
|
-
const
|
|
364
|
-
WorkspaceRetirement.
|
|
391
|
+
const workspaceProtectionObserver =
|
|
392
|
+
WorkspaceRetirement.createTelegramWorkspaceProtectionObserver({
|
|
365
393
|
listFollowers: telegramBusFollowerRegistry.list,
|
|
366
394
|
getActiveTurnTarget: activeTurnRuntime.getTarget,
|
|
367
395
|
getQueuedItems: telegramQueueStore.getQueuedItems,
|
|
368
396
|
resolveLeaderJournal: resolveTelegramUpdateJournalBinding,
|
|
369
397
|
createFollowerJournalResolver:
|
|
398
|
+
telegramJournalBindingRuntime.createLegacyRecipientResolver,
|
|
399
|
+
createSessionJournalResolver:
|
|
370
400
|
telegramJournalBindingRuntime.createRecipientResolver,
|
|
371
401
|
withJournalReference(binding, operation) {
|
|
372
402
|
if (!binding.recoveryKey) throw new Error(
|
|
@@ -378,12 +408,24 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
378
408
|
}, operation);
|
|
379
409
|
},
|
|
380
410
|
discoverFollowerJournals() {
|
|
381
|
-
return Journal.
|
|
411
|
+
return Journal.discoverTelegramRecipientJournalPaths({
|
|
382
412
|
directory: Paths.resolveTelegramTempDir(),
|
|
383
413
|
profileName: configStore.getActiveProfileName(),
|
|
384
414
|
});
|
|
385
415
|
},
|
|
386
416
|
createJournalPathResolver: telegramJournalBindingRuntime.createPathResolver,
|
|
417
|
+
inspectJournalNamespace() {
|
|
418
|
+
const botToken = configStore.getBotToken();
|
|
419
|
+
if (!botToken) throw new Error("Telegram namespace inspection requires current bot identity.");
|
|
420
|
+
return Journal.inspectTelegramSessionJournalNamespace({
|
|
421
|
+
directory: Paths.resolveTelegramTempDir(),
|
|
422
|
+
profile: configStore.getActiveProfileName() ?? "default",
|
|
423
|
+
pollingPath: telegramLeaderJournalPath.resolve(configStore.getActiveProfileName()),
|
|
424
|
+
botIdentity: Journal.createTelegramUpdateJournalBotIdentity({ botToken, botId: getTelegramBotId() }),
|
|
425
|
+
limits: { maxDirectoryEntries: 10_000, maxFiles: 4096, maxBytes: 64 * 1024 * 1024,
|
|
426
|
+
maxEntries: 10_000, maxWork: 100_000 },
|
|
427
|
+
});
|
|
428
|
+
},
|
|
387
429
|
getJournalWriterProtection(journalBindingKey) {
|
|
388
430
|
const owner = Threads.getTelegramThreadOwnerFromProfileKey(
|
|
389
431
|
journalBindingKey,
|
|
@@ -397,11 +439,24 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
397
439
|
: liveness === "dead" ? "clear" : "unknown";
|
|
398
440
|
},
|
|
399
441
|
getDeliveryAuthorityProtection(binding) {
|
|
400
|
-
|
|
442
|
+
const retainedRestore = resolveWorkspaceRestoreStore()?.list().some(function (intent) {
|
|
443
|
+
return intent.request.binding.bindingKey === binding.bindingKey ||
|
|
444
|
+
Targets.areTelegramTargetsEqual(intent.request.binding.target, binding.target) ||
|
|
445
|
+
Targets.areTelegramTargetsEqual(intent.request.target, binding.target);
|
|
446
|
+
});
|
|
447
|
+
return retainedRestore || telegramApiTargetActivityRuntime.hasPendingTarget(binding.target)
|
|
401
448
|
? "protected"
|
|
402
449
|
: "clear";
|
|
403
450
|
},
|
|
404
451
|
});
|
|
452
|
+
const captureWorkspaceExternalProtection = workspaceProtectionObserver.capture;
|
|
453
|
+
const pruneWorkspaceJournalEvidence = WorkspaceRetirement.createTelegramWorkspaceJournalEvidencePruner({
|
|
454
|
+
store: threadStore,
|
|
455
|
+
getAdmission: workspaceAdmissionRuntime.resolve,
|
|
456
|
+
getLeaderEpoch: getCurrentLeaderEpoch,
|
|
457
|
+
runExclusive: telegramWorkspaceOperationRuntime.runExclusive,
|
|
458
|
+
protection: workspaceProtectionObserver,
|
|
459
|
+
});
|
|
405
460
|
const reclaimTelegramWorkspaceDeadOwnerQueue =
|
|
406
461
|
WorkspaceRetirement.createTelegramWorkspaceDeadOwnerQueueReclaimer({
|
|
407
462
|
getExternalProtection: captureWorkspaceExternalProtection,
|
|
@@ -409,9 +464,11 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
409
464
|
getQueuedItems: telegramQueueStore.getQueuedItems,
|
|
410
465
|
resolveLeaderJournal: resolveTelegramUpdateJournalBinding,
|
|
411
466
|
createFollowerJournalResolver:
|
|
467
|
+
telegramJournalBindingRuntime.createLegacyRecipientResolver,
|
|
468
|
+
createSessionJournalResolver:
|
|
412
469
|
telegramJournalBindingRuntime.createRecipientResolver,
|
|
413
470
|
discoverFollowerJournals() {
|
|
414
|
-
return Journal.
|
|
471
|
+
return Journal.discoverTelegramRecipientJournalPaths({
|
|
415
472
|
directory: Paths.resolveTelegramTempDir(),
|
|
416
473
|
profileName: configStore.getActiveProfileName(),
|
|
417
474
|
});
|
|
@@ -460,7 +517,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
460
517
|
const botToken = configStore.getBotToken();
|
|
461
518
|
if (!botToken) throw new Error("Telegram Thread cleanup review requires an active bot token.");
|
|
462
519
|
return ThreadCleanupManager.createTelegramThreadCleanupWorkStore({
|
|
463
|
-
|
|
520
|
+
...Paths.resolveTelegramServiceJournalStorage("thread-cleanup", undefined, profileName),
|
|
464
521
|
profileName,
|
|
465
522
|
tokenSha256: Journal.createTelegramUpdateJournalBotIdentity({ botToken }).tokenSha256,
|
|
466
523
|
});
|
|
@@ -573,9 +630,10 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
573
630
|
instanceId: telegramInstanceId,
|
|
574
631
|
updateStatus: statusRuntime.updateStatus,
|
|
575
632
|
getStatusState: statusRuntime.getStatusState,
|
|
633
|
+
session: telegramSessionContextStore,
|
|
576
634
|
async persistSnapshot(snapshot) {
|
|
577
635
|
threadStore.setStatusSnapshot(snapshot);
|
|
578
|
-
await threadStore.
|
|
636
|
+
await threadStore.persistStatus();
|
|
579
637
|
},
|
|
580
638
|
});
|
|
581
639
|
const updateStatus = runtimeDiagnostics.updateStatus;
|
|
@@ -592,6 +650,10 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
592
650
|
const directTelegramApiRuntime =
|
|
593
651
|
TelegramApi.createDefaultTelegramBridgeApiRuntime({
|
|
594
652
|
getBotToken: configStore.getBotToken,
|
|
653
|
+
getBotScope() {
|
|
654
|
+
const config = configStore.get();
|
|
655
|
+
return config.botUsername ?? (config.botId === undefined ? undefined : String(config.botId));
|
|
656
|
+
},
|
|
595
657
|
recordRuntimeEvent,
|
|
596
658
|
targetActivity: telegramApiTargetActivityRuntime,
|
|
597
659
|
workspaceAdmission: workspaceAdmissionRuntime.resolve,
|
|
@@ -896,6 +958,10 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
896
958
|
getActiveModel: currentModelRuntime.get,
|
|
897
959
|
getThinkingLevel,
|
|
898
960
|
getQueueItemCount,
|
|
961
|
+
getPendingCancellationCount() {
|
|
962
|
+
return getCurrentLeaderEpoch() === undefined ? 0 :
|
|
963
|
+
updateAdmissionRuntimeBinding.getActive()?.getState()?.abandoningClaimCount ?? 0;
|
|
964
|
+
},
|
|
899
965
|
buildStatusHtml: Commands.createTelegramAppMenuHtmlBuilder({
|
|
900
966
|
buildStatusHtml: Status.createTelegramStatusHtmlBuilder({
|
|
901
967
|
getActiveModel: currentModelRuntime.get,
|
|
@@ -988,21 +1054,12 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
988
1054
|
|
|
989
1055
|
const foreignOwnedUpdateForwarder =
|
|
990
1056
|
telegramBusFollowerClients.foreignOwnedUpdateForwarder;
|
|
991
|
-
const
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
telegramSyncStateRuntime.markSliceFresh(
|
|
998
|
-
Sync.TELEGRAM_SYNC_SLICE_TARGET_BINDINGS,
|
|
999
|
-
{
|
|
1000
|
-
nowMs: Date.now(),
|
|
1001
|
-
action: "follower-thread-restore",
|
|
1002
|
-
},
|
|
1003
|
-
);
|
|
1004
|
-
},
|
|
1005
|
-
});
|
|
1057
|
+
const workspaceRestoreFollowerController = Bus.createTelegramBusWorkspaceRestoreController({
|
|
1058
|
+
getFollower: telegramBusFollowerRegistry.get,
|
|
1059
|
+
localProtocolIdentity: telegramBusProtocolIdentity,
|
|
1060
|
+
createRequestId: telegramBusFollowerClients.createRequestId,
|
|
1061
|
+
getAuthSecret() { return telegramBusAuthSecret; },
|
|
1062
|
+
});
|
|
1006
1063
|
const observedThreadTargetBinding =
|
|
1007
1064
|
Polling.createTelegramThreadTargetObservationBinding<Pi.ExtensionContext>();
|
|
1008
1065
|
const topicLifecycleSync =
|
|
@@ -1057,7 +1114,66 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1057
1114
|
return observedThreadTargetBinding.handle(ctx);
|
|
1058
1115
|
},
|
|
1059
1116
|
foreignOwnedUpdateForwarder,
|
|
1060
|
-
|
|
1117
|
+
workspaceRestoreRecipient: {
|
|
1118
|
+
getSessionId: Pi.getExtensionContextSessionId,
|
|
1119
|
+
getCwd: Pi.getExtensionContextCwd,
|
|
1120
|
+
getLeaderIdentity: telegramBusLeaderState.getIdentity,
|
|
1121
|
+
followerRegistry: telegramBusFollowerRegistry,
|
|
1122
|
+
runFollower: workspaceRestoreFollowerController,
|
|
1123
|
+
},
|
|
1124
|
+
getWorkspaceRestoreStore: resolveWorkspaceRestoreStore,
|
|
1125
|
+
captureWorkspaceExternalProtection,
|
|
1126
|
+
inspectRestoreSourceCompletion(expected) {
|
|
1127
|
+
return telegramJournalReferenceRegistry.withReference({ referenceClass: "operator-disposition",
|
|
1128
|
+
recoveryKey: expected.journalBindingKey }, function () {
|
|
1129
|
+
const observed = telegramJournalBindingRuntime.inspectSourceCompletion(expected.journalBindingKey, { updateId: expected.updateId,
|
|
1130
|
+
sourceSha256: expected.sourceSha256, completionSha256: expected.completionSha256 });
|
|
1131
|
+
return observed && { journalBindingKey: expected.journalBindingKey, ...observed };
|
|
1132
|
+
});
|
|
1133
|
+
},
|
|
1134
|
+
inspectRestoreQueuedReceipt(expected) {
|
|
1135
|
+
return telegramJournalReferenceRegistry.withReference({ referenceClass: "operator-disposition",
|
|
1136
|
+
recoveryKey: expected.journalBindingKey }, function () {
|
|
1137
|
+
return telegramJournalBindingRuntime.inspectQueuedReceipt(expected.journalBindingKey, { queueKind: expected.queueKind, receiptId: expected.receiptId,
|
|
1138
|
+
sourceUpdateIds: [...expected.sourceUpdateIds], queueOwner: { ...expected.queueOwner } });
|
|
1139
|
+
});
|
|
1140
|
+
},
|
|
1141
|
+
inspectRestoreSourceAbandonment(updateId, journalBindingKey) {
|
|
1142
|
+
return telegramJournalReferenceRegistry.withReference({
|
|
1143
|
+
referenceClass: "operator-disposition",
|
|
1144
|
+
recoveryKey: journalBindingKey,
|
|
1145
|
+
}, function () {
|
|
1146
|
+
return telegramJournalBindingRuntime.inspectSourceAbandonment(journalBindingKey, updateId);
|
|
1147
|
+
});
|
|
1148
|
+
},
|
|
1149
|
+
inspectRoutingInputGroupExpiry(input) {
|
|
1150
|
+
return telegramJournalReferenceRegistry.withReference({ referenceClass: "operator-disposition", recoveryKey: input.journalBindingKey },
|
|
1151
|
+
function () { return telegramJournalBindingRuntime.inspectSourceGroupExpiry(input.journalBindingKey, input.updateIds); });
|
|
1152
|
+
},
|
|
1153
|
+
inspectTemporaryThreadSources(_target, requiredJournalBindingKeys) {
|
|
1154
|
+
const binding = resolveTelegramUpdateJournalBinding();
|
|
1155
|
+
const botToken = configStore.getBotToken();
|
|
1156
|
+
if (!binding || !botToken) return undefined;
|
|
1157
|
+
const profile = configStore.getActiveProfileName() ?? "default";
|
|
1158
|
+
const botIdentity = Journal.createTelegramUpdateJournalBotIdentity({ botToken, botId: getTelegramBotId() });
|
|
1159
|
+
return configStore.withSourceSerialization(function () {
|
|
1160
|
+
return Journal.isTelegramThreadCleanupJournalNamespaceClear({
|
|
1161
|
+
directory: Paths.resolveTelegramTempDir(), profile, botIdentity,
|
|
1162
|
+
pollingPath: telegramLeaderJournalPath.resolve(configStore.getActiveProfileName()),
|
|
1163
|
+
requiredJournalBindingKeys: [binding.recoveryKey, ...requiredJournalBindingKeys],
|
|
1164
|
+
limits: { maxDirectoryEntries: 10_000, maxFiles: 4096, maxBytes: 64 * 1024 * 1024,
|
|
1165
|
+
maxEntries: 10_000, maxWork: 100_000 },
|
|
1166
|
+
withSourceReference(path, operation) {
|
|
1167
|
+
return telegramJournalReferenceRegistry.withReference({ referenceClass: "operator-disposition",
|
|
1168
|
+
recoveryKey: Journal.createTelegramUpdateJournalBindingKey({ path, profileName: profile, botIdentity }) }, operation);
|
|
1169
|
+
},
|
|
1170
|
+
}) ? [] : undefined;
|
|
1171
|
+
});
|
|
1172
|
+
},
|
|
1173
|
+
hasWorkspaceRestoreAuthority() {
|
|
1174
|
+
return lockRuntime.owns() && Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE);
|
|
1175
|
+
},
|
|
1176
|
+
getSessionGeneration: telegramSessionContextStore.getGeneration,
|
|
1061
1177
|
bridgeRuntime,
|
|
1062
1178
|
requestNewSession(source) {
|
|
1063
1179
|
const updateId = Updates.getTelegramUpdateExecutionFence(source)?.updateId;
|
|
@@ -1131,7 +1247,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1131
1247
|
sendTextReply,
|
|
1132
1248
|
setMyCommands,
|
|
1133
1249
|
validateThreadName(threadName) {
|
|
1134
|
-
return
|
|
1250
|
+
return ThreadNaming.getTelegramManualThreadDisplayNameValidationError(
|
|
1135
1251
|
threadName,
|
|
1136
1252
|
);
|
|
1137
1253
|
},
|
|
@@ -1197,10 +1313,43 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1197
1313
|
dispatchNext: dispatchNextQueuedTelegramTurn,
|
|
1198
1314
|
requestQueueHandoffReconciliation:
|
|
1199
1315
|
queueHandoffReconciliationBinding.request,
|
|
1200
|
-
|
|
1316
|
+
afterQueueReceiptCommitted: inboundRouteRuntime.onQueueReceiptCommitted,
|
|
1317
|
+
afterUpdateCompleted(updateId, ctx, journalBindingKey) {
|
|
1318
|
+
sessionActionsRuntime.onUpdateCompleted(updateId);
|
|
1319
|
+
inboundRouteRuntime.onUpdateCompleted(updateId, ctx, journalBindingKey);
|
|
1320
|
+
},
|
|
1201
1321
|
},
|
|
1202
1322
|
worker: {
|
|
1323
|
+
expireRoutingInput: inboundRouteRuntime.expireRoutingInput,
|
|
1324
|
+
beforeQueueReceiptPublished: inboundRouteRuntime.beforeQueueReceiptPublished,
|
|
1325
|
+
onQueueReceiptCompleted: inboundRouteRuntime.onQueueReceiptCompleted,
|
|
1203
1326
|
defaultHandle: inboundRouteRuntime.handleUpdate,
|
|
1327
|
+
async shouldReviewHistoricalInput(entry, ctx, signal) {
|
|
1328
|
+
if (signal.aborted || !telegramSessionContextStore.isCurrent(ctx)) {
|
|
1329
|
+
throw new Error("Workspace Restore source generation ended.");
|
|
1330
|
+
}
|
|
1331
|
+
const verdict = await inboundRouteRuntime.shouldReviewHistoricalInput(entry, ctx, signal);
|
|
1332
|
+
if (signal.aborted || !telegramSessionContextStore.isCurrent(ctx)) {
|
|
1333
|
+
throw new Error("Workspace Restore source generation ended.");
|
|
1334
|
+
}
|
|
1335
|
+
if (verdict === "retain") return verdict;
|
|
1336
|
+
const journalBindingKey = getTelegramQueueJournalBinding();
|
|
1337
|
+
if (journalBindingKey && resolveWorkspaceRestoreStore()?.list().some(function (intent) {
|
|
1338
|
+
return intent.request.source.journalBindingKey === journalBindingKey &&
|
|
1339
|
+
intent.request.source.updateIds.includes(entry.updateId);
|
|
1340
|
+
})) return true;
|
|
1341
|
+
return verdict;
|
|
1342
|
+
},
|
|
1343
|
+
spendHistoricalInput: true,
|
|
1344
|
+
onHeldSourcesPrepared(input): Promise<void> {
|
|
1345
|
+
return inboundRouteRuntime.forgetPreviousWorld(input, lockedPollingRuntime.captureTransportAuthority).then(function () {});
|
|
1346
|
+
},
|
|
1347
|
+
async shouldHoldPendingInput(entry, ctx, signal) {
|
|
1348
|
+
if (signal.aborted || !telegramSessionContextStore.isCurrent(ctx)) {
|
|
1349
|
+
throw new Error("Temporary Thread source generation ended.");
|
|
1350
|
+
}
|
|
1351
|
+
return inboundRouteRuntime.shouldHoldPendingInput(entry, ctx, signal);
|
|
1352
|
+
},
|
|
1204
1353
|
onStateChange: runtimeDiagnostics.scheduleSnapshotPersist,
|
|
1205
1354
|
settleTerminalExecutionFailure(error) {
|
|
1206
1355
|
return Sync.settleStaleTelegramTopicExecutionFailure(
|
|
@@ -1217,6 +1366,11 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1217
1366
|
resolveBinding: resolveTelegramFollowerJournalBinding,
|
|
1218
1367
|
isRegistered: telegramBusFollowerRegistrationState.isRegistered,
|
|
1219
1368
|
getGeneration: telegramBusFollowerRegistrationState.getGeneration,
|
|
1369
|
+
prepareBinding(binding) {
|
|
1370
|
+
telegramJournalBindingRuntime.prepareActiveFollowerSuccession(function isCurrent() {
|
|
1371
|
+
return binding.hasAuthority?.() === true;
|
|
1372
|
+
});
|
|
1373
|
+
},
|
|
1220
1374
|
prepareUpdateForExecution(update) {
|
|
1221
1375
|
return BusFollower.prepareTelegramBusFollowerJournaledUpdateForExecution(
|
|
1222
1376
|
update,
|
|
@@ -1296,6 +1450,32 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1296
1450
|
local: agentMessageRuntime,
|
|
1297
1451
|
follower: telegramBusFollowerClients.agentMessages,
|
|
1298
1452
|
});
|
|
1453
|
+
const followerWorkspaceRestore = BusFollower.createTelegramBusFollowerWorkspaceRestoreHandler({
|
|
1454
|
+
instanceId: telegramInstanceId,
|
|
1455
|
+
getContextAuthority: BusFollower.createTelegramBusFollowerRestoreContextGetter({
|
|
1456
|
+
isContextCurrent: telegramSessionContextStore.isCurrent,
|
|
1457
|
+
getSessionId: Pi.getExtensionContextSessionId,
|
|
1458
|
+
getCwd: Pi.getExtensionContextCwd,
|
|
1459
|
+
getGeneration: telegramSessionContextStore.getGeneration,
|
|
1460
|
+
getProfileBindingKey() {
|
|
1461
|
+
return workspaceAdmissionRuntime.resolve()?.getProfileKey();
|
|
1462
|
+
},
|
|
1463
|
+
getOperatorUserId: configStore.getAllowedUserId,
|
|
1464
|
+
getLeaderState: lockRuntime.getState,
|
|
1465
|
+
getAuthenticatedSecret: telegramBusFollowerControlState.getActiveAuthSecret,
|
|
1466
|
+
getLeaderProtocol: telegramBusFollowerRegistrationState.getLeaderProtocol,
|
|
1467
|
+
}),
|
|
1468
|
+
readRestoreIntent(operationId, profileBindingKey) {
|
|
1469
|
+
if (profileBindingKey !== workspaceAdmissionRuntime.resolve()?.getProfileKey()) return undefined;
|
|
1470
|
+
return resolveWorkspaceRestoreStore()?.list().find(function (intent) {
|
|
1471
|
+
return intent.request.operationId === operationId;
|
|
1472
|
+
});
|
|
1473
|
+
},
|
|
1474
|
+
topicTargetStore: threadStore,
|
|
1475
|
+
registrationState: telegramBusFollowerRegistrationState,
|
|
1476
|
+
getWorkspaceAdmission: workspaceAdmissionRuntime.resolve,
|
|
1477
|
+
recordRuntimeEvent,
|
|
1478
|
+
});
|
|
1299
1479
|
const telegramBusFollowerAssembly: BusFollower.TelegramBusFollowerRuntimeAssembly<Pi.ExtensionContext> =
|
|
1300
1480
|
BusFollower.createTelegramBusFollowerRuntimeAssembly<Pi.ExtensionContext>({
|
|
1301
1481
|
instanceId: telegramInstanceId,
|
|
@@ -1308,15 +1488,11 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1308
1488
|
getRecipientBindingKey: getTelegramManualFollowerProfileKey,
|
|
1309
1489
|
durableAdmission: followerDurableAdmissionRuntime,
|
|
1310
1490
|
handleQueueHandoff: acceptStagedQueueHandoff,
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
getWorkspaceAdmission: workspaceAdmissionRuntime.resolve,
|
|
1317
|
-
getSyncState: telegramSyncStateRuntime.getState,
|
|
1318
|
-
setSyncState: telegramSyncStateRuntime.setState,
|
|
1319
|
-
updateStatus,
|
|
1491
|
+
handleWorkspaceRestore: followerWorkspaceRestore,
|
|
1492
|
+
isWorkspaceRestoreEnabled() {
|
|
1493
|
+
return Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE) &&
|
|
1494
|
+
Bus.hasTelegramBusCapability(telegramBusFollowerRegistrationState.getLeaderProtocol(), Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE);
|
|
1495
|
+
},
|
|
1320
1496
|
},
|
|
1321
1497
|
recovery: {
|
|
1322
1498
|
getLeaderState: lockRuntime.getState,
|
|
@@ -1424,6 +1600,17 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1424
1600
|
const authorizeFollowerApiCall = Bus.createTelegramFollowerApiCallAuthorizer({
|
|
1425
1601
|
isMessageOwned: messageOwnershipRuntime.isOwnedByFollower,
|
|
1426
1602
|
});
|
|
1603
|
+
const telegramSessionFolderSweeper = Recovery.createTelegramSessionFolderSweeper({
|
|
1604
|
+
getSessionsDir: Paths.resolveTelegramSessionsDir,
|
|
1605
|
+
getProfileName: configStore.getActiveProfileName,
|
|
1606
|
+
getKeptSessionIds() {
|
|
1607
|
+
return [
|
|
1608
|
+
...threadStore.listWorkspaceBindings().map(function bindingSession(binding) { return binding.sessionId; }),
|
|
1609
|
+
...telegramBusFollowerRegistry.list().map(function followerSession(follower) { return follower.sessionId; }),
|
|
1610
|
+
Pi.getExtensionContextSessionId(telegramSessionContextStore.get()),
|
|
1611
|
+
];
|
|
1612
|
+
},
|
|
1613
|
+
});
|
|
1427
1614
|
const telegramBusLeaderRuntime =
|
|
1428
1615
|
BusLeader.createTelegramBusLeaderRuntimeAssembly<Pi.ExtensionContext>({
|
|
1429
1616
|
runtime: {
|
|
@@ -1448,11 +1635,15 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1448
1635
|
});
|
|
1449
1636
|
},
|
|
1450
1637
|
isFollowerProcessAlive: Locks.isProcessAlive,
|
|
1638
|
+
afterFollowerPrune() { telegramSessionFolderSweeper.sweep(); },
|
|
1451
1639
|
shouldCleanupConfirmedDeadFollower:
|
|
1452
1640
|
configControls.resolveAutomaticThreadCleanupEnabled,
|
|
1453
1641
|
recordFollowerMessageOwnership(record) {
|
|
1454
1642
|
messageOwnershipRuntime.recordFollower(record);
|
|
1455
1643
|
},
|
|
1644
|
+
onWorkspaceRestoreRecipientObserved(follower, isCurrent) {
|
|
1645
|
+
return inboundRouteRuntime.onWorkspaceRestoreRecipientObserved(follower, isCurrent, telegramSessionContextStore.get());
|
|
1646
|
+
},
|
|
1456
1647
|
},
|
|
1457
1648
|
getAllowedUserId: configStore.getAllowedUserId,
|
|
1458
1649
|
instanceId: telegramInstanceId,
|
|
@@ -1481,6 +1672,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1481
1672
|
getAdmission: workspaceAdmissionRuntime.resolve,
|
|
1482
1673
|
runExclusive: telegramWorkspaceOperationRuntime.runExclusive,
|
|
1483
1674
|
deleteThread: directTelegramApiRuntime.deleteWorkspaceThread,
|
|
1675
|
+
pruneJournalEvidence: pruneWorkspaceJournalEvidence,
|
|
1484
1676
|
reclaimDeadOwnerQueuedWork(binding, isCurrent) {
|
|
1485
1677
|
return telegramWorkspaceOperationRuntime.run({
|
|
1486
1678
|
operationId: WorkspaceAdmission.createTelegramWorkspaceAdmissionOperationId(),
|
|
@@ -1583,6 +1775,12 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1583
1775
|
const threadAwarePollingPorts = telegramThreadCapabilityRuntime.pollingPorts;
|
|
1584
1776
|
const lockedPollingRuntime = Locks.createTelegramLockedPollingRuntime({
|
|
1585
1777
|
lock: lockRuntime,
|
|
1778
|
+
resetDamagedState() {
|
|
1779
|
+
return Locks.resetDamagedTelegramRuntimeState(Paths.resolveTelegramStatePath(), function (profile, sections) {
|
|
1780
|
+
Threads.parseTelegramWorkspaceStateSection(sections.workspace, profile);
|
|
1781
|
+
WorkspaceAdmission.assertTelegramConsolidatedAdmissionSection(sections.admission, profile);
|
|
1782
|
+
});
|
|
1783
|
+
},
|
|
1586
1784
|
transportMonitor: telegramThreadCapabilityMonitor,
|
|
1587
1785
|
hasBotToken: configStore.hasBotToken,
|
|
1588
1786
|
getBotTokenDiagnostic: configStore.getBotTokenDiagnostic,
|
|
@@ -1666,7 +1864,10 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1666
1864
|
syncCounters: queue.syncCounters,
|
|
1667
1865
|
syncFlags: lifecycle.syncFlags,
|
|
1668
1866
|
bindDeferredDispatchContext: deferredQueueDispatchRuntime.bind,
|
|
1669
|
-
prepareTempDir
|
|
1867
|
+
prepareTempDir() {
|
|
1868
|
+
Recovery.removeTelegramLegacyRecoveryStorage(Paths.resolveTelegramTempDir());
|
|
1869
|
+
return prepareTempDir();
|
|
1870
|
+
},
|
|
1670
1871
|
updateStatus,
|
|
1671
1872
|
unbindDeferredDispatchContext: deferredQueueDispatchRuntime.unbind,
|
|
1672
1873
|
discardQueuedItems: queueMutationRuntime.clear,
|
|
@@ -1824,20 +2025,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1824
2025
|
activeTurnRuntime,
|
|
1825
2026
|
lockedPollingRuntime,
|
|
1826
2027
|
stopPolling: disconnectTelegramAndDeleteCurrentThread,
|
|
1827
|
-
|
|
1828
|
-
getOwnersPath: Paths.resolveTelegramOwnersPath,
|
|
1829
|
-
getStatePaths() {
|
|
1830
|
-
return [
|
|
1831
|
-
Threads.getTelegramTopicTargetsPath(
|
|
1832
|
-
undefined,
|
|
1833
|
-
configStore.getActiveProfileName(),
|
|
1834
|
-
),
|
|
1835
|
-
];
|
|
1836
|
-
},
|
|
1837
|
-
suspendPolling: lockedPollingRuntime.suspend,
|
|
1838
|
-
releaseOwnership: lockRuntime.release,
|
|
1839
|
-
recordRuntimeEvent,
|
|
1840
|
-
}),
|
|
2028
|
+
// Consolidated envelope failures remain protective; legacy whole-file recovery cannot reset sibling authority.
|
|
1841
2029
|
getDisconnectThreadName() {
|
|
1842
2030
|
const record = findCurrentThreadRecord();
|
|
1843
2031
|
if (!record?.target.threadId) return undefined;
|
|
@@ -1862,7 +2050,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1862
2050
|
const botToken = configStore.getBotToken();
|
|
1863
2051
|
if (!botToken) throw new Error("Telegram channel delivery requires an active bot token.");
|
|
1864
2052
|
const store = ChannelPosts.createTelegramChannelPostJournalStore({
|
|
1865
|
-
|
|
2053
|
+
...Paths.resolveTelegramServiceJournalStorage("channel-posts", undefined, profileName),
|
|
1866
2054
|
profileName,
|
|
1867
2055
|
tokenSha256: Journal.createTelegramUpdateJournalBotIdentity({ botToken }).tokenSha256,
|
|
1868
2056
|
});
|
|
@@ -1893,7 +2081,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1893
2081
|
const caption = Replies.renderTelegramMarkdownToHtmlDraft(markdown);
|
|
1894
2082
|
ChannelPosts.assertTelegramChannelPostCaptionWithinLimit(caption);
|
|
1895
2083
|
const store = ChannelPosts.createTelegramChannelPostJournalStore({
|
|
1896
|
-
|
|
2084
|
+
...Paths.resolveTelegramServiceJournalStorage("channel-posts", undefined, profileName),
|
|
1897
2085
|
profileName,
|
|
1898
2086
|
tokenSha256: Journal.createTelegramUpdateJournalBotIdentity({ botToken }).tokenSha256,
|
|
1899
2087
|
});
|
|
@@ -1922,7 +2110,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1922
2110
|
const botToken = configStore.getBotToken();
|
|
1923
2111
|
if (!botToken) throw new Error("Telegram channel posts require an active bot token.");
|
|
1924
2112
|
return ChannelPosts.createTelegramChannelPostJournalStore({
|
|
1925
|
-
|
|
2113
|
+
...Paths.resolveTelegramServiceJournalStorage("channel-posts", undefined, profileName),
|
|
1926
2114
|
profileName,
|
|
1927
2115
|
tokenSha256: Journal.createTelegramUpdateJournalBotIdentity({ botToken }).tokenSha256,
|
|
1928
2116
|
}).list(input);
|
|
@@ -1933,7 +2121,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1933
2121
|
const botToken = configStore.getBotToken();
|
|
1934
2122
|
if (!botToken) throw new Error("Telegram channel post mutation requires an active bot token.");
|
|
1935
2123
|
const store = ChannelPosts.createTelegramChannelPostJournalStore({
|
|
1936
|
-
|
|
2124
|
+
...Paths.resolveTelegramServiceJournalStorage("channel-posts", undefined, profileName), profileName,
|
|
1937
2125
|
tokenSha256: Journal.createTelegramUpdateJournalBotIdentity({ botToken }).tokenSha256,
|
|
1938
2126
|
});
|
|
1939
2127
|
if (input.action === "edit") {
|
|
@@ -1995,6 +2183,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1995
2183
|
},
|
|
1996
2184
|
activityRuntime,
|
|
1997
2185
|
activityVerbosityRuntime,
|
|
2186
|
+
diagnostics: runtimeDiagnostics,
|
|
1998
2187
|
assistantOutputRuntime,
|
|
1999
2188
|
publicationRuntime,
|
|
2000
2189
|
configStore,
|
package/lib/generative-apps.ts
CHANGED
|
@@ -44,28 +44,6 @@ export type GenerativeAppJsonValue =
|
|
|
44
44
|
| GenerativeAppJsonValue[]
|
|
45
45
|
| { [key: string]: GenerativeAppJsonValue };
|
|
46
46
|
|
|
47
|
-
export interface GenerativeAppProcessInput {
|
|
48
|
-
command: string;
|
|
49
|
-
args?: string[];
|
|
50
|
-
cwd: string;
|
|
51
|
-
timeoutMs?: number;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export interface GenerativeAppProcessResult {
|
|
55
|
-
code: number;
|
|
56
|
-
killed: boolean;
|
|
57
|
-
stderr: string;
|
|
58
|
-
stdout: string;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export interface GenerativeAppMethodContext {
|
|
62
|
-
argument?: GenerativeAppJsonValue;
|
|
63
|
-
revision: number;
|
|
64
|
-
run: (input: GenerativeAppProcessInput) => Promise<GenerativeAppProcessResult>;
|
|
65
|
-
signal: AbortSignal;
|
|
66
|
-
state?: GenerativeAppJsonValue;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
47
|
export interface GenerativeAppMethodResult {
|
|
70
48
|
output: string;
|
|
71
49
|
refreshAfterMs?: number;
|