@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
|
@@ -11,7 +11,6 @@ import * as BusLeader from "./bus-leader.js";
|
|
|
11
11
|
import * as BusTransport from "./bus-transport.js";
|
|
12
12
|
import * as Bus from "./bus.js";
|
|
13
13
|
import * as ChannelPosts from "./channel-posts.js";
|
|
14
|
-
import * as ThreadCleanupManager from "./thread-cleanup-manager.js";
|
|
15
14
|
import * as CommandTemplates from "./command-templates.js";
|
|
16
15
|
import * as Commands from "./commands.js";
|
|
17
16
|
import * as Config from "./config.js";
|
|
@@ -32,6 +31,7 @@ import * as Paths from "./paths.js";
|
|
|
32
31
|
import * as Pi from "./pi.js";
|
|
33
32
|
import * as Polling from "./polling.js";
|
|
34
33
|
import * as Preview from "./preview.js";
|
|
34
|
+
import * as ProcessIdentity from "./process-identity.js";
|
|
35
35
|
import * as PromptTemplates from "./prompt-templates.js";
|
|
36
36
|
import * as Prompts from "./prompts.js";
|
|
37
37
|
import * as Queue from "./queue.js";
|
|
@@ -43,12 +43,13 @@ import * as Sections from "./sections.js";
|
|
|
43
43
|
import * as Skills from "./skills.js";
|
|
44
44
|
import * as Status from "./status.js";
|
|
45
45
|
import * as Sync from "./sync.js";
|
|
46
|
+
import * as Targets from "./target.js";
|
|
46
47
|
import * as TelegramApi from "./telegram-api.js";
|
|
47
48
|
import * as TextGroups from "./text-groups.js";
|
|
48
|
-
import * as
|
|
49
|
-
import * as Targets from "./target.js";
|
|
49
|
+
import * as ThreadCleanupManager from "./thread-cleanup-manager.js";
|
|
50
50
|
import * as ThreadDisplay from "./thread-display.js";
|
|
51
51
|
import * as ThreadNaming from "./thread-naming.js";
|
|
52
|
+
import * as ThreadReconciler from "./thread-reconciler.js";
|
|
52
53
|
import * as Threads from "./threads.js";
|
|
53
54
|
import * as TimeInjection from "./time-injection.js";
|
|
54
55
|
import * as Updates from "./updates.js";
|
|
@@ -64,6 +65,11 @@ const telegramBusProtocolIdentity = Bus.createTelegramCurrentBusProtocolIdentity
|
|
|
64
65
|
Bus.TELEGRAM_BUS_CAPABILITY_DIRECTORY_DISPLAY_FORMAT,
|
|
65
66
|
Bus.TELEGRAM_BUS_CAPABILITY_SESSION_REPLACEMENT_INTENT,
|
|
66
67
|
Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE,
|
|
68
|
+
Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_SAVE,
|
|
69
|
+
Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_APPLY,
|
|
70
|
+
Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_SETTLE,
|
|
71
|
+
Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_COMMAND_SET,
|
|
72
|
+
Bus.TELEGRAM_BUS_CAPABILITY_SELECTED_MENU_DELIVERY,
|
|
67
73
|
]);
|
|
68
74
|
// --- Extension Runtime ---
|
|
69
75
|
export default function (pi) {
|
|
@@ -71,7 +77,9 @@ export default function (pi) {
|
|
|
71
77
|
const piRuntime = Pi.createExtensionApiRuntimePorts(pi);
|
|
72
78
|
const { getActiveTools, getCommands, getThinkingLevel, sendUserMessage, registerCommand, setActiveTools, setModel, setThinkingLevel, } = piRuntime;
|
|
73
79
|
const bridgeRuntime = Runtime.createTelegramBridgeRuntime();
|
|
74
|
-
const runtimeDiagnostics = Logging.createTelegramRuntimeDiagnosticsRuntime({
|
|
80
|
+
const runtimeDiagnostics = Logging.createTelegramRuntimeDiagnosticsRuntime({
|
|
81
|
+
sharedFile: true,
|
|
82
|
+
});
|
|
75
83
|
const runtimeEvents = runtimeDiagnostics.events;
|
|
76
84
|
const recordRuntimeEvent = runtimeDiagnostics.recordRuntimeEvent;
|
|
77
85
|
const configStore = Config.createTelegramConfigStore({ recordRuntimeEvent });
|
|
@@ -126,8 +134,12 @@ export default function (pi) {
|
|
|
126
134
|
getBotId: getTelegramBotId,
|
|
127
135
|
});
|
|
128
136
|
const telegramLeaderJournalPath = Locks.createTelegramLeaderJournalPathResolver({
|
|
129
|
-
getNamedJournalPath() {
|
|
130
|
-
|
|
137
|
+
getNamedJournalPath() {
|
|
138
|
+
return lockRuntime.getJournalPath();
|
|
139
|
+
},
|
|
140
|
+
getSessionId() {
|
|
141
|
+
return Pi.getExtensionContextSessionId(telegramSessionContextStore.get());
|
|
142
|
+
},
|
|
131
143
|
getProfileName: configStore.getActiveProfileName,
|
|
132
144
|
});
|
|
133
145
|
const telegramJournalBindingRuntime = Journal.createTelegramUpdateJournalBindingRuntime({
|
|
@@ -175,7 +187,6 @@ export default function (pi) {
|
|
|
175
187
|
const resolveTelegramFollowerJournalBinding = telegramJournalBindingRuntime.resolveFollower;
|
|
176
188
|
const getTelegramQueueJournalBinding = telegramJournalBindingRuntime.getActiveRecoveryKey;
|
|
177
189
|
const isTelegramBusRuntimeEnabled = telegramThreadCapabilityState.isBusRuntimeEnabled;
|
|
178
|
-
Config.bindGlobalTelegramConfigRuntime(configStore);
|
|
179
190
|
const configControls = Config.createTelegramConfigControls(configStore);
|
|
180
191
|
const lockRuntime = Locks.createTelegramLockRuntime({
|
|
181
192
|
key: Locks.createTelegramLockKeyResolver(configStore),
|
|
@@ -184,7 +195,9 @@ export default function (pi) {
|
|
|
184
195
|
busSecret: telegramBusAuthSecret,
|
|
185
196
|
staleHeartbeatMs: Locks.TELEGRAM_BUS_LEADER_STALE_HEARTBEAT_MS,
|
|
186
197
|
legacyLocksPath: Paths.resolveLegacyTelegramOwnersPath(),
|
|
187
|
-
createJournalPath() {
|
|
198
|
+
createJournalPath() {
|
|
199
|
+
return telegramLeaderJournalPath.createJournalPath();
|
|
200
|
+
},
|
|
188
201
|
});
|
|
189
202
|
const telegramSessionContextStore = Lifecycle.createTelegramSessionContextStore({
|
|
190
203
|
getIdentity(ctx) {
|
|
@@ -228,9 +241,9 @@ export default function (pi) {
|
|
|
228
241
|
instanceId: telegramInstanceId,
|
|
229
242
|
isRegisteredFor(target) {
|
|
230
243
|
const registered = telegramBusFollowerRegistrationState.getTarget();
|
|
231
|
-
return telegramBusFollowerRegistrationState.isRegistered() &&
|
|
244
|
+
return (telegramBusFollowerRegistrationState.isRegistered() &&
|
|
232
245
|
registered?.chatId === target.chatId &&
|
|
233
|
-
registered.threadId === target.threadId;
|
|
246
|
+
registered.threadId === target.threadId);
|
|
234
247
|
},
|
|
235
248
|
async requestSessionReplacement(operation, intent) {
|
|
236
249
|
const request = telegramBusFollowerRegistration.requestSessionReplacement;
|
|
@@ -241,10 +254,14 @@ export default function (pi) {
|
|
|
241
254
|
},
|
|
242
255
|
async sendResult(target, html) {
|
|
243
256
|
const delivery = await Delivery.sendTelegramView({ text: html, parseMode: "html", replyMarkup: { inline_keyboard: [] } }, { scope: { kind: "target", target } });
|
|
244
|
-
return delivery.ok
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
257
|
+
return delivery.ok
|
|
258
|
+
? { ok: true }
|
|
259
|
+
: {
|
|
260
|
+
ok: false,
|
|
261
|
+
retryable: delivery.reason === "runtime-unavailable" ||
|
|
262
|
+
delivery.reason === "target-unavailable" ||
|
|
263
|
+
delivery.reason === "transport-retryable",
|
|
264
|
+
};
|
|
248
265
|
},
|
|
249
266
|
handoffTtlMs: Threads.TELEGRAM_LEADER_SESSION_HANDOFF_TTL_MS,
|
|
250
267
|
recordRuntimeEvent,
|
|
@@ -302,13 +319,24 @@ export default function (pi) {
|
|
|
302
319
|
});
|
|
303
320
|
const telegramQueueStore = Queue.createTelegramTransportStampedQueueStore(rawTelegramQueueStore, telegramTransportStampRuntime.getStamp);
|
|
304
321
|
const telegramApiTargetActivityRuntime = TelegramApi.createTelegramApiTargetActivityRuntime();
|
|
305
|
-
|
|
306
|
-
|
|
322
|
+
// Retirement protection and dead-owner reclamation must inspect the same journal sources.
|
|
323
|
+
const workspaceRetirementJournalPorts = {
|
|
307
324
|
getActiveTurnTarget: activeTurnRuntime.getTarget,
|
|
308
325
|
getQueuedItems: telegramQueueStore.getQueuedItems,
|
|
309
326
|
resolveLeaderJournal: resolveTelegramUpdateJournalBinding,
|
|
310
327
|
createFollowerJournalResolver: telegramJournalBindingRuntime.createLegacyRecipientResolver,
|
|
311
328
|
createSessionJournalResolver: telegramJournalBindingRuntime.createRecipientResolver,
|
|
329
|
+
createJournalPathResolver: telegramJournalBindingRuntime.createPathResolver,
|
|
330
|
+
discoverFollowerJournals() {
|
|
331
|
+
return Journal.discoverTelegramRecipientJournalPaths({
|
|
332
|
+
directory: Paths.resolveTelegramTempDir(),
|
|
333
|
+
profileName: configStore.getActiveProfileName(),
|
|
334
|
+
});
|
|
335
|
+
},
|
|
336
|
+
};
|
|
337
|
+
const workspaceProtectionObserver = WorkspaceRetirement.createTelegramWorkspaceProtectionObserver({
|
|
338
|
+
listFollowers: telegramBusFollowerRegistry.list,
|
|
339
|
+
...workspaceRetirementJournalPorts,
|
|
312
340
|
withJournalReference(binding, operation) {
|
|
313
341
|
if (!binding.recoveryKey)
|
|
314
342
|
throw new Error("Telegram workspace journal reference identity is unavailable.");
|
|
@@ -317,13 +345,6 @@ export default function (pi) {
|
|
|
317
345
|
recoveryKey: binding.recoveryKey,
|
|
318
346
|
}, operation);
|
|
319
347
|
},
|
|
320
|
-
discoverFollowerJournals() {
|
|
321
|
-
return Journal.discoverTelegramRecipientJournalPaths({
|
|
322
|
-
directory: Paths.resolveTelegramTempDir(),
|
|
323
|
-
profileName: configStore.getActiveProfileName(),
|
|
324
|
-
});
|
|
325
|
-
},
|
|
326
|
-
createJournalPathResolver: telegramJournalBindingRuntime.createPathResolver,
|
|
327
348
|
inspectJournalNamespace() {
|
|
328
349
|
const botToken = configStore.getBotToken();
|
|
329
350
|
if (!botToken)
|
|
@@ -332,27 +353,40 @@ export default function (pi) {
|
|
|
332
353
|
directory: Paths.resolveTelegramTempDir(),
|
|
333
354
|
profile: configStore.getActiveProfileName() ?? "default",
|
|
334
355
|
pollingPath: telegramLeaderJournalPath.resolve(configStore.getActiveProfileName()),
|
|
335
|
-
botIdentity: Journal.createTelegramUpdateJournalBotIdentity({
|
|
336
|
-
|
|
337
|
-
|
|
356
|
+
botIdentity: Journal.createTelegramUpdateJournalBotIdentity({
|
|
357
|
+
botToken,
|
|
358
|
+
botId: getTelegramBotId(),
|
|
359
|
+
}),
|
|
360
|
+
limits: {
|
|
361
|
+
maxDirectoryEntries: 10_000,
|
|
362
|
+
maxFiles: 4096,
|
|
363
|
+
maxBytes: 64 * 1024 * 1024,
|
|
364
|
+
maxEntries: 10_000,
|
|
365
|
+
maxWork: 100_000,
|
|
366
|
+
},
|
|
338
367
|
});
|
|
339
368
|
},
|
|
340
369
|
getJournalWriterProtection(journalBindingKey) {
|
|
341
370
|
const owner = Threads.getTelegramThreadOwnerFromProfileKey(journalBindingKey);
|
|
342
371
|
if (owner.kind !== "manual-follower")
|
|
343
372
|
return "unknown";
|
|
344
|
-
const liveness =
|
|
373
|
+
const liveness = ProcessIdentity.getTelegramProcessBirthIdentityLiveness(owner.instanceId);
|
|
345
374
|
return liveness === "alive"
|
|
346
375
|
? "protected"
|
|
347
|
-
: liveness === "dead"
|
|
376
|
+
: liveness === "dead"
|
|
377
|
+
? "clear"
|
|
378
|
+
: "unknown";
|
|
348
379
|
},
|
|
349
380
|
getDeliveryAuthorityProtection(binding) {
|
|
350
|
-
const retainedRestore = resolveWorkspaceRestoreStore()
|
|
351
|
-
|
|
381
|
+
const retainedRestore = resolveWorkspaceRestoreStore()
|
|
382
|
+
?.list()
|
|
383
|
+
.some(function (intent) {
|
|
384
|
+
return (intent.request.binding.bindingKey === binding.bindingKey ||
|
|
352
385
|
Targets.areTelegramTargetsEqual(intent.request.binding.target, binding.target) ||
|
|
353
|
-
Targets.areTelegramTargetsEqual(intent.request.target, binding.target);
|
|
386
|
+
Targets.areTelegramTargetsEqual(intent.request.target, binding.target));
|
|
354
387
|
});
|
|
355
|
-
return retainedRestore ||
|
|
388
|
+
return retainedRestore ||
|
|
389
|
+
telegramApiTargetActivityRuntime.hasPendingTarget(binding.target)
|
|
356
390
|
? "protected"
|
|
357
391
|
: "clear";
|
|
358
392
|
},
|
|
@@ -367,18 +401,7 @@ export default function (pi) {
|
|
|
367
401
|
});
|
|
368
402
|
const reclaimTelegramWorkspaceDeadOwnerQueue = WorkspaceRetirement.createTelegramWorkspaceDeadOwnerQueueReclaimer({
|
|
369
403
|
getExternalProtection: captureWorkspaceExternalProtection,
|
|
370
|
-
|
|
371
|
-
getQueuedItems: telegramQueueStore.getQueuedItems,
|
|
372
|
-
resolveLeaderJournal: resolveTelegramUpdateJournalBinding,
|
|
373
|
-
createFollowerJournalResolver: telegramJournalBindingRuntime.createLegacyRecipientResolver,
|
|
374
|
-
createSessionJournalResolver: telegramJournalBindingRuntime.createRecipientResolver,
|
|
375
|
-
discoverFollowerJournals() {
|
|
376
|
-
return Journal.discoverTelegramRecipientJournalPaths({
|
|
377
|
-
directory: Paths.resolveTelegramTempDir(),
|
|
378
|
-
profileName: configStore.getActiveProfileName(),
|
|
379
|
-
});
|
|
380
|
-
},
|
|
381
|
-
createJournalPathResolver: telegramJournalBindingRuntime.createPathResolver,
|
|
404
|
+
...workspaceRetirementJournalPorts,
|
|
382
405
|
withJournalReference(binding, operation) {
|
|
383
406
|
if (!binding.recoveryKey)
|
|
384
407
|
throw new Error("Telegram workspace journal reference identity is unavailable.");
|
|
@@ -395,7 +418,7 @@ export default function (pi) {
|
|
|
395
418
|
sessionGeneration: telegramSessionContextStore.getGeneration(),
|
|
396
419
|
};
|
|
397
420
|
},
|
|
398
|
-
getQueueOwnerLiveness:
|
|
421
|
+
getQueueOwnerLiveness: ProcessIdentity.getTelegramProcessLiveness,
|
|
399
422
|
onMutationError(error) {
|
|
400
423
|
recordRuntimeEvent("Telegram dead-owner queue reclamation was refused.", {
|
|
401
424
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -406,7 +429,9 @@ export default function (pi) {
|
|
|
406
429
|
},
|
|
407
430
|
});
|
|
408
431
|
const inactiveThreadCleanupReviewRuntime = ThreadCleanupManager.createTelegramInactiveThreadCleanupReviewRuntime({
|
|
409
|
-
getProfileName() {
|
|
432
|
+
getProfileName() {
|
|
433
|
+
return configStore.getActiveProfileName() ?? "default";
|
|
434
|
+
},
|
|
410
435
|
listBindings: threadStore.listWorkspaceBindings,
|
|
411
436
|
getProtection: captureWorkspaceExternalProtection,
|
|
412
437
|
listReservations: threadStore.listReservations,
|
|
@@ -420,7 +445,9 @@ export default function (pi) {
|
|
|
420
445
|
return ThreadCleanupManager.createTelegramThreadCleanupWorkStore({
|
|
421
446
|
...Paths.resolveTelegramServiceJournalStorage("thread-cleanup", undefined, profileName),
|
|
422
447
|
profileName,
|
|
423
|
-
tokenSha256: Journal.createTelegramUpdateJournalBotIdentity({
|
|
448
|
+
tokenSha256: Journal.createTelegramUpdateJournalBotIdentity({
|
|
449
|
+
botToken,
|
|
450
|
+
}).tokenSha256,
|
|
424
451
|
});
|
|
425
452
|
},
|
|
426
453
|
runWorkspaceOperation: telegramWorkspaceOperationRuntime.run,
|
|
@@ -484,7 +511,9 @@ export default function (pi) {
|
|
|
484
511
|
registry: telegramJournalReferenceRegistry,
|
|
485
512
|
resolveBinding: resolveTelegramUpdateJournalBinding,
|
|
486
513
|
referenceClass: "polling-cursor",
|
|
487
|
-
operation(binding) {
|
|
514
|
+
operation(binding) {
|
|
515
|
+
return binding.journal.read().acceptedThroughUpdateId;
|
|
516
|
+
},
|
|
488
517
|
});
|
|
489
518
|
},
|
|
490
519
|
getActiveSourceMessageIds: activeTurnRuntime.getSourceMessageIds,
|
|
@@ -534,7 +563,8 @@ export default function (pi) {
|
|
|
534
563
|
getBotToken: configStore.getBotToken,
|
|
535
564
|
getBotScope() {
|
|
536
565
|
const config = configStore.get();
|
|
537
|
-
return config.botUsername ??
|
|
566
|
+
return (config.botUsername ??
|
|
567
|
+
(config.botId === undefined ? undefined : String(config.botId)));
|
|
538
568
|
},
|
|
539
569
|
recordRuntimeEvent,
|
|
540
570
|
targetActivity: telegramApiTargetActivityRuntime,
|
|
@@ -762,15 +792,21 @@ export default function (pi) {
|
|
|
762
792
|
getCommands,
|
|
763
793
|
getReservedCommandNames: Commands.getTelegramReservedCommandNames,
|
|
764
794
|
});
|
|
765
|
-
const
|
|
795
|
+
const getQueueMenuState = Menu.createTelegramModelMenuStateBuilder({
|
|
766
796
|
runtime: modelMenuRuntime,
|
|
767
797
|
createSettingsManager: Pi.createSettingsManager,
|
|
768
798
|
getActiveModel: currentModelRuntime.get,
|
|
799
|
+
});
|
|
800
|
+
const menuActionPorts = {
|
|
801
|
+
getModelMenuState: getQueueMenuState,
|
|
802
|
+
getActiveModel: currentModelRuntime.get,
|
|
769
803
|
getThinkingLevel,
|
|
770
804
|
getQueueItemCount,
|
|
771
805
|
getPendingCancellationCount() {
|
|
772
|
-
return getCurrentLeaderEpoch() === undefined
|
|
773
|
-
|
|
806
|
+
return getCurrentLeaderEpoch() === undefined
|
|
807
|
+
? 0
|
|
808
|
+
: (updateAdmissionRuntimeBinding.getActive()?.getState()
|
|
809
|
+
?.abandoningClaimCount ?? 0);
|
|
774
810
|
},
|
|
775
811
|
buildStatusHtml: Commands.createTelegramAppMenuHtmlBuilder({
|
|
776
812
|
buildStatusHtml: Status.createTelegramStatusHtmlBuilder({
|
|
@@ -783,22 +819,20 @@ export default function (pi) {
|
|
|
783
819
|
storeModelMenuState: modelMenuRuntime.storeState,
|
|
784
820
|
isIdle,
|
|
785
821
|
canOfferInFlightModelSwitch: modelSwitchController.canOfferInFlightSwitch,
|
|
786
|
-
sendTextReply,
|
|
787
|
-
editInteractiveMessage,
|
|
788
|
-
sendInteractiveMessage,
|
|
789
822
|
sectionRegistry,
|
|
790
823
|
// Menu/status UI uses this to reflect whether the active Telegram turn expects voice delivery.
|
|
791
824
|
isVoiceReplyActive: function () {
|
|
792
825
|
const turn = activeTurnRuntime.get();
|
|
793
826
|
return Voice.isVoiceTurn(turn);
|
|
794
827
|
},
|
|
828
|
+
};
|
|
829
|
+
const menuActions = Menu.createTelegramMenuActionRuntime({
|
|
830
|
+
...menuActionPorts,
|
|
831
|
+
sendTextReply,
|
|
832
|
+
editInteractiveMessage,
|
|
833
|
+
sendInteractiveMessage,
|
|
795
834
|
});
|
|
796
835
|
// --- Queue And Settings Menus ---
|
|
797
|
-
const getQueueMenuState = Menu.createTelegramModelMenuStateBuilder({
|
|
798
|
-
runtime: modelMenuRuntime,
|
|
799
|
-
createSettingsManager: Pi.createSettingsManager,
|
|
800
|
-
getActiveModel: currentModelRuntime.get,
|
|
801
|
-
});
|
|
802
836
|
const queueMenuRuntime = MenuQueue.createTelegramQueueMenuRuntime({
|
|
803
837
|
telegramQueueStore,
|
|
804
838
|
queueMutationRuntime,
|
|
@@ -814,20 +848,30 @@ export default function (pi) {
|
|
|
814
848
|
});
|
|
815
849
|
const threadDisplaySettingsRuntime = ThreadDisplay.createTelegramThreadDisplaySettingsRuntime({
|
|
816
850
|
getTarget() {
|
|
817
|
-
return telegramBusFollowerRegistrationState.getTarget() ??
|
|
818
|
-
telegramBusLeaderState.getTarget();
|
|
851
|
+
return (telegramBusFollowerRegistrationState.getTarget() ??
|
|
852
|
+
telegramBusLeaderState.getTarget());
|
|
853
|
+
},
|
|
854
|
+
getBinding(target) {
|
|
855
|
+
return threadStore.getWorkspaceBindingByTarget(target);
|
|
819
856
|
},
|
|
820
|
-
getBinding(target) { return threadStore.getWorkspaceBindingByTarget(target); },
|
|
821
857
|
apply(mode) {
|
|
822
858
|
return ThreadDisplay.applyTelegramThreadDisplaySetting(mode, {
|
|
823
859
|
getProfileKey: configStore.getActiveProfileName,
|
|
824
|
-
ownsLeader() {
|
|
825
|
-
|
|
826
|
-
|
|
860
|
+
ownsLeader() {
|
|
861
|
+
return getCurrentLeaderEpoch() !== undefined;
|
|
862
|
+
},
|
|
863
|
+
getLeaderSetter() {
|
|
864
|
+
return telegramBusLeaderRuntime.setThreadDisplayMode;
|
|
865
|
+
},
|
|
866
|
+
getFollowerSetter() {
|
|
867
|
+
return telegramBusFollowerRegistration.setThreadDisplayMode;
|
|
868
|
+
},
|
|
827
869
|
reloadConfig: configStore.load,
|
|
828
870
|
});
|
|
829
871
|
},
|
|
830
|
-
reset(target) {
|
|
872
|
+
reset(target) {
|
|
873
|
+
return telegramThreadDisplayNameResetBinding.reset(target);
|
|
874
|
+
},
|
|
831
875
|
});
|
|
832
876
|
const settingsMenuRuntime = MenuSettings.createTelegramSettingsMenuRuntime({
|
|
833
877
|
reloadConfig: configStore.load,
|
|
@@ -841,7 +885,8 @@ export default function (pi) {
|
|
|
841
885
|
reviewInactiveThreads: inactiveThreadCleanupReviewRuntime.review,
|
|
842
886
|
getThreadDisplayMode() {
|
|
843
887
|
return threadStore.getBotState().threadMode === "enabled"
|
|
844
|
-
? Config.resolveTelegramThreadDisplayMode(configStore.get())
|
|
888
|
+
? Config.resolveTelegramThreadDisplayMode(configStore.get())
|
|
889
|
+
: undefined;
|
|
845
890
|
},
|
|
846
891
|
isThreadDisplayCustom: threadDisplaySettingsRuntime.isCustom,
|
|
847
892
|
async setThreadDisplayMode(mode) {
|
|
@@ -860,8 +905,42 @@ export default function (pi) {
|
|
|
860
905
|
getFollower: telegramBusFollowerRegistry.get,
|
|
861
906
|
localProtocolIdentity: telegramBusProtocolIdentity,
|
|
862
907
|
createRequestId: telegramBusFollowerClients.createRequestId,
|
|
863
|
-
getAuthSecret() {
|
|
908
|
+
getAuthSecret() {
|
|
909
|
+
return telegramBusAuthSecret;
|
|
910
|
+
},
|
|
864
911
|
});
|
|
912
|
+
const liveRebindFollowerController = Bus.createTelegramBusLiveRebindController({
|
|
913
|
+
getFollower: telegramBusFollowerRegistry.get,
|
|
914
|
+
localProtocolIdentity: telegramBusProtocolIdentity,
|
|
915
|
+
createRequestId: telegramBusFollowerClients.createRequestId,
|
|
916
|
+
getAuthSecret() {
|
|
917
|
+
return telegramBusAuthSecret;
|
|
918
|
+
},
|
|
919
|
+
});
|
|
920
|
+
const liveFollowerPorts = {
|
|
921
|
+
getJournalBindingKey(follower) {
|
|
922
|
+
if (!follower.profileKey || !follower.sessionId)
|
|
923
|
+
return undefined;
|
|
924
|
+
return telegramJournalBindingRuntime.createRecipientResolver(follower.profileKey, follower.sessionId)()?.recoveryKey;
|
|
925
|
+
},
|
|
926
|
+
isSelectedCommandAvailable(follower, name) {
|
|
927
|
+
return (Bus.hasTelegramBusSharedCapabilities(telegramBusProtocolIdentity, follower.protocol, [
|
|
928
|
+
...Bus.TELEGRAM_BUS_LIVE_REBIND_CAPABILITIES,
|
|
929
|
+
...Bus.TELEGRAM_BUS_HELD_COMMAND_CAPABILITIES,
|
|
930
|
+
]) &&
|
|
931
|
+
typeof selectedMenuDelivery === "function" &&
|
|
932
|
+
typeof inboundRouteRuntime.prepareHeldCommand === "function" &&
|
|
933
|
+
typeof inboundRouteRuntime.canPrepareHeldCommand === "function" &&
|
|
934
|
+
inboundRouteRuntime.canPrepareHeldCommand(name, {
|
|
935
|
+
showStatus: menuActions.sendStatusMessage,
|
|
936
|
+
sendTextReply,
|
|
937
|
+
}) &&
|
|
938
|
+
!!captureTelegramStateAuthority() &&
|
|
939
|
+
!!workspaceAdmissionRuntime.resolve() &&
|
|
940
|
+
!!resolveWorkspaceRestoreStore());
|
|
941
|
+
},
|
|
942
|
+
run: liveRebindFollowerController,
|
|
943
|
+
};
|
|
865
944
|
const observedThreadTargetBinding = Polling.createTelegramThreadTargetObservationBinding();
|
|
866
945
|
const topicLifecycleSync = Sync.createTelegramObservedTopicLifecycleSyncHandler({
|
|
867
946
|
topicTargetStore: threadStore,
|
|
@@ -890,6 +969,18 @@ export default function (pi) {
|
|
|
890
969
|
});
|
|
891
970
|
const telegramThreadDisplayNameRenameBinding = Commands.createTelegramThreadDisplayNameRenameBinding();
|
|
892
971
|
const telegramThreadDisplayNameResetBinding = Commands.createTelegramThreadDisplayNameResetBinding();
|
|
972
|
+
const observeLiveTargetWork = Bindings.createTelegramLiveTargetWorkObserver({
|
|
973
|
+
queue: telegramQueueStore,
|
|
974
|
+
activeTurn: activeTurnRuntime,
|
|
975
|
+
lifecycle: bridgeRuntime.lifecycle,
|
|
976
|
+
isIdle,
|
|
977
|
+
hasPendingMessages,
|
|
978
|
+
hasPendingControl: pendingModelSwitchStore.has,
|
|
979
|
+
publication: publicationRuntime,
|
|
980
|
+
activity: activityRuntime,
|
|
981
|
+
delivery: deliveryLifecycleRuntime,
|
|
982
|
+
api: telegramApiTargetActivityRuntime,
|
|
983
|
+
});
|
|
893
984
|
const inboundRouteRuntime = Routing.createTelegramInboundRouteRuntime({
|
|
894
985
|
configStore,
|
|
895
986
|
callApi: callTelegramApi,
|
|
@@ -898,6 +989,7 @@ export default function (pi) {
|
|
|
898
989
|
},
|
|
899
990
|
getAdmissionScope: getTelegramUpdateAdmissionScope,
|
|
900
991
|
getAdmissionJournalBinding: getTelegramQueueJournalBinding,
|
|
992
|
+
beginCommandEffectWork: publicationRuntime.beginWork,
|
|
901
993
|
getMessageOwnership: messageOwnershipRuntime.getForwardOwnership,
|
|
902
994
|
recordMessageOwnership: messageOwnershipRuntime.recordRouted,
|
|
903
995
|
...inboundBusProjectionRuntime,
|
|
@@ -915,24 +1007,40 @@ export default function (pi) {
|
|
|
915
1007
|
getSessionId: Pi.getExtensionContextSessionId,
|
|
916
1008
|
getCwd: Pi.getExtensionContextCwd,
|
|
917
1009
|
getLeaderIdentity: telegramBusLeaderState.getIdentity,
|
|
1010
|
+
observeLeaderWork: observeLiveTargetWork,
|
|
918
1011
|
followerRegistry: telegramBusFollowerRegistry,
|
|
919
1012
|
runFollower: workspaceRestoreFollowerController,
|
|
1013
|
+
liveFollower: liveFollowerPorts,
|
|
920
1014
|
},
|
|
921
1015
|
getWorkspaceRestoreStore: resolveWorkspaceRestoreStore,
|
|
922
1016
|
captureWorkspaceExternalProtection,
|
|
923
1017
|
inspectRestoreSourceCompletion(expected) {
|
|
924
|
-
return telegramJournalReferenceRegistry.withReference({
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
1018
|
+
return telegramJournalReferenceRegistry.withReference({
|
|
1019
|
+
referenceClass: "operator-disposition",
|
|
1020
|
+
recoveryKey: expected.journalBindingKey,
|
|
1021
|
+
}, function () {
|
|
1022
|
+
const observed = telegramJournalBindingRuntime.inspectSourceCompletion(expected.journalBindingKey, {
|
|
1023
|
+
updateId: expected.updateId,
|
|
1024
|
+
sourceSha256: expected.sourceSha256,
|
|
1025
|
+
completionSha256: expected.completionSha256,
|
|
1026
|
+
});
|
|
1027
|
+
return (observed && {
|
|
1028
|
+
journalBindingKey: expected.journalBindingKey,
|
|
1029
|
+
...observed,
|
|
1030
|
+
});
|
|
929
1031
|
});
|
|
930
1032
|
},
|
|
931
1033
|
inspectRestoreQueuedReceipt(expected) {
|
|
932
|
-
return telegramJournalReferenceRegistry.withReference({
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
1034
|
+
return telegramJournalReferenceRegistry.withReference({
|
|
1035
|
+
referenceClass: "operator-disposition",
|
|
1036
|
+
recoveryKey: expected.journalBindingKey,
|
|
1037
|
+
}, function () {
|
|
1038
|
+
return telegramJournalBindingRuntime.inspectQueuedReceipt(expected.journalBindingKey, {
|
|
1039
|
+
queueKind: expected.queueKind,
|
|
1040
|
+
receiptId: expected.receiptId,
|
|
1041
|
+
sourceUpdateIds: [...expected.sourceUpdateIds],
|
|
1042
|
+
queueOwner: { ...expected.queueOwner },
|
|
1043
|
+
});
|
|
936
1044
|
});
|
|
937
1045
|
},
|
|
938
1046
|
inspectRestoreSourceAbandonment(updateId, journalBindingKey) {
|
|
@@ -943,29 +1051,73 @@ export default function (pi) {
|
|
|
943
1051
|
return telegramJournalBindingRuntime.inspectSourceAbandonment(journalBindingKey, updateId);
|
|
944
1052
|
});
|
|
945
1053
|
},
|
|
946
|
-
|
|
1054
|
+
inspectRoutingInputGroupExpiry(input) {
|
|
1055
|
+
return telegramJournalReferenceRegistry.withReference({
|
|
1056
|
+
referenceClass: "operator-disposition",
|
|
1057
|
+
recoveryKey: input.journalBindingKey,
|
|
1058
|
+
}, function () {
|
|
1059
|
+
return telegramJournalBindingRuntime.inspectSourceGroupExpiry(input.journalBindingKey, input.updateIds);
|
|
1060
|
+
});
|
|
1061
|
+
},
|
|
1062
|
+
inspectTemporaryThreadSources(target, requiredJournalBindingKeys, ownInputs) {
|
|
947
1063
|
const binding = resolveTelegramUpdateJournalBinding();
|
|
948
1064
|
const botToken = configStore.getBotToken();
|
|
949
1065
|
if (!binding || !botToken)
|
|
950
1066
|
return undefined;
|
|
951
1067
|
const profile = configStore.getActiveProfileName() ?? "default";
|
|
952
|
-
const botIdentity = Journal.createTelegramUpdateJournalBotIdentity({
|
|
1068
|
+
const botIdentity = Journal.createTelegramUpdateJournalBotIdentity({
|
|
1069
|
+
botToken,
|
|
1070
|
+
botId: getTelegramBotId(),
|
|
1071
|
+
});
|
|
953
1072
|
return configStore.withSourceSerialization(function () {
|
|
954
1073
|
return Journal.isTelegramThreadCleanupJournalNamespaceClear({
|
|
955
|
-
directory: Paths.resolveTelegramTempDir(),
|
|
1074
|
+
directory: Paths.resolveTelegramTempDir(),
|
|
1075
|
+
profile,
|
|
1076
|
+
botIdentity,
|
|
956
1077
|
pollingPath: telegramLeaderJournalPath.resolve(configStore.getActiveProfileName()),
|
|
957
|
-
requiredJournalBindingKeys: [
|
|
958
|
-
|
|
959
|
-
|
|
1078
|
+
requiredJournalBindingKeys: [
|
|
1079
|
+
binding.recoveryKey,
|
|
1080
|
+
...requiredJournalBindingKeys,
|
|
1081
|
+
],
|
|
1082
|
+
...(target.threadId !== undefined && ownInputs
|
|
1083
|
+
? {
|
|
1084
|
+
cleanup: {
|
|
1085
|
+
target: { chatId: target.chatId, threadId: target.threadId },
|
|
1086
|
+
ownInputs,
|
|
1087
|
+
},
|
|
1088
|
+
}
|
|
1089
|
+
: {}),
|
|
1090
|
+
limits: {
|
|
1091
|
+
maxDirectoryEntries: 10_000,
|
|
1092
|
+
maxFiles: 4096,
|
|
1093
|
+
maxBytes: 64 * 1024 * 1024,
|
|
1094
|
+
maxEntries: 10_000,
|
|
1095
|
+
maxWork: 100_000,
|
|
1096
|
+
},
|
|
960
1097
|
withSourceReference(path, operation) {
|
|
961
|
-
return telegramJournalReferenceRegistry.withReference({
|
|
962
|
-
|
|
1098
|
+
return telegramJournalReferenceRegistry.withReference({
|
|
1099
|
+
referenceClass: "operator-disposition",
|
|
1100
|
+
recoveryKey: Journal.createTelegramUpdateJournalBindingKey({
|
|
1101
|
+
path,
|
|
1102
|
+
profileName: profile,
|
|
1103
|
+
botIdentity,
|
|
1104
|
+
}),
|
|
1105
|
+
}, operation);
|
|
963
1106
|
},
|
|
964
|
-
})
|
|
1107
|
+
})
|
|
1108
|
+
? []
|
|
1109
|
+
: undefined;
|
|
965
1110
|
});
|
|
966
1111
|
},
|
|
967
1112
|
hasWorkspaceRestoreAuthority() {
|
|
968
|
-
return lockRuntime.owns() &&
|
|
1113
|
+
return (lockRuntime.owns() &&
|
|
1114
|
+
Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE));
|
|
1115
|
+
},
|
|
1116
|
+
hasWorkspaceLiveRebindAuthority() {
|
|
1117
|
+
return (lockRuntime.owns() &&
|
|
1118
|
+
Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_SAVE) &&
|
|
1119
|
+
Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_APPLY) &&
|
|
1120
|
+
Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_SETTLE));
|
|
969
1121
|
},
|
|
970
1122
|
getSessionGeneration: telegramSessionContextStore.getGeneration,
|
|
971
1123
|
bridgeRuntime,
|
|
@@ -1004,6 +1156,7 @@ export default function (pi) {
|
|
|
1004
1156
|
currentModelRuntime,
|
|
1005
1157
|
modelSwitchController,
|
|
1006
1158
|
menuActions,
|
|
1159
|
+
isVoiceReplyActive: menuActionPorts.isVoiceReplyActive,
|
|
1007
1160
|
updateSettingsMenuMessage: settingsMenuRuntime.updateSettingsMenuMessage,
|
|
1008
1161
|
openQueueMenu: queueMenuRuntime.openQueueMenu,
|
|
1009
1162
|
queueMenuCallbackHandler: queueMenuRuntime.handleCallbackQuery,
|
|
@@ -1016,6 +1169,7 @@ export default function (pi) {
|
|
|
1016
1169
|
inboundHandlerRuntime,
|
|
1017
1170
|
threadStore,
|
|
1018
1171
|
runWorkspaceOperation: telegramWorkspaceOperationRuntime.run,
|
|
1172
|
+
liveRebindCleanupSchedule: Routing.TELEGRAM_LIVE_REBIND_CLEANUP_SCHEDULE,
|
|
1019
1173
|
updateStatus,
|
|
1020
1174
|
isContextActive: telegramSessionContextStore.isCurrent,
|
|
1021
1175
|
dispatchNextQueuedTelegramTurn,
|
|
@@ -1035,6 +1189,22 @@ export default function (pi) {
|
|
|
1035
1189
|
startGuestPlaceholder: guestPlaceholderRuntime.start,
|
|
1036
1190
|
sendTextReply,
|
|
1037
1191
|
setMyCommands,
|
|
1192
|
+
captureThreadNameRecipientAuthority(target, ctx) {
|
|
1193
|
+
// Ordinary follower/classic dialogs keep their unguarded policy; closures are leader-local only.
|
|
1194
|
+
if (telegramBusFollowerRegistrationState.isRegistered() ||
|
|
1195
|
+
target.threadId === undefined)
|
|
1196
|
+
return undefined;
|
|
1197
|
+
return Threads.createTelegramWorkspaceThreadRenameRecipient({
|
|
1198
|
+
store: threadStore,
|
|
1199
|
+
instanceId: telegramInstanceId,
|
|
1200
|
+
target,
|
|
1201
|
+
assertAuthority() {
|
|
1202
|
+
if (telegramSessionContextStore.get() !== ctx)
|
|
1203
|
+
throw new Error("Telegram Thread name dialog lost Pi context.");
|
|
1204
|
+
},
|
|
1205
|
+
getAuthority: threadNameRecipientAuthority.getAuthority,
|
|
1206
|
+
}).assertAuthority;
|
|
1207
|
+
},
|
|
1038
1208
|
validateThreadName(threadName) {
|
|
1039
1209
|
return ThreadNaming.getTelegramManualThreadDisplayNameValidationError(threadName);
|
|
1040
1210
|
},
|
|
@@ -1107,16 +1277,21 @@ export default function (pi) {
|
|
|
1107
1277
|
if (verdict === "retain")
|
|
1108
1278
|
return verdict;
|
|
1109
1279
|
const journalBindingKey = getTelegramQueueJournalBinding();
|
|
1110
|
-
if (journalBindingKey &&
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1280
|
+
if (journalBindingKey &&
|
|
1281
|
+
resolveWorkspaceRestoreStore()
|
|
1282
|
+
?.list()
|
|
1283
|
+
.some(function (intent) {
|
|
1284
|
+
return (intent.request.source.journalBindingKey === journalBindingKey &&
|
|
1285
|
+
intent.request.source.updateIds.includes(entry.updateId));
|
|
1286
|
+
}))
|
|
1114
1287
|
return true;
|
|
1115
1288
|
return verdict;
|
|
1116
1289
|
},
|
|
1117
1290
|
spendHistoricalInput: true,
|
|
1118
1291
|
onHeldSourcesPrepared(input) {
|
|
1119
|
-
return inboundRouteRuntime
|
|
1292
|
+
return inboundRouteRuntime
|
|
1293
|
+
.forgetPreviousWorld(input, lockedPollingRuntime.captureTransportAuthority)
|
|
1294
|
+
.then(function () { });
|
|
1120
1295
|
},
|
|
1121
1296
|
async shouldHoldPendingInput(entry, ctx, signal) {
|
|
1122
1297
|
if (signal.aborted || !telegramSessionContextStore.isCurrent(ctx)) {
|
|
@@ -1138,7 +1313,7 @@ export default function (pi) {
|
|
|
1138
1313
|
isRegistered: telegramBusFollowerRegistrationState.isRegistered,
|
|
1139
1314
|
getGeneration: telegramBusFollowerRegistrationState.getGeneration,
|
|
1140
1315
|
prepareBinding(binding) {
|
|
1141
|
-
telegramJournalBindingRuntime.prepareActiveFollowerSuccession(function
|
|
1316
|
+
telegramJournalBindingRuntime.prepareActiveFollowerSuccession(function () {
|
|
1142
1317
|
return binding.hasAuthority?.() === true;
|
|
1143
1318
|
});
|
|
1144
1319
|
},
|
|
@@ -1211,25 +1386,38 @@ export default function (pi) {
|
|
|
1211
1386
|
local: agentMessageRuntime,
|
|
1212
1387
|
follower: telegramBusFollowerClients.agentMessages,
|
|
1213
1388
|
});
|
|
1214
|
-
const
|
|
1389
|
+
const followerWorkspaceTargetContextPorts = {
|
|
1390
|
+
isContextCurrent: telegramSessionContextStore.isCurrent,
|
|
1391
|
+
getSessionId: Pi.getExtensionContextSessionId,
|
|
1392
|
+
getCwd: Pi.getExtensionContextCwd,
|
|
1393
|
+
getGeneration: telegramSessionContextStore.getGeneration,
|
|
1394
|
+
getProfileBindingKey() {
|
|
1395
|
+
return workspaceAdmissionRuntime.resolve()?.getProfileKey();
|
|
1396
|
+
},
|
|
1397
|
+
getOperatorUserId: configStore.getAllowedUserId,
|
|
1398
|
+
getLeaderState: lockRuntime.getState,
|
|
1399
|
+
getAuthenticatedSecret: telegramBusFollowerControlState.getActiveAuthSecret,
|
|
1400
|
+
getLeaderProtocol: telegramBusFollowerRegistrationState.getLeaderProtocol,
|
|
1401
|
+
};
|
|
1402
|
+
const followerWorkspaceTargetOwnerPorts = {
|
|
1215
1403
|
instanceId: telegramInstanceId,
|
|
1216
|
-
getContextAuthority: BusFollower.createTelegramBusFollowerRestoreContextGetter({
|
|
1217
|
-
isContextCurrent: telegramSessionContextStore.isCurrent,
|
|
1218
|
-
getSessionId: Pi.getExtensionContextSessionId,
|
|
1219
|
-
getCwd: Pi.getExtensionContextCwd,
|
|
1220
|
-
getGeneration: telegramSessionContextStore.getGeneration,
|
|
1221
|
-
getProfileBindingKey() {
|
|
1222
|
-
return workspaceAdmissionRuntime.resolve()?.getProfileKey();
|
|
1223
|
-
},
|
|
1224
|
-
getOperatorUserId: configStore.getAllowedUserId,
|
|
1225
|
-
getLeaderState: lockRuntime.getState,
|
|
1226
|
-
getAuthenticatedSecret: telegramBusFollowerControlState.getActiveAuthSecret,
|
|
1227
|
-
getLeaderProtocol: telegramBusFollowerRegistrationState.getLeaderProtocol,
|
|
1228
|
-
}),
|
|
1229
1404
|
readRestoreIntent(operationId, profileBindingKey) {
|
|
1230
|
-
if (profileBindingKey !==
|
|
1405
|
+
if (profileBindingKey !==
|
|
1406
|
+
workspaceAdmissionRuntime.resolve()?.getProfileKey())
|
|
1231
1407
|
return undefined;
|
|
1232
|
-
return resolveWorkspaceRestoreStore()
|
|
1408
|
+
return resolveWorkspaceRestoreStore()
|
|
1409
|
+
?.list()
|
|
1410
|
+
.find(function (intent) {
|
|
1411
|
+
return intent.request.operationId === operationId;
|
|
1412
|
+
});
|
|
1413
|
+
},
|
|
1414
|
+
readLiveRebindIntent(operationId, profileBindingKey) {
|
|
1415
|
+
if (profileBindingKey !==
|
|
1416
|
+
workspaceAdmissionRuntime.resolve()?.getProfileKey())
|
|
1417
|
+
return undefined;
|
|
1418
|
+
return resolveWorkspaceRestoreStore()
|
|
1419
|
+
?.listLiveRebindings()
|
|
1420
|
+
.find(function (intent) {
|
|
1233
1421
|
return intent.request.operationId === operationId;
|
|
1234
1422
|
});
|
|
1235
1423
|
},
|
|
@@ -1237,6 +1425,91 @@ export default function (pi) {
|
|
|
1237
1425
|
registrationState: telegramBusFollowerRegistrationState,
|
|
1238
1426
|
getWorkspaceAdmission: workspaceAdmissionRuntime.resolve,
|
|
1239
1427
|
recordRuntimeEvent,
|
|
1428
|
+
};
|
|
1429
|
+
const followerWorkspaceRestore = BusFollower.createTelegramBusFollowerWorkspaceRestoreHandler({
|
|
1430
|
+
...followerWorkspaceTargetOwnerPorts,
|
|
1431
|
+
getContextAuthority: BusFollower.createTelegramBusFollowerRestoreContextGetter(followerWorkspaceTargetContextPorts),
|
|
1432
|
+
});
|
|
1433
|
+
const followerLiveRebindTarget = BusFollower.createTelegramBusFollowerWorkspaceRestoreHandler({
|
|
1434
|
+
...followerWorkspaceTargetOwnerPorts,
|
|
1435
|
+
getContextAuthority: BusFollower.createTelegramBusFollowerRestoreContextGetter({
|
|
1436
|
+
...followerWorkspaceTargetContextPorts,
|
|
1437
|
+
capability: Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_APPLY,
|
|
1438
|
+
}),
|
|
1439
|
+
});
|
|
1440
|
+
const selectedMenuCaller = BusFollower.createTelegramBusFollowerSelectedMenuCaller({
|
|
1441
|
+
client: {
|
|
1442
|
+
socketPath: getTelegramBusSocketPath,
|
|
1443
|
+
instanceId: telegramInstanceId,
|
|
1444
|
+
createRequestId: telegramBusFollowerClients.createRequestId,
|
|
1445
|
+
getAuthSecret: telegramBusFollowerControlState.getActiveAuthSecret,
|
|
1446
|
+
getRegistrationGeneration: telegramBusFollowerRegistrationState.getGeneration,
|
|
1447
|
+
},
|
|
1448
|
+
protocolIdentity: telegramBusProtocolIdentity,
|
|
1449
|
+
recipient: {
|
|
1450
|
+
getContextAuthority: BusFollower.createTelegramBusFollowerRestoreContextGetter({
|
|
1451
|
+
...followerWorkspaceTargetContextPorts,
|
|
1452
|
+
// Wire recipient identity is the registered profile key, not the admission namespace.
|
|
1453
|
+
getProfileBindingKey: getTelegramManualFollowerProfileKey,
|
|
1454
|
+
capability: Bus.TELEGRAM_BUS_CAPABILITY_SELECTED_MENU_DELIVERY,
|
|
1455
|
+
}),
|
|
1456
|
+
getJournalBindingKey: followerAdmissionLifecycleRuntime.getJournalBindingKey,
|
|
1457
|
+
getProcessIdentity() {
|
|
1458
|
+
return {
|
|
1459
|
+
processId: telegramProcessId,
|
|
1460
|
+
processBirthId: telegramQueueProcessBirthId,
|
|
1461
|
+
};
|
|
1462
|
+
},
|
|
1463
|
+
registrationState: telegramBusFollowerRegistrationState,
|
|
1464
|
+
},
|
|
1465
|
+
});
|
|
1466
|
+
const followerLiveRebindRuntime = BusFollower.createTelegramBusFollowerLiveRebindRuntime({
|
|
1467
|
+
getAdmission(ctx) {
|
|
1468
|
+
return telegramSessionContextStore.isCurrent(ctx)
|
|
1469
|
+
? followerAdmissionLifecycleRuntime
|
|
1470
|
+
: undefined;
|
|
1471
|
+
},
|
|
1472
|
+
applyTarget: followerLiveRebindTarget,
|
|
1473
|
+
getCommandOwner(input, ctx) {
|
|
1474
|
+
if (!Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_COMMAND_SET) ||
|
|
1475
|
+
!Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_SELECTED_MENU_DELIVERY) ||
|
|
1476
|
+
!input.selectedCommand ||
|
|
1477
|
+
!telegramSessionContextStore.isCurrent(ctx) ||
|
|
1478
|
+
followerAdmissionLifecycleRuntime.getJournalBindingKey() !==
|
|
1479
|
+
input.recipientBindingKey)
|
|
1480
|
+
return undefined;
|
|
1481
|
+
const recipient = followerLiveRebindTarget.prepareLiveCommandRecipient({
|
|
1482
|
+
operationId: input.operationId,
|
|
1483
|
+
registrationGeneration: input.recipientRegistrationGeneration,
|
|
1484
|
+
sessionId: input.recipientSessionId,
|
|
1485
|
+
sourceUpdateIds: input.updates.map(function sourceUpdateId(update) {
|
|
1486
|
+
return update.update_id;
|
|
1487
|
+
}),
|
|
1488
|
+
target: input.selectedCommand.target,
|
|
1489
|
+
}, ctx);
|
|
1490
|
+
return (recipient &&
|
|
1491
|
+
Bindings.createTelegramFollowerSelectedCommandBinding({
|
|
1492
|
+
ctx,
|
|
1493
|
+
operationId: input.operationId,
|
|
1494
|
+
registrationGeneration: input.recipientRegistrationGeneration,
|
|
1495
|
+
name: input.selectedCommand.name,
|
|
1496
|
+
target: input.selectedCommand.target,
|
|
1497
|
+
recipient,
|
|
1498
|
+
command: inboundRouteRuntime,
|
|
1499
|
+
menu: menuActionPorts,
|
|
1500
|
+
recordOwnership: messageOwnershipRuntime.recordLocal,
|
|
1501
|
+
deliver(effect, assertAuthority) {
|
|
1502
|
+
return selectedMenuCaller({
|
|
1503
|
+
ctx,
|
|
1504
|
+
operationId: input.operationId,
|
|
1505
|
+
registrationGeneration: input.recipientRegistrationGeneration,
|
|
1506
|
+
effect,
|
|
1507
|
+
assertAuthority,
|
|
1508
|
+
});
|
|
1509
|
+
},
|
|
1510
|
+
}));
|
|
1511
|
+
},
|
|
1512
|
+
observeWork: observeLiveTargetWork,
|
|
1240
1513
|
});
|
|
1241
1514
|
const telegramBusFollowerAssembly = BusFollower.createTelegramBusFollowerRuntimeAssembly({
|
|
1242
1515
|
instanceId: telegramInstanceId,
|
|
@@ -1247,12 +1520,36 @@ export default function (pi) {
|
|
|
1247
1520
|
getContext: telegramSessionContextStore.get,
|
|
1248
1521
|
getAuthSecret: telegramBusFollowerControlState.getActiveAuthSecret,
|
|
1249
1522
|
getRecipientBindingKey: getTelegramManualFollowerProfileKey,
|
|
1523
|
+
getLiveRebindJournalBindingKey: followerAdmissionLifecycleRuntime.getJournalBindingKey,
|
|
1524
|
+
getSessionId() {
|
|
1525
|
+
return telegramBusFollowerAssembly.getReadySessionId();
|
|
1526
|
+
},
|
|
1527
|
+
getLeaderProtocol: telegramBusFollowerRegistrationState.getLeaderProtocol,
|
|
1528
|
+
getLocalProtocol() {
|
|
1529
|
+
return telegramBusProtocolIdentity;
|
|
1530
|
+
},
|
|
1531
|
+
isLiveRebindSaveEnabled() {
|
|
1532
|
+
return Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_SAVE);
|
|
1533
|
+
},
|
|
1534
|
+
isLiveRebindApplyEnabled() {
|
|
1535
|
+
return Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_APPLY);
|
|
1536
|
+
},
|
|
1537
|
+
isLiveRebindSettleEnabled() {
|
|
1538
|
+
return Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_SETTLE);
|
|
1539
|
+
},
|
|
1540
|
+
isLiveRebindCommandSetEnabled() {
|
|
1541
|
+
return (Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_LIVE_REBIND_COMMAND_SET) &&
|
|
1542
|
+
Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_SELECTED_MENU_DELIVERY));
|
|
1543
|
+
},
|
|
1544
|
+
handleLiveRebindSave: followerLiveRebindRuntime.save,
|
|
1545
|
+
handleLiveRebindApply: followerLiveRebindRuntime.apply,
|
|
1546
|
+
handleLiveRebindSettle: followerLiveRebindRuntime.settle,
|
|
1250
1547
|
durableAdmission: followerDurableAdmissionRuntime,
|
|
1251
1548
|
handleQueueHandoff: acceptStagedQueueHandoff,
|
|
1252
1549
|
handleWorkspaceRestore: followerWorkspaceRestore,
|
|
1253
1550
|
isWorkspaceRestoreEnabled() {
|
|
1254
|
-
return Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE) &&
|
|
1255
|
-
Bus.hasTelegramBusCapability(telegramBusFollowerRegistrationState.getLeaderProtocol(), Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE);
|
|
1551
|
+
return (Bus.hasTelegramBusCapability(telegramBusProtocolIdentity, Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE) &&
|
|
1552
|
+
Bus.hasTelegramBusCapability(telegramBusFollowerRegistrationState.getLeaderProtocol(), Bus.TELEGRAM_BUS_CAPABILITY_WORKSPACE_RESTORE));
|
|
1256
1553
|
},
|
|
1257
1554
|
},
|
|
1258
1555
|
recovery: {
|
|
@@ -1289,7 +1586,7 @@ export default function (pi) {
|
|
|
1289
1586
|
const { admission: pollingAdmissionRuntime } = Polling.createTelegramDurablePollingRuntimeAssembly({
|
|
1290
1587
|
state: pollingControllerState,
|
|
1291
1588
|
canStart(ctx) {
|
|
1292
|
-
return telegramSessionContextStore.isCurrent(ctx) && lockRuntime.owns(ctx);
|
|
1589
|
+
return (telegramSessionContextStore.isCurrent(ctx) && lockRuntime.owns(ctx));
|
|
1293
1590
|
},
|
|
1294
1591
|
onPersistentConflict(ctx, count) {
|
|
1295
1592
|
return lockedPollingRuntime.onPersistentConflict(ctx, count);
|
|
@@ -1309,7 +1606,9 @@ export default function (pi) {
|
|
|
1309
1606
|
registry: telegramJournalReferenceRegistry,
|
|
1310
1607
|
resolveBinding: resolveTelegramUpdateJournalBinding,
|
|
1311
1608
|
referenceClass: "polling-cursor",
|
|
1312
|
-
operation(binding) {
|
|
1609
|
+
operation(binding) {
|
|
1610
|
+
return binding.journal.read().acceptedThroughUpdateId;
|
|
1611
|
+
},
|
|
1313
1612
|
});
|
|
1314
1613
|
},
|
|
1315
1614
|
async prepareCursorCutover() {
|
|
@@ -1338,12 +1637,14 @@ export default function (pi) {
|
|
|
1338
1637
|
getEntryCount: updateAdmissionLifecycleRuntime.getJournalEntryCount,
|
|
1339
1638
|
signalWorker: updateAdmissionLifecycleRuntime.signal,
|
|
1340
1639
|
getBootstrapEntryCount() {
|
|
1341
|
-
return Journal.withTelegramResolvedUpdateJournalReference({
|
|
1640
|
+
return (Journal.withTelegramResolvedUpdateJournalReference({
|
|
1342
1641
|
registry: telegramJournalReferenceRegistry,
|
|
1343
1642
|
resolveBinding: resolveTelegramUpdateJournalBinding,
|
|
1344
1643
|
referenceClass: "polling-bootstrap",
|
|
1345
|
-
operation(binding) {
|
|
1346
|
-
|
|
1644
|
+
operation(binding) {
|
|
1645
|
+
return binding.journal.read().entries.length;
|
|
1646
|
+
},
|
|
1647
|
+
}) ?? 0);
|
|
1347
1648
|
},
|
|
1348
1649
|
onSessionStart: updateAdmissionLifecycleRuntime.onSessionStart,
|
|
1349
1650
|
},
|
|
@@ -1355,13 +1656,59 @@ export default function (pi) {
|
|
|
1355
1656
|
const authorizeFollowerApiCall = Bus.createTelegramFollowerApiCallAuthorizer({
|
|
1356
1657
|
isMessageOwned: messageOwnershipRuntime.isOwnedByFollower,
|
|
1357
1658
|
});
|
|
1659
|
+
const selectedMenuDelivery = BusLeader.createTelegramBusSelectedMenuDeliveryHandler({
|
|
1660
|
+
followerRegistry: telegramBusFollowerRegistry,
|
|
1661
|
+
protocolIdentity: telegramBusProtocolIdentity,
|
|
1662
|
+
workspace: {
|
|
1663
|
+
getScopeKey() {
|
|
1664
|
+
return workspaceAdmissionRuntime.resolve()?.getProfileKey();
|
|
1665
|
+
},
|
|
1666
|
+
captureAuthority() {
|
|
1667
|
+
const isCurrent = captureTelegramStateAuthority(), epoch = lockRuntime.getOwnedLeaderEpoch(), operatorUserId = configStore.getAllowedUserId();
|
|
1668
|
+
return isCurrent &&
|
|
1669
|
+
epoch !== undefined &&
|
|
1670
|
+
operatorUserId !== undefined
|
|
1671
|
+
? {
|
|
1672
|
+
executor: {
|
|
1673
|
+
instanceId: telegramInstanceId,
|
|
1674
|
+
leaderEpoch: String(epoch),
|
|
1675
|
+
},
|
|
1676
|
+
operatorUserId,
|
|
1677
|
+
isCurrent,
|
|
1678
|
+
}
|
|
1679
|
+
: undefined;
|
|
1680
|
+
},
|
|
1681
|
+
getStore: resolveWorkspaceRestoreStore,
|
|
1682
|
+
threadStore,
|
|
1683
|
+
getJournalBindingKey: liveFollowerPorts.getJournalBindingKey,
|
|
1684
|
+
run: telegramWorkspaceOperationRuntime.run,
|
|
1685
|
+
},
|
|
1686
|
+
api: {
|
|
1687
|
+
runtime: directTelegramApiRuntime,
|
|
1688
|
+
authorize: authorizeFollowerApiCall,
|
|
1689
|
+
record(record, assertCurrent) {
|
|
1690
|
+
assertCurrent();
|
|
1691
|
+
messageOwnershipRuntime.recordFollower(record);
|
|
1692
|
+
assertCurrent();
|
|
1693
|
+
return messageOwnershipRuntime.isOwnedByFollower(record);
|
|
1694
|
+
},
|
|
1695
|
+
},
|
|
1696
|
+
});
|
|
1358
1697
|
const telegramSessionFolderSweeper = Recovery.createTelegramSessionFolderSweeper({
|
|
1359
1698
|
getSessionsDir: Paths.resolveTelegramSessionsDir,
|
|
1360
1699
|
getProfileName: configStore.getActiveProfileName,
|
|
1361
1700
|
getKeptSessionIds() {
|
|
1362
1701
|
return [
|
|
1363
|
-
...threadStore
|
|
1364
|
-
|
|
1702
|
+
...threadStore
|
|
1703
|
+
.listWorkspaceBindings()
|
|
1704
|
+
.map(function bindingSession(binding) {
|
|
1705
|
+
return binding.sessionId;
|
|
1706
|
+
}),
|
|
1707
|
+
...telegramBusFollowerRegistry
|
|
1708
|
+
.list()
|
|
1709
|
+
.map(function followerSession(follower) {
|
|
1710
|
+
return follower.sessionId;
|
|
1711
|
+
}),
|
|
1365
1712
|
Pi.getExtensionContextSessionId(telegramSessionContextStore.get()),
|
|
1366
1713
|
];
|
|
1367
1714
|
},
|
|
@@ -1375,6 +1722,7 @@ export default function (pi) {
|
|
|
1375
1722
|
followerRegistry: telegramBusFollowerRegistry,
|
|
1376
1723
|
authSecret: telegramBusAuthSecret,
|
|
1377
1724
|
protocolIdentity: telegramBusProtocolIdentity,
|
|
1725
|
+
selectedMenuDelivery,
|
|
1378
1726
|
startPolling: pollingAdmissionRuntime.start,
|
|
1379
1727
|
stopPolling: pollingAdmissionRuntime.stop,
|
|
1380
1728
|
authorizeFollowerApiCall,
|
|
@@ -1388,8 +1736,10 @@ export default function (pi) {
|
|
|
1388
1736
|
message,
|
|
1389
1737
|
});
|
|
1390
1738
|
},
|
|
1391
|
-
isFollowerProcessAlive:
|
|
1392
|
-
afterFollowerPrune() {
|
|
1739
|
+
isFollowerProcessAlive: ProcessIdentity.isProcessAlive,
|
|
1740
|
+
afterFollowerPrune() {
|
|
1741
|
+
telegramSessionFolderSweeper.sweep();
|
|
1742
|
+
},
|
|
1393
1743
|
shouldCleanupConfirmedDeadFollower: configControls.resolveAutomaticThreadCleanupEnabled,
|
|
1394
1744
|
recordFollowerMessageOwnership(record) {
|
|
1395
1745
|
messageOwnershipRuntime.recordFollower(record);
|
|
@@ -1548,6 +1898,7 @@ export default function (pi) {
|
|
|
1548
1898
|
getSyncState: telegramSyncStateRuntime.getState,
|
|
1549
1899
|
setSyncState: telegramSyncStateRuntime.setState,
|
|
1550
1900
|
stopPolling: lockedPollingRuntime.stop,
|
|
1901
|
+
captureStopPolling: lockedPollingRuntime.captureStop,
|
|
1551
1902
|
suspendPolling: lockedPollingRuntime.suspend,
|
|
1552
1903
|
recordRuntimeEvent,
|
|
1553
1904
|
runWorkspaceOperation: telegramWorkspaceOperationRuntime.run,
|
|
@@ -1568,13 +1919,14 @@ export default function (pi) {
|
|
|
1568
1919
|
isCurrent: telegramSessionContextStore.isCurrent,
|
|
1569
1920
|
getProfileName: configStore.getActiveProfileName,
|
|
1570
1921
|
isConnected() {
|
|
1571
|
-
return lockRuntime.owns() ||
|
|
1922
|
+
return (lockRuntime.owns() ||
|
|
1923
|
+
telegramBusFollowerRegistrationState.isRegistered());
|
|
1572
1924
|
},
|
|
1573
1925
|
async activateProfile(profileName, isCurrent) {
|
|
1574
1926
|
await configStore.load();
|
|
1575
1927
|
if (!isCurrent())
|
|
1576
1928
|
return false;
|
|
1577
|
-
return configStore.activateProfile(profileName) && configStore.hasBotToken();
|
|
1929
|
+
return (configStore.activateProfile(profileName) && configStore.hasBotToken());
|
|
1578
1930
|
},
|
|
1579
1931
|
start(ctx) {
|
|
1580
1932
|
return lockedPollingRuntime.start(ctx);
|
|
@@ -1645,14 +1997,46 @@ export default function (pi) {
|
|
|
1645
1997
|
});
|
|
1646
1998
|
const sessionLifecycleRuntime = Lifecycle.createTelegramBridgeSessionLifecycleAssembly(telegramBridgeSessionLifecycleDeps);
|
|
1647
1999
|
// --- Extension API Bindings ---
|
|
2000
|
+
const threadNameRecipientAuthority = {
|
|
2001
|
+
getAuthority() {
|
|
2002
|
+
const ctx = telegramSessionContextStore.get();
|
|
2003
|
+
return {
|
|
2004
|
+
context: ctx,
|
|
2005
|
+
sessionId: Pi.getExtensionContextSessionId(ctx),
|
|
2006
|
+
sessionGeneration: telegramSessionContextStore.getGeneration(),
|
|
2007
|
+
cwd: ctx && Pi.getExtensionContextCwd(ctx),
|
|
2008
|
+
profileName: configStore.getActiveProfileName(),
|
|
2009
|
+
botToken: configStore.getBotToken(),
|
|
2010
|
+
operatorUserId: configStore.getAllowedUserId(),
|
|
2011
|
+
leaderEpoch: getCurrentLeaderEpoch(),
|
|
2012
|
+
ownsDirectDelivery: ownsTelegramDirectDelivery(),
|
|
2013
|
+
followerRegistered: telegramBusFollowerRegistrationState.isRegistered(),
|
|
2014
|
+
localTarget: telegramBusLeaderState.getTarget(),
|
|
2015
|
+
localSlot: telegramBusLeaderState.getIdentity()?.slot,
|
|
2016
|
+
};
|
|
2017
|
+
},
|
|
2018
|
+
};
|
|
1648
2019
|
telegramThreadDisplayNameRenameBinding.bind({
|
|
1649
|
-
async rename(expectedTarget, threadName) {
|
|
2020
|
+
async rename(expectedTarget, threadName, options) {
|
|
1650
2021
|
try {
|
|
2022
|
+
const assertCaller = options?.assertAuthority;
|
|
2023
|
+
assertCaller?.();
|
|
1651
2024
|
if (telegramBusFollowerRegistrationState.isRegistered()) {
|
|
2025
|
+
if (assertCaller)
|
|
2026
|
+
return {
|
|
2027
|
+
ok: false,
|
|
2028
|
+
message: "Guarded follower Workspace Thread rename is unavailable.",
|
|
2029
|
+
};
|
|
1652
2030
|
if (typeof expectedTarget.threadId !== "number") {
|
|
1653
|
-
return {
|
|
2031
|
+
return {
|
|
2032
|
+
ok: false,
|
|
2033
|
+
message: "Telegram Workspace Thread target is unavailable.",
|
|
2034
|
+
};
|
|
1654
2035
|
}
|
|
1655
|
-
const renamedThreadName = await telegramBusFollowerRegistration.renameThread?.({
|
|
2036
|
+
const renamedThreadName = await telegramBusFollowerRegistration.renameThread?.({
|
|
2037
|
+
chatId: expectedTarget.chatId,
|
|
2038
|
+
threadId: expectedTarget.threadId,
|
|
2039
|
+
}, threadName);
|
|
1656
2040
|
if (!renamedThreadName) {
|
|
1657
2041
|
return {
|
|
1658
2042
|
ok: false,
|
|
@@ -1671,14 +2055,32 @@ export default function (pi) {
|
|
|
1671
2055
|
};
|
|
1672
2056
|
}
|
|
1673
2057
|
if (typeof expectedTarget.threadId !== "number") {
|
|
1674
|
-
return {
|
|
2058
|
+
return {
|
|
2059
|
+
ok: false,
|
|
2060
|
+
message: "Telegram Workspace Thread target is unavailable.",
|
|
2061
|
+
};
|
|
1675
2062
|
}
|
|
1676
|
-
const
|
|
2063
|
+
const target = {
|
|
2064
|
+
chatId: expectedTarget.chatId,
|
|
2065
|
+
threadId: expectedTarget.threadId,
|
|
2066
|
+
};
|
|
2067
|
+
const recipient = assertCaller
|
|
2068
|
+
? Threads.createTelegramWorkspaceThreadRenameRecipient({
|
|
2069
|
+
store: threadStore,
|
|
2070
|
+
instanceId: telegramInstanceId,
|
|
2071
|
+
target,
|
|
2072
|
+
assertAuthority: assertCaller,
|
|
2073
|
+
getAuthority: threadNameRecipientAuthority.getAuthority,
|
|
2074
|
+
})
|
|
2075
|
+
: undefined;
|
|
2076
|
+
const renamed = await telegramBusLeaderRuntime.renameLeaderThreadAdmitted(threadName, target, recipient?.assertAuthority);
|
|
2077
|
+
recipient?.assertResult(renamed);
|
|
1677
2078
|
telegramBusLeaderState.set({
|
|
1678
2079
|
target: renamed.target,
|
|
1679
2080
|
slot: renamed.slot,
|
|
1680
2081
|
threadName: renamed.manualThreadName ?? renamed.threadName,
|
|
1681
2082
|
});
|
|
2083
|
+
recipient?.assertResult(renamed);
|
|
1682
2084
|
return {
|
|
1683
2085
|
ok: true,
|
|
1684
2086
|
threadName: renamed.manualThreadName,
|
|
@@ -1695,26 +2097,58 @@ export default function (pi) {
|
|
|
1695
2097
|
},
|
|
1696
2098
|
}.rename);
|
|
1697
2099
|
telegramThreadDisplayNameResetBinding.bind({
|
|
1698
|
-
async reset(expectedTarget) {
|
|
2100
|
+
async reset(expectedTarget, options) {
|
|
1699
2101
|
try {
|
|
2102
|
+
const assertCaller = options?.assertAuthority;
|
|
2103
|
+
assertCaller?.();
|
|
2104
|
+
const wasFollower = telegramBusFollowerRegistrationState.isRegistered();
|
|
2105
|
+
if (wasFollower && assertCaller)
|
|
2106
|
+
return {
|
|
2107
|
+
ok: false,
|
|
2108
|
+
message: "Guarded follower Workspace Thread reset is unavailable.",
|
|
2109
|
+
};
|
|
1700
2110
|
if (typeof expectedTarget.threadId !== "number") {
|
|
1701
|
-
return {
|
|
2111
|
+
return {
|
|
2112
|
+
ok: false,
|
|
2113
|
+
message: "Telegram Workspace Thread target is unavailable.",
|
|
2114
|
+
};
|
|
1702
2115
|
}
|
|
1703
2116
|
const target = {
|
|
1704
2117
|
chatId: expectedTarget.chatId,
|
|
1705
2118
|
threadId: expectedTarget.threadId,
|
|
1706
2119
|
};
|
|
1707
|
-
const
|
|
2120
|
+
const recipient = assertCaller
|
|
2121
|
+
? Threads.createTelegramWorkspaceThreadResetRecipient({
|
|
2122
|
+
store: threadStore,
|
|
2123
|
+
instanceId: telegramInstanceId,
|
|
2124
|
+
target,
|
|
2125
|
+
assertAuthority: assertCaller,
|
|
2126
|
+
getAuthority: threadNameRecipientAuthority.getAuthority,
|
|
2127
|
+
})
|
|
2128
|
+
: undefined;
|
|
1708
2129
|
const result = wasFollower
|
|
1709
2130
|
? await telegramBusFollowerRegistration.resetThreadName?.(target)
|
|
1710
|
-
: (await
|
|
2131
|
+
: (await (recipient
|
|
2132
|
+
? telegramBusLeaderRuntime.resetLeaderThreadName(target, recipient.assertAuthority)
|
|
2133
|
+
: telegramBusLeaderRuntime.resetLeaderThreadName(target))).threadName;
|
|
1711
2134
|
if (!result) {
|
|
1712
|
-
return {
|
|
2135
|
+
return {
|
|
2136
|
+
ok: false,
|
|
2137
|
+
message: "Thread display name reset is unavailable.",
|
|
2138
|
+
};
|
|
1713
2139
|
}
|
|
2140
|
+
recipient?.assertResult(result);
|
|
1714
2141
|
const leaderTarget = telegramBusLeaderState.getTarget();
|
|
1715
2142
|
if (!wasFollower && leaderTarget) {
|
|
1716
|
-
telegramBusLeaderState.set({
|
|
2143
|
+
telegramBusLeaderState.set({
|
|
2144
|
+
target: leaderTarget,
|
|
2145
|
+
threadName: result,
|
|
2146
|
+
...(recipient
|
|
2147
|
+
? { slot: telegramBusLeaderState.getIdentity()?.slot }
|
|
2148
|
+
: {}),
|
|
2149
|
+
});
|
|
1717
2150
|
}
|
|
2151
|
+
recipient?.assertResult(result);
|
|
1718
2152
|
return {
|
|
1719
2153
|
ok: true,
|
|
1720
2154
|
threadName: result,
|
|
@@ -1724,7 +2158,8 @@ export default function (pi) {
|
|
|
1724
2158
|
return {
|
|
1725
2159
|
ok: false,
|
|
1726
2160
|
message: error instanceof Error
|
|
1727
|
-
? error.message
|
|
2161
|
+
? error.message
|
|
2162
|
+
: "Thread display name reset failed.",
|
|
1728
2163
|
};
|
|
1729
2164
|
}
|
|
1730
2165
|
},
|
|
@@ -1765,20 +2200,28 @@ export default function (pi) {
|
|
|
1765
2200
|
const botToken = configStore.getBotToken();
|
|
1766
2201
|
if (!botToken)
|
|
1767
2202
|
throw new Error("Telegram channel delivery requires an active bot token.");
|
|
1768
|
-
const store = ChannelPosts.
|
|
1769
|
-
...Paths.resolveTelegramServiceJournalStorage("channel-posts", undefined, profileName),
|
|
2203
|
+
const store = ChannelPosts.openTelegramChannelPostJournalStore({
|
|
1770
2204
|
profileName,
|
|
1771
|
-
|
|
2205
|
+
botToken,
|
|
1772
2206
|
});
|
|
1773
2207
|
const record = await ChannelPosts.publishTelegramChannelPost({
|
|
1774
|
-
store,
|
|
1775
|
-
|
|
2208
|
+
store,
|
|
2209
|
+
operationId: options.operationId,
|
|
2210
|
+
channel: channel,
|
|
2211
|
+
markdown,
|
|
1776
2212
|
async observeChannel(channelAddress) {
|
|
1777
|
-
return telegramApiRuntime.call("getChat", {
|
|
2213
|
+
return telegramApiRuntime.call("getChat", {
|
|
2214
|
+
chat_id: channelAddress,
|
|
2215
|
+
});
|
|
1778
2216
|
},
|
|
1779
2217
|
async send(channelAddress, body) {
|
|
1780
|
-
const sent = await telegramApiRuntime.call("sendRichMessage", {
|
|
1781
|
-
|
|
2218
|
+
const sent = await telegramApiRuntime.call("sendRichMessage", {
|
|
2219
|
+
chat_id: channelAddress,
|
|
2220
|
+
rich_message: { markdown: body },
|
|
2221
|
+
...(options.replyMarkup
|
|
2222
|
+
? { reply_markup: options.replyMarkup }
|
|
2223
|
+
: {}),
|
|
2224
|
+
});
|
|
1782
2225
|
return { messageId: sent.message_id, chat: sent.chat };
|
|
1783
2226
|
},
|
|
1784
2227
|
});
|
|
@@ -1795,23 +2238,29 @@ export default function (pi) {
|
|
|
1795
2238
|
const media = await ChannelPosts.inspectTelegramChannelPostMedia(mediaPath);
|
|
1796
2239
|
const caption = Replies.renderTelegramMarkdownToHtmlDraft(markdown);
|
|
1797
2240
|
ChannelPosts.assertTelegramChannelPostCaptionWithinLimit(caption);
|
|
1798
|
-
const store = ChannelPosts.
|
|
1799
|
-
...Paths.resolveTelegramServiceJournalStorage("channel-posts", undefined, profileName),
|
|
2241
|
+
const store = ChannelPosts.openTelegramChannelPostJournalStore({
|
|
1800
2242
|
profileName,
|
|
1801
|
-
|
|
2243
|
+
botToken,
|
|
1802
2244
|
});
|
|
1803
2245
|
const record = await ChannelPosts.publishTelegramChannelPost({
|
|
1804
|
-
store,
|
|
1805
|
-
|
|
2246
|
+
store,
|
|
2247
|
+
operationId: options.operationId,
|
|
2248
|
+
channel: channel,
|
|
2249
|
+
markdown,
|
|
2250
|
+
media,
|
|
1806
2251
|
async observeChannel(channelAddress) {
|
|
1807
|
-
return telegramApiRuntime.call("getChat", {
|
|
2252
|
+
return telegramApiRuntime.call("getChat", {
|
|
2253
|
+
chat_id: channelAddress,
|
|
2254
|
+
});
|
|
1808
2255
|
},
|
|
1809
2256
|
async send(channelAddress) {
|
|
1810
2257
|
const sent = await telegramApiRuntime.callMultipart(media.kind === "photo" ? "sendPhoto" : "sendVideo", {
|
|
1811
2258
|
chat_id: String(channelAddress),
|
|
1812
2259
|
caption,
|
|
1813
2260
|
parse_mode: "HTML",
|
|
1814
|
-
...(options.replyMarkup
|
|
2261
|
+
...(options.replyMarkup
|
|
2262
|
+
? { reply_markup: JSON.stringify(options.replyMarkup) }
|
|
2263
|
+
: {}),
|
|
1815
2264
|
}, media.kind === "photo" ? "photo" : "video", mediaPath, media.fileName);
|
|
1816
2265
|
return { messageId: sent.message_id, chat: sent.chat };
|
|
1817
2266
|
},
|
|
@@ -1823,10 +2272,9 @@ export default function (pi) {
|
|
|
1823
2272
|
const botToken = configStore.getBotToken();
|
|
1824
2273
|
if (!botToken)
|
|
1825
2274
|
throw new Error("Telegram channel posts require an active bot token.");
|
|
1826
|
-
return ChannelPosts.
|
|
1827
|
-
...Paths.resolveTelegramServiceJournalStorage("channel-posts", undefined, profileName),
|
|
2275
|
+
return ChannelPosts.openTelegramChannelPostJournalStore({
|
|
1828
2276
|
profileName,
|
|
1829
|
-
|
|
2277
|
+
botToken,
|
|
1830
2278
|
}).list(input);
|
|
1831
2279
|
},
|
|
1832
2280
|
async mutateChannelPost(input) {
|
|
@@ -1836,23 +2284,28 @@ export default function (pi) {
|
|
|
1836
2284
|
const botToken = configStore.getBotToken();
|
|
1837
2285
|
if (!botToken)
|
|
1838
2286
|
throw new Error("Telegram channel post mutation requires an active bot token.");
|
|
1839
|
-
const store = ChannelPosts.
|
|
1840
|
-
|
|
1841
|
-
|
|
2287
|
+
const store = ChannelPosts.openTelegramChannelPostJournalStore({
|
|
2288
|
+
profileName,
|
|
2289
|
+
botToken,
|
|
1842
2290
|
});
|
|
1843
2291
|
if (input.action === "edit") {
|
|
1844
2292
|
if (!input.markdown)
|
|
1845
2293
|
throw new Error("Telegram channel post edit requires markdown.");
|
|
1846
2294
|
const current = store.get(input.operationId);
|
|
1847
2295
|
const caption = current?.media
|
|
1848
|
-
? Replies.renderTelegramMarkdownToHtmlDraft(input.markdown)
|
|
2296
|
+
? Replies.renderTelegramMarkdownToHtmlDraft(input.markdown)
|
|
2297
|
+
: undefined;
|
|
1849
2298
|
if (caption !== undefined) {
|
|
1850
2299
|
ChannelPosts.assertTelegramChannelPostCaptionWithinLimit(caption);
|
|
1851
2300
|
}
|
|
1852
|
-
const begun = store.beginEdit({
|
|
1853
|
-
|
|
2301
|
+
const begun = store.beginEdit({
|
|
2302
|
+
operationId: input.operationId,
|
|
2303
|
+
mutationId: input.mutationId,
|
|
2304
|
+
markdown: input.markdown,
|
|
2305
|
+
});
|
|
1854
2306
|
if (!begun.began) {
|
|
1855
|
-
if (begun.record.state === "published" &&
|
|
2307
|
+
if (begun.record.state === "published" &&
|
|
2308
|
+
begun.record.lastMutationId === input.mutationId)
|
|
1856
2309
|
return begun.record;
|
|
1857
2310
|
throw new Error("Telegram channel post edit outcome is unknown; refusing automatic replay.");
|
|
1858
2311
|
}
|
|
@@ -1862,29 +2315,48 @@ export default function (pi) {
|
|
|
1862
2315
|
if (caption === undefined) {
|
|
1863
2316
|
throw new Error("Telegram channel post media caption edit requires retained media identity.");
|
|
1864
2317
|
}
|
|
1865
|
-
await telegramApiRuntime.call("editMessageCaption", {
|
|
1866
|
-
|
|
2318
|
+
await telegramApiRuntime.call("editMessageCaption", {
|
|
2319
|
+
chat_id: begun.record.channelId,
|
|
2320
|
+
message_id: begun.record.messageId,
|
|
2321
|
+
caption,
|
|
2322
|
+
parse_mode: "HTML",
|
|
2323
|
+
});
|
|
1867
2324
|
}
|
|
1868
2325
|
else {
|
|
1869
|
-
await telegramApiRuntime.call("editMessageText", {
|
|
2326
|
+
await telegramApiRuntime.call("editMessageText", {
|
|
2327
|
+
chat_id: begun.record.channelId,
|
|
1870
2328
|
message_id: begun.record.messageId,
|
|
1871
|
-
text: Replies.renderTelegramMarkdownToHtmlDraft(input.markdown),
|
|
2329
|
+
text: Replies.renderTelegramMarkdownToHtmlDraft(input.markdown),
|
|
2330
|
+
parse_mode: "HTML",
|
|
2331
|
+
});
|
|
1872
2332
|
}
|
|
1873
|
-
return store.confirmEdited({
|
|
2333
|
+
return store.confirmEdited({
|
|
2334
|
+
operationId: input.operationId,
|
|
2335
|
+
mutationId: input.mutationId,
|
|
2336
|
+
}).record;
|
|
1874
2337
|
}
|
|
1875
2338
|
if (input.markdown !== undefined)
|
|
1876
2339
|
throw new Error("Telegram channel post deletion does not accept markdown.");
|
|
1877
|
-
const begun = store.beginDelete({
|
|
2340
|
+
const begun = store.beginDelete({
|
|
2341
|
+
operationId: input.operationId,
|
|
2342
|
+
mutationId: input.mutationId,
|
|
2343
|
+
});
|
|
1878
2344
|
if (!begun.began) {
|
|
1879
|
-
if (begun.record.state === "deleted" &&
|
|
2345
|
+
if (begun.record.state === "deleted" &&
|
|
2346
|
+
begun.record.mutationId === input.mutationId)
|
|
1880
2347
|
return begun.record;
|
|
1881
2348
|
throw new Error("Telegram channel post deletion outcome is unknown; refusing automatic replay.");
|
|
1882
2349
|
}
|
|
1883
2350
|
if (begun.record.state !== "delete-outcome-unknown")
|
|
1884
2351
|
throw new Error("Telegram channel post deletion authority is invalid.");
|
|
1885
|
-
await telegramApiRuntime.call("deleteMessage", {
|
|
1886
|
-
|
|
1887
|
-
|
|
2352
|
+
await telegramApiRuntime.call("deleteMessage", {
|
|
2353
|
+
chat_id: begun.record.channelId,
|
|
2354
|
+
message_id: begun.record.messageId,
|
|
2355
|
+
});
|
|
2356
|
+
return store.confirmDeleted({
|
|
2357
|
+
operationId: input.operationId,
|
|
2358
|
+
mutationId: input.mutationId,
|
|
2359
|
+
}).record;
|
|
1888
2360
|
},
|
|
1889
2361
|
callMultipart,
|
|
1890
2362
|
getDefaultChatId: proactivePushChatIdGetter,
|