@llblab/pi-telegram 0.52.2 → 0.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +9 -7
- package/BACKLOG.md +1 -18
- package/CHANGELOG.md +11 -0
- package/README.md +7 -11
- package/api/commands.ts +3 -0
- package/dist/api/commands.d.ts +1 -1
- package/dist/lib/activity-verbosity.d.ts +1 -5
- package/dist/lib/activity-verbosity.js +15 -42
- package/dist/lib/activity.d.ts +9 -0
- package/dist/lib/activity.js +39 -10
- package/dist/lib/agent-messages.js +7 -3
- package/dist/lib/bindings.d.ts +43 -5
- package/dist/lib/bindings.js +163 -20
- package/dist/lib/bus-api.d.ts +12 -0
- package/dist/lib/bus-api.js +182 -79
- package/dist/lib/bus-follower.d.ts +111 -31
- package/dist/lib/bus-follower.js +1324 -359
- package/dist/lib/bus-leader.d.ts +41 -91
- package/dist/lib/bus-leader.js +969 -637
- package/dist/lib/bus-transport.js +16 -9
- package/dist/lib/bus.d.ts +215 -18
- package/dist/lib/bus.js +1048 -327
- package/dist/lib/channel-posts.d.ts +5 -0
- package/dist/lib/channel-posts.js +434 -261
- package/dist/lib/command-templates.d.ts +26 -5
- package/dist/lib/command-templates.js +92 -176
- package/dist/lib/commands.d.ts +168 -82
- package/dist/lib/commands.js +1409 -291
- package/dist/lib/config.d.ts +1 -8
- package/dist/lib/config.js +34 -76
- package/dist/lib/delivery.d.ts +2 -2
- package/dist/lib/delivery.js +16 -16
- package/dist/lib/extension.js +639 -171
- package/dist/lib/generative-app-worker.mjs +19 -7
- package/dist/lib/generative-apps.d.ts +0 -5
- package/dist/lib/generative-apps.js +61 -49
- package/dist/lib/inbound.d.ts +5 -0
- package/dist/lib/inbound.js +35 -59
- package/dist/lib/journal.d.ts +33 -3
- package/dist/lib/journal.js +2063 -782
- package/dist/lib/lifecycle.d.ts +2 -6
- package/dist/lib/lifecycle.js +75 -58
- package/dist/lib/locks.d.ts +29 -3
- package/dist/lib/locks.js +289 -108
- package/dist/lib/logging.js +50 -14
- package/dist/lib/media.d.ts +22 -1
- package/dist/lib/media.js +46 -28
- package/dist/lib/menu-model.d.ts +19 -5
- package/dist/lib/menu-model.js +53 -11
- package/dist/lib/menu-queue.d.ts +5 -4
- package/dist/lib/menu-queue.js +45 -63
- package/dist/lib/menu-settings.d.ts +5 -4
- package/dist/lib/menu-settings.js +114 -78
- package/dist/lib/menu-status.d.ts +1 -1
- package/dist/lib/menu-status.js +8 -25
- package/dist/lib/menu-thinking.d.ts +6 -1
- package/dist/lib/menu-thinking.js +14 -21
- package/dist/lib/menu.d.ts +8 -61
- package/dist/lib/menu.js +92 -164
- package/dist/lib/model.d.ts +1 -1
- package/dist/lib/model.js +2 -16
- package/dist/lib/outbound-attachments.d.ts +6 -27
- package/dist/lib/outbound-attachments.js +45 -38
- package/dist/lib/outbound-buttons.js +22 -16
- package/dist/lib/outbound-markup.d.ts +0 -2
- package/dist/lib/outbound-markup.js +51 -64
- package/dist/lib/outbound-voice.js +6 -3
- package/dist/lib/outbound.d.ts +6 -6
- package/dist/lib/outbound.js +61 -51
- package/dist/lib/ownership.js +6 -2
- package/dist/lib/paths.d.ts +5 -0
- package/dist/lib/paths.js +37 -21
- package/dist/lib/pi.d.ts +2 -0
- package/dist/lib/pi.js +8 -1
- package/dist/lib/polling.d.ts +21 -37
- package/dist/lib/polling.js +59 -50
- package/dist/lib/preview.js +39 -19
- package/dist/lib/process-identity.d.ts +24 -0
- package/dist/lib/process-identity.js +133 -0
- package/dist/lib/prompts.js +2 -7
- package/dist/lib/queue.d.ts +14 -16
- package/dist/lib/queue.js +249 -126
- package/dist/lib/recovery.d.ts +2 -83
- package/dist/lib/recovery.js +20 -274
- package/dist/lib/replies.d.ts +16 -24
- package/dist/lib/replies.js +99 -116
- package/dist/lib/routing.d.ts +120 -7
- package/dist/lib/routing.js +4667 -1152
- package/dist/lib/runtime.d.ts +1 -11
- package/dist/lib/sections.d.ts +4 -29
- package/dist/lib/sections.js +7 -20
- package/dist/lib/skills.js +4 -3
- package/dist/lib/status.js +86 -57
- package/dist/lib/sync.d.ts +1 -3
- package/dist/lib/sync.js +67 -43
- package/dist/lib/target.d.ts +4 -0
- package/dist/lib/target.js +18 -0
- package/dist/lib/telegram-api.d.ts +18 -13
- package/dist/lib/telegram-api.js +148 -53
- package/dist/lib/text-groups.js +4 -39
- package/dist/lib/thread-cleanup-manager.d.ts +6 -27
- package/dist/lib/thread-cleanup-manager.js +369 -186
- package/dist/lib/thread-display.d.ts +1 -2
- package/dist/lib/thread-display.js +58 -38
- package/dist/lib/thread-naming.d.ts +28 -8
- package/dist/lib/thread-naming.js +175 -66
- package/dist/lib/thread-reconciler.d.ts +42 -16
- package/dist/lib/thread-reconciler.js +90 -50
- package/dist/lib/threads.d.ts +82 -20
- package/dist/lib/threads.js +2247 -855
- package/dist/lib/time-injection.js +1 -2
- package/dist/lib/turns.js +1 -19
- package/dist/lib/updates.d.ts +169 -80
- package/dist/lib/updates.js +2418 -641
- package/dist/lib/voice.d.ts +7 -22
- package/dist/lib/voice.js +7 -22
- package/dist/lib/wire.js +1 -1
- package/dist/lib/workspace-admission.d.ts +3 -1
- package/dist/lib/workspace-admission.js +425 -211
- package/dist/lib/workspace-identity.js +8 -13
- package/dist/lib/workspace-retirement.d.ts +1 -1
- package/dist/lib/workspace-retirement.js +328 -140
- package/dist/lib/workspace-slots.js +8 -4
- package/dist/package.json +1 -1
- package/docs/architecture.md +31 -29
- package/docs/inbound.md +1 -1
- package/docs/multi-instance-bus.md +15 -3
- package/docs/outbound.md +1 -1
- package/docs/public-api.md +29 -1
- package/docs/ui-style.md +25 -8
- package/lib/activity-verbosity.ts +59 -82
- package/lib/activity.ts +146 -102
- package/lib/agent-messages.ts +12 -5
- package/lib/bindings.ts +389 -82
- package/lib/bus-api.ts +263 -102
- package/lib/bus-follower.ts +2440 -601
- package/lib/bus-leader.ts +2209 -1290
- package/lib/bus-transport.ts +46 -12
- package/lib/bus.ts +1673 -444
- package/lib/channel-posts.ts +848 -327
- package/lib/command-templates.ts +152 -265
- package/lib/commands.ts +2398 -555
- package/lib/config.ts +177 -170
- package/lib/delivery.ts +41 -29
- package/lib/extension.ts +1206 -433
- package/lib/generative-app-worker.mjs +19 -7
- package/lib/generative-apps.ts +324 -211
- package/lib/inbound.ts +95 -97
- package/lib/journal.ts +5311 -1763
- package/lib/keyboard.ts +1 -3
- package/lib/lifecycle.ts +128 -78
- package/lib/locks.ts +677 -203
- package/lib/logging.ts +147 -58
- package/lib/media.ts +82 -43
- package/lib/menu-model.ts +85 -18
- package/lib/menu-queue.ts +88 -129
- package/lib/menu-settings.ts +260 -155
- package/lib/menu-status.ts +20 -60
- package/lib/menu-thinking.ts +41 -56
- package/lib/menu.ts +112 -285
- package/lib/model.ts +8 -22
- package/lib/outbound-attachments.ts +156 -125
- package/lib/outbound-buttons.ts +76 -49
- package/lib/outbound-markup.ts +96 -94
- package/lib/outbound-voice.ts +33 -27
- package/lib/outbound.ts +125 -125
- package/lib/ownership.ts +19 -10
- package/lib/paths.ts +148 -49
- package/lib/pi.ts +35 -15
- package/lib/polling.ts +144 -147
- package/lib/preview.ts +93 -40
- package/lib/process-identity.ts +164 -0
- package/lib/prompts.ts +4 -11
- package/lib/queue.ts +511 -300
- package/lib/recovery.ts +50 -454
- package/lib/rendering.ts +1 -3
- package/lib/replies.ts +248 -209
- package/lib/routing.ts +8509 -2186
- package/lib/runtime.ts +1 -12
- package/lib/sections.ts +24 -89
- package/lib/setup.ts +1 -3
- package/lib/skills.ts +9 -4
- package/lib/status.ts +215 -110
- package/lib/sync.ts +448 -361
- package/lib/target.ts +22 -3
- package/lib/telegram-api.ts +302 -127
- package/lib/text-groups.ts +5 -39
- package/lib/thread-cleanup-manager.ts +833 -331
- package/lib/thread-display.ts +213 -97
- package/lib/thread-naming.ts +232 -87
- package/lib/thread-reconciler.ts +155 -72
- package/lib/threads.ts +5318 -1845
- package/lib/time-injection.ts +1 -4
- package/lib/turns.ts +15 -28
- package/lib/updates.ts +5184 -1612
- package/lib/voice.ts +7 -35
- package/lib/wire.ts +1 -1
- package/lib/workspace-admission.ts +996 -416
- package/lib/workspace-identity.ts +14 -17
- package/lib/workspace-retirement.ts +878 -376
- package/lib/workspace-slots.ts +22 -13
- package/package.json +1 -1
- package/scripts/check-downgrade.mjs +0 -472
- package/scripts/measure-workspace.mjs +0 -108
package/dist/lib/config.d.ts
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* Zones: telegram config, pairing, filesystem
|
|
4
4
|
* Owns persisted bot/session pairing state, local config storage, live config controls, authorization policy, and first-user pairing side effects
|
|
5
5
|
*/
|
|
6
|
-
export { TELEGRAM_DEFAULT_PROFILE_NAME } from "./paths.ts";
|
|
7
6
|
import type { CommandTemplateObjectConfig } from "./command-templates.ts";
|
|
8
7
|
import type { TelegramInboundHandlerConfig } from "./inbound.ts";
|
|
8
|
+
export { TELEGRAM_DEFAULT_PROFILE_NAME } from "./paths.ts";
|
|
9
9
|
/** Parsed stored bot-token form: a literal secret or one environment-variable reference. */
|
|
10
10
|
export type TelegramBotTokenReference = {
|
|
11
11
|
kind: "literal";
|
|
@@ -152,20 +152,13 @@ export interface TelegramInvalidConfigRecovery {
|
|
|
152
152
|
recoveryPath: string;
|
|
153
153
|
error: unknown;
|
|
154
154
|
}
|
|
155
|
-
export interface TelegramConfigRuntime {
|
|
156
|
-
updateVoiceConfig: (voice: NonNullable<TelegramConfig["voice"]>) => void;
|
|
157
|
-
}
|
|
158
|
-
export declare function setGlobalTelegramConfigRuntime(runtime: TelegramConfigRuntime | undefined): void;
|
|
159
|
-
export declare function updateTelegramVoiceConfig(voice: NonNullable<TelegramConfig["voice"]>): boolean;
|
|
160
155
|
type TelegramMutableConfigStore = Pick<TelegramConfigStore, "get" | "set" | "persist"> & {
|
|
161
156
|
load?: () => Promise<void>;
|
|
162
157
|
didLastLoadRecoverInvalidConfig?: () => boolean;
|
|
163
158
|
};
|
|
164
|
-
export declare function bindGlobalTelegramConfigRuntime(configStore: TelegramMutableConfigStore): void;
|
|
165
159
|
export declare function readTelegramConfig(configPath: string, options?: {
|
|
166
160
|
onInvalidConfig?: (recovery: TelegramInvalidConfigRecovery) => void;
|
|
167
161
|
}): Promise<TelegramConfig>;
|
|
168
|
-
export declare function writeTelegramConfig(agentDir: string, configPath: string, config: TelegramConfig): Promise<void>;
|
|
169
162
|
export declare function getTelegramProfileFields(config: TelegramConfig): TelegramBotProfile | undefined;
|
|
170
163
|
export declare function normalizeTelegramDefaultProfileConfig(config: TelegramConfig): {
|
|
171
164
|
config: TelegramConfig;
|
package/dist/lib/config.js
CHANGED
|
@@ -5,12 +5,11 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { createHash, randomUUID } from "node:crypto";
|
|
7
7
|
import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
8
|
-
import {
|
|
8
|
+
import { withTelegramFileTransaction } from "./locks.js";
|
|
9
9
|
import { resolveAgentDir, resolveTelegramConfigPath, TELEGRAM_DEFAULT_PROFILE_NAME, } from "./paths.js";
|
|
10
|
-
|
|
10
|
+
import { isPiStaleContextError } from "./pi.js";
|
|
11
11
|
import { isWireRecord as isPlainConfigRecord } from "./wire.js";
|
|
12
|
-
|
|
13
|
-
const CONFIG_RUNTIME_KEY = "__piTelegramConfigRuntime__";
|
|
12
|
+
export { TELEGRAM_DEFAULT_PROFILE_NAME } from "./paths.js";
|
|
14
13
|
const CONFIG_REPLACE_RETRY_ATTEMPTS = 5;
|
|
15
14
|
const CONFIG_REPLACE_RETRY_DELAY_MS = 25;
|
|
16
15
|
function isRetryableConfigReplaceError(error) {
|
|
@@ -81,7 +80,10 @@ export function getTelegramBotTokenDiagnostic(value, env = process.env) {
|
|
|
81
80
|
return `Telegram bot token environment variable ${reference.variable} is not set.`;
|
|
82
81
|
}
|
|
83
82
|
const TELEGRAM_THREAD_DISPLAY_MODES = [
|
|
84
|
-
"letters",
|
|
83
|
+
"letters",
|
|
84
|
+
"names",
|
|
85
|
+
"directory-snake",
|
|
86
|
+
"directory-title",
|
|
85
87
|
];
|
|
86
88
|
export function resolveTelegramThreadDisplayMode(config) {
|
|
87
89
|
return TELEGRAM_THREAD_DISPLAY_MODES.includes(config.threadDisplayMode)
|
|
@@ -124,20 +126,6 @@ export function createTelegramConfigBotIdGetter(store) {
|
|
|
124
126
|
export function createTelegramActiveProfileKeyGetter(store) {
|
|
125
127
|
return () => store.getActiveProfileName() ?? TELEGRAM_DEFAULT_PROFILE_NAME;
|
|
126
128
|
}
|
|
127
|
-
export function setGlobalTelegramConfigRuntime(runtime) {
|
|
128
|
-
const globals = globalThis;
|
|
129
|
-
if (runtime)
|
|
130
|
-
globals[CONFIG_RUNTIME_KEY] = runtime;
|
|
131
|
-
else
|
|
132
|
-
delete globals[CONFIG_RUNTIME_KEY];
|
|
133
|
-
}
|
|
134
|
-
export function updateTelegramVoiceConfig(voice) {
|
|
135
|
-
const runtime = globalThis[CONFIG_RUNTIME_KEY];
|
|
136
|
-
if (!runtime || typeof runtime.updateVoiceConfig !== "function")
|
|
137
|
-
return false;
|
|
138
|
-
runtime.updateVoiceConfig(voice);
|
|
139
|
-
return true;
|
|
140
|
-
}
|
|
141
129
|
function isEmptyTelegramConfig(config) {
|
|
142
130
|
return Object.keys(config).length === 0;
|
|
143
131
|
}
|
|
@@ -151,19 +139,6 @@ async function loadLatestTelegramConfig(configStore) {
|
|
|
151
139
|
configStore.set(before);
|
|
152
140
|
}
|
|
153
141
|
}
|
|
154
|
-
export function bindGlobalTelegramConfigRuntime(configStore) {
|
|
155
|
-
setGlobalTelegramConfigRuntime({
|
|
156
|
-
updateVoiceConfig(voice) {
|
|
157
|
-
const current = configStore.get();
|
|
158
|
-
const next = {
|
|
159
|
-
...current,
|
|
160
|
-
voice: { ...(current.voice ?? {}), ...voice },
|
|
161
|
-
};
|
|
162
|
-
configStore.set(next);
|
|
163
|
-
void configStore.persist(next);
|
|
164
|
-
},
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
142
|
function getInvalidTelegramConfigRecoveryPath(configPath) {
|
|
168
143
|
return `${configPath}.invalid-${process.pid}-${Date.now()}`;
|
|
169
144
|
}
|
|
@@ -201,17 +176,6 @@ export async function readTelegramConfig(configPath, options = {}) {
|
|
|
201
176
|
});
|
|
202
177
|
}
|
|
203
178
|
}
|
|
204
|
-
export async function writeTelegramConfig(agentDir, configPath, config) {
|
|
205
|
-
await mkdir(agentDir, { recursive: true });
|
|
206
|
-
const tempConfigPath = `${configPath}.tmp-${process.pid}-${Date.now()}`;
|
|
207
|
-
await writeFile(tempConfigPath, JSON.stringify(config, null, "\t") + "\n", {
|
|
208
|
-
encoding: "utf8",
|
|
209
|
-
mode: 0o600,
|
|
210
|
-
});
|
|
211
|
-
await chmod(tempConfigPath, 0o600);
|
|
212
|
-
await rename(tempConfigPath, configPath);
|
|
213
|
-
await chmod(configPath, 0o600);
|
|
214
|
-
}
|
|
215
179
|
function cloneTelegramConfig(value) {
|
|
216
180
|
return structuredClone(value);
|
|
217
181
|
}
|
|
@@ -275,10 +239,13 @@ export function getTelegramProfileFields(config) {
|
|
|
275
239
|
const token = config.botToken?.trim();
|
|
276
240
|
if (!token)
|
|
277
241
|
return undefined;
|
|
242
|
+
return { botToken: token, ...pickTelegramRootProfileFields(config) };
|
|
243
|
+
}
|
|
244
|
+
/** Root-level profile fields other than the token, including the retired legacy cursor. */
|
|
245
|
+
function pickTelegramRootProfileFields(config) {
|
|
278
246
|
const legacyCursor = config
|
|
279
247
|
.lastUpdateId;
|
|
280
248
|
return {
|
|
281
|
-
botToken: token,
|
|
282
249
|
...(config.botUsername !== undefined
|
|
283
250
|
? { botUsername: config.botUsername }
|
|
284
251
|
: {}),
|
|
@@ -332,23 +299,7 @@ export function normalizeTelegramDefaultProfileConfig(config) {
|
|
|
332
299
|
}
|
|
333
300
|
const legacyProfile = {
|
|
334
301
|
...(legacyToken ? { botToken: legacyToken } : {}),
|
|
335
|
-
...(config
|
|
336
|
-
? { botUsername: config.botUsername }
|
|
337
|
-
: {}),
|
|
338
|
-
...(config.botId !== undefined ? { botId: config.botId } : {}),
|
|
339
|
-
...(config.allowedUserId !== undefined
|
|
340
|
-
? { allowedUserId: config.allowedUserId }
|
|
341
|
-
: {}),
|
|
342
|
-
...(config.threadDisplayMode !== undefined
|
|
343
|
-
? { threadDisplayMode: config.threadDisplayMode }
|
|
344
|
-
: {}),
|
|
345
|
-
...(config
|
|
346
|
-
.lastUpdateId !== undefined
|
|
347
|
-
? {
|
|
348
|
-
lastUpdateId: config
|
|
349
|
-
.lastUpdateId,
|
|
350
|
-
}
|
|
351
|
-
: {}),
|
|
302
|
+
...pickTelegramRootProfileFields(config),
|
|
352
303
|
};
|
|
353
304
|
if (!canonicalProfile && !legacyToken) {
|
|
354
305
|
throw new Error("Legacy Telegram default profile has no bot token");
|
|
@@ -421,7 +372,8 @@ export function createTelegramConfigStore(options = {}) {
|
|
|
421
372
|
config = nextConfig;
|
|
422
373
|
};
|
|
423
374
|
const withPersistedPairingProfile = (profileName, tokenSha256, observe) => {
|
|
424
|
-
if ((profileName !== TELEGRAM_DEFAULT_PROFILE_NAME &&
|
|
375
|
+
if ((profileName !== TELEGRAM_DEFAULT_PROFILE_NAME &&
|
|
376
|
+
!isValidTelegramProfileName(profileName)) ||
|
|
425
377
|
!/^[a-f0-9]{64}$/u.test(tokenSha256)) {
|
|
426
378
|
throw new Error("Invalid Telegram pairing admission identity.");
|
|
427
379
|
}
|
|
@@ -431,10 +383,13 @@ export function createTelegramConfigStore(options = {}) {
|
|
|
431
383
|
const resolvedToken = typeof profile?.botToken === "string"
|
|
432
384
|
? resolveTelegramBotToken(profile.botToken, env)
|
|
433
385
|
: undefined;
|
|
434
|
-
if (!profile ||
|
|
435
|
-
|
|
386
|
+
if (!profile ||
|
|
387
|
+
!resolvedToken ||
|
|
388
|
+
createHash("sha256").update(resolvedToken).digest("hex") !==
|
|
389
|
+
tokenSha256 ||
|
|
436
390
|
(profile.allowedUserId !== undefined &&
|
|
437
|
-
(!Number.isSafeInteger(profile.allowedUserId) ||
|
|
391
|
+
(!Number.isSafeInteger(profile.allowedUserId) ||
|
|
392
|
+
profile.allowedUserId <= 0))) {
|
|
438
393
|
throw new Error("Telegram pairing admission authority is unavailable or changed.");
|
|
439
394
|
}
|
|
440
395
|
return observe(latest, profile);
|
|
@@ -506,9 +461,11 @@ export function createTelegramConfigStore(options = {}) {
|
|
|
506
461
|
assertExecutionCurrent?.();
|
|
507
462
|
const current = getEffectiveConfig();
|
|
508
463
|
const previousOwner = persistedConfig.profiles?.[profileName]?.allowedUserId;
|
|
509
|
-
if ((activeProfileName ?? TELEGRAM_DEFAULT_PROFILE_NAME) !==
|
|
464
|
+
if ((activeProfileName ?? TELEGRAM_DEFAULT_PROFILE_NAME) !==
|
|
465
|
+
profileName ||
|
|
510
466
|
current.botToken !== profile.botToken ||
|
|
511
|
-
(current.allowedUserId !== undefined &&
|
|
467
|
+
(current.allowedUserId !== undefined &&
|
|
468
|
+
current.allowedUserId !== userId) ||
|
|
512
469
|
(current.allowedUserId === undefined && previousOwner !== undefined)) {
|
|
513
470
|
throw new Error("Telegram paired admission lost local profile authority.");
|
|
514
471
|
}
|
|
@@ -524,7 +481,8 @@ export function createTelegramConfigStore(options = {}) {
|
|
|
524
481
|
const previousOwner = getEffectiveConfig().allowedUserId;
|
|
525
482
|
const assertCurrent = () => {
|
|
526
483
|
assertExecutionCurrent?.();
|
|
527
|
-
if (activeProfileName !== profileName ||
|
|
484
|
+
if (activeProfileName !== profileName ||
|
|
485
|
+
getEffectiveConfig().botToken !== botToken ||
|
|
528
486
|
getEffectiveConfig().allowedUserId !== previousOwner) {
|
|
529
487
|
throw new Error("Telegram pairing lost its originating profile authority.");
|
|
530
488
|
}
|
|
@@ -544,8 +502,13 @@ export function createTelegramConfigStore(options = {}) {
|
|
|
544
502
|
assertCurrent();
|
|
545
503
|
if (profile.allowedUserId !== undefined)
|
|
546
504
|
return latest;
|
|
547
|
-
const next = {
|
|
548
|
-
|
|
505
|
+
const next = {
|
|
506
|
+
...latest,
|
|
507
|
+
profiles: {
|
|
508
|
+
...latest.profiles,
|
|
509
|
+
[profileKey]: { ...profile, allowedUserId: userId },
|
|
510
|
+
},
|
|
511
|
+
};
|
|
549
512
|
writeTelegramConfigInTransaction(agentDir, configPath, next);
|
|
550
513
|
return next;
|
|
551
514
|
});
|
|
@@ -851,11 +814,6 @@ export function getTelegramAuthorizationState(userId, allowedUserId) {
|
|
|
851
814
|
}
|
|
852
815
|
return { kind: "deny" };
|
|
853
816
|
}
|
|
854
|
-
function isTelegramStaleContextError(error) {
|
|
855
|
-
return (error instanceof Error &&
|
|
856
|
-
(error.message.includes("stale after session") ||
|
|
857
|
-
error.message.includes("stale ctx")));
|
|
858
|
-
}
|
|
859
817
|
export async function pairTelegramUserIfNeeded(userId, deps) {
|
|
860
818
|
const authorization = getTelegramAuthorizationState(userId, deps.allowedUserId);
|
|
861
819
|
if (authorization.kind !== "pair")
|
|
@@ -869,7 +827,7 @@ export async function pairTelegramUserIfNeeded(userId, deps) {
|
|
|
869
827
|
deps.updateStatus(deps.ctx);
|
|
870
828
|
}
|
|
871
829
|
catch (error) {
|
|
872
|
-
if (!
|
|
830
|
+
if (!isPiStaleContextError(error))
|
|
873
831
|
throw error;
|
|
874
832
|
}
|
|
875
833
|
return true;
|
package/dist/lib/delivery.d.ts
CHANGED
|
@@ -49,6 +49,7 @@ export type TelegramDeliveryChatAction = "typing" | "upload_document" | "upload_
|
|
|
49
49
|
/** @internal */
|
|
50
50
|
export interface TelegramDeliveryRuntime {
|
|
51
51
|
readonly generation: string;
|
|
52
|
+
hasPendingTarget?: (target: TelegramDeliveryTarget) => boolean;
|
|
52
53
|
shutdown: () => void;
|
|
53
54
|
sendView: (view: TelegramDeliveryView, options: SendTelegramViewOptions) => Promise<TelegramDeliveryResult<TelegramDeliveryHandle>>;
|
|
54
55
|
editView: (handle: TelegramDeliveryHandle, view: TelegramDeliveryView) => Promise<TelegramDeliveryResult<TelegramDeliveryHandle>>;
|
|
@@ -100,6 +101,7 @@ export interface TelegramBridgeDeliveryRuntimeDeps {
|
|
|
100
101
|
export declare function createTelegramDeliveryLifecycleHooks(createRuntime: () => TelegramDeliveryRuntime): {
|
|
101
102
|
onSessionStart: () => Promise<void>;
|
|
102
103
|
onSessionShutdown: () => Promise<void>;
|
|
104
|
+
hasPendingTarget: (target: TelegramDeliveryTarget) => boolean | undefined;
|
|
103
105
|
};
|
|
104
106
|
export declare function createTelegramDeliveryGenerationSeed(instanceId: string): string;
|
|
105
107
|
/** @internal */
|
|
@@ -152,8 +154,6 @@ export declare function clearTelegramDeliveryRuntime(): void;
|
|
|
152
154
|
/** @internal */
|
|
153
155
|
export declare function isTelegramDeliveryHandleCurrent(handle: TelegramDeliveryHandle): boolean;
|
|
154
156
|
export declare function sendTelegramView(view: TelegramDeliveryView, options: SendTelegramViewOptions): Promise<TelegramDeliveryResult<TelegramDeliveryHandle>>;
|
|
155
|
-
/** @internal Edit an exact Telegram message through the currently bound runtime generation. */
|
|
156
|
-
export declare function editTelegramTargetView(target: TelegramDeliveryTarget, messageId: number, view: TelegramDeliveryView): Promise<TelegramDeliveryResult<TelegramDeliveryHandle>>;
|
|
157
157
|
export declare function editTelegramView(handle: TelegramDeliveryHandle, view: TelegramDeliveryView): Promise<TelegramDeliveryResult<TelegramDeliveryHandle>>;
|
|
158
158
|
export declare function deleteTelegramView(handle: TelegramDeliveryHandle): Promise<TelegramDeliveryResult<void>>;
|
|
159
159
|
export declare function sendTelegramChatAction(action: TelegramDeliveryChatAction, options: {
|
package/dist/lib/delivery.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { markTelegramBusAggregateDelivery } from "./bus.js";
|
|
7
7
|
import { assertTelegramInlineKeyboardCallbackData, } from "./keyboard.js";
|
|
8
|
-
import {
|
|
8
|
+
import { renderTelegramMessage, withTelegramReplyParameters, } from "./replies.js";
|
|
9
9
|
import { areTelegramTargetsEqual as areDeliveryTargetsEqual, getTelegramTargetThreadParams, } from "./target.js";
|
|
10
10
|
import { getTelegramApiRetryAfterMs, isRetryableTelegramApiError, isTelegramApiCommitUnknownError, isTelegramMessageUnavailableError, } from "./telegram-api.js";
|
|
11
11
|
const TELEGRAM_DELIVERY_RUNTIME_KEY = "__piTelegramDeliveryRuntime__";
|
|
@@ -26,6 +26,7 @@ export function createTelegramDeliveryLifecycleHooks(createRuntime) {
|
|
|
26
26
|
runtime = undefined;
|
|
27
27
|
};
|
|
28
28
|
return {
|
|
29
|
+
hasPendingTarget: (target) => runtime?.hasPendingTarget?.(target),
|
|
29
30
|
onSessionStart: async () => {
|
|
30
31
|
stopCurrentRuntime();
|
|
31
32
|
runtime = createRuntime();
|
|
@@ -167,7 +168,7 @@ function resolveTelegramDeliveryTarget(scope, deps) {
|
|
|
167
168
|
}
|
|
168
169
|
function createTelegramDeliveryTargetQueue() {
|
|
169
170
|
const queues = new Map();
|
|
170
|
-
|
|
171
|
+
async function run(target, operation) {
|
|
171
172
|
const key = targetKey(target);
|
|
172
173
|
const previous = queues.get(key) ?? Promise.resolve();
|
|
173
174
|
const current = previous.then(operation, operation);
|
|
@@ -180,6 +181,10 @@ function createTelegramDeliveryTargetQueue() {
|
|
|
180
181
|
if (queues.get(key) === settled)
|
|
181
182
|
queues.delete(key);
|
|
182
183
|
}
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
run,
|
|
187
|
+
hasPendingTarget: (target) => queues.has(targetKey(target)),
|
|
183
188
|
};
|
|
184
189
|
}
|
|
185
190
|
function getChunkTransportOptions(view, index, chunkCount, replyToMessageId, editing = false) {
|
|
@@ -198,7 +203,8 @@ function getChunkTransportOptions(view, index, chunkCount, replyToMessageId, edi
|
|
|
198
203
|
export function createTelegramDeliveryRuntime(deps) {
|
|
199
204
|
let active = true;
|
|
200
205
|
const handleBindings = new WeakMap();
|
|
201
|
-
const
|
|
206
|
+
const targetQueue = createTelegramDeliveryTargetQueue();
|
|
207
|
+
const runForTarget = targetQueue.run;
|
|
202
208
|
const render = (view) => {
|
|
203
209
|
const chunks = deps.renderView(view);
|
|
204
210
|
if (chunks.length === 0 ||
|
|
@@ -247,6 +253,7 @@ export function createTelegramDeliveryRuntime(deps) {
|
|
|
247
253
|
};
|
|
248
254
|
return {
|
|
249
255
|
generation: deps.generation,
|
|
256
|
+
hasPendingTarget: targetQueue.hasPendingTarget,
|
|
250
257
|
shutdown() {
|
|
251
258
|
active = false;
|
|
252
259
|
},
|
|
@@ -420,10 +427,14 @@ export function createTelegramBridgeDeliveryRuntime(deps) {
|
|
|
420
427
|
const body = {
|
|
421
428
|
chat_id: target.chatId,
|
|
422
429
|
text: chunk.text,
|
|
423
|
-
...(chunk.parseMode === "html"
|
|
430
|
+
...(chunk.parseMode === "html"
|
|
431
|
+
? { parse_mode: "HTML" }
|
|
432
|
+
: {}),
|
|
424
433
|
...getTelegramTargetThreadParams(target),
|
|
425
434
|
...(replyParameters ? { reply_parameters: replyParameters } : {}),
|
|
426
|
-
...(options.replyMarkup
|
|
435
|
+
...(options.replyMarkup
|
|
436
|
+
? { reply_markup: options.replyMarkup }
|
|
437
|
+
: {}),
|
|
427
438
|
};
|
|
428
439
|
return deps.api.sendMessage(target.threadId === undefined
|
|
429
440
|
? markTelegramBusAggregateDelivery(body)
|
|
@@ -515,17 +526,6 @@ export async function sendTelegramView(view, options) {
|
|
|
515
526
|
return invalid;
|
|
516
527
|
return runDeliveryOperation((runtime) => runtime.sendView(view, options));
|
|
517
528
|
}
|
|
518
|
-
/** @internal Edit an exact Telegram message through the currently bound runtime generation. */
|
|
519
|
-
export async function editTelegramTargetView(target, messageId, view) {
|
|
520
|
-
const invalid = validateView(view);
|
|
521
|
-
if (invalid)
|
|
522
|
-
return invalid;
|
|
523
|
-
return runDeliveryOperation((runtime) => runtime.editView({
|
|
524
|
-
target: { ...target },
|
|
525
|
-
messageIds: [messageId],
|
|
526
|
-
generation: runtime.generation,
|
|
527
|
-
}, view));
|
|
528
|
-
}
|
|
529
529
|
export async function editTelegramView(handle, view) {
|
|
530
530
|
const invalid = validateView(view);
|
|
531
531
|
if (invalid)
|