@llblab/pi-telegram 0.51.5 → 0.52.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 +10 -8
- package/BACKLOG.md +1 -8
- package/CHANGELOG.md +23 -0
- package/LICENSE +21 -0
- package/README.md +16 -6
- package/dist/lib/activity-verbosity.d.ts +1 -5
- package/dist/lib/activity-verbosity.js +5 -7
- package/dist/lib/bindings.d.ts +9 -2
- package/dist/lib/bindings.js +22 -13
- package/dist/lib/bus-api.js +4 -2
- package/dist/lib/bus-follower.d.ts +55 -57
- package/dist/lib/bus-follower.js +213 -140
- 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 +12 -26
- package/dist/lib/commands.js +152 -98
- 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 +281 -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 +177 -16
- package/dist/lib/journal.js +1115 -249
- package/dist/lib/keyboard.d.ts +0 -2
- package/dist/lib/keyboard.js +2 -2
- package/dist/lib/lifecycle.d.ts +57 -2
- package/dist/lib/lifecycle.js +110 -5
- 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/model.js +2 -4
- 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 +3 -15
- package/dist/lib/queue.js +69 -8
- 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 +73 -8
- package/dist/lib/routing.js +2206 -307
- package/dist/lib/sections.d.ts +0 -2
- package/dist/lib/sections.js +1 -1
- package/dist/lib/status.d.ts +46 -9
- package/dist/lib/status.js +179 -27
- package/dist/lib/sync.d.ts +0 -5
- package/dist/lib/sync.js +9 -8
- package/dist/lib/telegram-api.d.ts +11 -3
- package/dist/lib/telegram-api.js +34 -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 +292 -59
- package/dist/lib/threads.js +1664 -373
- package/dist/lib/turns.d.ts +0 -1
- package/dist/lib/turns.js +1 -1
- package/dist/lib/updates.d.ts +184 -28
- package/dist/lib/updates.js +1032 -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 +45 -10
- package/dist/lib/workspace-retirement.js +196 -64
- 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 +158 -39
- 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 +127 -19
- package/docs/public-api.md +5 -3
- package/docs/ui-style.md +26 -8
- package/docs/updates.md +1 -1
- package/lib/activity-verbosity.ts +5 -9
- package/lib/bindings.ts +23 -10
- package/lib/bus-api.ts +5 -2
- package/lib/bus-follower.ts +251 -226
- 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 +150 -112
- package/lib/config.ts +12 -17
- package/lib/delivery.ts +2 -8
- package/lib/extension.ts +282 -72
- package/lib/generative-apps.ts +0 -22
- package/lib/inbound.ts +2 -2
- package/lib/journal.ts +1182 -326
- package/lib/keyboard.ts +2 -2
- package/lib/lifecycle.ts +141 -5
- 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/model.ts +2 -4
- 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 +67 -9
- package/lib/recovery.ts +104 -44
- package/lib/replies.ts +1 -1
- package/lib/routing.ts +1955 -375
- package/lib/sections.ts +1 -1
- package/lib/status.ts +185 -36
- package/lib/sync.ts +8 -8
- package/lib/telegram-api.ts +48 -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 +1718 -491
- package/lib/turns.ts +1 -1
- package/lib/updates.ts +1072 -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 +234 -102
- 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/dist/lib/extension.js
CHANGED
|
@@ -46,7 +46,9 @@ import * as Sync from "./sync.js";
|
|
|
46
46
|
import * as TelegramApi from "./telegram-api.js";
|
|
47
47
|
import * as TextGroups from "./text-groups.js";
|
|
48
48
|
import * as ThreadReconciler from "./thread-reconciler.js";
|
|
49
|
+
import * as Targets from "./target.js";
|
|
49
50
|
import * as ThreadDisplay from "./thread-display.js";
|
|
51
|
+
import * as ThreadNaming from "./thread-naming.js";
|
|
50
52
|
import * as Threads from "./threads.js";
|
|
51
53
|
import * as TimeInjection from "./time-injection.js";
|
|
52
54
|
import * as Updates from "./updates.js";
|
|
@@ -61,6 +63,7 @@ const telegramBusProtocolIdentity = Bus.createTelegramCurrentBusProtocolIdentity
|
|
|
61
63
|
Bus.TELEGRAM_BUS_CAPABILITY_THREAD_DISPLAY_MODE,
|
|
62
64
|
Bus.TELEGRAM_BUS_CAPABILITY_DIRECTORY_DISPLAY_FORMAT,
|
|
63
65
|
Bus.TELEGRAM_BUS_CAPABILITY_SESSION_REPLACEMENT_INTENT,
|
|
66
|
+
Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE,
|
|
64
67
|
]);
|
|
65
68
|
// --- Extension Runtime ---
|
|
66
69
|
export default function (pi) {
|
|
@@ -68,19 +71,20 @@ export default function (pi) {
|
|
|
68
71
|
const piRuntime = Pi.createExtensionApiRuntimePorts(pi);
|
|
69
72
|
const { getActiveTools, getCommands, getThinkingLevel, sendUserMessage, registerCommand, setActiveTools, setModel, setThinkingLevel, } = piRuntime;
|
|
70
73
|
const bridgeRuntime = Runtime.createTelegramBridgeRuntime();
|
|
71
|
-
const runtimeDiagnostics = Logging.createTelegramRuntimeDiagnosticsRuntime();
|
|
74
|
+
const runtimeDiagnostics = Logging.createTelegramRuntimeDiagnosticsRuntime({ sharedFile: true });
|
|
72
75
|
const runtimeEvents = runtimeDiagnostics.events;
|
|
73
76
|
const recordRuntimeEvent = runtimeDiagnostics.recordRuntimeEvent;
|
|
74
77
|
const configStore = Config.createTelegramConfigStore({ recordRuntimeEvent });
|
|
75
78
|
const busProcessRuntime = Bus.createCurrentTelegramBusProcessRuntime({
|
|
76
79
|
getActiveProfileName: configStore.getActiveProfileName,
|
|
80
|
+
endpointLayout: "consolidated",
|
|
77
81
|
});
|
|
78
82
|
const { instanceId: telegramInstanceId, processId: telegramProcessId, processBirthId: telegramQueueProcessBirthId, manualFollowerOwnerId: telegramManualFollowerOwnerId, getLeaderSocketPath: getTelegramBusSocketPath, getFollowerSocketPath: getTelegramBusFollowerSocketPath, } = busProcessRuntime;
|
|
79
83
|
const getTelegramBotId = Config.createTelegramConfigBotIdGetter(configStore);
|
|
80
84
|
const workspaceAdmissionRuntime = WorkspaceAdmission.createTelegramWorkspaceAdmissionRuntimeBinding({
|
|
81
85
|
getProfileName: configStore.getActiveProfileName,
|
|
82
86
|
getBotToken: configStore.getBotToken,
|
|
83
|
-
|
|
87
|
+
getStatePath: Paths.resolveTelegramStatePath,
|
|
84
88
|
owner: {
|
|
85
89
|
processId: telegramProcessId,
|
|
86
90
|
processBirthId: telegramQueueProcessBirthId,
|
|
@@ -121,20 +125,26 @@ export default function (pi) {
|
|
|
121
125
|
getBotToken: configStore.getBotToken,
|
|
122
126
|
getBotId: getTelegramBotId,
|
|
123
127
|
});
|
|
128
|
+
const telegramLeaderJournalPath = Locks.createTelegramLeaderJournalPathResolver({
|
|
129
|
+
getNamedJournalPath() { return lockRuntime.getJournalPath(); },
|
|
130
|
+
getSessionId() { return Pi.getExtensionContextSessionId(telegramSessionContextStore.get()); },
|
|
131
|
+
getProfileName: configStore.getActiveProfileName,
|
|
132
|
+
});
|
|
124
133
|
const telegramJournalBindingRuntime = Journal.createTelegramUpdateJournalBindingRuntime({
|
|
125
134
|
base: {
|
|
126
135
|
getProfileName: configStore.getActiveProfileName,
|
|
127
136
|
getBotToken: configStore.getBotToken,
|
|
128
137
|
getBotId: getTelegramBotId,
|
|
138
|
+
withSourceSerialization: configStore.withSourceSerialization,
|
|
129
139
|
onRecovery(event) {
|
|
130
140
|
recordRuntimeEvent("recovery", event.kind === "repaired"
|
|
131
141
|
? "Telegram update journal was repaired automatically."
|
|
132
|
-
: "Telegram update journal was reset after its damaged files were
|
|
142
|
+
: "Telegram update journal was reset after its damaged files were deleted.", {
|
|
133
143
|
phase: "journal-auto-recovery",
|
|
134
144
|
recoveryKind: event.kind,
|
|
135
145
|
journalPath: event.path,
|
|
136
146
|
revision: event.revision,
|
|
137
|
-
|
|
147
|
+
deletedPaths: event.deletedPaths,
|
|
138
148
|
reason: event.reason,
|
|
139
149
|
});
|
|
140
150
|
},
|
|
@@ -147,11 +157,17 @@ export default function (pi) {
|
|
|
147
157
|
},
|
|
148
158
|
getWorkspaceAdmission: workspaceAdmissionRuntime.resolve,
|
|
149
159
|
},
|
|
150
|
-
getLeaderJournalPath:
|
|
151
|
-
|
|
160
|
+
getLeaderJournalPath: telegramLeaderJournalPath.resolve,
|
|
161
|
+
getRuntimeDir: Paths.resolveTelegramTempDir,
|
|
162
|
+
getFollowerJournalPath(bindingKey, profileName, sessionId) {
|
|
163
|
+
if (sessionId !== undefined)
|
|
164
|
+
return Paths.resolveTelegramSessionJournalPath(sessionId, bindingKey, undefined, profileName);
|
|
152
165
|
return Paths.resolveTelegramFollowerJournalPath(bindingKey, undefined, profileName);
|
|
153
166
|
},
|
|
154
167
|
getActiveFollowerBindingKey: getTelegramManualFollowerProfileKey,
|
|
168
|
+
getActiveFollowerSessionId() {
|
|
169
|
+
return telegramBusFollowerRegistrationState.getSessionId(Pi.getExtensionContextSessionId(telegramSessionContextStore.get()));
|
|
170
|
+
},
|
|
155
171
|
isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
|
|
156
172
|
});
|
|
157
173
|
const telegramJournalReferenceRegistry = Journal.createTelegramUpdateJournalReferenceRegistry();
|
|
@@ -163,28 +179,44 @@ export default function (pi) {
|
|
|
163
179
|
const configControls = Config.createTelegramConfigControls(configStore);
|
|
164
180
|
const lockRuntime = Locks.createTelegramLockRuntime({
|
|
165
181
|
key: Locks.createTelegramLockKeyResolver(configStore),
|
|
182
|
+
statePath: Paths.resolveTelegramStatePath(),
|
|
166
183
|
instanceId: telegramInstanceId,
|
|
167
184
|
busSecret: telegramBusAuthSecret,
|
|
168
185
|
staleHeartbeatMs: Locks.TELEGRAM_BUS_LEADER_STALE_HEARTBEAT_MS,
|
|
186
|
+
legacyLocksPath: Paths.resolveLegacyTelegramOwnersPath(),
|
|
187
|
+
createJournalPath() { return telegramLeaderJournalPath.createJournalPath(); },
|
|
169
188
|
});
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
return
|
|
189
|
+
const telegramSessionContextStore = Lifecycle.createTelegramSessionContextStore({
|
|
190
|
+
getIdentity(ctx) {
|
|
191
|
+
return ctx.sessionManager ?? ctx.cwd;
|
|
173
192
|
},
|
|
193
|
+
});
|
|
194
|
+
const captureTelegramStateAuthority = Locks.createTelegramOwnedStateAuthorityCapture(lockRuntime, telegramSessionContextStore);
|
|
195
|
+
const threadStore = Threads.createTelegramTopicTargetStore({
|
|
196
|
+
path: Paths.resolveTelegramStatePath,
|
|
174
197
|
telegramProfile: function () {
|
|
175
198
|
return configStore.getActiveProfileName();
|
|
176
199
|
},
|
|
177
200
|
canPersist: lockRuntime.owns,
|
|
178
|
-
|
|
201
|
+
consolidated: {
|
|
202
|
+
captureAuthority: captureTelegramStateAuthority,
|
|
203
|
+
publishIfOwned: lockRuntime.publishStateSectionIfOwned,
|
|
204
|
+
},
|
|
179
205
|
getExternalReservedSlots: function () {
|
|
180
206
|
return workspaceAdmissionRuntime.resolve()?.listReservedSlots() ?? [];
|
|
181
207
|
},
|
|
182
208
|
});
|
|
209
|
+
const resolveWorkspaceRestoreStore = Threads.createTelegramWorkspaceRestoreResolver({
|
|
210
|
+
getProfileName: configStore.getActiveProfileName,
|
|
211
|
+
getBotToken: configStore.getBotToken,
|
|
212
|
+
threadStore,
|
|
213
|
+
});
|
|
183
214
|
runtimeDiagnostics.bindStorage({
|
|
184
215
|
getBotToken: configStore.getBotToken,
|
|
185
216
|
getProfileName: configStore.getActiveProfileName,
|
|
186
217
|
canReset: lockRuntime.owns,
|
|
187
218
|
commitReset: lockRuntime.commitIfOwned,
|
|
219
|
+
captureAuthority: captureTelegramStateAuthority,
|
|
188
220
|
});
|
|
189
221
|
const sessionActionAssembly = Commands.createTelegramSessionActionAssembly({
|
|
190
222
|
registerCommand,
|
|
@@ -220,11 +252,6 @@ export default function (pi) {
|
|
|
220
252
|
const sessionActionsRuntime = sessionActionAssembly.action;
|
|
221
253
|
const lockOwnershipGuard = Locks.createTelegramLockOwnershipGuard(lockRuntime);
|
|
222
254
|
const getCurrentLeaderEpoch = lockRuntime.getOwnedLeaderEpoch;
|
|
223
|
-
const telegramSessionContextStore = Lifecycle.createTelegramSessionContextStore({
|
|
224
|
-
getIdentity(ctx) {
|
|
225
|
-
return ctx.sessionManager ?? ctx.cwd;
|
|
226
|
-
},
|
|
227
|
-
});
|
|
228
255
|
const ownsTelegramDirectDelivery = Locks.createTelegramDirectDeliveryOwnershipChecker({
|
|
229
256
|
lock: lockRuntime,
|
|
230
257
|
contextStore: telegramSessionContextStore,
|
|
@@ -275,12 +302,13 @@ export default function (pi) {
|
|
|
275
302
|
});
|
|
276
303
|
const telegramQueueStore = Queue.createTelegramTransportStampedQueueStore(rawTelegramQueueStore, telegramTransportStampRuntime.getStamp);
|
|
277
304
|
const telegramApiTargetActivityRuntime = TelegramApi.createTelegramApiTargetActivityRuntime();
|
|
278
|
-
const
|
|
305
|
+
const workspaceProtectionObserver = WorkspaceRetirement.createTelegramWorkspaceProtectionObserver({
|
|
279
306
|
listFollowers: telegramBusFollowerRegistry.list,
|
|
280
307
|
getActiveTurnTarget: activeTurnRuntime.getTarget,
|
|
281
308
|
getQueuedItems: telegramQueueStore.getQueuedItems,
|
|
282
309
|
resolveLeaderJournal: resolveTelegramUpdateJournalBinding,
|
|
283
|
-
createFollowerJournalResolver: telegramJournalBindingRuntime.
|
|
310
|
+
createFollowerJournalResolver: telegramJournalBindingRuntime.createLegacyRecipientResolver,
|
|
311
|
+
createSessionJournalResolver: telegramJournalBindingRuntime.createRecipientResolver,
|
|
284
312
|
withJournalReference(binding, operation) {
|
|
285
313
|
if (!binding.recoveryKey)
|
|
286
314
|
throw new Error("Telegram workspace journal reference identity is unavailable.");
|
|
@@ -290,12 +318,25 @@ export default function (pi) {
|
|
|
290
318
|
}, operation);
|
|
291
319
|
},
|
|
292
320
|
discoverFollowerJournals() {
|
|
293
|
-
return Journal.
|
|
321
|
+
return Journal.discoverTelegramRecipientJournalPaths({
|
|
294
322
|
directory: Paths.resolveTelegramTempDir(),
|
|
295
323
|
profileName: configStore.getActiveProfileName(),
|
|
296
324
|
});
|
|
297
325
|
},
|
|
298
326
|
createJournalPathResolver: telegramJournalBindingRuntime.createPathResolver,
|
|
327
|
+
inspectJournalNamespace() {
|
|
328
|
+
const botToken = configStore.getBotToken();
|
|
329
|
+
if (!botToken)
|
|
330
|
+
throw new Error("Telegram namespace inspection requires current bot identity.");
|
|
331
|
+
return Journal.inspectTelegramSessionJournalNamespace({
|
|
332
|
+
directory: Paths.resolveTelegramTempDir(),
|
|
333
|
+
profile: configStore.getActiveProfileName() ?? "default",
|
|
334
|
+
pollingPath: telegramLeaderJournalPath.resolve(configStore.getActiveProfileName()),
|
|
335
|
+
botIdentity: Journal.createTelegramUpdateJournalBotIdentity({ botToken, botId: getTelegramBotId() }),
|
|
336
|
+
limits: { maxDirectoryEntries: 10_000, maxFiles: 4096, maxBytes: 64 * 1024 * 1024,
|
|
337
|
+
maxEntries: 10_000, maxWork: 100_000 },
|
|
338
|
+
});
|
|
339
|
+
},
|
|
299
340
|
getJournalWriterProtection(journalBindingKey) {
|
|
300
341
|
const owner = Threads.getTelegramThreadOwnerFromProfileKey(journalBindingKey);
|
|
301
342
|
if (owner.kind !== "manual-follower")
|
|
@@ -306,19 +347,33 @@ export default function (pi) {
|
|
|
306
347
|
: liveness === "dead" ? "clear" : "unknown";
|
|
307
348
|
},
|
|
308
349
|
getDeliveryAuthorityProtection(binding) {
|
|
309
|
-
|
|
350
|
+
const retainedRestore = resolveWorkspaceRestoreStore()?.list().some(function (intent) {
|
|
351
|
+
return intent.request.binding.bindingKey === binding.bindingKey ||
|
|
352
|
+
Targets.areTelegramTargetsEqual(intent.request.binding.target, binding.target) ||
|
|
353
|
+
Targets.areTelegramTargetsEqual(intent.request.target, binding.target);
|
|
354
|
+
});
|
|
355
|
+
return retainedRestore || telegramApiTargetActivityRuntime.hasPendingTarget(binding.target)
|
|
310
356
|
? "protected"
|
|
311
357
|
: "clear";
|
|
312
358
|
},
|
|
313
359
|
});
|
|
360
|
+
const captureWorkspaceExternalProtection = workspaceProtectionObserver.capture;
|
|
361
|
+
const pruneWorkspaceJournalEvidence = WorkspaceRetirement.createTelegramWorkspaceJournalEvidencePruner({
|
|
362
|
+
store: threadStore,
|
|
363
|
+
getAdmission: workspaceAdmissionRuntime.resolve,
|
|
364
|
+
getLeaderEpoch: getCurrentLeaderEpoch,
|
|
365
|
+
runExclusive: telegramWorkspaceOperationRuntime.runExclusive,
|
|
366
|
+
protection: workspaceProtectionObserver,
|
|
367
|
+
});
|
|
314
368
|
const reclaimTelegramWorkspaceDeadOwnerQueue = WorkspaceRetirement.createTelegramWorkspaceDeadOwnerQueueReclaimer({
|
|
315
369
|
getExternalProtection: captureWorkspaceExternalProtection,
|
|
316
370
|
getActiveTurnTarget: activeTurnRuntime.getTarget,
|
|
317
371
|
getQueuedItems: telegramQueueStore.getQueuedItems,
|
|
318
372
|
resolveLeaderJournal: resolveTelegramUpdateJournalBinding,
|
|
319
|
-
createFollowerJournalResolver: telegramJournalBindingRuntime.
|
|
373
|
+
createFollowerJournalResolver: telegramJournalBindingRuntime.createLegacyRecipientResolver,
|
|
374
|
+
createSessionJournalResolver: telegramJournalBindingRuntime.createRecipientResolver,
|
|
320
375
|
discoverFollowerJournals() {
|
|
321
|
-
return Journal.
|
|
376
|
+
return Journal.discoverTelegramRecipientJournalPaths({
|
|
322
377
|
directory: Paths.resolveTelegramTempDir(),
|
|
323
378
|
profileName: configStore.getActiveProfileName(),
|
|
324
379
|
});
|
|
@@ -363,7 +418,7 @@ export default function (pi) {
|
|
|
363
418
|
if (!botToken)
|
|
364
419
|
throw new Error("Telegram Thread cleanup review requires an active bot token.");
|
|
365
420
|
return ThreadCleanupManager.createTelegramThreadCleanupWorkStore({
|
|
366
|
-
|
|
421
|
+
...Paths.resolveTelegramServiceJournalStorage("thread-cleanup", undefined, profileName),
|
|
367
422
|
profileName,
|
|
368
423
|
tokenSha256: Journal.createTelegramUpdateJournalBotIdentity({ botToken }).tokenSha256,
|
|
369
424
|
});
|
|
@@ -460,9 +515,10 @@ export default function (pi) {
|
|
|
460
515
|
instanceId: telegramInstanceId,
|
|
461
516
|
updateStatus: statusRuntime.updateStatus,
|
|
462
517
|
getStatusState: statusRuntime.getStatusState,
|
|
518
|
+
session: telegramSessionContextStore,
|
|
463
519
|
async persistSnapshot(snapshot) {
|
|
464
520
|
threadStore.setStatusSnapshot(snapshot);
|
|
465
|
-
await threadStore.
|
|
521
|
+
await threadStore.persistStatus();
|
|
466
522
|
},
|
|
467
523
|
});
|
|
468
524
|
const updateStatus = runtimeDiagnostics.updateStatus;
|
|
@@ -476,6 +532,10 @@ export default function (pi) {
|
|
|
476
532
|
// --- Telegram API ---
|
|
477
533
|
const directTelegramApiRuntime = TelegramApi.createDefaultTelegramBridgeApiRuntime({
|
|
478
534
|
getBotToken: configStore.getBotToken,
|
|
535
|
+
getBotScope() {
|
|
536
|
+
const config = configStore.get();
|
|
537
|
+
return config.botUsername ?? (config.botId === undefined ? undefined : String(config.botId));
|
|
538
|
+
},
|
|
479
539
|
recordRuntimeEvent,
|
|
480
540
|
targetActivity: telegramApiTargetActivityRuntime,
|
|
481
541
|
workspaceAdmission: workspaceAdmissionRuntime.resolve,
|
|
@@ -708,6 +768,10 @@ export default function (pi) {
|
|
|
708
768
|
getActiveModel: currentModelRuntime.get,
|
|
709
769
|
getThinkingLevel,
|
|
710
770
|
getQueueItemCount,
|
|
771
|
+
getPendingCancellationCount() {
|
|
772
|
+
return getCurrentLeaderEpoch() === undefined ? 0 :
|
|
773
|
+
updateAdmissionRuntimeBinding.getActive()?.getState()?.abandoningClaimCount ?? 0;
|
|
774
|
+
},
|
|
711
775
|
buildStatusHtml: Commands.createTelegramAppMenuHtmlBuilder({
|
|
712
776
|
buildStatusHtml: Status.createTelegramStatusHtmlBuilder({
|
|
713
777
|
getActiveModel: currentModelRuntime.get,
|
|
@@ -792,16 +856,11 @@ export default function (pi) {
|
|
|
792
856
|
}, sectionRegistry);
|
|
793
857
|
// --- Polling ---
|
|
794
858
|
const foreignOwnedUpdateForwarder = telegramBusFollowerClients.foreignOwnedUpdateForwarder;
|
|
795
|
-
const
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
telegramSyncStateRuntime.markSliceFresh(Sync.TELEGRAM_SYNC_SLICE_TARGET_BINDINGS, {
|
|
801
|
-
nowMs: Date.now(),
|
|
802
|
-
action: "follower-thread-restore",
|
|
803
|
-
});
|
|
804
|
-
},
|
|
859
|
+
const workspaceRestoreFollowerController = Bus.createTelegramBusWorkspaceRestoreController({
|
|
860
|
+
getFollower: telegramBusFollowerRegistry.get,
|
|
861
|
+
localProtocolIdentity: telegramBusProtocolIdentity,
|
|
862
|
+
createRequestId: telegramBusFollowerClients.createRequestId,
|
|
863
|
+
getAuthSecret() { return telegramBusAuthSecret; },
|
|
805
864
|
});
|
|
806
865
|
const observedThreadTargetBinding = Polling.createTelegramThreadTargetObservationBinding();
|
|
807
866
|
const topicLifecycleSync = Sync.createTelegramObservedTopicLifecycleSyncHandler({
|
|
@@ -852,7 +911,63 @@ export default function (pi) {
|
|
|
852
911
|
return observedThreadTargetBinding.handle(ctx);
|
|
853
912
|
},
|
|
854
913
|
foreignOwnedUpdateForwarder,
|
|
855
|
-
|
|
914
|
+
workspaceRestoreRecipient: {
|
|
915
|
+
getSessionId: Pi.getExtensionContextSessionId,
|
|
916
|
+
getCwd: Pi.getExtensionContextCwd,
|
|
917
|
+
getLeaderIdentity: telegramBusLeaderState.getIdentity,
|
|
918
|
+
followerRegistry: telegramBusFollowerRegistry,
|
|
919
|
+
runFollower: workspaceRestoreFollowerController,
|
|
920
|
+
},
|
|
921
|
+
getWorkspaceRestoreStore: resolveWorkspaceRestoreStore,
|
|
922
|
+
captureWorkspaceExternalProtection,
|
|
923
|
+
inspectRestoreSourceCompletion(expected) {
|
|
924
|
+
return telegramJournalReferenceRegistry.withReference({ referenceClass: "operator-disposition",
|
|
925
|
+
recoveryKey: expected.journalBindingKey }, function () {
|
|
926
|
+
const observed = telegramJournalBindingRuntime.inspectSourceCompletion(expected.journalBindingKey, { updateId: expected.updateId,
|
|
927
|
+
sourceSha256: expected.sourceSha256, completionSha256: expected.completionSha256 });
|
|
928
|
+
return observed && { journalBindingKey: expected.journalBindingKey, ...observed };
|
|
929
|
+
});
|
|
930
|
+
},
|
|
931
|
+
inspectRestoreQueuedReceipt(expected) {
|
|
932
|
+
return telegramJournalReferenceRegistry.withReference({ referenceClass: "operator-disposition",
|
|
933
|
+
recoveryKey: expected.journalBindingKey }, function () {
|
|
934
|
+
return telegramJournalBindingRuntime.inspectQueuedReceipt(expected.journalBindingKey, { queueKind: expected.queueKind, receiptId: expected.receiptId,
|
|
935
|
+
sourceUpdateIds: [...expected.sourceUpdateIds], queueOwner: { ...expected.queueOwner } });
|
|
936
|
+
});
|
|
937
|
+
},
|
|
938
|
+
inspectRestoreSourceAbandonment(updateId, journalBindingKey) {
|
|
939
|
+
return telegramJournalReferenceRegistry.withReference({
|
|
940
|
+
referenceClass: "operator-disposition",
|
|
941
|
+
recoveryKey: journalBindingKey,
|
|
942
|
+
}, function () {
|
|
943
|
+
return telegramJournalBindingRuntime.inspectSourceAbandonment(journalBindingKey, updateId);
|
|
944
|
+
});
|
|
945
|
+
},
|
|
946
|
+
inspectTemporaryThreadSources(_target, requiredJournalBindingKeys) {
|
|
947
|
+
const binding = resolveTelegramUpdateJournalBinding();
|
|
948
|
+
const botToken = configStore.getBotToken();
|
|
949
|
+
if (!binding || !botToken)
|
|
950
|
+
return undefined;
|
|
951
|
+
const profile = configStore.getActiveProfileName() ?? "default";
|
|
952
|
+
const botIdentity = Journal.createTelegramUpdateJournalBotIdentity({ botToken, botId: getTelegramBotId() });
|
|
953
|
+
return configStore.withSourceSerialization(function () {
|
|
954
|
+
return Journal.isTelegramThreadCleanupJournalNamespaceClear({
|
|
955
|
+
directory: Paths.resolveTelegramTempDir(), profile, botIdentity,
|
|
956
|
+
pollingPath: telegramLeaderJournalPath.resolve(configStore.getActiveProfileName()),
|
|
957
|
+
requiredJournalBindingKeys: [binding.recoveryKey, ...requiredJournalBindingKeys],
|
|
958
|
+
limits: { maxDirectoryEntries: 10_000, maxFiles: 4096, maxBytes: 64 * 1024 * 1024,
|
|
959
|
+
maxEntries: 10_000, maxWork: 100_000 },
|
|
960
|
+
withSourceReference(path, operation) {
|
|
961
|
+
return telegramJournalReferenceRegistry.withReference({ referenceClass: "operator-disposition",
|
|
962
|
+
recoveryKey: Journal.createTelegramUpdateJournalBindingKey({ path, profileName: profile, botIdentity }) }, operation);
|
|
963
|
+
},
|
|
964
|
+
}) ? [] : undefined;
|
|
965
|
+
});
|
|
966
|
+
},
|
|
967
|
+
hasWorkspaceRestoreAuthority() {
|
|
968
|
+
return lockRuntime.owns() && Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE);
|
|
969
|
+
},
|
|
970
|
+
getSessionGeneration: telegramSessionContextStore.getGeneration,
|
|
856
971
|
bridgeRuntime,
|
|
857
972
|
requestNewSession(source) {
|
|
858
973
|
const updateId = Updates.getTelegramUpdateExecutionFence(source)?.updateId;
|
|
@@ -921,7 +1036,7 @@ export default function (pi) {
|
|
|
921
1036
|
sendTextReply,
|
|
922
1037
|
setMyCommands,
|
|
923
1038
|
validateThreadName(threadName) {
|
|
924
|
-
return
|
|
1039
|
+
return ThreadNaming.getTelegramManualThreadDisplayNameValidationError(threadName);
|
|
925
1040
|
},
|
|
926
1041
|
renameCurrentThread: telegramThreadDisplayNameRenameBinding.rename,
|
|
927
1042
|
resetCurrentThreadName: telegramThreadDisplayNameResetBinding.reset,
|
|
@@ -970,10 +1085,45 @@ export default function (pi) {
|
|
|
970
1085
|
isContextCurrent: telegramSessionContextStore.isCurrent,
|
|
971
1086
|
dispatchNext: dispatchNextQueuedTelegramTurn,
|
|
972
1087
|
requestQueueHandoffReconciliation: queueHandoffReconciliationBinding.request,
|
|
973
|
-
|
|
1088
|
+
afterQueueReceiptCommitted: inboundRouteRuntime.onQueueReceiptCommitted,
|
|
1089
|
+
afterUpdateCompleted(updateId, ctx, journalBindingKey) {
|
|
1090
|
+
sessionActionsRuntime.onUpdateCompleted(updateId);
|
|
1091
|
+
inboundRouteRuntime.onUpdateCompleted(updateId, ctx, journalBindingKey);
|
|
1092
|
+
},
|
|
974
1093
|
},
|
|
975
1094
|
worker: {
|
|
1095
|
+
expireRoutingInput: inboundRouteRuntime.expireRoutingInput,
|
|
1096
|
+
beforeQueueReceiptPublished: inboundRouteRuntime.beforeQueueReceiptPublished,
|
|
1097
|
+
onQueueReceiptCompleted: inboundRouteRuntime.onQueueReceiptCompleted,
|
|
976
1098
|
defaultHandle: inboundRouteRuntime.handleUpdate,
|
|
1099
|
+
async shouldReviewHistoricalInput(entry, ctx, signal) {
|
|
1100
|
+
if (signal.aborted || !telegramSessionContextStore.isCurrent(ctx)) {
|
|
1101
|
+
throw new Error("Workspace Restore source generation ended.");
|
|
1102
|
+
}
|
|
1103
|
+
const verdict = await inboundRouteRuntime.shouldReviewHistoricalInput(entry, ctx, signal);
|
|
1104
|
+
if (signal.aborted || !telegramSessionContextStore.isCurrent(ctx)) {
|
|
1105
|
+
throw new Error("Workspace Restore source generation ended.");
|
|
1106
|
+
}
|
|
1107
|
+
if (verdict === "retain")
|
|
1108
|
+
return verdict;
|
|
1109
|
+
const journalBindingKey = getTelegramQueueJournalBinding();
|
|
1110
|
+
if (journalBindingKey && resolveWorkspaceRestoreStore()?.list().some(function (intent) {
|
|
1111
|
+
return intent.request.source.journalBindingKey === journalBindingKey &&
|
|
1112
|
+
intent.request.source.updateIds.includes(entry.updateId);
|
|
1113
|
+
}))
|
|
1114
|
+
return true;
|
|
1115
|
+
return verdict;
|
|
1116
|
+
},
|
|
1117
|
+
spendHistoricalInput: true,
|
|
1118
|
+
onHeldSourcesPrepared(input) {
|
|
1119
|
+
return inboundRouteRuntime.forgetPreviousWorld(input, lockedPollingRuntime.captureTransportAuthority).then(function () { });
|
|
1120
|
+
},
|
|
1121
|
+
async shouldHoldPendingInput(entry, ctx, signal) {
|
|
1122
|
+
if (signal.aborted || !telegramSessionContextStore.isCurrent(ctx)) {
|
|
1123
|
+
throw new Error("Temporary Thread source generation ended.");
|
|
1124
|
+
}
|
|
1125
|
+
return inboundRouteRuntime.shouldHoldPendingInput(entry, ctx, signal);
|
|
1126
|
+
},
|
|
977
1127
|
onStateChange: runtimeDiagnostics.scheduleSnapshotPersist,
|
|
978
1128
|
settleTerminalExecutionFailure(error) {
|
|
979
1129
|
return Sync.settleStaleTelegramTopicExecutionFailure(error, staleTopicApiErrorRecoveryDeps);
|
|
@@ -987,6 +1137,11 @@ export default function (pi) {
|
|
|
987
1137
|
resolveBinding: resolveTelegramFollowerJournalBinding,
|
|
988
1138
|
isRegistered: telegramBusFollowerRegistrationState.isRegistered,
|
|
989
1139
|
getGeneration: telegramBusFollowerRegistrationState.getGeneration,
|
|
1140
|
+
prepareBinding(binding) {
|
|
1141
|
+
telegramJournalBindingRuntime.prepareActiveFollowerSuccession(function isCurrent() {
|
|
1142
|
+
return binding.hasAuthority?.() === true;
|
|
1143
|
+
});
|
|
1144
|
+
},
|
|
990
1145
|
prepareUpdateForExecution(update) {
|
|
991
1146
|
return BusFollower.prepareTelegramBusFollowerJournaledUpdateForExecution(update, textGroupRuntime.prepareForwardedMessage);
|
|
992
1147
|
},
|
|
@@ -1056,6 +1211,33 @@ export default function (pi) {
|
|
|
1056
1211
|
local: agentMessageRuntime,
|
|
1057
1212
|
follower: telegramBusFollowerClients.agentMessages,
|
|
1058
1213
|
});
|
|
1214
|
+
const followerWorkspaceRestore = BusFollower.createTelegramBusFollowerWorkspaceRestoreHandler({
|
|
1215
|
+
instanceId: telegramInstanceId,
|
|
1216
|
+
getContextAuthority: BusFollower.createTelegramBusFollowerRestoreContextGetter({
|
|
1217
|
+
isContextCurrent: telegramSessionContextStore.isCurrent,
|
|
1218
|
+
getSessionId: Pi.getExtensionContextSessionId,
|
|
1219
|
+
getCwd: Pi.getExtensionContextCwd,
|
|
1220
|
+
getGeneration: telegramSessionContextStore.getGeneration,
|
|
1221
|
+
getProfileBindingKey() {
|
|
1222
|
+
return workspaceAdmissionRuntime.resolve()?.getProfileKey();
|
|
1223
|
+
},
|
|
1224
|
+
getOperatorUserId: configStore.getAllowedUserId,
|
|
1225
|
+
getLeaderState: lockRuntime.getState,
|
|
1226
|
+
getAuthenticatedSecret: telegramBusFollowerControlState.getActiveAuthSecret,
|
|
1227
|
+
getLeaderProtocol: telegramBusFollowerRegistrationState.getLeaderProtocol,
|
|
1228
|
+
}),
|
|
1229
|
+
readRestoreIntent(operationId, profileBindingKey) {
|
|
1230
|
+
if (profileBindingKey !== workspaceAdmissionRuntime.resolve()?.getProfileKey())
|
|
1231
|
+
return undefined;
|
|
1232
|
+
return resolveWorkspaceRestoreStore()?.list().find(function (intent) {
|
|
1233
|
+
return intent.request.operationId === operationId;
|
|
1234
|
+
});
|
|
1235
|
+
},
|
|
1236
|
+
topicTargetStore: threadStore,
|
|
1237
|
+
registrationState: telegramBusFollowerRegistrationState,
|
|
1238
|
+
getWorkspaceAdmission: workspaceAdmissionRuntime.resolve,
|
|
1239
|
+
recordRuntimeEvent,
|
|
1240
|
+
});
|
|
1059
1241
|
const telegramBusFollowerAssembly = BusFollower.createTelegramBusFollowerRuntimeAssembly({
|
|
1060
1242
|
instanceId: telegramInstanceId,
|
|
1061
1243
|
registrationState: telegramBusFollowerRegistrationState,
|
|
@@ -1067,15 +1249,11 @@ export default function (pi) {
|
|
|
1067
1249
|
getRecipientBindingKey: getTelegramManualFollowerProfileKey,
|
|
1068
1250
|
durableAdmission: followerDurableAdmissionRuntime,
|
|
1069
1251
|
handleQueueHandoff: acceptStagedQueueHandoff,
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
getWorkspaceAdmission: workspaceAdmissionRuntime.resolve,
|
|
1076
|
-
getSyncState: telegramSyncStateRuntime.getState,
|
|
1077
|
-
setSyncState: telegramSyncStateRuntime.setState,
|
|
1078
|
-
updateStatus,
|
|
1252
|
+
handleWorkspaceRestore: followerWorkspaceRestore,
|
|
1253
|
+
isWorkspaceRestoreEnabled() {
|
|
1254
|
+
return Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE) &&
|
|
1255
|
+
Bus.hasTelegramBusCapability(telegramBusFollowerRegistrationState.getLeaderProtocol(), Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE);
|
|
1256
|
+
},
|
|
1079
1257
|
},
|
|
1080
1258
|
recovery: {
|
|
1081
1259
|
getLeaderState: lockRuntime.getState,
|
|
@@ -1177,6 +1355,17 @@ export default function (pi) {
|
|
|
1177
1355
|
const authorizeFollowerApiCall = Bus.createTelegramFollowerApiCallAuthorizer({
|
|
1178
1356
|
isMessageOwned: messageOwnershipRuntime.isOwnedByFollower,
|
|
1179
1357
|
});
|
|
1358
|
+
const telegramSessionFolderSweeper = Recovery.createTelegramSessionFolderSweeper({
|
|
1359
|
+
getSessionsDir: Paths.resolveTelegramSessionsDir,
|
|
1360
|
+
getProfileName: configStore.getActiveProfileName,
|
|
1361
|
+
getKeptSessionIds() {
|
|
1362
|
+
return [
|
|
1363
|
+
...threadStore.listWorkspaceBindings().map(function bindingSession(binding) { return binding.sessionId; }),
|
|
1364
|
+
...telegramBusFollowerRegistry.list().map(function followerSession(follower) { return follower.sessionId; }),
|
|
1365
|
+
Pi.getExtensionContextSessionId(telegramSessionContextStore.get()),
|
|
1366
|
+
];
|
|
1367
|
+
},
|
|
1368
|
+
});
|
|
1180
1369
|
const telegramBusLeaderRuntime = BusLeader.createTelegramBusLeaderRuntimeAssembly({
|
|
1181
1370
|
runtime: {
|
|
1182
1371
|
socketPath: getTelegramBusSocketPath,
|
|
@@ -1200,10 +1389,14 @@ export default function (pi) {
|
|
|
1200
1389
|
});
|
|
1201
1390
|
},
|
|
1202
1391
|
isFollowerProcessAlive: Locks.isProcessAlive,
|
|
1392
|
+
afterFollowerPrune() { telegramSessionFolderSweeper.sweep(); },
|
|
1203
1393
|
shouldCleanupConfirmedDeadFollower: configControls.resolveAutomaticThreadCleanupEnabled,
|
|
1204
1394
|
recordFollowerMessageOwnership(record) {
|
|
1205
1395
|
messageOwnershipRuntime.recordFollower(record);
|
|
1206
1396
|
},
|
|
1397
|
+
onWorkspaceRestoreRecipientObserved(follower, isCurrent) {
|
|
1398
|
+
return inboundRouteRuntime.onWorkspaceRestoreRecipientObserved(follower, isCurrent, telegramSessionContextStore.get());
|
|
1399
|
+
},
|
|
1207
1400
|
},
|
|
1208
1401
|
getAllowedUserId: configStore.getAllowedUserId,
|
|
1209
1402
|
instanceId: telegramInstanceId,
|
|
@@ -1231,6 +1424,7 @@ export default function (pi) {
|
|
|
1231
1424
|
getAdmission: workspaceAdmissionRuntime.resolve,
|
|
1232
1425
|
runExclusive: telegramWorkspaceOperationRuntime.runExclusive,
|
|
1233
1426
|
deleteThread: directTelegramApiRuntime.deleteWorkspaceThread,
|
|
1427
|
+
pruneJournalEvidence: pruneWorkspaceJournalEvidence,
|
|
1234
1428
|
reclaimDeadOwnerQueuedWork(binding, isCurrent) {
|
|
1235
1429
|
return telegramWorkspaceOperationRuntime.run({
|
|
1236
1430
|
operationId: WorkspaceAdmission.createTelegramWorkspaceAdmissionOperationId(),
|
|
@@ -1316,6 +1510,12 @@ export default function (pi) {
|
|
|
1316
1510
|
const threadAwarePollingPorts = telegramThreadCapabilityRuntime.pollingPorts;
|
|
1317
1511
|
const lockedPollingRuntime = Locks.createTelegramLockedPollingRuntime({
|
|
1318
1512
|
lock: lockRuntime,
|
|
1513
|
+
resetDamagedState() {
|
|
1514
|
+
return Locks.resetDamagedTelegramRuntimeState(Paths.resolveTelegramStatePath(), function (profile, sections) {
|
|
1515
|
+
Threads.parseTelegramWorkspaceStateSection(sections.workspace, profile);
|
|
1516
|
+
WorkspaceAdmission.assertTelegramConsolidatedAdmissionSection(sections.admission, profile);
|
|
1517
|
+
});
|
|
1518
|
+
},
|
|
1319
1519
|
transportMonitor: telegramThreadCapabilityMonitor,
|
|
1320
1520
|
hasBotToken: configStore.hasBotToken,
|
|
1321
1521
|
getBotTokenDiagnostic: configStore.getBotTokenDiagnostic,
|
|
@@ -1361,6 +1561,28 @@ export default function (pi) {
|
|
|
1361
1561
|
resolveAutomaticThreadCleanupEnabled: configControls.resolveAutomaticThreadCleanupEnabled,
|
|
1362
1562
|
runWorkspaceOperation: telegramWorkspaceOperationRuntime.run,
|
|
1363
1563
|
});
|
|
1564
|
+
const connectionIntent = Lifecycle.createTelegramConnectionIntentRuntime();
|
|
1565
|
+
const connectionLifecycle = Lifecycle.createTelegramConnectionLifecycle({
|
|
1566
|
+
intent: connectionIntent,
|
|
1567
|
+
getGeneration: telegramSessionContextStore.getGeneration,
|
|
1568
|
+
isCurrent: telegramSessionContextStore.isCurrent,
|
|
1569
|
+
getProfileName: configStore.getActiveProfileName,
|
|
1570
|
+
isConnected() {
|
|
1571
|
+
return lockRuntime.owns() || telegramBusFollowerRegistrationState.isRegistered();
|
|
1572
|
+
},
|
|
1573
|
+
async activateProfile(profileName, isCurrent) {
|
|
1574
|
+
await configStore.load();
|
|
1575
|
+
if (!isCurrent())
|
|
1576
|
+
return false;
|
|
1577
|
+
return configStore.activateProfile(profileName) && configStore.hasBotToken();
|
|
1578
|
+
},
|
|
1579
|
+
start(ctx) {
|
|
1580
|
+
return lockedPollingRuntime.start(ctx);
|
|
1581
|
+
},
|
|
1582
|
+
recordError(error) {
|
|
1583
|
+
recordRuntimeEvent("connection", error, { phase: "resume-connect" });
|
|
1584
|
+
},
|
|
1585
|
+
});
|
|
1364
1586
|
const telegramBridgeSessionLifecycleDeps = Lifecycle.createTelegramBridgeSessionLifecycleDeps({
|
|
1365
1587
|
contextStore: telegramSessionContextStore,
|
|
1366
1588
|
queue: {
|
|
@@ -1372,7 +1594,10 @@ export default function (pi) {
|
|
|
1372
1594
|
syncCounters: queue.syncCounters,
|
|
1373
1595
|
syncFlags: lifecycle.syncFlags,
|
|
1374
1596
|
bindDeferredDispatchContext: deferredQueueDispatchRuntime.bind,
|
|
1375
|
-
prepareTempDir
|
|
1597
|
+
prepareTempDir() {
|
|
1598
|
+
Recovery.removeTelegramLegacyRecoveryStorage(Paths.resolveTelegramTempDir());
|
|
1599
|
+
return prepareTempDir();
|
|
1600
|
+
},
|
|
1376
1601
|
updateStatus,
|
|
1377
1602
|
unbindDeferredDispatchContext: deferredQueueDispatchRuntime.unbind,
|
|
1378
1603
|
discardQueuedItems: queueMutationRuntime.clear,
|
|
@@ -1408,6 +1633,7 @@ export default function (pi) {
|
|
|
1408
1633
|
},
|
|
1409
1634
|
delivery: deliveryLifecycleRuntime,
|
|
1410
1635
|
polling: lockedPollingRuntime,
|
|
1636
|
+
connection: connectionLifecycle,
|
|
1411
1637
|
inboundWorker: {
|
|
1412
1638
|
onSessionShutdown: updateAdmissionRuntimeBinding.onSessionShutdown,
|
|
1413
1639
|
},
|
|
@@ -1513,17 +1739,7 @@ export default function (pi) {
|
|
|
1513
1739
|
activeTurnRuntime,
|
|
1514
1740
|
lockedPollingRuntime,
|
|
1515
1741
|
stopPolling: disconnectTelegramAndDeleteCurrentThread,
|
|
1516
|
-
|
|
1517
|
-
getOwnersPath: Paths.resolveTelegramOwnersPath,
|
|
1518
|
-
getStatePaths() {
|
|
1519
|
-
return [
|
|
1520
|
-
Threads.getTelegramTopicTargetsPath(undefined, configStore.getActiveProfileName()),
|
|
1521
|
-
];
|
|
1522
|
-
},
|
|
1523
|
-
suspendPolling: lockedPollingRuntime.suspend,
|
|
1524
|
-
releaseOwnership: lockRuntime.release,
|
|
1525
|
-
recordRuntimeEvent,
|
|
1526
|
-
}),
|
|
1742
|
+
// Consolidated envelope failures remain protective; legacy whole-file recovery cannot reset sibling authority.
|
|
1527
1743
|
getDisconnectThreadName() {
|
|
1528
1744
|
const record = findCurrentThreadRecord();
|
|
1529
1745
|
if (!record?.target.threadId)
|
|
@@ -1536,6 +1752,9 @@ export default function (pi) {
|
|
|
1536
1752
|
modelContextAvailabilityRuntime.reconcile();
|
|
1537
1753
|
},
|
|
1538
1754
|
getStatusLines,
|
|
1755
|
+
isContextCurrent: telegramSessionContextStore.isCurrent,
|
|
1756
|
+
getSessionGeneration: telegramSessionContextStore.getGeneration,
|
|
1757
|
+
connectionIntent,
|
|
1539
1758
|
buttonActionStore,
|
|
1540
1759
|
sendMarkdownReply,
|
|
1541
1760
|
async sendChannelMarkdownMessage(channel, markdown, options) {
|
|
@@ -1547,7 +1766,7 @@ export default function (pi) {
|
|
|
1547
1766
|
if (!botToken)
|
|
1548
1767
|
throw new Error("Telegram channel delivery requires an active bot token.");
|
|
1549
1768
|
const store = ChannelPosts.createTelegramChannelPostJournalStore({
|
|
1550
|
-
|
|
1769
|
+
...Paths.resolveTelegramServiceJournalStorage("channel-posts", undefined, profileName),
|
|
1551
1770
|
profileName,
|
|
1552
1771
|
tokenSha256: Journal.createTelegramUpdateJournalBotIdentity({ botToken }).tokenSha256,
|
|
1553
1772
|
});
|
|
@@ -1577,7 +1796,7 @@ export default function (pi) {
|
|
|
1577
1796
|
const caption = Replies.renderTelegramMarkdownToHtmlDraft(markdown);
|
|
1578
1797
|
ChannelPosts.assertTelegramChannelPostCaptionWithinLimit(caption);
|
|
1579
1798
|
const store = ChannelPosts.createTelegramChannelPostJournalStore({
|
|
1580
|
-
|
|
1799
|
+
...Paths.resolveTelegramServiceJournalStorage("channel-posts", undefined, profileName),
|
|
1581
1800
|
profileName,
|
|
1582
1801
|
tokenSha256: Journal.createTelegramUpdateJournalBotIdentity({ botToken }).tokenSha256,
|
|
1583
1802
|
});
|
|
@@ -1605,7 +1824,7 @@ export default function (pi) {
|
|
|
1605
1824
|
if (!botToken)
|
|
1606
1825
|
throw new Error("Telegram channel posts require an active bot token.");
|
|
1607
1826
|
return ChannelPosts.createTelegramChannelPostJournalStore({
|
|
1608
|
-
|
|
1827
|
+
...Paths.resolveTelegramServiceJournalStorage("channel-posts", undefined, profileName),
|
|
1609
1828
|
profileName,
|
|
1610
1829
|
tokenSha256: Journal.createTelegramUpdateJournalBotIdentity({ botToken }).tokenSha256,
|
|
1611
1830
|
}).list(input);
|
|
@@ -1618,7 +1837,7 @@ export default function (pi) {
|
|
|
1618
1837
|
if (!botToken)
|
|
1619
1838
|
throw new Error("Telegram channel post mutation requires an active bot token.");
|
|
1620
1839
|
const store = ChannelPosts.createTelegramChannelPostJournalStore({
|
|
1621
|
-
|
|
1840
|
+
...Paths.resolveTelegramServiceJournalStorage("channel-posts", undefined, profileName), profileName,
|
|
1622
1841
|
tokenSha256: Journal.createTelegramUpdateJournalBotIdentity({ botToken }).tokenSha256,
|
|
1623
1842
|
});
|
|
1624
1843
|
if (input.action === "edit") {
|
|
@@ -1684,6 +1903,7 @@ export default function (pi) {
|
|
|
1684
1903
|
},
|
|
1685
1904
|
activityRuntime,
|
|
1686
1905
|
activityVerbosityRuntime,
|
|
1906
|
+
diagnostics: runtimeDiagnostics,
|
|
1687
1907
|
assistantOutputRuntime,
|
|
1688
1908
|
publicationRuntime,
|
|
1689
1909
|
configStore,
|