@llblab/pi-kit 0.29.1 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BACKLOG.md +3 -1
- package/CHANGELOG.md +10 -0
- package/README.md +4 -4
- package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +12 -0
- package/node_modules/@llblab/pi-state-flow/README.md +2 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/context.d.ts +2 -2
- package/node_modules/@llblab/pi-state-flow/dist/lib/context.js +17 -8
- package/node_modules/@llblab/pi-state-flow/dist/lib/extension.js +7 -3
- package/node_modules/@llblab/pi-state-flow/dist/lib/protocol.d.ts +2 -1
- package/node_modules/@llblab/pi-state-flow/dist/lib/protocol.js +3 -2
- package/node_modules/@llblab/pi-state-flow/dist/package.json +1 -1
- package/node_modules/@llblab/pi-state-flow/docs/architecture.md +3 -3
- package/node_modules/@llblab/pi-state-flow/docs/usage.md +3 -2
- package/node_modules/@llblab/pi-state-flow/lib/context.ts +17 -8
- package/node_modules/@llblab/pi-state-flow/lib/extension.ts +6 -3
- package/node_modules/@llblab/pi-state-flow/lib/protocol.ts +4 -2
- package/node_modules/@llblab/pi-state-flow/package.json +1 -1
- package/node_modules/@llblab/pi-telegram/AGENTS.md +13 -10
- package/node_modules/@llblab/pi-telegram/BACKLOG.md +1 -1
- package/node_modules/@llblab/pi-telegram/CHANGELOG.md +23 -0
- package/node_modules/@llblab/pi-telegram/README.md +10 -11
- package/node_modules/@llblab/pi-telegram/api/commands.ts +3 -0
- package/node_modules/@llblab/pi-telegram/dist/api/commands.d.ts +1 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/activity-verbosity.d.ts +1 -5
- package/node_modules/@llblab/pi-telegram/dist/lib/activity-verbosity.js +15 -42
- package/node_modules/@llblab/pi-telegram/dist/lib/activity.d.ts +9 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/activity.js +39 -10
- package/node_modules/@llblab/pi-telegram/dist/lib/agent-messages.js +7 -3
- package/node_modules/@llblab/pi-telegram/dist/lib/bindings.d.ts +43 -5
- package/node_modules/@llblab/pi-telegram/dist/lib/bindings.js +164 -20
- package/node_modules/@llblab/pi-telegram/dist/lib/bus-api.d.ts +12 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/bus-api.js +181 -77
- package/node_modules/@llblab/pi-telegram/dist/lib/bus-follower.d.ts +111 -31
- package/node_modules/@llblab/pi-telegram/dist/lib/bus-follower.js +1324 -359
- package/node_modules/@llblab/pi-telegram/dist/lib/bus-leader.d.ts +41 -91
- package/node_modules/@llblab/pi-telegram/dist/lib/bus-leader.js +969 -637
- package/node_modules/@llblab/pi-telegram/dist/lib/bus-transport.js +16 -9
- package/node_modules/@llblab/pi-telegram/dist/lib/bus.d.ts +215 -18
- package/node_modules/@llblab/pi-telegram/dist/lib/bus.js +1048 -327
- package/node_modules/@llblab/pi-telegram/dist/lib/channel-posts.d.ts +5 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/channel-posts.js +434 -261
- package/node_modules/@llblab/pi-telegram/dist/lib/command-templates.d.ts +26 -5
- package/node_modules/@llblab/pi-telegram/dist/lib/command-templates.js +92 -176
- package/node_modules/@llblab/pi-telegram/dist/lib/commands.d.ts +168 -82
- package/node_modules/@llblab/pi-telegram/dist/lib/commands.js +1409 -291
- package/node_modules/@llblab/pi-telegram/dist/lib/config.d.ts +1 -8
- package/node_modules/@llblab/pi-telegram/dist/lib/config.js +34 -76
- package/node_modules/@llblab/pi-telegram/dist/lib/delivery.d.ts +2 -2
- package/node_modules/@llblab/pi-telegram/dist/lib/delivery.js +16 -16
- package/node_modules/@llblab/pi-telegram/dist/lib/extension.js +642 -170
- package/node_modules/@llblab/pi-telegram/dist/lib/generative-app-worker.mjs +19 -7
- package/node_modules/@llblab/pi-telegram/dist/lib/generative-apps.d.ts +0 -5
- package/node_modules/@llblab/pi-telegram/dist/lib/generative-apps.js +61 -49
- package/node_modules/@llblab/pi-telegram/dist/lib/inbound.d.ts +5 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/inbound.js +35 -59
- package/node_modules/@llblab/pi-telegram/dist/lib/journal.d.ts +40 -4
- package/node_modules/@llblab/pi-telegram/dist/lib/journal.js +2102 -760
- package/node_modules/@llblab/pi-telegram/dist/lib/lifecycle.d.ts +2 -6
- package/node_modules/@llblab/pi-telegram/dist/lib/lifecycle.js +75 -58
- package/node_modules/@llblab/pi-telegram/dist/lib/locks.d.ts +34 -3
- package/node_modules/@llblab/pi-telegram/dist/lib/locks.js +318 -119
- package/node_modules/@llblab/pi-telegram/dist/lib/logging.js +50 -14
- package/node_modules/@llblab/pi-telegram/dist/lib/media.d.ts +22 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/media.js +46 -28
- package/node_modules/@llblab/pi-telegram/dist/lib/menu-model.d.ts +19 -5
- package/node_modules/@llblab/pi-telegram/dist/lib/menu-model.js +53 -11
- package/node_modules/@llblab/pi-telegram/dist/lib/menu-queue.d.ts +5 -4
- package/node_modules/@llblab/pi-telegram/dist/lib/menu-queue.js +45 -63
- package/node_modules/@llblab/pi-telegram/dist/lib/menu-settings.d.ts +5 -4
- package/node_modules/@llblab/pi-telegram/dist/lib/menu-settings.js +114 -78
- package/node_modules/@llblab/pi-telegram/dist/lib/menu-status.d.ts +1 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/menu-status.js +8 -25
- package/node_modules/@llblab/pi-telegram/dist/lib/menu-thinking.d.ts +6 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/menu-thinking.js +14 -21
- package/node_modules/@llblab/pi-telegram/dist/lib/menu.d.ts +8 -61
- package/node_modules/@llblab/pi-telegram/dist/lib/menu.js +92 -164
- package/node_modules/@llblab/pi-telegram/dist/lib/model.d.ts +1 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/model.js +2 -16
- package/node_modules/@llblab/pi-telegram/dist/lib/outbound-attachments.d.ts +6 -27
- package/node_modules/@llblab/pi-telegram/dist/lib/outbound-attachments.js +45 -38
- package/node_modules/@llblab/pi-telegram/dist/lib/outbound-buttons.js +22 -16
- package/node_modules/@llblab/pi-telegram/dist/lib/outbound-markup.d.ts +0 -2
- package/node_modules/@llblab/pi-telegram/dist/lib/outbound-markup.js +51 -64
- package/node_modules/@llblab/pi-telegram/dist/lib/outbound-voice.js +6 -3
- package/node_modules/@llblab/pi-telegram/dist/lib/outbound.d.ts +6 -6
- package/node_modules/@llblab/pi-telegram/dist/lib/outbound.js +61 -51
- package/node_modules/@llblab/pi-telegram/dist/lib/ownership.js +6 -2
- package/node_modules/@llblab/pi-telegram/dist/lib/paths.d.ts +5 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/paths.js +37 -21
- package/node_modules/@llblab/pi-telegram/dist/lib/pi.d.ts +2 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/pi.js +8 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/polling.d.ts +23 -37
- package/node_modules/@llblab/pi-telegram/dist/lib/polling.js +71 -52
- package/node_modules/@llblab/pi-telegram/dist/lib/preview.js +39 -19
- package/node_modules/@llblab/pi-telegram/dist/lib/process-identity.d.ts +24 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/process-identity.js +133 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/prompts.js +2 -7
- package/node_modules/@llblab/pi-telegram/dist/lib/queue.d.ts +16 -16
- package/node_modules/@llblab/pi-telegram/dist/lib/queue.js +261 -116
- package/node_modules/@llblab/pi-telegram/dist/lib/recovery.d.ts +2 -83
- package/node_modules/@llblab/pi-telegram/dist/lib/recovery.js +20 -274
- package/node_modules/@llblab/pi-telegram/dist/lib/replies.d.ts +16 -24
- package/node_modules/@llblab/pi-telegram/dist/lib/replies.js +99 -116
- package/node_modules/@llblab/pi-telegram/dist/lib/routing.d.ts +121 -7
- package/node_modules/@llblab/pi-telegram/dist/lib/routing.js +4750 -1161
- package/node_modules/@llblab/pi-telegram/dist/lib/runtime.d.ts +1 -11
- package/node_modules/@llblab/pi-telegram/dist/lib/sections.d.ts +4 -29
- package/node_modules/@llblab/pi-telegram/dist/lib/sections.js +7 -20
- package/node_modules/@llblab/pi-telegram/dist/lib/skills.js +4 -3
- package/node_modules/@llblab/pi-telegram/dist/lib/status.js +86 -57
- package/node_modules/@llblab/pi-telegram/dist/lib/sync.d.ts +6 -3
- package/node_modules/@llblab/pi-telegram/dist/lib/sync.js +112 -45
- package/node_modules/@llblab/pi-telegram/dist/lib/target.d.ts +4 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/target.js +18 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/telegram-api.d.ts +18 -11
- package/node_modules/@llblab/pi-telegram/dist/lib/telegram-api.js +165 -49
- package/node_modules/@llblab/pi-telegram/dist/lib/text-groups.js +4 -39
- package/node_modules/@llblab/pi-telegram/dist/lib/thread-cleanup-manager.d.ts +6 -27
- package/node_modules/@llblab/pi-telegram/dist/lib/thread-cleanup-manager.js +369 -186
- package/node_modules/@llblab/pi-telegram/dist/lib/thread-display.d.ts +1 -2
- package/node_modules/@llblab/pi-telegram/dist/lib/thread-display.js +58 -38
- package/node_modules/@llblab/pi-telegram/dist/lib/thread-naming.d.ts +28 -8
- package/node_modules/@llblab/pi-telegram/dist/lib/thread-naming.js +175 -66
- package/node_modules/@llblab/pi-telegram/dist/lib/thread-reconciler.d.ts +42 -16
- package/node_modules/@llblab/pi-telegram/dist/lib/thread-reconciler.js +90 -50
- package/node_modules/@llblab/pi-telegram/dist/lib/threads.d.ts +88 -24
- package/node_modules/@llblab/pi-telegram/dist/lib/threads.js +2276 -842
- package/node_modules/@llblab/pi-telegram/dist/lib/time-injection.js +1 -2
- package/node_modules/@llblab/pi-telegram/dist/lib/turns.js +1 -19
- package/node_modules/@llblab/pi-telegram/dist/lib/updates.d.ts +178 -82
- package/node_modules/@llblab/pi-telegram/dist/lib/updates.js +2438 -645
- package/node_modules/@llblab/pi-telegram/dist/lib/voice.d.ts +7 -22
- package/node_modules/@llblab/pi-telegram/dist/lib/voice.js +7 -22
- package/node_modules/@llblab/pi-telegram/dist/lib/wire.js +1 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/workspace-admission.d.ts +3 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/workspace-admission.js +425 -211
- package/node_modules/@llblab/pi-telegram/dist/lib/workspace-identity.js +8 -13
- package/node_modules/@llblab/pi-telegram/dist/lib/workspace-retirement.d.ts +1 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/workspace-retirement.js +328 -140
- package/node_modules/@llblab/pi-telegram/dist/lib/workspace-slots.js +8 -4
- package/node_modules/@llblab/pi-telegram/dist/package.json +1 -1
- package/node_modules/@llblab/pi-telegram/docs/architecture.md +43 -35
- package/node_modules/@llblab/pi-telegram/docs/inbound.md +1 -1
- package/node_modules/@llblab/pi-telegram/docs/multi-instance-bus.md +15 -3
- package/node_modules/@llblab/pi-telegram/docs/outbound.md +1 -1
- package/node_modules/@llblab/pi-telegram/docs/public-api.md +29 -1
- package/node_modules/@llblab/pi-telegram/docs/ui-style.md +25 -8
- package/node_modules/@llblab/pi-telegram/lib/activity-verbosity.ts +59 -82
- package/node_modules/@llblab/pi-telegram/lib/activity.ts +146 -102
- package/node_modules/@llblab/pi-telegram/lib/agent-messages.ts +12 -5
- package/node_modules/@llblab/pi-telegram/lib/bindings.ts +390 -82
- package/node_modules/@llblab/pi-telegram/lib/bus-api.ts +262 -99
- package/node_modules/@llblab/pi-telegram/lib/bus-follower.ts +2440 -601
- package/node_modules/@llblab/pi-telegram/lib/bus-leader.ts +2209 -1290
- package/node_modules/@llblab/pi-telegram/lib/bus-transport.ts +46 -12
- package/node_modules/@llblab/pi-telegram/lib/bus.ts +1673 -444
- package/node_modules/@llblab/pi-telegram/lib/channel-posts.ts +848 -327
- package/node_modules/@llblab/pi-telegram/lib/command-templates.ts +152 -265
- package/node_modules/@llblab/pi-telegram/lib/commands.ts +2398 -555
- package/node_modules/@llblab/pi-telegram/lib/config.ts +177 -170
- package/node_modules/@llblab/pi-telegram/lib/delivery.ts +41 -29
- package/node_modules/@llblab/pi-telegram/lib/extension.ts +1209 -431
- package/node_modules/@llblab/pi-telegram/lib/generative-app-worker.mjs +19 -7
- package/node_modules/@llblab/pi-telegram/lib/generative-apps.ts +324 -211
- package/node_modules/@llblab/pi-telegram/lib/inbound.ts +95 -97
- package/node_modules/@llblab/pi-telegram/lib/journal.ts +5329 -1712
- package/node_modules/@llblab/pi-telegram/lib/keyboard.ts +1 -3
- package/node_modules/@llblab/pi-telegram/lib/lifecycle.ts +128 -78
- package/node_modules/@llblab/pi-telegram/lib/locks.ts +703 -212
- package/node_modules/@llblab/pi-telegram/lib/logging.ts +147 -58
- package/node_modules/@llblab/pi-telegram/lib/media.ts +82 -43
- package/node_modules/@llblab/pi-telegram/lib/menu-model.ts +85 -18
- package/node_modules/@llblab/pi-telegram/lib/menu-queue.ts +88 -129
- package/node_modules/@llblab/pi-telegram/lib/menu-settings.ts +260 -155
- package/node_modules/@llblab/pi-telegram/lib/menu-status.ts +20 -60
- package/node_modules/@llblab/pi-telegram/lib/menu-thinking.ts +41 -56
- package/node_modules/@llblab/pi-telegram/lib/menu.ts +112 -285
- package/node_modules/@llblab/pi-telegram/lib/model.ts +8 -22
- package/node_modules/@llblab/pi-telegram/lib/outbound-attachments.ts +156 -125
- package/node_modules/@llblab/pi-telegram/lib/outbound-buttons.ts +76 -49
- package/node_modules/@llblab/pi-telegram/lib/outbound-markup.ts +96 -94
- package/node_modules/@llblab/pi-telegram/lib/outbound-voice.ts +33 -27
- package/node_modules/@llblab/pi-telegram/lib/outbound.ts +125 -125
- package/node_modules/@llblab/pi-telegram/lib/ownership.ts +19 -10
- package/node_modules/@llblab/pi-telegram/lib/paths.ts +148 -49
- package/node_modules/@llblab/pi-telegram/lib/pi.ts +35 -15
- package/node_modules/@llblab/pi-telegram/lib/polling.ts +165 -149
- package/node_modules/@llblab/pi-telegram/lib/preview.ts +93 -40
- package/node_modules/@llblab/pi-telegram/lib/process-identity.ts +164 -0
- package/node_modules/@llblab/pi-telegram/lib/prompts.ts +4 -11
- package/node_modules/@llblab/pi-telegram/lib/queue.ts +523 -289
- package/node_modules/@llblab/pi-telegram/lib/recovery.ts +50 -454
- package/node_modules/@llblab/pi-telegram/lib/rendering.ts +1 -3
- package/node_modules/@llblab/pi-telegram/lib/replies.ts +248 -209
- package/node_modules/@llblab/pi-telegram/lib/routing.ts +8527 -2149
- package/node_modules/@llblab/pi-telegram/lib/runtime.ts +1 -12
- package/node_modules/@llblab/pi-telegram/lib/sections.ts +24 -89
- package/node_modules/@llblab/pi-telegram/lib/setup.ts +1 -3
- package/node_modules/@llblab/pi-telegram/lib/skills.ts +9 -4
- package/node_modules/@llblab/pi-telegram/lib/status.ts +215 -110
- package/node_modules/@llblab/pi-telegram/lib/sync.ts +488 -359
- package/node_modules/@llblab/pi-telegram/lib/target.ts +22 -3
- package/node_modules/@llblab/pi-telegram/lib/telegram-api.ts +322 -122
- package/node_modules/@llblab/pi-telegram/lib/text-groups.ts +5 -39
- package/node_modules/@llblab/pi-telegram/lib/thread-cleanup-manager.ts +833 -331
- package/node_modules/@llblab/pi-telegram/lib/thread-display.ts +213 -97
- package/node_modules/@llblab/pi-telegram/lib/thread-naming.ts +232 -87
- package/node_modules/@llblab/pi-telegram/lib/thread-reconciler.ts +155 -72
- package/node_modules/@llblab/pi-telegram/lib/threads.ts +5329 -1817
- package/node_modules/@llblab/pi-telegram/lib/time-injection.ts +1 -4
- package/node_modules/@llblab/pi-telegram/lib/turns.ts +15 -28
- package/node_modules/@llblab/pi-telegram/lib/updates.ts +5194 -1600
- package/node_modules/@llblab/pi-telegram/lib/voice.ts +7 -35
- package/node_modules/@llblab/pi-telegram/lib/wire.ts +1 -1
- package/node_modules/@llblab/pi-telegram/lib/workspace-admission.ts +996 -416
- package/node_modules/@llblab/pi-telegram/lib/workspace-identity.ts +14 -17
- package/node_modules/@llblab/pi-telegram/lib/workspace-retirement.ts +878 -376
- package/node_modules/@llblab/pi-telegram/lib/workspace-slots.ts +22 -13
- package/node_modules/@llblab/pi-telegram/package.json +1 -1
- package/package.json +3 -3
- package/node_modules/@llblab/pi-telegram/scripts/check-downgrade.mjs +0 -472
- package/node_modules/@llblab/pi-telegram/scripts/measure-workspace.mjs +0 -108
|
@@ -12,7 +12,6 @@ import * as BusLeader from "./bus-leader.ts";
|
|
|
12
12
|
import * as BusTransport from "./bus-transport.ts";
|
|
13
13
|
import * as Bus from "./bus.ts";
|
|
14
14
|
import * as ChannelPosts from "./channel-posts.ts";
|
|
15
|
-
import * as ThreadCleanupManager from "./thread-cleanup-manager.ts";
|
|
16
15
|
import * as CommandTemplates from "./command-templates.ts";
|
|
17
16
|
import * as Commands from "./commands.ts";
|
|
18
17
|
import * as Config from "./config.ts";
|
|
@@ -33,6 +32,7 @@ import * as Paths from "./paths.ts";
|
|
|
33
32
|
import * as Pi from "./pi.ts";
|
|
34
33
|
import * as Polling from "./polling.ts";
|
|
35
34
|
import * as Preview from "./preview.ts";
|
|
35
|
+
import * as ProcessIdentity from "./process-identity.ts";
|
|
36
36
|
import * as PromptTemplates from "./prompt-templates.ts";
|
|
37
37
|
import * as Prompts from "./prompts.ts";
|
|
38
38
|
import * as Queue from "./queue.ts";
|
|
@@ -44,12 +44,13 @@ import * as Sections from "./sections.ts";
|
|
|
44
44
|
import * as Skills from "./skills.ts";
|
|
45
45
|
import * as Status from "./status.ts";
|
|
46
46
|
import * as Sync from "./sync.ts";
|
|
47
|
+
import * as Targets from "./target.ts";
|
|
47
48
|
import * as TelegramApi from "./telegram-api.ts";
|
|
48
49
|
import * as TextGroups from "./text-groups.ts";
|
|
49
|
-
import * as
|
|
50
|
-
import * as Targets from "./target.ts";
|
|
50
|
+
import * as ThreadCleanupManager from "./thread-cleanup-manager.ts";
|
|
51
51
|
import * as ThreadDisplay from "./thread-display.ts";
|
|
52
52
|
import * as ThreadNaming from "./thread-naming.ts";
|
|
53
|
+
import * as ThreadReconciler from "./thread-reconciler.ts";
|
|
53
54
|
import * as Threads from "./threads.ts";
|
|
54
55
|
import * as TimeInjection from "./time-injection.ts";
|
|
55
56
|
import * as Updates from "./updates.ts";
|
|
@@ -69,6 +70,11 @@ const telegramBusProtocolIdentity =
|
|
|
69
70
|
Bus.TELEGRAM_BUS_CAPABILITY_DIRECTORY_DISPLAY_FORMAT,
|
|
70
71
|
Bus.TELEGRAM_BUS_CAPABILITY_SESSION_REPLACEMENT_INTENT,
|
|
71
72
|
Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE,
|
|
73
|
+
Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_SAVE,
|
|
74
|
+
Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_APPLY,
|
|
75
|
+
Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_SETTLE,
|
|
76
|
+
Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_COMMAND_SET,
|
|
77
|
+
Bus.TELEGRAM_BUS_CAPABILITY_SELECTED_MENU_DELIVERY,
|
|
72
78
|
]);
|
|
73
79
|
|
|
74
80
|
// --- Extension Runtime ---
|
|
@@ -88,7 +94,9 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
88
94
|
} = piRuntime;
|
|
89
95
|
const bridgeRuntime = Runtime.createTelegramBridgeRuntime();
|
|
90
96
|
const runtimeDiagnostics =
|
|
91
|
-
Logging.createTelegramRuntimeDiagnosticsRuntime<Pi.ExtensionContext>({
|
|
97
|
+
Logging.createTelegramRuntimeDiagnosticsRuntime<Pi.ExtensionContext>({
|
|
98
|
+
sharedFile: true,
|
|
99
|
+
});
|
|
92
100
|
const runtimeEvents = runtimeDiagnostics.events;
|
|
93
101
|
const recordRuntimeEvent = runtimeDiagnostics.recordRuntimeEvent;
|
|
94
102
|
const configStore = Config.createTelegramConfigStore({ recordRuntimeEvent });
|
|
@@ -161,11 +169,18 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
161
169
|
getBotToken: configStore.getBotToken,
|
|
162
170
|
getBotId: getTelegramBotId,
|
|
163
171
|
});
|
|
164
|
-
const telegramLeaderJournalPath =
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
172
|
+
const telegramLeaderJournalPath =
|
|
173
|
+
Locks.createTelegramLeaderJournalPathResolver({
|
|
174
|
+
getNamedJournalPath() {
|
|
175
|
+
return lockRuntime.getJournalPath();
|
|
176
|
+
},
|
|
177
|
+
getSessionId() {
|
|
178
|
+
return Pi.getExtensionContextSessionId(
|
|
179
|
+
telegramSessionContextStore.get(),
|
|
180
|
+
);
|
|
181
|
+
},
|
|
182
|
+
getProfileName: configStore.getActiveProfileName,
|
|
183
|
+
});
|
|
169
184
|
const telegramJournalBindingRuntime =
|
|
170
185
|
Journal.createTelegramUpdateJournalBindingRuntime({
|
|
171
186
|
base: {
|
|
@@ -201,9 +216,13 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
201
216
|
getLeaderJournalPath: telegramLeaderJournalPath.resolve,
|
|
202
217
|
getRuntimeDir: Paths.resolveTelegramTempDir,
|
|
203
218
|
getFollowerJournalPath(bindingKey, profileName, sessionId) {
|
|
204
|
-
if (sessionId !== undefined)
|
|
205
|
-
|
|
206
|
-
|
|
219
|
+
if (sessionId !== undefined)
|
|
220
|
+
return Paths.resolveTelegramSessionJournalPath(
|
|
221
|
+
sessionId,
|
|
222
|
+
bindingKey,
|
|
223
|
+
undefined,
|
|
224
|
+
profileName,
|
|
225
|
+
);
|
|
207
226
|
return Paths.resolveTelegramFollowerJournalPath(
|
|
208
227
|
bindingKey,
|
|
209
228
|
undefined,
|
|
@@ -228,7 +247,6 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
228
247
|
telegramJournalBindingRuntime.getActiveRecoveryKey;
|
|
229
248
|
const isTelegramBusRuntimeEnabled =
|
|
230
249
|
telegramThreadCapabilityState.isBusRuntimeEnabled;
|
|
231
|
-
Config.bindGlobalTelegramConfigRuntime(configStore);
|
|
232
250
|
const configControls = Config.createTelegramConfigControls(configStore);
|
|
233
251
|
const lockRuntime = Locks.createTelegramLockRuntime<Pi.ExtensionContext>({
|
|
234
252
|
key: Locks.createTelegramLockKeyResolver(configStore),
|
|
@@ -237,7 +255,9 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
237
255
|
busSecret: telegramBusAuthSecret,
|
|
238
256
|
staleHeartbeatMs: Locks.TELEGRAM_BUS_LEADER_STALE_HEARTBEAT_MS,
|
|
239
257
|
legacyLocksPath: Paths.resolveLegacyTelegramOwnersPath(),
|
|
240
|
-
createJournalPath() {
|
|
258
|
+
createJournalPath() {
|
|
259
|
+
return telegramLeaderJournalPath.createJournalPath();
|
|
260
|
+
},
|
|
241
261
|
});
|
|
242
262
|
const telegramSessionContextStore =
|
|
243
263
|
Lifecycle.createTelegramSessionContextStore<Pi.ExtensionContext>({
|
|
@@ -245,8 +265,11 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
245
265
|
return ctx.sessionManager ?? ctx.cwd;
|
|
246
266
|
},
|
|
247
267
|
});
|
|
248
|
-
const captureTelegramStateAuthority =
|
|
249
|
-
|
|
268
|
+
const captureTelegramStateAuthority =
|
|
269
|
+
Locks.createTelegramOwnedStateAuthorityCapture(
|
|
270
|
+
lockRuntime,
|
|
271
|
+
telegramSessionContextStore,
|
|
272
|
+
);
|
|
250
273
|
const threadStore = Threads.createTelegramTopicTargetStore({
|
|
251
274
|
path: Paths.resolveTelegramStatePath,
|
|
252
275
|
telegramProfile: function () {
|
|
@@ -261,11 +284,12 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
261
284
|
return workspaceAdmissionRuntime.resolve()?.listReservedSlots() ?? [];
|
|
262
285
|
},
|
|
263
286
|
});
|
|
264
|
-
const resolveWorkspaceRestoreStore =
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
287
|
+
const resolveWorkspaceRestoreStore =
|
|
288
|
+
Threads.createTelegramWorkspaceRestoreResolver({
|
|
289
|
+
getProfileName: configStore.getActiveProfileName,
|
|
290
|
+
getBotToken: configStore.getBotToken,
|
|
291
|
+
threadStore,
|
|
292
|
+
});
|
|
269
293
|
runtimeDiagnostics.bindStorage({
|
|
270
294
|
getBotToken: configStore.getBotToken,
|
|
271
295
|
getProfileName: configStore.getActiveProfileName,
|
|
@@ -283,12 +307,15 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
283
307
|
instanceId: telegramInstanceId,
|
|
284
308
|
isRegisteredFor(target) {
|
|
285
309
|
const registered = telegramBusFollowerRegistrationState.getTarget();
|
|
286
|
-
return
|
|
310
|
+
return (
|
|
311
|
+
telegramBusFollowerRegistrationState.isRegistered() &&
|
|
287
312
|
registered?.chatId === target.chatId &&
|
|
288
|
-
registered.threadId === target.threadId
|
|
313
|
+
registered.threadId === target.threadId
|
|
314
|
+
);
|
|
289
315
|
},
|
|
290
316
|
async requestSessionReplacement(operation, intent) {
|
|
291
|
-
const request =
|
|
317
|
+
const request =
|
|
318
|
+
telegramBusFollowerRegistration.requestSessionReplacement;
|
|
292
319
|
if (!request) return false;
|
|
293
320
|
return await request(operation, intent);
|
|
294
321
|
},
|
|
@@ -298,10 +325,15 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
298
325
|
{ text: html, parseMode: "html", replyMarkup: { inline_keyboard: [] } },
|
|
299
326
|
{ scope: { kind: "target", target } },
|
|
300
327
|
);
|
|
301
|
-
return delivery.ok
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
328
|
+
return delivery.ok
|
|
329
|
+
? { ok: true }
|
|
330
|
+
: {
|
|
331
|
+
ok: false,
|
|
332
|
+
retryable:
|
|
333
|
+
delivery.reason === "runtime-unavailable" ||
|
|
334
|
+
delivery.reason === "target-unavailable" ||
|
|
335
|
+
delivery.reason === "transport-retryable",
|
|
336
|
+
};
|
|
305
337
|
},
|
|
306
338
|
handoffTtlMs: Threads.TELEGRAM_LEADER_SESSION_HANDOFF_TTL_MS,
|
|
307
339
|
recordRuntimeEvent,
|
|
@@ -346,11 +378,10 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
346
378
|
const proactivePushChatIdGetter =
|
|
347
379
|
Config.createTelegramProactivePushChatIdGetter(proactivePushTargetGetter);
|
|
348
380
|
const buttonActionStore = Outbound.createTelegramButtonActionStore();
|
|
349
|
-
const planGenerativeAppOutput =
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
);
|
|
381
|
+
const planGenerativeAppOutput = Outbound.createTelegramOutboundReplyPlanner(
|
|
382
|
+
buttonActionStore,
|
|
383
|
+
configControls.getAssistantRenderingMode,
|
|
384
|
+
);
|
|
354
385
|
const pendingModelSwitchStore =
|
|
355
386
|
Model.createPendingModelSwitchStore<
|
|
356
387
|
Model.ScopedTelegramModel<ActivePiModel>
|
|
@@ -388,100 +419,127 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
388
419
|
);
|
|
389
420
|
const telegramApiTargetActivityRuntime =
|
|
390
421
|
TelegramApi.createTelegramApiTargetActivityRuntime();
|
|
422
|
+
// Retirement protection and dead-owner reclamation must inspect the same journal sources.
|
|
423
|
+
const workspaceRetirementJournalPorts = {
|
|
424
|
+
getActiveTurnTarget: activeTurnRuntime.getTarget,
|
|
425
|
+
getQueuedItems: telegramQueueStore.getQueuedItems,
|
|
426
|
+
resolveLeaderJournal: resolveTelegramUpdateJournalBinding,
|
|
427
|
+
createFollowerJournalResolver:
|
|
428
|
+
telegramJournalBindingRuntime.createLegacyRecipientResolver,
|
|
429
|
+
createSessionJournalResolver:
|
|
430
|
+
telegramJournalBindingRuntime.createRecipientResolver,
|
|
431
|
+
createJournalPathResolver: telegramJournalBindingRuntime.createPathResolver,
|
|
432
|
+
discoverFollowerJournals() {
|
|
433
|
+
return Journal.discoverTelegramRecipientJournalPaths({
|
|
434
|
+
directory: Paths.resolveTelegramTempDir(),
|
|
435
|
+
profileName: configStore.getActiveProfileName(),
|
|
436
|
+
});
|
|
437
|
+
},
|
|
438
|
+
};
|
|
391
439
|
const workspaceProtectionObserver =
|
|
392
440
|
WorkspaceRetirement.createTelegramWorkspaceProtectionObserver({
|
|
393
441
|
listFollowers: telegramBusFollowerRegistry.list,
|
|
394
|
-
|
|
395
|
-
getQueuedItems: telegramQueueStore.getQueuedItems,
|
|
396
|
-
resolveLeaderJournal: resolveTelegramUpdateJournalBinding,
|
|
397
|
-
createFollowerJournalResolver:
|
|
398
|
-
telegramJournalBindingRuntime.createLegacyRecipientResolver,
|
|
399
|
-
createSessionJournalResolver:
|
|
400
|
-
telegramJournalBindingRuntime.createRecipientResolver,
|
|
442
|
+
...workspaceRetirementJournalPorts,
|
|
401
443
|
withJournalReference(binding, operation) {
|
|
402
|
-
if (!binding.recoveryKey)
|
|
403
|
-
|
|
444
|
+
if (!binding.recoveryKey)
|
|
445
|
+
throw new Error(
|
|
446
|
+
"Telegram workspace journal reference identity is unavailable.",
|
|
447
|
+
);
|
|
448
|
+
return telegramJournalReferenceRegistry.withReference(
|
|
449
|
+
{
|
|
450
|
+
referenceClass: "workspace-retirement",
|
|
451
|
+
recoveryKey: binding.recoveryKey,
|
|
452
|
+
},
|
|
453
|
+
operation,
|
|
404
454
|
);
|
|
405
|
-
return telegramJournalReferenceRegistry.withReference({
|
|
406
|
-
referenceClass: "workspace-retirement",
|
|
407
|
-
recoveryKey: binding.recoveryKey,
|
|
408
|
-
}, operation);
|
|
409
|
-
},
|
|
410
|
-
discoverFollowerJournals() {
|
|
411
|
-
return Journal.discoverTelegramRecipientJournalPaths({
|
|
412
|
-
directory: Paths.resolveTelegramTempDir(),
|
|
413
|
-
profileName: configStore.getActiveProfileName(),
|
|
414
|
-
});
|
|
415
455
|
},
|
|
416
|
-
createJournalPathResolver: telegramJournalBindingRuntime.createPathResolver,
|
|
417
456
|
inspectJournalNamespace() {
|
|
418
457
|
const botToken = configStore.getBotToken();
|
|
419
|
-
if (!botToken)
|
|
458
|
+
if (!botToken)
|
|
459
|
+
throw new Error(
|
|
460
|
+
"Telegram namespace inspection requires current bot identity.",
|
|
461
|
+
);
|
|
420
462
|
return Journal.inspectTelegramSessionJournalNamespace({
|
|
421
463
|
directory: Paths.resolveTelegramTempDir(),
|
|
422
464
|
profile: configStore.getActiveProfileName() ?? "default",
|
|
423
|
-
pollingPath: telegramLeaderJournalPath.resolve(
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
465
|
+
pollingPath: telegramLeaderJournalPath.resolve(
|
|
466
|
+
configStore.getActiveProfileName(),
|
|
467
|
+
),
|
|
468
|
+
botIdentity: Journal.createTelegramUpdateJournalBotIdentity({
|
|
469
|
+
botToken,
|
|
470
|
+
botId: getTelegramBotId(),
|
|
471
|
+
}),
|
|
472
|
+
limits: {
|
|
473
|
+
maxDirectoryEntries: 10_000,
|
|
474
|
+
maxFiles: 4096,
|
|
475
|
+
maxBytes: 64 * 1024 * 1024,
|
|
476
|
+
maxEntries: 10_000,
|
|
477
|
+
maxWork: 100_000,
|
|
478
|
+
},
|
|
427
479
|
});
|
|
428
480
|
},
|
|
429
481
|
getJournalWriterProtection(journalBindingKey) {
|
|
430
|
-
const owner =
|
|
431
|
-
journalBindingKey
|
|
432
|
-
);
|
|
482
|
+
const owner =
|
|
483
|
+
Threads.getTelegramThreadOwnerFromProfileKey(journalBindingKey);
|
|
433
484
|
if (owner.kind !== "manual-follower") return "unknown";
|
|
434
|
-
const liveness =
|
|
435
|
-
|
|
436
|
-
|
|
485
|
+
const liveness =
|
|
486
|
+
ProcessIdentity.getTelegramProcessBirthIdentityLiveness(
|
|
487
|
+
owner.instanceId,
|
|
488
|
+
);
|
|
437
489
|
return liveness === "alive"
|
|
438
490
|
? "protected"
|
|
439
|
-
: liveness === "dead"
|
|
491
|
+
: liveness === "dead"
|
|
492
|
+
? "clear"
|
|
493
|
+
: "unknown";
|
|
440
494
|
},
|
|
441
495
|
getDeliveryAuthorityProtection(binding) {
|
|
442
|
-
const retainedRestore = resolveWorkspaceRestoreStore()
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
496
|
+
const retainedRestore = resolveWorkspaceRestoreStore()
|
|
497
|
+
?.list()
|
|
498
|
+
.some(function (intent) {
|
|
499
|
+
return (
|
|
500
|
+
intent.request.binding.bindingKey === binding.bindingKey ||
|
|
501
|
+
Targets.areTelegramTargetsEqual(
|
|
502
|
+
intent.request.binding.target,
|
|
503
|
+
binding.target,
|
|
504
|
+
) ||
|
|
505
|
+
Targets.areTelegramTargetsEqual(
|
|
506
|
+
intent.request.target,
|
|
507
|
+
binding.target,
|
|
508
|
+
)
|
|
509
|
+
);
|
|
510
|
+
});
|
|
511
|
+
return retainedRestore ||
|
|
512
|
+
telegramApiTargetActivityRuntime.hasPendingTarget(binding.target)
|
|
448
513
|
? "protected"
|
|
449
514
|
: "clear";
|
|
450
515
|
},
|
|
451
516
|
});
|
|
452
|
-
const captureWorkspaceExternalProtection =
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
517
|
+
const captureWorkspaceExternalProtection =
|
|
518
|
+
workspaceProtectionObserver.capture;
|
|
519
|
+
const pruneWorkspaceJournalEvidence =
|
|
520
|
+
WorkspaceRetirement.createTelegramWorkspaceJournalEvidencePruner({
|
|
521
|
+
store: threadStore,
|
|
522
|
+
getAdmission: workspaceAdmissionRuntime.resolve,
|
|
523
|
+
getLeaderEpoch: getCurrentLeaderEpoch,
|
|
524
|
+
runExclusive: telegramWorkspaceOperationRuntime.runExclusive,
|
|
525
|
+
protection: workspaceProtectionObserver,
|
|
526
|
+
});
|
|
460
527
|
const reclaimTelegramWorkspaceDeadOwnerQueue =
|
|
461
528
|
WorkspaceRetirement.createTelegramWorkspaceDeadOwnerQueueReclaimer({
|
|
462
529
|
getExternalProtection: captureWorkspaceExternalProtection,
|
|
463
|
-
|
|
464
|
-
getQueuedItems: telegramQueueStore.getQueuedItems,
|
|
465
|
-
resolveLeaderJournal: resolveTelegramUpdateJournalBinding,
|
|
466
|
-
createFollowerJournalResolver:
|
|
467
|
-
telegramJournalBindingRuntime.createLegacyRecipientResolver,
|
|
468
|
-
createSessionJournalResolver:
|
|
469
|
-
telegramJournalBindingRuntime.createRecipientResolver,
|
|
470
|
-
discoverFollowerJournals() {
|
|
471
|
-
return Journal.discoverTelegramRecipientJournalPaths({
|
|
472
|
-
directory: Paths.resolveTelegramTempDir(),
|
|
473
|
-
profileName: configStore.getActiveProfileName(),
|
|
474
|
-
});
|
|
475
|
-
},
|
|
476
|
-
createJournalPathResolver: telegramJournalBindingRuntime.createPathResolver,
|
|
530
|
+
...workspaceRetirementJournalPorts,
|
|
477
531
|
withJournalReference(binding, operation) {
|
|
478
|
-
if (!binding.recoveryKey)
|
|
479
|
-
|
|
532
|
+
if (!binding.recoveryKey)
|
|
533
|
+
throw new Error(
|
|
534
|
+
"Telegram workspace journal reference identity is unavailable.",
|
|
535
|
+
);
|
|
536
|
+
return telegramJournalReferenceRegistry.withReference(
|
|
537
|
+
{
|
|
538
|
+
referenceClass: "workspace-retirement",
|
|
539
|
+
recoveryKey: binding.recoveryKey,
|
|
540
|
+
},
|
|
541
|
+
operation,
|
|
480
542
|
);
|
|
481
|
-
return telegramJournalReferenceRegistry.withReference({
|
|
482
|
-
referenceClass: "workspace-retirement",
|
|
483
|
-
recoveryKey: binding.recoveryKey,
|
|
484
|
-
}, operation);
|
|
485
543
|
},
|
|
486
544
|
getRecoveryOwner() {
|
|
487
545
|
return {
|
|
@@ -491,11 +549,14 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
491
549
|
sessionGeneration: telegramSessionContextStore.getGeneration(),
|
|
492
550
|
};
|
|
493
551
|
},
|
|
494
|
-
getQueueOwnerLiveness:
|
|
552
|
+
getQueueOwnerLiveness: ProcessIdentity.getTelegramProcessLiveness,
|
|
495
553
|
onMutationError(error) {
|
|
496
|
-
recordRuntimeEvent(
|
|
497
|
-
|
|
498
|
-
|
|
554
|
+
recordRuntimeEvent(
|
|
555
|
+
"Telegram dead-owner queue reclamation was refused.",
|
|
556
|
+
{
|
|
557
|
+
error: error instanceof Error ? error.message : String(error),
|
|
558
|
+
},
|
|
559
|
+
);
|
|
499
560
|
},
|
|
500
561
|
isBindingCurrent(binding) {
|
|
501
562
|
return WorkspaceRetirement.isCurrentTelegramWorkspaceBinding(
|
|
@@ -506,7 +567,9 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
506
567
|
});
|
|
507
568
|
const inactiveThreadCleanupReviewRuntime =
|
|
508
569
|
ThreadCleanupManager.createTelegramInactiveThreadCleanupReviewRuntime({
|
|
509
|
-
getProfileName() {
|
|
570
|
+
getProfileName() {
|
|
571
|
+
return configStore.getActiveProfileName() ?? "default";
|
|
572
|
+
},
|
|
510
573
|
listBindings: threadStore.listWorkspaceBindings,
|
|
511
574
|
getProtection: captureWorkspaceExternalProtection,
|
|
512
575
|
listReservations: threadStore.listReservations,
|
|
@@ -515,11 +578,20 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
515
578
|
getWorkStore() {
|
|
516
579
|
const profileName = configStore.getActiveProfileName() ?? "default";
|
|
517
580
|
const botToken = configStore.getBotToken();
|
|
518
|
-
if (!botToken)
|
|
581
|
+
if (!botToken)
|
|
582
|
+
throw new Error(
|
|
583
|
+
"Telegram Thread cleanup review requires an active bot token.",
|
|
584
|
+
);
|
|
519
585
|
return ThreadCleanupManager.createTelegramThreadCleanupWorkStore({
|
|
520
|
-
...Paths.resolveTelegramServiceJournalStorage(
|
|
586
|
+
...Paths.resolveTelegramServiceJournalStorage(
|
|
587
|
+
"thread-cleanup",
|
|
588
|
+
undefined,
|
|
589
|
+
profileName,
|
|
590
|
+
),
|
|
521
591
|
profileName,
|
|
522
|
-
tokenSha256: Journal.createTelegramUpdateJournalBotIdentity({
|
|
592
|
+
tokenSha256: Journal.createTelegramUpdateJournalBotIdentity({
|
|
593
|
+
botToken,
|
|
594
|
+
}).tokenSha256,
|
|
523
595
|
});
|
|
524
596
|
},
|
|
525
597
|
runWorkspaceOperation: telegramWorkspaceOperationRuntime.run,
|
|
@@ -553,7 +625,8 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
553
625
|
instanceId: telegramInstanceId,
|
|
554
626
|
listRecords: threadStore.list,
|
|
555
627
|
listWorkspaceBindings: threadStore.listWorkspaceBindings,
|
|
556
|
-
getFollowerDisplayTitle:
|
|
628
|
+
getFollowerDisplayTitle:
|
|
629
|
+
telegramBusFollowerRegistrationState.getDisplayTitle,
|
|
557
630
|
getActiveTurnTarget: activeTurnRuntime.getTarget,
|
|
558
631
|
getFollowerTarget: telegramBusFollowerRegistrationState.getTarget,
|
|
559
632
|
isFollowerRegistered: telegramBusFollowerRegistrationState.isRegistered,
|
|
@@ -599,7 +672,9 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
599
672
|
registry: telegramJournalReferenceRegistry,
|
|
600
673
|
resolveBinding: resolveTelegramUpdateJournalBinding,
|
|
601
674
|
referenceClass: "polling-cursor",
|
|
602
|
-
operation(binding) {
|
|
675
|
+
operation(binding) {
|
|
676
|
+
return binding.journal.read().acceptedThroughUpdateId;
|
|
677
|
+
},
|
|
603
678
|
});
|
|
604
679
|
},
|
|
605
680
|
getActiveSourceMessageIds: activeTurnRuntime.getSourceMessageIds,
|
|
@@ -652,7 +727,10 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
652
727
|
getBotToken: configStore.getBotToken,
|
|
653
728
|
getBotScope() {
|
|
654
729
|
const config = configStore.get();
|
|
655
|
-
return
|
|
730
|
+
return (
|
|
731
|
+
config.botUsername ??
|
|
732
|
+
(config.botId === undefined ? undefined : String(config.botId))
|
|
733
|
+
);
|
|
656
734
|
},
|
|
657
735
|
recordRuntimeEvent,
|
|
658
736
|
targetActivity: telegramApiTargetActivityRuntime,
|
|
@@ -686,8 +764,9 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
686
764
|
telegramBusFollowerRegistrationState.waitForGeneration,
|
|
687
765
|
getForwardCommentBatchPosition:
|
|
688
766
|
textGroupRuntime.getPreparedForwardingPosition,
|
|
689
|
-
validateForwardOwnership:
|
|
690
|
-
|
|
767
|
+
validateForwardOwnership: Bus.createTelegramBusForwardOwnershipValidator(
|
|
768
|
+
telegramBusFollowerRegistry,
|
|
769
|
+
),
|
|
691
770
|
recordRuntimeEvent,
|
|
692
771
|
});
|
|
693
772
|
const telegramApiRuntime = BusApi.createTelegramBusAwareApiRuntime({
|
|
@@ -733,11 +812,12 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
733
812
|
editGuestInlineMessage: telegramApiRuntime.editGuestInlineMessage,
|
|
734
813
|
});
|
|
735
814
|
// Rotate the guest placeholder frames until the final replacement stops them.
|
|
736
|
-
const guestPlaceholderRuntime =
|
|
737
|
-
|
|
815
|
+
const guestPlaceholderRuntime = Replies.createTelegramGuestPlaceholderRuntime(
|
|
816
|
+
{
|
|
738
817
|
editGuestInlineMessage: telegramApiRuntime.editGuestInlineMessage,
|
|
739
818
|
recordRuntimeEvent,
|
|
740
|
-
}
|
|
819
|
+
},
|
|
820
|
+
);
|
|
741
821
|
|
|
742
822
|
const promptDispatchRuntime = Runtime.createTelegramPromptDispatchRuntime({
|
|
743
823
|
lifecycle,
|
|
@@ -751,7 +831,8 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
751
831
|
const epoch = getCurrentLeaderEpoch();
|
|
752
832
|
return epoch === undefined ? undefined : `direct:${epoch}`;
|
|
753
833
|
}
|
|
754
|
-
if (!telegramBusFollowerRegistrationState.isRegistered())
|
|
834
|
+
if (!telegramBusFollowerRegistrationState.isRegistered())
|
|
835
|
+
return undefined;
|
|
755
836
|
const generation = telegramBusFollowerRegistrationState.getGeneration();
|
|
756
837
|
return generation ? `follower:${generation}` : undefined;
|
|
757
838
|
},
|
|
@@ -952,15 +1033,21 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
952
1033
|
getCommands,
|
|
953
1034
|
getReservedCommandNames: Commands.getTelegramReservedCommandNames,
|
|
954
1035
|
});
|
|
955
|
-
const
|
|
1036
|
+
const getQueueMenuState = Menu.createTelegramModelMenuStateBuilder({
|
|
956
1037
|
runtime: modelMenuRuntime,
|
|
957
1038
|
createSettingsManager: Pi.createSettingsManager,
|
|
958
1039
|
getActiveModel: currentModelRuntime.get,
|
|
1040
|
+
});
|
|
1041
|
+
const menuActionPorts = {
|
|
1042
|
+
getModelMenuState: getQueueMenuState,
|
|
1043
|
+
getActiveModel: currentModelRuntime.get,
|
|
959
1044
|
getThinkingLevel,
|
|
960
1045
|
getQueueItemCount,
|
|
961
1046
|
getPendingCancellationCount() {
|
|
962
|
-
return getCurrentLeaderEpoch() === undefined
|
|
963
|
-
|
|
1047
|
+
return getCurrentLeaderEpoch() === undefined
|
|
1048
|
+
? 0
|
|
1049
|
+
: (updateAdmissionRuntimeBinding.getActive()?.getState()
|
|
1050
|
+
?.abandoningClaimCount ?? 0);
|
|
964
1051
|
},
|
|
965
1052
|
buildStatusHtml: Commands.createTelegramAppMenuHtmlBuilder({
|
|
966
1053
|
buildStatusHtml: Status.createTelegramStatusHtmlBuilder({
|
|
@@ -973,9 +1060,6 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
973
1060
|
storeModelMenuState: modelMenuRuntime.storeState,
|
|
974
1061
|
isIdle,
|
|
975
1062
|
canOfferInFlightModelSwitch: modelSwitchController.canOfferInFlightSwitch,
|
|
976
|
-
sendTextReply,
|
|
977
|
-
editInteractiveMessage,
|
|
978
|
-
sendInteractiveMessage,
|
|
979
1063
|
sectionRegistry,
|
|
980
1064
|
|
|
981
1065
|
// Menu/status UI uses this to reflect whether the active Telegram turn expects voice delivery.
|
|
@@ -983,15 +1067,15 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
983
1067
|
const turn = activeTurnRuntime.get();
|
|
984
1068
|
return Voice.isVoiceTurn(turn);
|
|
985
1069
|
},
|
|
1070
|
+
};
|
|
1071
|
+
const menuActions = Menu.createTelegramMenuActionRuntime({
|
|
1072
|
+
...menuActionPorts,
|
|
1073
|
+
sendTextReply,
|
|
1074
|
+
editInteractiveMessage,
|
|
1075
|
+
sendInteractiveMessage,
|
|
986
1076
|
});
|
|
987
1077
|
|
|
988
1078
|
// --- Queue And Settings Menus ---
|
|
989
|
-
|
|
990
|
-
const getQueueMenuState = Menu.createTelegramModelMenuStateBuilder({
|
|
991
|
-
runtime: modelMenuRuntime,
|
|
992
|
-
createSettingsManager: Pi.createSettingsManager,
|
|
993
|
-
getActiveModel: currentModelRuntime.get,
|
|
994
|
-
});
|
|
995
1079
|
const queueMenuRuntime = MenuQueue.createTelegramQueueMenuRuntime({
|
|
996
1080
|
telegramQueueStore,
|
|
997
1081
|
queueMutationRuntime,
|
|
@@ -1008,20 +1092,32 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1008
1092
|
const threadDisplaySettingsRuntime =
|
|
1009
1093
|
ThreadDisplay.createTelegramThreadDisplaySettingsRuntime({
|
|
1010
1094
|
getTarget() {
|
|
1011
|
-
return
|
|
1012
|
-
|
|
1095
|
+
return (
|
|
1096
|
+
telegramBusFollowerRegistrationState.getTarget() ??
|
|
1097
|
+
telegramBusLeaderState.getTarget()
|
|
1098
|
+
);
|
|
1099
|
+
},
|
|
1100
|
+
getBinding(target) {
|
|
1101
|
+
return threadStore.getWorkspaceBindingByTarget(target);
|
|
1013
1102
|
},
|
|
1014
|
-
getBinding(target) { return threadStore.getWorkspaceBindingByTarget(target); },
|
|
1015
1103
|
apply(mode) {
|
|
1016
1104
|
return ThreadDisplay.applyTelegramThreadDisplaySetting(mode, {
|
|
1017
1105
|
getProfileKey: configStore.getActiveProfileName,
|
|
1018
|
-
ownsLeader() {
|
|
1019
|
-
|
|
1020
|
-
|
|
1106
|
+
ownsLeader() {
|
|
1107
|
+
return getCurrentLeaderEpoch() !== undefined;
|
|
1108
|
+
},
|
|
1109
|
+
getLeaderSetter() {
|
|
1110
|
+
return telegramBusLeaderRuntime.setThreadDisplayMode;
|
|
1111
|
+
},
|
|
1112
|
+
getFollowerSetter() {
|
|
1113
|
+
return telegramBusFollowerRegistration.setThreadDisplayMode;
|
|
1114
|
+
},
|
|
1021
1115
|
reloadConfig: configStore.load,
|
|
1022
1116
|
});
|
|
1023
1117
|
},
|
|
1024
|
-
reset(target) {
|
|
1118
|
+
reset(target) {
|
|
1119
|
+
return telegramThreadDisplayNameResetBinding.reset(target);
|
|
1120
|
+
},
|
|
1025
1121
|
});
|
|
1026
1122
|
const settingsMenuRuntime = MenuSettings.createTelegramSettingsMenuRuntime(
|
|
1027
1123
|
{
|
|
@@ -1036,12 +1132,14 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1036
1132
|
reviewInactiveThreads: inactiveThreadCleanupReviewRuntime.review,
|
|
1037
1133
|
getThreadDisplayMode() {
|
|
1038
1134
|
return threadStore.getBotState().threadMode === "enabled"
|
|
1039
|
-
? Config.resolveTelegramThreadDisplayMode(configStore.get())
|
|
1135
|
+
? Config.resolveTelegramThreadDisplayMode(configStore.get())
|
|
1136
|
+
: undefined;
|
|
1040
1137
|
},
|
|
1041
1138
|
isThreadDisplayCustom: threadDisplaySettingsRuntime.isCustom,
|
|
1042
1139
|
async setThreadDisplayMode(mode) {
|
|
1043
|
-
try {
|
|
1044
|
-
|
|
1140
|
+
try {
|
|
1141
|
+
await threadDisplaySettingsRuntime.setMode(mode);
|
|
1142
|
+
} catch (error) {
|
|
1045
1143
|
recordRuntimeEvent("bus", error, { phase: "thread-display-setting" });
|
|
1046
1144
|
throw error;
|
|
1047
1145
|
}
|
|
@@ -1054,12 +1152,59 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1054
1152
|
|
|
1055
1153
|
const foreignOwnedUpdateForwarder =
|
|
1056
1154
|
telegramBusFollowerClients.foreignOwnedUpdateForwarder;
|
|
1057
|
-
const workspaceRestoreFollowerController =
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1155
|
+
const workspaceRestoreFollowerController =
|
|
1156
|
+
Bus.createTelegramBusWorkspaceRestoreController({
|
|
1157
|
+
getFollower: telegramBusFollowerRegistry.get,
|
|
1158
|
+
localProtocolIdentity: telegramBusProtocolIdentity,
|
|
1159
|
+
createRequestId: telegramBusFollowerClients.createRequestId,
|
|
1160
|
+
getAuthSecret() {
|
|
1161
|
+
return telegramBusAuthSecret;
|
|
1162
|
+
},
|
|
1163
|
+
});
|
|
1164
|
+
const liveRebindFollowerController =
|
|
1165
|
+
Bus.createTelegramBusLiveRebindController({
|
|
1166
|
+
getFollower: telegramBusFollowerRegistry.get,
|
|
1167
|
+
localProtocolIdentity: telegramBusProtocolIdentity,
|
|
1168
|
+
createRequestId: telegramBusFollowerClients.createRequestId,
|
|
1169
|
+
getAuthSecret() {
|
|
1170
|
+
return telegramBusAuthSecret;
|
|
1171
|
+
},
|
|
1172
|
+
});
|
|
1173
|
+
const liveFollowerPorts = {
|
|
1174
|
+
getJournalBindingKey(follower: Bus.TelegramBusFollowerView) {
|
|
1175
|
+
if (!follower.profileKey || !follower.sessionId) return undefined;
|
|
1176
|
+
return telegramJournalBindingRuntime.createRecipientResolver(
|
|
1177
|
+
follower.profileKey,
|
|
1178
|
+
follower.sessionId,
|
|
1179
|
+
)()?.recoveryKey;
|
|
1180
|
+
},
|
|
1181
|
+
isSelectedCommandAvailable(
|
|
1182
|
+
follower: Readonly<Bus.TelegramBusFollowerView>,
|
|
1183
|
+
name: string,
|
|
1184
|
+
): boolean {
|
|
1185
|
+
return (
|
|
1186
|
+
Bus.hasTelegramBusSharedCapabilities(
|
|
1187
|
+
telegramBusProtocolIdentity,
|
|
1188
|
+
follower.protocol,
|
|
1189
|
+
[
|
|
1190
|
+
...Bus.TELEGRAM_BUS_LIVE_REBIND_CAPABILITIES,
|
|
1191
|
+
...Bus.TELEGRAM_BUS_HELD_COMMAND_CAPABILITIES,
|
|
1192
|
+
],
|
|
1193
|
+
) &&
|
|
1194
|
+
typeof selectedMenuDelivery === "function" &&
|
|
1195
|
+
typeof inboundRouteRuntime.prepareHeldCommand === "function" &&
|
|
1196
|
+
typeof inboundRouteRuntime.canPrepareHeldCommand === "function" &&
|
|
1197
|
+
inboundRouteRuntime.canPrepareHeldCommand(name, {
|
|
1198
|
+
showStatus: menuActions.sendStatusMessage,
|
|
1199
|
+
sendTextReply,
|
|
1200
|
+
}) &&
|
|
1201
|
+
!!captureTelegramStateAuthority() &&
|
|
1202
|
+
!!workspaceAdmissionRuntime.resolve() &&
|
|
1203
|
+
!!resolveWorkspaceRestoreStore()
|
|
1204
|
+
);
|
|
1205
|
+
},
|
|
1206
|
+
run: liveRebindFollowerController,
|
|
1207
|
+
};
|
|
1063
1208
|
const observedThreadTargetBinding =
|
|
1064
1209
|
Polling.createTelegramThreadTargetObservationBinding<Pi.ExtensionContext>();
|
|
1065
1210
|
const topicLifecycleSync =
|
|
@@ -1093,6 +1238,18 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1093
1238
|
Commands.createTelegramThreadDisplayNameRenameBinding();
|
|
1094
1239
|
const telegramThreadDisplayNameResetBinding =
|
|
1095
1240
|
Commands.createTelegramThreadDisplayNameResetBinding();
|
|
1241
|
+
const observeLiveTargetWork = Bindings.createTelegramLiveTargetWorkObserver({
|
|
1242
|
+
queue: telegramQueueStore,
|
|
1243
|
+
activeTurn: activeTurnRuntime,
|
|
1244
|
+
lifecycle: bridgeRuntime.lifecycle,
|
|
1245
|
+
isIdle,
|
|
1246
|
+
hasPendingMessages,
|
|
1247
|
+
hasPendingControl: pendingModelSwitchStore.has,
|
|
1248
|
+
publication: publicationRuntime,
|
|
1249
|
+
activity: activityRuntime,
|
|
1250
|
+
delivery: deliveryLifecycleRuntime,
|
|
1251
|
+
api: telegramApiTargetActivityRuntime,
|
|
1252
|
+
});
|
|
1096
1253
|
const inboundRouteRuntime = Routing.createTelegramInboundRouteRuntime({
|
|
1097
1254
|
configStore,
|
|
1098
1255
|
callApi: callTelegramApi,
|
|
@@ -1101,6 +1258,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1101
1258
|
},
|
|
1102
1259
|
getAdmissionScope: getTelegramUpdateAdmissionScope,
|
|
1103
1260
|
getAdmissionJournalBinding: getTelegramQueueJournalBinding,
|
|
1261
|
+
beginCommandEffectWork: publicationRuntime.beginWork,
|
|
1104
1262
|
getMessageOwnership: messageOwnershipRuntime.getForwardOwnership,
|
|
1105
1263
|
recordMessageOwnership: messageOwnershipRuntime.recordRouted,
|
|
1106
1264
|
...inboundBusProjectionRuntime,
|
|
@@ -1118,82 +1276,201 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1118
1276
|
getSessionId: Pi.getExtensionContextSessionId,
|
|
1119
1277
|
getCwd: Pi.getExtensionContextCwd,
|
|
1120
1278
|
getLeaderIdentity: telegramBusLeaderState.getIdentity,
|
|
1279
|
+
observeLeaderWork: observeLiveTargetWork,
|
|
1121
1280
|
followerRegistry: telegramBusFollowerRegistry,
|
|
1122
1281
|
runFollower: workspaceRestoreFollowerController,
|
|
1282
|
+
liveFollower: liveFollowerPorts,
|
|
1123
1283
|
},
|
|
1124
1284
|
getWorkspaceRestoreStore: resolveWorkspaceRestoreStore,
|
|
1125
1285
|
captureWorkspaceExternalProtection,
|
|
1126
1286
|
inspectRestoreSourceCompletion(expected) {
|
|
1127
|
-
return telegramJournalReferenceRegistry.withReference(
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1287
|
+
return telegramJournalReferenceRegistry.withReference(
|
|
1288
|
+
{
|
|
1289
|
+
referenceClass: "operator-disposition",
|
|
1290
|
+
recoveryKey: expected.journalBindingKey,
|
|
1291
|
+
},
|
|
1292
|
+
function () {
|
|
1293
|
+
const observed =
|
|
1294
|
+
telegramJournalBindingRuntime.inspectSourceCompletion(
|
|
1295
|
+
expected.journalBindingKey,
|
|
1296
|
+
{
|
|
1297
|
+
updateId: expected.updateId,
|
|
1298
|
+
sourceSha256: expected.sourceSha256,
|
|
1299
|
+
completionSha256: expected.completionSha256,
|
|
1300
|
+
},
|
|
1301
|
+
);
|
|
1302
|
+
return (
|
|
1303
|
+
observed && {
|
|
1304
|
+
journalBindingKey: expected.journalBindingKey,
|
|
1305
|
+
...observed,
|
|
1306
|
+
}
|
|
1307
|
+
);
|
|
1308
|
+
},
|
|
1309
|
+
);
|
|
1133
1310
|
},
|
|
1134
1311
|
inspectRestoreQueuedReceipt(expected) {
|
|
1135
|
-
return telegramJournalReferenceRegistry.withReference(
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
}
|
|
1312
|
+
return telegramJournalReferenceRegistry.withReference(
|
|
1313
|
+
{
|
|
1314
|
+
referenceClass: "operator-disposition",
|
|
1315
|
+
recoveryKey: expected.journalBindingKey,
|
|
1316
|
+
},
|
|
1317
|
+
function () {
|
|
1318
|
+
return telegramJournalBindingRuntime.inspectQueuedReceipt(
|
|
1319
|
+
expected.journalBindingKey,
|
|
1320
|
+
{
|
|
1321
|
+
queueKind: expected.queueKind,
|
|
1322
|
+
receiptId: expected.receiptId,
|
|
1323
|
+
sourceUpdateIds: [...expected.sourceUpdateIds],
|
|
1324
|
+
queueOwner: { ...expected.queueOwner },
|
|
1325
|
+
},
|
|
1326
|
+
);
|
|
1327
|
+
},
|
|
1328
|
+
);
|
|
1140
1329
|
},
|
|
1141
1330
|
inspectRestoreSourceAbandonment(updateId, journalBindingKey) {
|
|
1142
|
-
return telegramJournalReferenceRegistry.withReference(
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1331
|
+
return telegramJournalReferenceRegistry.withReference(
|
|
1332
|
+
{
|
|
1333
|
+
referenceClass: "operator-disposition",
|
|
1334
|
+
recoveryKey: journalBindingKey,
|
|
1335
|
+
},
|
|
1336
|
+
function () {
|
|
1337
|
+
return telegramJournalBindingRuntime.inspectSourceAbandonment(
|
|
1338
|
+
journalBindingKey,
|
|
1339
|
+
updateId,
|
|
1340
|
+
);
|
|
1341
|
+
},
|
|
1342
|
+
);
|
|
1148
1343
|
},
|
|
1149
|
-
|
|
1344
|
+
inspectRoutingInputGroupExpiry(input) {
|
|
1345
|
+
return telegramJournalReferenceRegistry.withReference(
|
|
1346
|
+
{
|
|
1347
|
+
referenceClass: "operator-disposition",
|
|
1348
|
+
recoveryKey: input.journalBindingKey,
|
|
1349
|
+
},
|
|
1350
|
+
function () {
|
|
1351
|
+
return telegramJournalBindingRuntime.inspectSourceGroupExpiry(
|
|
1352
|
+
input.journalBindingKey,
|
|
1353
|
+
input.updateIds,
|
|
1354
|
+
);
|
|
1355
|
+
},
|
|
1356
|
+
);
|
|
1357
|
+
},
|
|
1358
|
+
inspectTemporaryThreadSources(
|
|
1359
|
+
target,
|
|
1360
|
+
requiredJournalBindingKeys,
|
|
1361
|
+
ownInputs,
|
|
1362
|
+
) {
|
|
1150
1363
|
const binding = resolveTelegramUpdateJournalBinding();
|
|
1151
1364
|
const botToken = configStore.getBotToken();
|
|
1152
1365
|
if (!binding || !botToken) return undefined;
|
|
1153
1366
|
const profile = configStore.getActiveProfileName() ?? "default";
|
|
1154
|
-
const botIdentity = Journal.createTelegramUpdateJournalBotIdentity({
|
|
1367
|
+
const botIdentity = Journal.createTelegramUpdateJournalBotIdentity({
|
|
1368
|
+
botToken,
|
|
1369
|
+
botId: getTelegramBotId(),
|
|
1370
|
+
});
|
|
1155
1371
|
return configStore.withSourceSerialization(function () {
|
|
1156
1372
|
return Journal.isTelegramThreadCleanupJournalNamespaceClear({
|
|
1157
|
-
directory: Paths.resolveTelegramTempDir(),
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1373
|
+
directory: Paths.resolveTelegramTempDir(),
|
|
1374
|
+
profile,
|
|
1375
|
+
botIdentity,
|
|
1376
|
+
pollingPath: telegramLeaderJournalPath.resolve(
|
|
1377
|
+
configStore.getActiveProfileName(),
|
|
1378
|
+
),
|
|
1379
|
+
requiredJournalBindingKeys: [
|
|
1380
|
+
binding.recoveryKey,
|
|
1381
|
+
...requiredJournalBindingKeys,
|
|
1382
|
+
],
|
|
1383
|
+
...(target.threadId !== undefined && ownInputs
|
|
1384
|
+
? {
|
|
1385
|
+
cleanup: {
|
|
1386
|
+
target: { chatId: target.chatId, threadId: target.threadId },
|
|
1387
|
+
ownInputs,
|
|
1388
|
+
},
|
|
1389
|
+
}
|
|
1390
|
+
: {}),
|
|
1391
|
+
limits: {
|
|
1392
|
+
maxDirectoryEntries: 10_000,
|
|
1393
|
+
maxFiles: 4096,
|
|
1394
|
+
maxBytes: 64 * 1024 * 1024,
|
|
1395
|
+
maxEntries: 10_000,
|
|
1396
|
+
maxWork: 100_000,
|
|
1397
|
+
},
|
|
1162
1398
|
withSourceReference(path, operation) {
|
|
1163
|
-
return telegramJournalReferenceRegistry.withReference(
|
|
1164
|
-
|
|
1399
|
+
return telegramJournalReferenceRegistry.withReference(
|
|
1400
|
+
{
|
|
1401
|
+
referenceClass: "operator-disposition",
|
|
1402
|
+
recoveryKey: Journal.createTelegramUpdateJournalBindingKey({
|
|
1403
|
+
path,
|
|
1404
|
+
profileName: profile,
|
|
1405
|
+
botIdentity,
|
|
1406
|
+
}),
|
|
1407
|
+
},
|
|
1408
|
+
operation,
|
|
1409
|
+
);
|
|
1165
1410
|
},
|
|
1166
|
-
})
|
|
1411
|
+
})
|
|
1412
|
+
? []
|
|
1413
|
+
: undefined;
|
|
1167
1414
|
});
|
|
1168
1415
|
},
|
|
1169
1416
|
hasWorkspaceRestoreAuthority() {
|
|
1170
|
-
return
|
|
1417
|
+
return (
|
|
1418
|
+
lockRuntime.owns() &&
|
|
1419
|
+
Bus.hasTelegramBusCapability(
|
|
1420
|
+
telegramBusProtocolIdentity,
|
|
1421
|
+
Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE,
|
|
1422
|
+
)
|
|
1423
|
+
);
|
|
1424
|
+
},
|
|
1425
|
+
hasWorkspaceLiveRebindAuthority() {
|
|
1426
|
+
return (
|
|
1427
|
+
lockRuntime.owns() &&
|
|
1428
|
+
Bus.hasTelegramBusCapability(
|
|
1429
|
+
telegramBusProtocolIdentity,
|
|
1430
|
+
Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_SAVE,
|
|
1431
|
+
) &&
|
|
1432
|
+
Bus.hasTelegramBusCapability(
|
|
1433
|
+
telegramBusProtocolIdentity,
|
|
1434
|
+
Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_APPLY,
|
|
1435
|
+
) &&
|
|
1436
|
+
Bus.hasTelegramBusCapability(
|
|
1437
|
+
telegramBusProtocolIdentity,
|
|
1438
|
+
Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_SETTLE,
|
|
1439
|
+
)
|
|
1440
|
+
);
|
|
1171
1441
|
},
|
|
1172
1442
|
getSessionGeneration: telegramSessionContextStore.getGeneration,
|
|
1173
1443
|
bridgeRuntime,
|
|
1174
1444
|
requestNewSession(source) {
|
|
1175
|
-
const updateId =
|
|
1445
|
+
const updateId =
|
|
1446
|
+
Updates.getTelegramUpdateExecutionFence(source)?.updateId;
|
|
1176
1447
|
if (updateId === undefined) {
|
|
1177
|
-
throw new Error(
|
|
1448
|
+
throw new Error(
|
|
1449
|
+
"Telegram session replacement requires durable update authority.",
|
|
1450
|
+
);
|
|
1178
1451
|
}
|
|
1179
|
-
const callbackMessage =
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
typeof messageTarget.message_id === "number"
|
|
1189
|
-
? {
|
|
1190
|
-
chatId: messageTarget.chat.id,
|
|
1191
|
-
messageId: messageTarget.message_id,
|
|
1192
|
-
...(typeof messageTarget.message_thread_id === "number"
|
|
1193
|
-
? { threadId: messageTarget.message_thread_id }
|
|
1194
|
-
: {}),
|
|
1452
|
+
const callbackMessage =
|
|
1453
|
+
source && typeof source === "object" && "message" in source
|
|
1454
|
+
? (source as { message?: unknown }).message
|
|
1455
|
+
: source;
|
|
1456
|
+
const messageTarget = callbackMessage as
|
|
1457
|
+
| {
|
|
1458
|
+
chat?: { id?: unknown };
|
|
1459
|
+
message_id?: unknown;
|
|
1460
|
+
message_thread_id?: unknown;
|
|
1195
1461
|
}
|
|
1196
|
-
|
|
1462
|
+
| undefined;
|
|
1463
|
+
const target =
|
|
1464
|
+
typeof messageTarget?.chat?.id === "number" &&
|
|
1465
|
+
typeof messageTarget.message_id === "number"
|
|
1466
|
+
? {
|
|
1467
|
+
chatId: messageTarget.chat.id,
|
|
1468
|
+
messageId: messageTarget.message_id,
|
|
1469
|
+
...(typeof messageTarget.message_thread_id === "number"
|
|
1470
|
+
? { threadId: messageTarget.message_thread_id }
|
|
1471
|
+
: {}),
|
|
1472
|
+
}
|
|
1473
|
+
: undefined;
|
|
1197
1474
|
if (!target) {
|
|
1198
1475
|
throw new Error("Telegram session replacement target is unavailable.");
|
|
1199
1476
|
}
|
|
@@ -1210,6 +1487,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1210
1487
|
currentModelRuntime,
|
|
1211
1488
|
modelSwitchController,
|
|
1212
1489
|
menuActions,
|
|
1490
|
+
isVoiceReplyActive: menuActionPorts.isVoiceReplyActive,
|
|
1213
1491
|
updateSettingsMenuMessage: settingsMenuRuntime.updateSettingsMenuMessage,
|
|
1214
1492
|
openQueueMenu: queueMenuRuntime.openQueueMenu,
|
|
1215
1493
|
queueMenuCallbackHandler: queueMenuRuntime.handleCallbackQuery,
|
|
@@ -1222,6 +1500,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1222
1500
|
inboundHandlerRuntime,
|
|
1223
1501
|
threadStore,
|
|
1224
1502
|
runWorkspaceOperation: telegramWorkspaceOperationRuntime.run,
|
|
1503
|
+
liveRebindCleanupSchedule: Routing.TELEGRAM_LIVE_REBIND_CLEANUP_SCHEDULE,
|
|
1225
1504
|
updateStatus,
|
|
1226
1505
|
isContextActive: telegramSessionContextStore.isCurrent,
|
|
1227
1506
|
dispatchNextQueuedTelegramTurn,
|
|
@@ -1242,6 +1521,24 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1242
1521
|
startGuestPlaceholder: guestPlaceholderRuntime.start,
|
|
1243
1522
|
sendTextReply,
|
|
1244
1523
|
setMyCommands,
|
|
1524
|
+
captureThreadNameRecipientAuthority(target, ctx) {
|
|
1525
|
+
// Ordinary follower/classic dialogs keep their unguarded policy; closures are leader-local only.
|
|
1526
|
+
if (
|
|
1527
|
+
telegramBusFollowerRegistrationState.isRegistered() ||
|
|
1528
|
+
target.threadId === undefined
|
|
1529
|
+
)
|
|
1530
|
+
return undefined;
|
|
1531
|
+
return Threads.createTelegramWorkspaceThreadRenameRecipient({
|
|
1532
|
+
store: threadStore,
|
|
1533
|
+
instanceId: telegramInstanceId,
|
|
1534
|
+
target,
|
|
1535
|
+
assertAuthority() {
|
|
1536
|
+
if (telegramSessionContextStore.get() !== ctx)
|
|
1537
|
+
throw new Error("Telegram Thread name dialog lost Pi context.");
|
|
1538
|
+
},
|
|
1539
|
+
getAuthority: threadNameRecipientAuthority.getAuthority,
|
|
1540
|
+
}).assertAuthority;
|
|
1541
|
+
},
|
|
1245
1542
|
validateThreadName(threadName) {
|
|
1246
1543
|
return ThreadNaming.getTelegramManualThreadDisplayNameValidationError(
|
|
1247
1544
|
threadName,
|
|
@@ -1296,7 +1593,8 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1296
1593
|
runtimeBinding: updateAdmissionRuntimeBinding,
|
|
1297
1594
|
acquireSourceReference(role, binding) {
|
|
1298
1595
|
return telegramJournalReferenceRegistry.acquire({
|
|
1299
|
-
referenceClass:
|
|
1596
|
+
referenceClass:
|
|
1597
|
+
role === "leader" ? "leader-lifecycle" : "follower-lifecycle",
|
|
1300
1598
|
recoveryKey: binding.recoveryKey,
|
|
1301
1599
|
});
|
|
1302
1600
|
},
|
|
@@ -1317,28 +1615,46 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1317
1615
|
},
|
|
1318
1616
|
worker: {
|
|
1319
1617
|
expireRoutingInput: inboundRouteRuntime.expireRoutingInput,
|
|
1320
|
-
beforeQueueReceiptPublished:
|
|
1618
|
+
beforeQueueReceiptPublished:
|
|
1619
|
+
inboundRouteRuntime.beforeQueueReceiptPublished,
|
|
1321
1620
|
onQueueReceiptCompleted: inboundRouteRuntime.onQueueReceiptCompleted,
|
|
1322
1621
|
defaultHandle: inboundRouteRuntime.handleUpdate,
|
|
1323
1622
|
async shouldReviewHistoricalInput(entry, ctx, signal) {
|
|
1324
1623
|
if (signal.aborted || !telegramSessionContextStore.isCurrent(ctx)) {
|
|
1325
1624
|
throw new Error("Workspace Restore source generation ended.");
|
|
1326
1625
|
}
|
|
1327
|
-
const verdict = await inboundRouteRuntime.shouldReviewHistoricalInput(
|
|
1626
|
+
const verdict = await inboundRouteRuntime.shouldReviewHistoricalInput(
|
|
1627
|
+
entry,
|
|
1628
|
+
ctx,
|
|
1629
|
+
signal,
|
|
1630
|
+
);
|
|
1328
1631
|
if (signal.aborted || !telegramSessionContextStore.isCurrent(ctx)) {
|
|
1329
1632
|
throw new Error("Workspace Restore source generation ended.");
|
|
1330
1633
|
}
|
|
1331
1634
|
if (verdict === "retain") return verdict;
|
|
1332
1635
|
const journalBindingKey = getTelegramQueueJournalBinding();
|
|
1333
|
-
if (
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1636
|
+
if (
|
|
1637
|
+
journalBindingKey &&
|
|
1638
|
+
resolveWorkspaceRestoreStore()
|
|
1639
|
+
?.list()
|
|
1640
|
+
.some(function (intent) {
|
|
1641
|
+
return (
|
|
1642
|
+
intent.request.source.journalBindingKey === journalBindingKey &&
|
|
1643
|
+
intent.request.source.updateIds.includes(entry.updateId)
|
|
1644
|
+
);
|
|
1645
|
+
})
|
|
1646
|
+
)
|
|
1647
|
+
return true;
|
|
1337
1648
|
return verdict;
|
|
1338
1649
|
},
|
|
1339
1650
|
spendHistoricalInput: true,
|
|
1340
1651
|
onHeldSourcesPrepared(input): Promise<void> {
|
|
1341
|
-
return inboundRouteRuntime
|
|
1652
|
+
return inboundRouteRuntime
|
|
1653
|
+
.forgetPreviousWorld(
|
|
1654
|
+
input,
|
|
1655
|
+
lockedPollingRuntime.captureTransportAuthority,
|
|
1656
|
+
)
|
|
1657
|
+
.then(function () {});
|
|
1342
1658
|
},
|
|
1343
1659
|
async shouldHoldPendingInput(entry, ctx, signal) {
|
|
1344
1660
|
if (signal.aborted || !telegramSessionContextStore.isCurrent(ctx)) {
|
|
@@ -1363,9 +1679,11 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1363
1679
|
isRegistered: telegramBusFollowerRegistrationState.isRegistered,
|
|
1364
1680
|
getGeneration: telegramBusFollowerRegistrationState.getGeneration,
|
|
1365
1681
|
prepareBinding(binding) {
|
|
1366
|
-
telegramJournalBindingRuntime.prepareActiveFollowerSuccession(
|
|
1367
|
-
|
|
1368
|
-
|
|
1682
|
+
telegramJournalBindingRuntime.prepareActiveFollowerSuccession(
|
|
1683
|
+
function () {
|
|
1684
|
+
return binding.hasAuthority?.() === true;
|
|
1685
|
+
},
|
|
1686
|
+
);
|
|
1369
1687
|
},
|
|
1370
1688
|
prepareUpdateForExecution(update) {
|
|
1371
1689
|
return BusFollower.prepareTelegramBusFollowerJournaledUpdateForExecution(
|
|
@@ -1446,32 +1764,159 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1446
1764
|
local: agentMessageRuntime,
|
|
1447
1765
|
follower: telegramBusFollowerClients.agentMessages,
|
|
1448
1766
|
});
|
|
1449
|
-
const
|
|
1767
|
+
const followerWorkspaceTargetContextPorts = {
|
|
1768
|
+
isContextCurrent: telegramSessionContextStore.isCurrent,
|
|
1769
|
+
getSessionId: Pi.getExtensionContextSessionId,
|
|
1770
|
+
getCwd: Pi.getExtensionContextCwd,
|
|
1771
|
+
getGeneration: telegramSessionContextStore.getGeneration,
|
|
1772
|
+
getProfileBindingKey() {
|
|
1773
|
+
return workspaceAdmissionRuntime.resolve()?.getProfileKey();
|
|
1774
|
+
},
|
|
1775
|
+
getOperatorUserId: configStore.getAllowedUserId,
|
|
1776
|
+
getLeaderState: lockRuntime.getState,
|
|
1777
|
+
getAuthenticatedSecret: telegramBusFollowerControlState.getActiveAuthSecret,
|
|
1778
|
+
getLeaderProtocol: telegramBusFollowerRegistrationState.getLeaderProtocol,
|
|
1779
|
+
};
|
|
1780
|
+
const followerWorkspaceTargetOwnerPorts = {
|
|
1450
1781
|
instanceId: telegramInstanceId,
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1782
|
+
readRestoreIntent(operationId: string, profileBindingKey: string) {
|
|
1783
|
+
if (
|
|
1784
|
+
profileBindingKey !==
|
|
1785
|
+
workspaceAdmissionRuntime.resolve()?.getProfileKey()
|
|
1786
|
+
)
|
|
1787
|
+
return undefined;
|
|
1788
|
+
return resolveWorkspaceRestoreStore()
|
|
1789
|
+
?.list()
|
|
1790
|
+
.find(function (intent) {
|
|
1791
|
+
return intent.request.operationId === operationId;
|
|
1792
|
+
});
|
|
1793
|
+
},
|
|
1794
|
+
readLiveRebindIntent(operationId: string, profileBindingKey: string) {
|
|
1795
|
+
if (
|
|
1796
|
+
profileBindingKey !==
|
|
1797
|
+
workspaceAdmissionRuntime.resolve()?.getProfileKey()
|
|
1798
|
+
)
|
|
1799
|
+
return undefined;
|
|
1800
|
+
return resolveWorkspaceRestoreStore()
|
|
1801
|
+
?.listLiveRebindings()
|
|
1802
|
+
.find(function (intent) {
|
|
1803
|
+
return intent.request.operationId === operationId;
|
|
1804
|
+
});
|
|
1469
1805
|
},
|
|
1470
1806
|
topicTargetStore: threadStore,
|
|
1471
1807
|
registrationState: telegramBusFollowerRegistrationState,
|
|
1472
1808
|
getWorkspaceAdmission: workspaceAdmissionRuntime.resolve,
|
|
1473
1809
|
recordRuntimeEvent,
|
|
1474
|
-
}
|
|
1810
|
+
};
|
|
1811
|
+
const followerWorkspaceRestore =
|
|
1812
|
+
BusFollower.createTelegramBusFollowerWorkspaceRestoreHandler({
|
|
1813
|
+
...followerWorkspaceTargetOwnerPorts,
|
|
1814
|
+
getContextAuthority:
|
|
1815
|
+
BusFollower.createTelegramBusFollowerRestoreContextGetter(
|
|
1816
|
+
followerWorkspaceTargetContextPorts,
|
|
1817
|
+
),
|
|
1818
|
+
});
|
|
1819
|
+
const followerLiveRebindTarget =
|
|
1820
|
+
BusFollower.createTelegramBusFollowerWorkspaceRestoreHandler({
|
|
1821
|
+
...followerWorkspaceTargetOwnerPorts,
|
|
1822
|
+
getContextAuthority:
|
|
1823
|
+
BusFollower.createTelegramBusFollowerRestoreContextGetter({
|
|
1824
|
+
...followerWorkspaceTargetContextPorts,
|
|
1825
|
+
capability: Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_APPLY,
|
|
1826
|
+
}),
|
|
1827
|
+
});
|
|
1828
|
+
const selectedMenuCaller =
|
|
1829
|
+
BusFollower.createTelegramBusFollowerSelectedMenuCaller({
|
|
1830
|
+
client: {
|
|
1831
|
+
socketPath: getTelegramBusSocketPath,
|
|
1832
|
+
instanceId: telegramInstanceId,
|
|
1833
|
+
createRequestId: telegramBusFollowerClients.createRequestId,
|
|
1834
|
+
getAuthSecret: telegramBusFollowerControlState.getActiveAuthSecret,
|
|
1835
|
+
getRegistrationGeneration:
|
|
1836
|
+
telegramBusFollowerRegistrationState.getGeneration,
|
|
1837
|
+
},
|
|
1838
|
+
protocolIdentity: telegramBusProtocolIdentity,
|
|
1839
|
+
recipient: {
|
|
1840
|
+
getContextAuthority:
|
|
1841
|
+
BusFollower.createTelegramBusFollowerRestoreContextGetter({
|
|
1842
|
+
...followerWorkspaceTargetContextPorts,
|
|
1843
|
+
// Wire recipient identity is the registered profile key, not the admission namespace.
|
|
1844
|
+
getProfileBindingKey: getTelegramManualFollowerProfileKey,
|
|
1845
|
+
capability: Bus.TELEGRAM_BUS_CAPABILITY_SELECTED_MENU_DELIVERY,
|
|
1846
|
+
}),
|
|
1847
|
+
getJournalBindingKey:
|
|
1848
|
+
followerAdmissionLifecycleRuntime.getJournalBindingKey,
|
|
1849
|
+
getProcessIdentity() {
|
|
1850
|
+
return {
|
|
1851
|
+
processId: telegramProcessId,
|
|
1852
|
+
processBirthId: telegramQueueProcessBirthId,
|
|
1853
|
+
};
|
|
1854
|
+
},
|
|
1855
|
+
registrationState: telegramBusFollowerRegistrationState,
|
|
1856
|
+
},
|
|
1857
|
+
});
|
|
1858
|
+
const followerLiveRebindRuntime =
|
|
1859
|
+
BusFollower.createTelegramBusFollowerLiveRebindRuntime({
|
|
1860
|
+
getAdmission(ctx: Pi.ExtensionContext) {
|
|
1861
|
+
return telegramSessionContextStore.isCurrent(ctx)
|
|
1862
|
+
? followerAdmissionLifecycleRuntime
|
|
1863
|
+
: undefined;
|
|
1864
|
+
},
|
|
1865
|
+
applyTarget: followerLiveRebindTarget,
|
|
1866
|
+
getCommandOwner(input, ctx) {
|
|
1867
|
+
if (
|
|
1868
|
+
!Bus.hasTelegramBusCapability(
|
|
1869
|
+
telegramBusProtocolIdentity,
|
|
1870
|
+
Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_COMMAND_SET,
|
|
1871
|
+
) ||
|
|
1872
|
+
!Bus.hasTelegramBusCapability(
|
|
1873
|
+
telegramBusProtocolIdentity,
|
|
1874
|
+
Bus.TELEGRAM_BUS_CAPABILITY_SELECTED_MENU_DELIVERY,
|
|
1875
|
+
) ||
|
|
1876
|
+
!input.selectedCommand ||
|
|
1877
|
+
!telegramSessionContextStore.isCurrent(ctx) ||
|
|
1878
|
+
followerAdmissionLifecycleRuntime.getJournalBindingKey() !==
|
|
1879
|
+
input.recipientBindingKey
|
|
1880
|
+
)
|
|
1881
|
+
return undefined;
|
|
1882
|
+
const recipient = followerLiveRebindTarget.prepareLiveCommandRecipient(
|
|
1883
|
+
{
|
|
1884
|
+
operationId: input.operationId,
|
|
1885
|
+
registrationGeneration: input.recipientRegistrationGeneration,
|
|
1886
|
+
sessionId: input.recipientSessionId,
|
|
1887
|
+
sourceUpdateIds: input.updates.map(function sourceUpdateId(update) {
|
|
1888
|
+
return update.update_id;
|
|
1889
|
+
}),
|
|
1890
|
+
target: input.selectedCommand.target,
|
|
1891
|
+
},
|
|
1892
|
+
ctx,
|
|
1893
|
+
);
|
|
1894
|
+
return (
|
|
1895
|
+
recipient &&
|
|
1896
|
+
Bindings.createTelegramFollowerSelectedCommandBinding({
|
|
1897
|
+
ctx,
|
|
1898
|
+
operationId: input.operationId,
|
|
1899
|
+
registrationGeneration: input.recipientRegistrationGeneration,
|
|
1900
|
+
name: input.selectedCommand.name,
|
|
1901
|
+
target: input.selectedCommand.target,
|
|
1902
|
+
recipient,
|
|
1903
|
+
command: inboundRouteRuntime,
|
|
1904
|
+
menu: menuActionPorts,
|
|
1905
|
+
recordOwnership: messageOwnershipRuntime.recordLocal,
|
|
1906
|
+
deliver(effect, assertAuthority) {
|
|
1907
|
+
return selectedMenuCaller({
|
|
1908
|
+
ctx,
|
|
1909
|
+
operationId: input.operationId,
|
|
1910
|
+
registrationGeneration: input.recipientRegistrationGeneration,
|
|
1911
|
+
effect,
|
|
1912
|
+
assertAuthority,
|
|
1913
|
+
});
|
|
1914
|
+
},
|
|
1915
|
+
})
|
|
1916
|
+
);
|
|
1917
|
+
},
|
|
1918
|
+
observeWork: observeLiveTargetWork,
|
|
1919
|
+
});
|
|
1475
1920
|
const telegramBusFollowerAssembly: BusFollower.TelegramBusFollowerRuntimeAssembly<Pi.ExtensionContext> =
|
|
1476
1921
|
BusFollower.createTelegramBusFollowerRuntimeAssembly<Pi.ExtensionContext>({
|
|
1477
1922
|
instanceId: telegramInstanceId,
|
|
@@ -1482,12 +1927,63 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1482
1927
|
getContext: telegramSessionContextStore.get,
|
|
1483
1928
|
getAuthSecret: telegramBusFollowerControlState.getActiveAuthSecret,
|
|
1484
1929
|
getRecipientBindingKey: getTelegramManualFollowerProfileKey,
|
|
1930
|
+
getLiveRebindJournalBindingKey:
|
|
1931
|
+
followerAdmissionLifecycleRuntime.getJournalBindingKey,
|
|
1932
|
+
getSessionId() {
|
|
1933
|
+
return telegramBusFollowerAssembly.getReadySessionId();
|
|
1934
|
+
},
|
|
1935
|
+
getLeaderProtocol:
|
|
1936
|
+
telegramBusFollowerRegistrationState.getLeaderProtocol,
|
|
1937
|
+
getLocalProtocol() {
|
|
1938
|
+
return telegramBusProtocolIdentity;
|
|
1939
|
+
},
|
|
1940
|
+
isLiveRebindSaveEnabled() {
|
|
1941
|
+
return Bus.hasTelegramBusCapability(
|
|
1942
|
+
telegramBusProtocolIdentity,
|
|
1943
|
+
Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_SAVE,
|
|
1944
|
+
);
|
|
1945
|
+
},
|
|
1946
|
+
isLiveRebindApplyEnabled() {
|
|
1947
|
+
return Bus.hasTelegramBusCapability(
|
|
1948
|
+
telegramBusProtocolIdentity,
|
|
1949
|
+
Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_APPLY,
|
|
1950
|
+
);
|
|
1951
|
+
},
|
|
1952
|
+
isLiveRebindSettleEnabled() {
|
|
1953
|
+
return Bus.hasTelegramBusCapability(
|
|
1954
|
+
telegramBusProtocolIdentity,
|
|
1955
|
+
Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_SETTLE,
|
|
1956
|
+
);
|
|
1957
|
+
},
|
|
1958
|
+
isLiveRebindCommandSetEnabled() {
|
|
1959
|
+
return (
|
|
1960
|
+
Bus.hasTelegramBusCapability(
|
|
1961
|
+
telegramBusProtocolIdentity,
|
|
1962
|
+
Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_COMMAND_SET,
|
|
1963
|
+
) &&
|
|
1964
|
+
Bus.hasTelegramBusCapability(
|
|
1965
|
+
telegramBusProtocolIdentity,
|
|
1966
|
+
Bus.TELEGRAM_BUS_CAPABILITY_SELECTED_MENU_DELIVERY,
|
|
1967
|
+
)
|
|
1968
|
+
);
|
|
1969
|
+
},
|
|
1970
|
+
handleLiveRebindSave: followerLiveRebindRuntime.save,
|
|
1971
|
+
handleLiveRebindApply: followerLiveRebindRuntime.apply,
|
|
1972
|
+
handleLiveRebindSettle: followerLiveRebindRuntime.settle,
|
|
1485
1973
|
durableAdmission: followerDurableAdmissionRuntime,
|
|
1486
1974
|
handleQueueHandoff: acceptStagedQueueHandoff,
|
|
1487
1975
|
handleWorkspaceRestore: followerWorkspaceRestore,
|
|
1488
1976
|
isWorkspaceRestoreEnabled() {
|
|
1489
|
-
return
|
|
1490
|
-
Bus.hasTelegramBusCapability(
|
|
1977
|
+
return (
|
|
1978
|
+
Bus.hasTelegramBusCapability(
|
|
1979
|
+
telegramBusProtocolIdentity,
|
|
1980
|
+
Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE,
|
|
1981
|
+
) &&
|
|
1982
|
+
Bus.hasTelegramBusCapability(
|
|
1983
|
+
telegramBusFollowerRegistrationState.getLeaderProtocol(),
|
|
1984
|
+
Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE,
|
|
1985
|
+
)
|
|
1986
|
+
);
|
|
1491
1987
|
},
|
|
1492
1988
|
},
|
|
1493
1989
|
recovery: {
|
|
@@ -1530,7 +2026,9 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1530
2026
|
>({
|
|
1531
2027
|
state: pollingControllerState,
|
|
1532
2028
|
canStart(ctx) {
|
|
1533
|
-
return
|
|
2029
|
+
return (
|
|
2030
|
+
telegramSessionContextStore.isCurrent(ctx) && lockRuntime.owns(ctx)
|
|
2031
|
+
);
|
|
1534
2032
|
},
|
|
1535
2033
|
onPersistentConflict(ctx, count): Promise<void> {
|
|
1536
2034
|
return lockedPollingRuntime.onPersistentConflict(ctx, count);
|
|
@@ -1553,7 +2051,9 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1553
2051
|
registry: telegramJournalReferenceRegistry,
|
|
1554
2052
|
resolveBinding: resolveTelegramUpdateJournalBinding,
|
|
1555
2053
|
referenceClass: "polling-cursor",
|
|
1556
|
-
operation(binding) {
|
|
2054
|
+
operation(binding) {
|
|
2055
|
+
return binding.journal.read().acceptedThroughUpdateId;
|
|
2056
|
+
},
|
|
1557
2057
|
});
|
|
1558
2058
|
},
|
|
1559
2059
|
async prepareCursorCutover() {
|
|
@@ -1561,30 +2061,37 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1561
2061
|
registry: telegramJournalReferenceRegistry,
|
|
1562
2062
|
resolveBinding: resolveTelegramUpdateJournalBinding,
|
|
1563
2063
|
referenceClass: "polling-cursor",
|
|
1564
|
-
operation(binding) {
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
2064
|
+
operation(binding) {
|
|
2065
|
+
return Polling.cutOverTelegramPollingCursor({
|
|
2066
|
+
getLegacyCursor: configStore.getLegacyPollingCursor,
|
|
2067
|
+
readJournal: binding.journal.read,
|
|
2068
|
+
publishJournalCursor(acceptedThroughUpdateId) {
|
|
2069
|
+
binding.journal.appendBatch([], acceptedThroughUpdateId);
|
|
2070
|
+
},
|
|
2071
|
+
async removeLegacyCursor() {
|
|
2072
|
+
configStore.removeLegacyPollingCursor();
|
|
2073
|
+
await persistTelegramConfigWithSync();
|
|
2074
|
+
},
|
|
2075
|
+
});
|
|
2076
|
+
},
|
|
1575
2077
|
});
|
|
1576
|
-
if (!cutover)
|
|
2078
|
+
if (!cutover)
|
|
2079
|
+
throw new Error("Telegram update journal binding is unavailable.");
|
|
1577
2080
|
await cutover;
|
|
1578
2081
|
},
|
|
1579
2082
|
getEntryCount: updateAdmissionLifecycleRuntime.getJournalEntryCount,
|
|
1580
2083
|
signalWorker: updateAdmissionLifecycleRuntime.signal,
|
|
1581
2084
|
getBootstrapEntryCount() {
|
|
1582
|
-
return
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
2085
|
+
return (
|
|
2086
|
+
Journal.withTelegramResolvedUpdateJournalReference({
|
|
2087
|
+
registry: telegramJournalReferenceRegistry,
|
|
2088
|
+
resolveBinding: resolveTelegramUpdateJournalBinding,
|
|
2089
|
+
referenceClass: "polling-bootstrap",
|
|
2090
|
+
operation(binding) {
|
|
2091
|
+
return binding.journal.read().entries.length;
|
|
2092
|
+
},
|
|
2093
|
+
}) ?? 0
|
|
2094
|
+
);
|
|
1588
2095
|
},
|
|
1589
2096
|
onSessionStart: updateAdmissionLifecycleRuntime.onSessionStart,
|
|
1590
2097
|
},
|
|
@@ -1596,17 +2103,67 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1596
2103
|
const authorizeFollowerApiCall = Bus.createTelegramFollowerApiCallAuthorizer({
|
|
1597
2104
|
isMessageOwned: messageOwnershipRuntime.isOwnedByFollower,
|
|
1598
2105
|
});
|
|
1599
|
-
const
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
2106
|
+
const selectedMenuDelivery =
|
|
2107
|
+
BusLeader.createTelegramBusSelectedMenuDeliveryHandler({
|
|
2108
|
+
followerRegistry: telegramBusFollowerRegistry,
|
|
2109
|
+
protocolIdentity: telegramBusProtocolIdentity,
|
|
2110
|
+
workspace: {
|
|
2111
|
+
getScopeKey() {
|
|
2112
|
+
return workspaceAdmissionRuntime.resolve()?.getProfileKey();
|
|
2113
|
+
},
|
|
2114
|
+
captureAuthority() {
|
|
2115
|
+
const isCurrent = captureTelegramStateAuthority(),
|
|
2116
|
+
epoch = lockRuntime.getOwnedLeaderEpoch(),
|
|
2117
|
+
operatorUserId = configStore.getAllowedUserId();
|
|
2118
|
+
return isCurrent &&
|
|
2119
|
+
epoch !== undefined &&
|
|
2120
|
+
operatorUserId !== undefined
|
|
2121
|
+
? {
|
|
2122
|
+
executor: {
|
|
2123
|
+
instanceId: telegramInstanceId,
|
|
2124
|
+
leaderEpoch: String(epoch),
|
|
2125
|
+
},
|
|
2126
|
+
operatorUserId,
|
|
2127
|
+
isCurrent,
|
|
2128
|
+
}
|
|
2129
|
+
: undefined;
|
|
2130
|
+
},
|
|
2131
|
+
getStore: resolveWorkspaceRestoreStore,
|
|
2132
|
+
threadStore,
|
|
2133
|
+
getJournalBindingKey: liveFollowerPorts.getJournalBindingKey,
|
|
2134
|
+
run: telegramWorkspaceOperationRuntime.run,
|
|
2135
|
+
},
|
|
2136
|
+
api: {
|
|
2137
|
+
runtime: directTelegramApiRuntime,
|
|
2138
|
+
authorize: authorizeFollowerApiCall,
|
|
2139
|
+
record(record, assertCurrent) {
|
|
2140
|
+
assertCurrent();
|
|
2141
|
+
messageOwnershipRuntime.recordFollower(record);
|
|
2142
|
+
assertCurrent();
|
|
2143
|
+
return messageOwnershipRuntime.isOwnedByFollower(record);
|
|
2144
|
+
},
|
|
2145
|
+
},
|
|
2146
|
+
});
|
|
2147
|
+
const telegramSessionFolderSweeper =
|
|
2148
|
+
Recovery.createTelegramSessionFolderSweeper({
|
|
2149
|
+
getSessionsDir: Paths.resolveTelegramSessionsDir,
|
|
2150
|
+
getProfileName: configStore.getActiveProfileName,
|
|
2151
|
+
getKeptSessionIds() {
|
|
2152
|
+
return [
|
|
2153
|
+
...threadStore
|
|
2154
|
+
.listWorkspaceBindings()
|
|
2155
|
+
.map(function bindingSession(binding) {
|
|
2156
|
+
return binding.sessionId;
|
|
2157
|
+
}),
|
|
2158
|
+
...telegramBusFollowerRegistry
|
|
2159
|
+
.list()
|
|
2160
|
+
.map(function followerSession(follower) {
|
|
2161
|
+
return follower.sessionId;
|
|
2162
|
+
}),
|
|
2163
|
+
Pi.getExtensionContextSessionId(telegramSessionContextStore.get()),
|
|
2164
|
+
];
|
|
2165
|
+
},
|
|
2166
|
+
});
|
|
1610
2167
|
const telegramBusLeaderRuntime =
|
|
1611
2168
|
BusLeader.createTelegramBusLeaderRuntimeAssembly<Pi.ExtensionContext>({
|
|
1612
2169
|
runtime: {
|
|
@@ -1617,6 +2174,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1617
2174
|
followerRegistry: telegramBusFollowerRegistry,
|
|
1618
2175
|
authSecret: telegramBusAuthSecret,
|
|
1619
2176
|
protocolIdentity: telegramBusProtocolIdentity,
|
|
2177
|
+
selectedMenuDelivery,
|
|
1620
2178
|
startPolling: pollingAdmissionRuntime.start,
|
|
1621
2179
|
stopPolling: pollingAdmissionRuntime.stop,
|
|
1622
2180
|
authorizeFollowerApiCall,
|
|
@@ -1630,15 +2188,21 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1630
2188
|
message,
|
|
1631
2189
|
});
|
|
1632
2190
|
},
|
|
1633
|
-
isFollowerProcessAlive:
|
|
1634
|
-
afterFollowerPrune() {
|
|
2191
|
+
isFollowerProcessAlive: ProcessIdentity.isProcessAlive,
|
|
2192
|
+
afterFollowerPrune() {
|
|
2193
|
+
telegramSessionFolderSweeper.sweep();
|
|
2194
|
+
},
|
|
1635
2195
|
shouldCleanupConfirmedDeadFollower:
|
|
1636
2196
|
configControls.resolveAutomaticThreadCleanupEnabled,
|
|
1637
2197
|
recordFollowerMessageOwnership(record) {
|
|
1638
2198
|
messageOwnershipRuntime.recordFollower(record);
|
|
1639
2199
|
},
|
|
1640
2200
|
onWorkspaceRestoreRecipientObserved(follower, isCurrent) {
|
|
1641
|
-
return inboundRouteRuntime.onWorkspaceRestoreRecipientObserved(
|
|
2201
|
+
return inboundRouteRuntime.onWorkspaceRestoreRecipientObserved(
|
|
2202
|
+
follower,
|
|
2203
|
+
isCurrent,
|
|
2204
|
+
telegramSessionContextStore.get(),
|
|
2205
|
+
);
|
|
1642
2206
|
},
|
|
1643
2207
|
},
|
|
1644
2208
|
getAllowedUserId: configStore.getAllowedUserId,
|
|
@@ -1650,7 +2214,11 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1650
2214
|
return Config.resolveTelegramThreadDisplayMode(configStore.get());
|
|
1651
2215
|
},
|
|
1652
2216
|
persistThreadDisplayMode(mode, isCurrent) {
|
|
1653
|
-
return Config.setTelegramThreadDisplayMode(
|
|
2217
|
+
return Config.setTelegramThreadDisplayMode(
|
|
2218
|
+
configStore,
|
|
2219
|
+
mode,
|
|
2220
|
+
isCurrent,
|
|
2221
|
+
);
|
|
1654
2222
|
},
|
|
1655
2223
|
onThreadDisplayChanged() {
|
|
1656
2224
|
const ctx = telegramSessionContextStore.get();
|
|
@@ -1670,11 +2238,19 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1670
2238
|
deleteThread: directTelegramApiRuntime.deleteWorkspaceThread,
|
|
1671
2239
|
pruneJournalEvidence: pruneWorkspaceJournalEvidence,
|
|
1672
2240
|
reclaimDeadOwnerQueuedWork(binding, isCurrent) {
|
|
1673
|
-
return telegramWorkspaceOperationRuntime.run(
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
2241
|
+
return telegramWorkspaceOperationRuntime.run(
|
|
2242
|
+
{
|
|
2243
|
+
operationId:
|
|
2244
|
+
WorkspaceAdmission.createTelegramWorkspaceAdmissionOperationId(),
|
|
2245
|
+
operationKind: "workspace.reclaim-dead-owner-queue",
|
|
2246
|
+
scopes: [{ kind: "target", target: binding.target }],
|
|
2247
|
+
},
|
|
2248
|
+
reclaimTelegramWorkspaceDeadOwnerQueue.bind(
|
|
2249
|
+
undefined,
|
|
2250
|
+
binding,
|
|
2251
|
+
isCurrent,
|
|
2252
|
+
),
|
|
2253
|
+
);
|
|
1678
2254
|
},
|
|
1679
2255
|
},
|
|
1680
2256
|
callApi(method, body, options) {
|
|
@@ -1772,10 +2348,19 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1772
2348
|
const lockedPollingRuntime = Locks.createTelegramLockedPollingRuntime({
|
|
1773
2349
|
lock: lockRuntime,
|
|
1774
2350
|
resetDamagedState() {
|
|
1775
|
-
return Locks.resetDamagedTelegramRuntimeState(
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
2351
|
+
return Locks.resetDamagedTelegramRuntimeState(
|
|
2352
|
+
Paths.resolveTelegramStatePath(),
|
|
2353
|
+
function (profile, sections) {
|
|
2354
|
+
Threads.parseTelegramWorkspaceStateSection(
|
|
2355
|
+
sections.workspace,
|
|
2356
|
+
profile,
|
|
2357
|
+
);
|
|
2358
|
+
WorkspaceAdmission.assertTelegramConsolidatedAdmissionSection(
|
|
2359
|
+
sections.admission,
|
|
2360
|
+
profile,
|
|
2361
|
+
);
|
|
2362
|
+
},
|
|
2363
|
+
);
|
|
1779
2364
|
},
|
|
1780
2365
|
transportMonitor: telegramThreadCapabilityMonitor,
|
|
1781
2366
|
hasBotToken: configStore.hasBotToken,
|
|
@@ -1787,8 +2372,7 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1787
2372
|
stopPolling: threadAwarePollingPorts.stopPolling,
|
|
1788
2373
|
registerFollowerWithOwner:
|
|
1789
2374
|
threadAwarePollingPorts.registerFollowerWithOwner,
|
|
1790
|
-
restoreFollowerWithOwner:
|
|
1791
|
-
threadAwarePollingPorts.restoreFollowerWithOwner,
|
|
2375
|
+
restoreFollowerWithOwner: threadAwarePollingPorts.restoreFollowerWithOwner,
|
|
1792
2376
|
stopFollowerRegistration: threadAwarePollingPorts.stopFollowerRegistration,
|
|
1793
2377
|
onTransportAvailabilityChanged() {
|
|
1794
2378
|
modelContextAvailabilityRuntime.reconcile();
|
|
@@ -1814,19 +2398,22 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1814
2398
|
getSyncState: telegramSyncStateRuntime.getState,
|
|
1815
2399
|
setSyncState: telegramSyncStateRuntime.setState,
|
|
1816
2400
|
stopPolling: lockedPollingRuntime.stop,
|
|
2401
|
+
captureStopPolling: lockedPollingRuntime.captureStop,
|
|
1817
2402
|
suspendPolling: lockedPollingRuntime.suspend,
|
|
1818
2403
|
recordRuntimeEvent,
|
|
1819
2404
|
runWorkspaceOperation: telegramWorkspaceOperationRuntime.run,
|
|
1820
2405
|
});
|
|
1821
|
-
const prepareThreadPreservationOnQuit =
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
2406
|
+
const prepareThreadPreservationOnQuit =
|
|
2407
|
+
Sync.createTelegramPreservedLeaderQuitHandler({
|
|
2408
|
+
instanceId: telegramInstanceId,
|
|
2409
|
+
topicTargetStore: threadStore,
|
|
2410
|
+
getCurrentLeaderEpoch,
|
|
2411
|
+
getProfileName: configStore.getActiveProfileName,
|
|
2412
|
+
isPollingSuspended: lockedPollingRuntime.isSuspended,
|
|
2413
|
+
resolveAutomaticThreadCleanupEnabled:
|
|
2414
|
+
configControls.resolveAutomaticThreadCleanupEnabled,
|
|
2415
|
+
runWorkspaceOperation: telegramWorkspaceOperationRuntime.run,
|
|
2416
|
+
});
|
|
1830
2417
|
const connectionIntent = Lifecycle.createTelegramConnectionIntentRuntime();
|
|
1831
2418
|
const connectionLifecycle = Lifecycle.createTelegramConnectionLifecycle({
|
|
1832
2419
|
intent: connectionIntent,
|
|
@@ -1834,12 +2421,17 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1834
2421
|
isCurrent: telegramSessionContextStore.isCurrent,
|
|
1835
2422
|
getProfileName: configStore.getActiveProfileName,
|
|
1836
2423
|
isConnected() {
|
|
1837
|
-
return
|
|
2424
|
+
return (
|
|
2425
|
+
lockRuntime.owns() ||
|
|
2426
|
+
telegramBusFollowerRegistrationState.isRegistered()
|
|
2427
|
+
);
|
|
1838
2428
|
},
|
|
1839
2429
|
async activateProfile(profileName, isCurrent) {
|
|
1840
2430
|
await configStore.load();
|
|
1841
2431
|
if (!isCurrent()) return false;
|
|
1842
|
-
return
|
|
2432
|
+
return (
|
|
2433
|
+
configStore.activateProfile(profileName) && configStore.hasBotToken()
|
|
2434
|
+
);
|
|
1843
2435
|
},
|
|
1844
2436
|
start(ctx) {
|
|
1845
2437
|
return lockedPollingRuntime.start(ctx);
|
|
@@ -1861,7 +2453,9 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1861
2453
|
syncFlags: lifecycle.syncFlags,
|
|
1862
2454
|
bindDeferredDispatchContext: deferredQueueDispatchRuntime.bind,
|
|
1863
2455
|
prepareTempDir() {
|
|
1864
|
-
Recovery.removeTelegramLegacyRecoveryStorage(
|
|
2456
|
+
Recovery.removeTelegramLegacyRecoveryStorage(
|
|
2457
|
+
Paths.resolveTelegramTempDir(),
|
|
2458
|
+
);
|
|
1865
2459
|
return prepareTempDir();
|
|
1866
2460
|
},
|
|
1867
2461
|
updateStatus,
|
|
@@ -1916,101 +2510,203 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
1916
2510
|
|
|
1917
2511
|
// --- Extension API Bindings ---
|
|
1918
2512
|
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
threadName: string,
|
|
1923
|
-
) {
|
|
1924
|
-
try {
|
|
1925
|
-
if (telegramBusFollowerRegistrationState.isRegistered()) {
|
|
1926
|
-
if (typeof expectedTarget.threadId !== "number") {
|
|
1927
|
-
return { ok: false, message: "Telegram Workspace Thread target is unavailable." };
|
|
1928
|
-
}
|
|
1929
|
-
const renamedThreadName =
|
|
1930
|
-
await telegramBusFollowerRegistration.renameThread?.(
|
|
1931
|
-
{ chatId: expectedTarget.chatId, threadId: expectedTarget.threadId },
|
|
1932
|
-
threadName,
|
|
1933
|
-
);
|
|
1934
|
-
if (!renamedThreadName) {
|
|
1935
|
-
return {
|
|
1936
|
-
ok: false,
|
|
1937
|
-
message: "Telegram follower Workspace Thread rename is unavailable.",
|
|
1938
|
-
};
|
|
1939
|
-
}
|
|
1940
|
-
return {
|
|
1941
|
-
ok: true,
|
|
1942
|
-
threadName: renamedThreadName,
|
|
1943
|
-
};
|
|
1944
|
-
}
|
|
1945
|
-
if (!ownsTelegramDirectDelivery()) {
|
|
1946
|
-
return {
|
|
1947
|
-
ok: false,
|
|
1948
|
-
message: "Telegram Workspace Thread rename requires an active leader or follower connection.",
|
|
1949
|
-
};
|
|
1950
|
-
}
|
|
1951
|
-
if (typeof expectedTarget.threadId !== "number") {
|
|
1952
|
-
return { ok: false, message: "Telegram Workspace Thread target is unavailable." };
|
|
1953
|
-
}
|
|
1954
|
-
const renamed = await telegramBusLeaderRuntime.renameLeaderThreadAdmitted(
|
|
1955
|
-
threadName,
|
|
1956
|
-
{ chatId: expectedTarget.chatId, threadId: expectedTarget.threadId },
|
|
1957
|
-
);
|
|
1958
|
-
telegramBusLeaderState.set({
|
|
1959
|
-
target: renamed.target,
|
|
1960
|
-
slot: renamed.slot,
|
|
1961
|
-
threadName: renamed.manualThreadName ?? renamed.threadName,
|
|
1962
|
-
});
|
|
2513
|
+
const threadNameRecipientAuthority = {
|
|
2514
|
+
getAuthority(): Threads.TelegramWorkspaceThreadRenameAuthority {
|
|
2515
|
+
const ctx = telegramSessionContextStore.get();
|
|
1963
2516
|
return {
|
|
1964
|
-
|
|
1965
|
-
|
|
2517
|
+
context: ctx,
|
|
2518
|
+
sessionId: Pi.getExtensionContextSessionId(ctx),
|
|
2519
|
+
sessionGeneration: telegramSessionContextStore.getGeneration(),
|
|
2520
|
+
cwd: ctx && Pi.getExtensionContextCwd(ctx),
|
|
2521
|
+
profileName: configStore.getActiveProfileName(),
|
|
2522
|
+
botToken: configStore.getBotToken(),
|
|
2523
|
+
operatorUserId: configStore.getAllowedUserId(),
|
|
2524
|
+
leaderEpoch: getCurrentLeaderEpoch(),
|
|
2525
|
+
ownsDirectDelivery: ownsTelegramDirectDelivery(),
|
|
2526
|
+
followerRegistered: telegramBusFollowerRegistrationState.isRegistered(),
|
|
2527
|
+
localTarget: telegramBusLeaderState.getTarget(),
|
|
2528
|
+
localSlot: telegramBusLeaderState.getIdentity()?.slot,
|
|
1966
2529
|
};
|
|
1967
|
-
} catch (error) {
|
|
1968
|
-
return {
|
|
1969
|
-
ok: false,
|
|
1970
|
-
message:
|
|
1971
|
-
error instanceof Error
|
|
1972
|
-
? error.message
|
|
1973
|
-
: "Telegram Workspace Thread rename failed.",
|
|
1974
|
-
};
|
|
1975
|
-
}
|
|
1976
2530
|
},
|
|
1977
|
-
}
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
2531
|
+
};
|
|
2532
|
+
telegramThreadDisplayNameRenameBinding.bind(
|
|
2533
|
+
{
|
|
2534
|
+
async rename(
|
|
2535
|
+
expectedTarget: Parameters<Commands.TelegramThreadDisplayNameRenamePort>[0],
|
|
2536
|
+
threadName: string,
|
|
2537
|
+
options?: Parameters<Commands.TelegramThreadDisplayNameRenamePort>[2],
|
|
2538
|
+
) {
|
|
2539
|
+
try {
|
|
2540
|
+
const assertCaller = options?.assertAuthority;
|
|
2541
|
+
assertCaller?.();
|
|
2542
|
+
if (telegramBusFollowerRegistrationState.isRegistered()) {
|
|
2543
|
+
if (assertCaller)
|
|
2544
|
+
return {
|
|
2545
|
+
ok: false,
|
|
2546
|
+
message:
|
|
2547
|
+
"Guarded follower Workspace Thread rename is unavailable.",
|
|
2548
|
+
};
|
|
2549
|
+
if (typeof expectedTarget.threadId !== "number") {
|
|
2550
|
+
return {
|
|
2551
|
+
ok: false,
|
|
2552
|
+
message: "Telegram Workspace Thread target is unavailable.",
|
|
2553
|
+
};
|
|
2554
|
+
}
|
|
2555
|
+
const renamedThreadName =
|
|
2556
|
+
await telegramBusFollowerRegistration.renameThread?.(
|
|
2557
|
+
{
|
|
2558
|
+
chatId: expectedTarget.chatId,
|
|
2559
|
+
threadId: expectedTarget.threadId,
|
|
2560
|
+
},
|
|
2561
|
+
threadName,
|
|
2562
|
+
);
|
|
2563
|
+
if (!renamedThreadName) {
|
|
2564
|
+
return {
|
|
2565
|
+
ok: false,
|
|
2566
|
+
message:
|
|
2567
|
+
"Telegram follower Workspace Thread rename is unavailable.",
|
|
2568
|
+
};
|
|
2569
|
+
}
|
|
2570
|
+
return {
|
|
2571
|
+
ok: true,
|
|
2572
|
+
threadName: renamedThreadName,
|
|
2573
|
+
};
|
|
2574
|
+
}
|
|
2575
|
+
if (!ownsTelegramDirectDelivery()) {
|
|
2576
|
+
return {
|
|
2577
|
+
ok: false,
|
|
2578
|
+
message:
|
|
2579
|
+
"Telegram Workspace Thread rename requires an active leader or follower connection.",
|
|
2580
|
+
};
|
|
2581
|
+
}
|
|
2582
|
+
if (typeof expectedTarget.threadId !== "number") {
|
|
2583
|
+
return {
|
|
2584
|
+
ok: false,
|
|
2585
|
+
message: "Telegram Workspace Thread target is unavailable.",
|
|
2586
|
+
};
|
|
2587
|
+
}
|
|
2588
|
+
const target = {
|
|
2589
|
+
chatId: expectedTarget.chatId,
|
|
2590
|
+
threadId: expectedTarget.threadId,
|
|
2591
|
+
};
|
|
2592
|
+
const recipient = assertCaller
|
|
2593
|
+
? Threads.createTelegramWorkspaceThreadRenameRecipient({
|
|
2594
|
+
store: threadStore,
|
|
2595
|
+
instanceId: telegramInstanceId,
|
|
2596
|
+
target,
|
|
2597
|
+
assertAuthority: assertCaller,
|
|
2598
|
+
getAuthority: threadNameRecipientAuthority.getAuthority,
|
|
2599
|
+
})
|
|
2600
|
+
: undefined;
|
|
2601
|
+
const renamed =
|
|
2602
|
+
await telegramBusLeaderRuntime.renameLeaderThreadAdmitted(
|
|
2603
|
+
threadName,
|
|
2604
|
+
target,
|
|
2605
|
+
recipient?.assertAuthority,
|
|
2606
|
+
);
|
|
2607
|
+
recipient?.assertResult(renamed);
|
|
2608
|
+
telegramBusLeaderState.set({
|
|
2609
|
+
target: renamed.target,
|
|
2610
|
+
slot: renamed.slot,
|
|
2611
|
+
threadName: renamed.manualThreadName ?? renamed.threadName,
|
|
2612
|
+
});
|
|
2613
|
+
recipient?.assertResult(renamed);
|
|
2614
|
+
return {
|
|
2615
|
+
ok: true,
|
|
2616
|
+
threadName: renamed.manualThreadName,
|
|
2617
|
+
};
|
|
2618
|
+
} catch (error) {
|
|
2619
|
+
return {
|
|
2620
|
+
ok: false,
|
|
2621
|
+
message:
|
|
2622
|
+
error instanceof Error
|
|
2623
|
+
? error.message
|
|
2624
|
+
: "Telegram Workspace Thread rename failed.",
|
|
2625
|
+
};
|
|
1996
2626
|
}
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2627
|
+
},
|
|
2628
|
+
}.rename,
|
|
2629
|
+
);
|
|
2630
|
+
telegramThreadDisplayNameResetBinding.bind(
|
|
2631
|
+
{
|
|
2632
|
+
async reset(
|
|
2633
|
+
expectedTarget: Parameters<Commands.TelegramThreadDisplayNameResetPort>[0],
|
|
2634
|
+
options?: Parameters<Commands.TelegramThreadDisplayNameResetPort>[1],
|
|
2635
|
+
) {
|
|
2636
|
+
try {
|
|
2637
|
+
const assertCaller = options?.assertAuthority;
|
|
2638
|
+
assertCaller?.();
|
|
2639
|
+
const wasFollower =
|
|
2640
|
+
telegramBusFollowerRegistrationState.isRegistered();
|
|
2641
|
+
if (wasFollower && assertCaller)
|
|
2642
|
+
return {
|
|
2643
|
+
ok: false,
|
|
2644
|
+
message:
|
|
2645
|
+
"Guarded follower Workspace Thread reset is unavailable.",
|
|
2646
|
+
};
|
|
2647
|
+
if (typeof expectedTarget.threadId !== "number") {
|
|
2648
|
+
return {
|
|
2649
|
+
ok: false,
|
|
2650
|
+
message: "Telegram Workspace Thread target is unavailable.",
|
|
2651
|
+
};
|
|
2652
|
+
}
|
|
2653
|
+
const target = {
|
|
2654
|
+
chatId: expectedTarget.chatId,
|
|
2655
|
+
threadId: expectedTarget.threadId,
|
|
2656
|
+
};
|
|
2657
|
+
const recipient = assertCaller
|
|
2658
|
+
? Threads.createTelegramWorkspaceThreadResetRecipient({
|
|
2659
|
+
store: threadStore,
|
|
2660
|
+
instanceId: telegramInstanceId,
|
|
2661
|
+
target,
|
|
2662
|
+
assertAuthority: assertCaller,
|
|
2663
|
+
getAuthority: threadNameRecipientAuthority.getAuthority,
|
|
2664
|
+
})
|
|
2665
|
+
: undefined;
|
|
2666
|
+
const result = wasFollower
|
|
2667
|
+
? await telegramBusFollowerRegistration.resetThreadName?.(target)
|
|
2668
|
+
: (
|
|
2669
|
+
await (recipient
|
|
2670
|
+
? telegramBusLeaderRuntime.resetLeaderThreadName(
|
|
2671
|
+
target,
|
|
2672
|
+
recipient.assertAuthority,
|
|
2673
|
+
)
|
|
2674
|
+
: telegramBusLeaderRuntime.resetLeaderThreadName(target))
|
|
2675
|
+
).threadName;
|
|
2676
|
+
if (!result) {
|
|
2677
|
+
return {
|
|
2678
|
+
ok: false,
|
|
2679
|
+
message: "Thread display name reset is unavailable.",
|
|
2680
|
+
};
|
|
2681
|
+
}
|
|
2682
|
+
recipient?.assertResult(result);
|
|
2683
|
+
const leaderTarget = telegramBusLeaderState.getTarget();
|
|
2684
|
+
if (!wasFollower && leaderTarget) {
|
|
2685
|
+
telegramBusLeaderState.set({
|
|
2686
|
+
target: leaderTarget,
|
|
2687
|
+
threadName: result,
|
|
2688
|
+
...(recipient
|
|
2689
|
+
? { slot: telegramBusLeaderState.getIdentity()?.slot }
|
|
2690
|
+
: {}),
|
|
2691
|
+
});
|
|
2692
|
+
}
|
|
2693
|
+
recipient?.assertResult(result);
|
|
2694
|
+
return {
|
|
2695
|
+
ok: true,
|
|
2696
|
+
threadName: result,
|
|
2697
|
+
};
|
|
2698
|
+
} catch (error) {
|
|
2699
|
+
return {
|
|
2700
|
+
ok: false,
|
|
2701
|
+
message:
|
|
2702
|
+
error instanceof Error
|
|
2703
|
+
? error.message
|
|
2704
|
+
: "Thread display name reset failed.",
|
|
2705
|
+
};
|
|
2000
2706
|
}
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
};
|
|
2005
|
-
} catch (error) {
|
|
2006
|
-
return {
|
|
2007
|
-
ok: false,
|
|
2008
|
-
message: error instanceof Error
|
|
2009
|
-
? error.message : "Thread display name reset failed.",
|
|
2010
|
-
};
|
|
2011
|
-
}
|
|
2012
|
-
},
|
|
2013
|
-
}.reset);
|
|
2707
|
+
},
|
|
2708
|
+
}.reset,
|
|
2709
|
+
);
|
|
2014
2710
|
sessionActionsRuntime.register();
|
|
2015
2711
|
Bindings.registerTelegramCommandsAndTools({
|
|
2016
2712
|
pi,
|
|
@@ -2040,27 +2736,42 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
2040
2736
|
sendMarkdownReply,
|
|
2041
2737
|
async sendChannelMarkdownMessage(channel, markdown, options) {
|
|
2042
2738
|
if (!lockRuntime.owns()) {
|
|
2043
|
-
throw new Error(
|
|
2739
|
+
throw new Error(
|
|
2740
|
+
"Telegram channel delivery requires direct leader transport ownership.",
|
|
2741
|
+
);
|
|
2044
2742
|
}
|
|
2045
2743
|
const profileName = configStore.getActiveProfileName() ?? "default";
|
|
2046
2744
|
const botToken = configStore.getBotToken();
|
|
2047
|
-
if (!botToken)
|
|
2048
|
-
|
|
2049
|
-
|
|
2745
|
+
if (!botToken)
|
|
2746
|
+
throw new Error(
|
|
2747
|
+
"Telegram channel delivery requires an active bot token.",
|
|
2748
|
+
);
|
|
2749
|
+
const store = ChannelPosts.openTelegramChannelPostJournalStore({
|
|
2050
2750
|
profileName,
|
|
2051
|
-
|
|
2751
|
+
botToken,
|
|
2052
2752
|
});
|
|
2053
2753
|
const record = await ChannelPosts.publishTelegramChannelPost({
|
|
2054
|
-
store,
|
|
2055
|
-
|
|
2754
|
+
store,
|
|
2755
|
+
operationId: options.operationId,
|
|
2756
|
+
channel: channel as ChannelPosts.TelegramChannelPostAddress,
|
|
2757
|
+
markdown,
|
|
2056
2758
|
async observeChannel(channelAddress) {
|
|
2057
|
-
return telegramApiRuntime.call("getChat", {
|
|
2759
|
+
return telegramApiRuntime.call("getChat", {
|
|
2760
|
+
chat_id: channelAddress,
|
|
2761
|
+
});
|
|
2058
2762
|
},
|
|
2059
2763
|
async send(channelAddress, body) {
|
|
2060
|
-
const sent = await telegramApiRuntime.call<
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2764
|
+
const sent = await telegramApiRuntime.call<
|
|
2765
|
+
TelegramApi.TelegramSentMessage & {
|
|
2766
|
+
chat: { id: number; type: string };
|
|
2767
|
+
}
|
|
2768
|
+
>("sendRichMessage", {
|
|
2769
|
+
chat_id: channelAddress,
|
|
2770
|
+
rich_message: { markdown: body },
|
|
2771
|
+
...(options.replyMarkup
|
|
2772
|
+
? { reply_markup: options.replyMarkup }
|
|
2773
|
+
: {}),
|
|
2774
|
+
});
|
|
2064
2775
|
return { messageId: sent.message_id, chat: sent.chat };
|
|
2065
2776
|
},
|
|
2066
2777
|
});
|
|
@@ -2068,34 +2779,54 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
2068
2779
|
},
|
|
2069
2780
|
async sendChannelMediaMessage(channel, mediaPath, markdown, options) {
|
|
2070
2781
|
if (!lockRuntime.owns()) {
|
|
2071
|
-
throw new Error(
|
|
2782
|
+
throw new Error(
|
|
2783
|
+
"Telegram channel media delivery requires direct leader transport ownership.",
|
|
2784
|
+
);
|
|
2072
2785
|
}
|
|
2073
2786
|
const profileName = configStore.getActiveProfileName() ?? "default";
|
|
2074
2787
|
const botToken = configStore.getBotToken();
|
|
2075
|
-
if (!botToken)
|
|
2076
|
-
|
|
2788
|
+
if (!botToken)
|
|
2789
|
+
throw new Error(
|
|
2790
|
+
"Telegram channel media delivery requires an active bot token.",
|
|
2791
|
+
);
|
|
2792
|
+
const media =
|
|
2793
|
+
await ChannelPosts.inspectTelegramChannelPostMedia(mediaPath);
|
|
2077
2794
|
const caption = Replies.renderTelegramMarkdownToHtmlDraft(markdown);
|
|
2078
2795
|
ChannelPosts.assertTelegramChannelPostCaptionWithinLimit(caption);
|
|
2079
|
-
const store = ChannelPosts.
|
|
2080
|
-
...Paths.resolveTelegramServiceJournalStorage("channel-posts", undefined, profileName),
|
|
2796
|
+
const store = ChannelPosts.openTelegramChannelPostJournalStore({
|
|
2081
2797
|
profileName,
|
|
2082
|
-
|
|
2798
|
+
botToken,
|
|
2083
2799
|
});
|
|
2084
2800
|
const record = await ChannelPosts.publishTelegramChannelPost({
|
|
2085
|
-
store,
|
|
2086
|
-
|
|
2801
|
+
store,
|
|
2802
|
+
operationId: options.operationId,
|
|
2803
|
+
channel: channel as ChannelPosts.TelegramChannelPostAddress,
|
|
2804
|
+
markdown,
|
|
2805
|
+
media,
|
|
2087
2806
|
async observeChannel(channelAddress) {
|
|
2088
|
-
return telegramApiRuntime.call("getChat", {
|
|
2807
|
+
return telegramApiRuntime.call("getChat", {
|
|
2808
|
+
chat_id: channelAddress,
|
|
2809
|
+
});
|
|
2089
2810
|
},
|
|
2090
2811
|
async send(channelAddress) {
|
|
2091
|
-
const sent = await telegramApiRuntime.callMultipart<
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2812
|
+
const sent = await telegramApiRuntime.callMultipart<
|
|
2813
|
+
TelegramApi.TelegramSentMessage & {
|
|
2814
|
+
chat: { id: number; type: string };
|
|
2815
|
+
}
|
|
2816
|
+
>(
|
|
2817
|
+
media.kind === "photo" ? "sendPhoto" : "sendVideo",
|
|
2818
|
+
{
|
|
2819
|
+
chat_id: String(channelAddress),
|
|
2820
|
+
caption,
|
|
2821
|
+
parse_mode: "HTML",
|
|
2822
|
+
...(options.replyMarkup
|
|
2823
|
+
? { reply_markup: JSON.stringify(options.replyMarkup) }
|
|
2824
|
+
: {}),
|
|
2825
|
+
},
|
|
2826
|
+
media.kind === "photo" ? "photo" : "video",
|
|
2827
|
+
mediaPath,
|
|
2828
|
+
media.fileName,
|
|
2829
|
+
);
|
|
2099
2830
|
return { messageId: sent.message_id, chat: sent.chat };
|
|
2100
2831
|
},
|
|
2101
2832
|
});
|
|
@@ -2104,61 +2835,108 @@ export default function (pi: Pi.ExtensionAPI) {
|
|
|
2104
2835
|
listChannelPosts(input) {
|
|
2105
2836
|
const profileName = configStore.getActiveProfileName() ?? "default";
|
|
2106
2837
|
const botToken = configStore.getBotToken();
|
|
2107
|
-
if (!botToken)
|
|
2108
|
-
|
|
2109
|
-
|
|
2838
|
+
if (!botToken)
|
|
2839
|
+
throw new Error("Telegram channel posts require an active bot token.");
|
|
2840
|
+
return ChannelPosts.openTelegramChannelPostJournalStore({
|
|
2110
2841
|
profileName,
|
|
2111
|
-
|
|
2842
|
+
botToken,
|
|
2112
2843
|
}).list(input);
|
|
2113
2844
|
},
|
|
2114
2845
|
async mutateChannelPost(input) {
|
|
2115
|
-
if (!lockRuntime.owns())
|
|
2846
|
+
if (!lockRuntime.owns())
|
|
2847
|
+
throw new Error(
|
|
2848
|
+
"Telegram channel post mutation requires direct leader ownership.",
|
|
2849
|
+
);
|
|
2116
2850
|
const profileName = configStore.getActiveProfileName() ?? "default";
|
|
2117
2851
|
const botToken = configStore.getBotToken();
|
|
2118
|
-
if (!botToken)
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2852
|
+
if (!botToken)
|
|
2853
|
+
throw new Error(
|
|
2854
|
+
"Telegram channel post mutation requires an active bot token.",
|
|
2855
|
+
);
|
|
2856
|
+
const store = ChannelPosts.openTelegramChannelPostJournalStore({
|
|
2857
|
+
profileName,
|
|
2858
|
+
botToken,
|
|
2122
2859
|
});
|
|
2123
2860
|
if (input.action === "edit") {
|
|
2124
|
-
if (!input.markdown)
|
|
2861
|
+
if (!input.markdown)
|
|
2862
|
+
throw new Error("Telegram channel post edit requires markdown.");
|
|
2125
2863
|
const current = store.get(input.operationId);
|
|
2126
2864
|
const caption = current?.media
|
|
2127
|
-
? Replies.renderTelegramMarkdownToHtmlDraft(input.markdown)
|
|
2865
|
+
? Replies.renderTelegramMarkdownToHtmlDraft(input.markdown)
|
|
2866
|
+
: undefined;
|
|
2128
2867
|
if (caption !== undefined) {
|
|
2129
2868
|
ChannelPosts.assertTelegramChannelPostCaptionWithinLimit(caption);
|
|
2130
2869
|
}
|
|
2131
|
-
const begun = store.beginEdit({
|
|
2132
|
-
|
|
2870
|
+
const begun = store.beginEdit({
|
|
2871
|
+
operationId: input.operationId,
|
|
2872
|
+
mutationId: input.mutationId,
|
|
2873
|
+
markdown: input.markdown,
|
|
2874
|
+
});
|
|
2133
2875
|
if (!begun.began) {
|
|
2134
|
-
if (
|
|
2876
|
+
if (
|
|
2877
|
+
begun.record.state === "published" &&
|
|
2878
|
+
begun.record.lastMutationId === input.mutationId
|
|
2879
|
+
)
|
|
2135
2880
|
return begun.record;
|
|
2136
|
-
throw new Error(
|
|
2881
|
+
throw new Error(
|
|
2882
|
+
"Telegram channel post edit outcome is unknown; refusing automatic replay.",
|
|
2883
|
+
);
|
|
2137
2884
|
}
|
|
2138
|
-
if (begun.record.state !== "edit-outcome-unknown")
|
|
2885
|
+
if (begun.record.state !== "edit-outcome-unknown")
|
|
2886
|
+
throw new Error("Telegram channel post edit authority is invalid.");
|
|
2139
2887
|
if (begun.record.media) {
|
|
2140
2888
|
if (caption === undefined) {
|
|
2141
|
-
throw new Error(
|
|
2889
|
+
throw new Error(
|
|
2890
|
+
"Telegram channel post media caption edit requires retained media identity.",
|
|
2891
|
+
);
|
|
2142
2892
|
}
|
|
2143
|
-
await telegramApiRuntime.call("editMessageCaption", {
|
|
2144
|
-
|
|
2893
|
+
await telegramApiRuntime.call("editMessageCaption", {
|
|
2894
|
+
chat_id: begun.record.channelId,
|
|
2895
|
+
message_id: begun.record.messageId,
|
|
2896
|
+
caption,
|
|
2897
|
+
parse_mode: "HTML",
|
|
2898
|
+
});
|
|
2145
2899
|
} else {
|
|
2146
|
-
await telegramApiRuntime.call("editMessageText", {
|
|
2900
|
+
await telegramApiRuntime.call("editMessageText", {
|
|
2901
|
+
chat_id: begun.record.channelId,
|
|
2147
2902
|
message_id: begun.record.messageId,
|
|
2148
|
-
text: Replies.renderTelegramMarkdownToHtmlDraft(input.markdown),
|
|
2903
|
+
text: Replies.renderTelegramMarkdownToHtmlDraft(input.markdown),
|
|
2904
|
+
parse_mode: "HTML",
|
|
2905
|
+
});
|
|
2149
2906
|
}
|
|
2150
|
-
return store.confirmEdited({
|
|
2907
|
+
return store.confirmEdited({
|
|
2908
|
+
operationId: input.operationId,
|
|
2909
|
+
mutationId: input.mutationId,
|
|
2910
|
+
}).record;
|
|
2151
2911
|
}
|
|
2152
|
-
if (input.markdown !== undefined)
|
|
2153
|
-
|
|
2912
|
+
if (input.markdown !== undefined)
|
|
2913
|
+
throw new Error(
|
|
2914
|
+
"Telegram channel post deletion does not accept markdown.",
|
|
2915
|
+
);
|
|
2916
|
+
const begun = store.beginDelete({
|
|
2917
|
+
operationId: input.operationId,
|
|
2918
|
+
mutationId: input.mutationId,
|
|
2919
|
+
});
|
|
2154
2920
|
if (!begun.began) {
|
|
2155
|
-
if (
|
|
2156
|
-
|
|
2921
|
+
if (
|
|
2922
|
+
begun.record.state === "deleted" &&
|
|
2923
|
+
begun.record.mutationId === input.mutationId
|
|
2924
|
+
)
|
|
2925
|
+
return begun.record;
|
|
2926
|
+
throw new Error(
|
|
2927
|
+
"Telegram channel post deletion outcome is unknown; refusing automatic replay.",
|
|
2928
|
+
);
|
|
2157
2929
|
}
|
|
2158
|
-
if (begun.record.state !== "delete-outcome-unknown")
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2930
|
+
if (begun.record.state !== "delete-outcome-unknown")
|
|
2931
|
+
throw new Error("Telegram channel post deletion authority is invalid.");
|
|
2932
|
+
await telegramApiRuntime.call("deleteMessage", {
|
|
2933
|
+
chat_id: begun.record.channelId,
|
|
2934
|
+
message_id: begun.record.messageId,
|
|
2935
|
+
});
|
|
2936
|
+
return store.confirmDeleted({
|
|
2937
|
+
operationId: input.operationId,
|
|
2938
|
+
mutationId: input.mutationId,
|
|
2939
|
+
}).record;
|
|
2162
2940
|
},
|
|
2163
2941
|
callMultipart,
|
|
2164
2942
|
getDefaultChatId: proactivePushChatIdGetter,
|