@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/lib/activity.ts
CHANGED
|
@@ -20,10 +20,7 @@ import {
|
|
|
20
20
|
const TELEGRAM_ACTIVITY_REGISTRY_KEY = "__piTelegramActivityRegistry__";
|
|
21
21
|
|
|
22
22
|
export type TelegramActivitySource =
|
|
23
|
-
| "
|
|
24
|
-
| "local"
|
|
25
|
-
| "autonomous"
|
|
26
|
-
| "unknown";
|
|
23
|
+
"telegram" | "local" | "autonomous" | "unknown";
|
|
27
24
|
|
|
28
25
|
export type TelegramActivityTarget = Readonly<TelegramDeliveryTarget>;
|
|
29
26
|
|
|
@@ -38,61 +35,61 @@ export interface TelegramActivityEnvelope {
|
|
|
38
35
|
|
|
39
36
|
export type TelegramActivityPayload =
|
|
40
37
|
| { type: "agent-start" }
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
38
|
+
| {
|
|
39
|
+
type: "assistant-text-delta";
|
|
40
|
+
contentIndex: number;
|
|
41
|
+
delta: string;
|
|
42
|
+
}
|
|
43
|
+
| {
|
|
44
|
+
type: "assistant-segment";
|
|
45
|
+
contentIndex: number;
|
|
46
|
+
text: string;
|
|
47
|
+
placement: "intermediate" | "final" | "terminal-partial";
|
|
48
|
+
}
|
|
49
|
+
| {
|
|
50
|
+
type: "reasoning-delta";
|
|
51
|
+
contentIndex: number;
|
|
52
|
+
delta: string;
|
|
53
|
+
}
|
|
54
|
+
| {
|
|
55
|
+
type: "reasoning-end";
|
|
56
|
+
contentIndex: number;
|
|
57
|
+
text: string;
|
|
58
|
+
}
|
|
59
|
+
| {
|
|
60
|
+
type: "tool-start";
|
|
61
|
+
toolCallId: string;
|
|
62
|
+
toolName: string;
|
|
63
|
+
args: unknown;
|
|
64
|
+
}
|
|
65
|
+
| {
|
|
66
|
+
type: "tool-update";
|
|
67
|
+
toolCallId: string;
|
|
68
|
+
toolName: string;
|
|
69
|
+
update: unknown;
|
|
70
|
+
}
|
|
71
|
+
| {
|
|
72
|
+
type: "tool-end";
|
|
73
|
+
toolCallId: string;
|
|
74
|
+
toolName: string;
|
|
75
|
+
result: unknown;
|
|
76
|
+
isError: boolean;
|
|
77
|
+
}
|
|
78
|
+
| {
|
|
79
|
+
type: "compaction-start";
|
|
80
|
+
reason: "manual" | "threshold" | "overflow" | "unknown";
|
|
81
|
+
}
|
|
82
|
+
| {
|
|
83
|
+
type: "compaction-end";
|
|
84
|
+
reason: "manual" | "threshold" | "overflow" | "unknown";
|
|
85
|
+
}
|
|
86
|
+
| {
|
|
87
|
+
type: "ui-prompt-start";
|
|
88
|
+
kind: "select" | "confirm" | "input" | "editor" | "custom";
|
|
89
|
+
title?: string;
|
|
90
|
+
}
|
|
91
|
+
| { type: "ui-prompt-end" }
|
|
92
|
+
| { type: "agent-end" }
|
|
96
93
|
| { type: "agent-settled" };
|
|
97
94
|
|
|
98
95
|
export type TelegramActivityEvent = TelegramActivityEnvelope &
|
|
@@ -135,8 +132,7 @@ export interface TelegramActivityHandlerRegistration {
|
|
|
135
132
|
) => void | Promise<void>;
|
|
136
133
|
}
|
|
137
134
|
|
|
138
|
-
interface RegisteredTelegramActivityHandler
|
|
139
|
-
extends TelegramActivityHandlerRegistration {
|
|
135
|
+
interface RegisteredTelegramActivityHandler extends TelegramActivityHandlerRegistration {
|
|
140
136
|
id: string;
|
|
141
137
|
order: number;
|
|
142
138
|
}
|
|
@@ -257,10 +253,7 @@ function canCoalesceActivityEvents(
|
|
|
257
253
|
previous: TelegramActivityEvent,
|
|
258
254
|
next: TelegramActivityEvent,
|
|
259
255
|
): boolean {
|
|
260
|
-
if (
|
|
261
|
-
previous.activityId !== next.activityId ||
|
|
262
|
-
previous.type !== next.type
|
|
263
|
-
) {
|
|
256
|
+
if (previous.activityId !== next.activityId || previous.type !== next.type) {
|
|
264
257
|
return false;
|
|
265
258
|
}
|
|
266
259
|
if (
|
|
@@ -269,10 +262,7 @@ function canCoalesceActivityEvents(
|
|
|
269
262
|
) {
|
|
270
263
|
return previous.contentIndex === next.contentIndex;
|
|
271
264
|
}
|
|
272
|
-
if (
|
|
273
|
-
previous.type === "reasoning-delta" &&
|
|
274
|
-
next.type === "reasoning-delta"
|
|
275
|
-
) {
|
|
265
|
+
if (previous.type === "reasoning-delta" && next.type === "reasoning-delta") {
|
|
276
266
|
return previous.contentIndex === next.contentIndex;
|
|
277
267
|
}
|
|
278
268
|
if (previous.type === "tool-update" && next.type === "tool-update") {
|
|
@@ -291,10 +281,7 @@ function coalesceActivityEvents(
|
|
|
291
281
|
) {
|
|
292
282
|
return { ...next, delta: previous.delta + next.delta };
|
|
293
283
|
}
|
|
294
|
-
if (
|
|
295
|
-
previous.type === "reasoning-delta" &&
|
|
296
|
-
next.type === "reasoning-delta"
|
|
297
|
-
) {
|
|
284
|
+
if (previous.type === "reasoning-delta" && next.type === "reasoning-delta") {
|
|
298
285
|
return { ...next, delta: previous.delta + next.delta };
|
|
299
286
|
}
|
|
300
287
|
return next;
|
|
@@ -302,18 +289,21 @@ function coalesceActivityEvents(
|
|
|
302
289
|
|
|
303
290
|
/** @internal */
|
|
304
291
|
export interface TelegramActivityDispatcher {
|
|
292
|
+
hasPending?: () => boolean;
|
|
305
293
|
dispatch: (event: TelegramActivityEvent) => void;
|
|
306
294
|
stop: () => void;
|
|
307
295
|
}
|
|
308
296
|
|
|
309
297
|
/** @internal */
|
|
310
|
-
export function createTelegramActivityDispatcher(
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
298
|
+
export function createTelegramActivityDispatcher(
|
|
299
|
+
deps: {
|
|
300
|
+
recordFailure?: (
|
|
301
|
+
handlerId: string,
|
|
302
|
+
event: TelegramActivityEvent,
|
|
303
|
+
error: unknown,
|
|
304
|
+
) => void;
|
|
305
|
+
} = {},
|
|
306
|
+
): TelegramActivityDispatcher {
|
|
317
307
|
const queues = new Map<string, TelegramActivityHandlerQueue>();
|
|
318
308
|
let stopped = false;
|
|
319
309
|
const drain = async (queue: TelegramActivityHandlerQueue): Promise<void> => {
|
|
@@ -335,12 +325,14 @@ export function createTelegramActivityDispatcher(deps: {
|
|
|
335
325
|
try {
|
|
336
326
|
await queue.registration.handle(
|
|
337
327
|
event,
|
|
338
|
-
createTelegramActivityContext(
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
328
|
+
createTelegramActivityContext(
|
|
329
|
+
event,
|
|
330
|
+
() =>
|
|
331
|
+
queue.active &&
|
|
332
|
+
!stopped &&
|
|
333
|
+
getOrCreateTelegramActivityRegistry().handlers.get(
|
|
334
|
+
queue.registration.id,
|
|
335
|
+
) === queue.registration,
|
|
344
336
|
),
|
|
345
337
|
);
|
|
346
338
|
} catch (error) {
|
|
@@ -352,6 +344,10 @@ export function createTelegramActivityDispatcher(deps: {
|
|
|
352
344
|
}
|
|
353
345
|
};
|
|
354
346
|
return {
|
|
347
|
+
hasPending: () =>
|
|
348
|
+
Array.from(queues.values()).some(
|
|
349
|
+
(queue) => queue.active && (queue.running || queue.events.length > 0),
|
|
350
|
+
),
|
|
355
351
|
dispatch(event) {
|
|
356
352
|
if (stopped) return;
|
|
357
353
|
for (const registration of getTelegramActivityHandlers()) {
|
|
@@ -405,6 +401,7 @@ export function createTelegramActivityBridgeRuntime(deps: {
|
|
|
405
401
|
let runtime: TelegramActivityRuntime | undefined;
|
|
406
402
|
const getRuntime = (): TelegramActivityRuntime | undefined => runtime;
|
|
407
403
|
return {
|
|
404
|
+
hasPending: () => getRuntime()?.hasPending?.(),
|
|
408
405
|
onSessionStart() {
|
|
409
406
|
runtime?.onSessionShutdown();
|
|
410
407
|
runtime = createTelegramActivityRuntime({
|
|
@@ -470,10 +467,7 @@ export function createTelegramActivityBridgeRuntime(deps: {
|
|
|
470
467
|
}
|
|
471
468
|
|
|
472
469
|
export type TelegramActivityInputSource =
|
|
473
|
-
| "
|
|
474
|
-
| "rpc"
|
|
475
|
-
| "extension"
|
|
476
|
-
| "unknown";
|
|
470
|
+
"interactive" | "rpc" | "extension" | "unknown";
|
|
477
471
|
|
|
478
472
|
export type TelegramAssistantStreamEvent =
|
|
479
473
|
| { type: "start" }
|
|
@@ -491,9 +485,13 @@ export type TelegramAssistantStreamEvent =
|
|
|
491
485
|
|
|
492
486
|
/** @internal */
|
|
493
487
|
export interface TelegramActivityRuntime {
|
|
488
|
+
hasPending?: () => boolean | undefined;
|
|
494
489
|
onSessionStart?: () => void;
|
|
495
490
|
recordInputSource: (source: TelegramActivityInputSource) => void;
|
|
496
|
-
onAgentStart: (
|
|
491
|
+
onAgentStart: (
|
|
492
|
+
activeTelegramTarget?: TelegramActivityTarget,
|
|
493
|
+
replyToMessageId?: number,
|
|
494
|
+
) => void;
|
|
497
495
|
onAssistantEvent: (event: TelegramAssistantStreamEvent) => void;
|
|
498
496
|
onAssistantMessageEnd: (stopReason?: string) => void;
|
|
499
497
|
onToolStart: (event: {
|
|
@@ -586,7 +584,9 @@ export function createTelegramActivityRuntime(deps: {
|
|
|
586
584
|
sequence,
|
|
587
585
|
source: activitySource,
|
|
588
586
|
...(activityTarget ? { target: activityTarget } : {}),
|
|
589
|
-
...(activityReplyToMessageId !== undefined
|
|
587
|
+
...(activityReplyToMessageId !== undefined
|
|
588
|
+
? { replyToMessageId: activityReplyToMessageId }
|
|
589
|
+
: {}),
|
|
590
590
|
timestamp: now(),
|
|
591
591
|
} as TelegramActivityEvent;
|
|
592
592
|
try {
|
|
@@ -628,13 +628,15 @@ export function createTelegramActivityRuntime(deps: {
|
|
|
628
628
|
if (shouldClearActivity) clearActivity();
|
|
629
629
|
};
|
|
630
630
|
return {
|
|
631
|
+
hasPending: () => deps.dispatcher.hasPending?.(),
|
|
631
632
|
recordInputSource(source) {
|
|
632
633
|
pendingInputSource = source;
|
|
633
634
|
},
|
|
634
635
|
onAgentStart(activeTelegramTarget, replyToMessageId) {
|
|
635
636
|
abandonCompaction();
|
|
636
637
|
ensureActivity(activeTelegramTarget);
|
|
637
|
-
activityReplyToMessageId =
|
|
638
|
+
activityReplyToMessageId =
|
|
639
|
+
activitySource === "telegram" ? replyToMessageId : undefined;
|
|
638
640
|
emit({ type: "agent-start" });
|
|
639
641
|
},
|
|
640
642
|
onAssistantEvent(event) {
|
|
@@ -750,21 +752,33 @@ export interface TelegramActivityPublicationReservation {
|
|
|
750
752
|
cancel: () => void;
|
|
751
753
|
}
|
|
752
754
|
|
|
755
|
+
export interface TelegramActivityPublicationWork {
|
|
756
|
+
settle(outcome: "settled" | "unconfirmed"): void;
|
|
757
|
+
}
|
|
758
|
+
|
|
753
759
|
export interface TelegramActivityPublicationRuntime {
|
|
754
760
|
enqueue: (task: () => Promise<void>) => Promise<void>;
|
|
755
761
|
reserve: () => TelegramActivityPublicationReservation;
|
|
762
|
+
hasPending: () => boolean;
|
|
763
|
+
/** Observation only; detached work never occupies the ordered publication tail. */
|
|
764
|
+
beginWork: () => TelegramActivityPublicationWork;
|
|
765
|
+
hasUnconfirmed: () => boolean;
|
|
756
766
|
reset: () => void;
|
|
757
767
|
}
|
|
758
768
|
|
|
759
769
|
export function createTelegramActivityPublicationRuntime(): TelegramActivityPublicationRuntime {
|
|
760
770
|
let generation = 0;
|
|
761
771
|
let tail = Promise.resolve();
|
|
772
|
+
let outstanding = 0,
|
|
773
|
+
unconfirmed = false;
|
|
762
774
|
const pending = new Set<() => void>();
|
|
763
775
|
const reserve = (): TelegramActivityPublicationReservation => {
|
|
764
776
|
const admittedGeneration = generation;
|
|
765
777
|
let state: "pending" | "published" | "cancelled" = "pending";
|
|
766
778
|
let resolve!: (task: (() => Promise<void>) | undefined) => void;
|
|
767
|
-
const ready = new Promise<(() => Promise<void>) | undefined>((accept) => {
|
|
779
|
+
const ready = new Promise<(() => Promise<void>) | undefined>((accept) => {
|
|
780
|
+
resolve = accept;
|
|
781
|
+
});
|
|
768
782
|
const cancel = () => {
|
|
769
783
|
if (state !== "pending") return;
|
|
770
784
|
state = "cancelled";
|
|
@@ -772,15 +786,23 @@ export function createTelegramActivityPublicationRuntime(): TelegramActivityPubl
|
|
|
772
786
|
resolve(undefined);
|
|
773
787
|
};
|
|
774
788
|
pending.add(cancel);
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
789
|
+
outstanding += 1;
|
|
790
|
+
const result = tail
|
|
791
|
+
.then(async () => {
|
|
792
|
+
const task = await ready;
|
|
793
|
+
if (admittedGeneration === generation && task) await task();
|
|
794
|
+
})
|
|
795
|
+
.finally(() => {
|
|
796
|
+
outstanding -= 1;
|
|
797
|
+
});
|
|
779
798
|
tail = result.catch(() => {});
|
|
780
799
|
return {
|
|
781
800
|
publish(task) {
|
|
782
801
|
if (state === "cancelled") return result;
|
|
783
|
-
if (state === "published")
|
|
802
|
+
if (state === "published")
|
|
803
|
+
return Promise.reject(
|
|
804
|
+
new Error("Publication reservation already published."),
|
|
805
|
+
);
|
|
784
806
|
state = "published";
|
|
785
807
|
pending.delete(cancel);
|
|
786
808
|
resolve(task);
|
|
@@ -792,8 +814,25 @@ export function createTelegramActivityPublicationRuntime(): TelegramActivityPubl
|
|
|
792
814
|
return {
|
|
793
815
|
reserve,
|
|
794
816
|
enqueue: (task) => reserve().publish(task),
|
|
817
|
+
hasPending: () => outstanding > 0,
|
|
818
|
+
hasUnconfirmed: () => unconfirmed,
|
|
819
|
+
beginWork() {
|
|
820
|
+
const admittedGeneration = generation;
|
|
821
|
+
let settled = false;
|
|
822
|
+
outstanding += 1;
|
|
823
|
+
return {
|
|
824
|
+
settle(outcome) {
|
|
825
|
+
if (settled) return;
|
|
826
|
+
settled = true;
|
|
827
|
+
outstanding -= 1;
|
|
828
|
+
if (outcome === "unconfirmed" && admittedGeneration === generation)
|
|
829
|
+
unconfirmed = true;
|
|
830
|
+
},
|
|
831
|
+
};
|
|
832
|
+
},
|
|
795
833
|
reset() {
|
|
796
834
|
generation += 1;
|
|
835
|
+
unconfirmed = false;
|
|
797
836
|
for (const cancel of pending) cancel();
|
|
798
837
|
tail = Promise.resolve();
|
|
799
838
|
},
|
|
@@ -816,8 +855,12 @@ export interface TelegramAssistantOutputPreparation {
|
|
|
816
855
|
settle: () => void;
|
|
817
856
|
}
|
|
818
857
|
|
|
819
|
-
export function createTelegramAssistantOutputRuntime<
|
|
820
|
-
|
|
858
|
+
export function createTelegramAssistantOutputRuntime<
|
|
859
|
+
TAuthority = undefined,
|
|
860
|
+
>(deps: {
|
|
861
|
+
prepareSend?: (
|
|
862
|
+
event: TelegramAssistantSegmentEvent,
|
|
863
|
+
) => TelegramAssistantOutputPreparation | undefined;
|
|
821
864
|
enqueue?: TelegramActivityPublicationRuntime["enqueue"];
|
|
822
865
|
captureAuthority?: () => TAuthority;
|
|
823
866
|
isAuthorityActive?: (authority: TAuthority) => boolean;
|
|
@@ -865,7 +908,8 @@ export function createTelegramAssistantOutputRuntime<TAuthority = undefined>(dep
|
|
|
865
908
|
const admittedGeneration = generation;
|
|
866
909
|
const admittedAuthority = deps.captureAuthority?.();
|
|
867
910
|
const preparation = deps.prepareSend?.(event);
|
|
868
|
-
const enqueue =
|
|
911
|
+
const enqueue =
|
|
912
|
+
deps.enqueue ?? ((task: () => Promise<void>) => tail.then(task));
|
|
869
913
|
tail = enqueue(async () => {
|
|
870
914
|
const isAdmittedAuthorityActive = () =>
|
|
871
915
|
running &&
|
package/lib/agent-messages.ts
CHANGED
|
@@ -39,8 +39,12 @@ export function createTelegramAgentMessageRuntime<TContext, TUpdate>(
|
|
|
39
39
|
const leaderTarget = deps.getLeaderTarget();
|
|
40
40
|
if (leaderTarget?.threadId) {
|
|
41
41
|
targets.push({
|
|
42
|
-
target: {
|
|
43
|
-
|
|
42
|
+
target: {
|
|
43
|
+
chatId: leaderTarget.chatId,
|
|
44
|
+
threadId: leaderTarget.threadId,
|
|
45
|
+
},
|
|
46
|
+
threadName:
|
|
47
|
+
deps.getDisplayTitle?.(leaderTarget) ?? deps.getLeaderThreadName(),
|
|
44
48
|
});
|
|
45
49
|
}
|
|
46
50
|
for (const follower of deps.followerRegistry.list()) {
|
|
@@ -50,7 +54,8 @@ export function createTelegramAgentMessageRuntime<TContext, TUpdate>(
|
|
|
50
54
|
chatId: follower.target.chatId,
|
|
51
55
|
threadId: follower.target.threadId,
|
|
52
56
|
},
|
|
53
|
-
threadName:
|
|
57
|
+
threadName:
|
|
58
|
+
deps.getDisplayTitle?.(follower.target) ?? follower.threadName,
|
|
54
59
|
});
|
|
55
60
|
}
|
|
56
61
|
return targets;
|
|
@@ -99,8 +104,10 @@ export function createTelegramAgentMessageRuntime<TContext, TUpdate>(
|
|
|
99
104
|
if (allowedChatId === undefined || !ctx) {
|
|
100
105
|
throw new Error("Telegram agent turn routing is unavailable.");
|
|
101
106
|
}
|
|
102
|
-
const sourceTitle =
|
|
103
|
-
|
|
107
|
+
const sourceTitle =
|
|
108
|
+
(input.sourceTarget
|
|
109
|
+
? deps.getDisplayTitle?.(input.sourceTarget)
|
|
110
|
+
: undefined) ?? input.sourceThreadName;
|
|
104
111
|
const sourceLabel =
|
|
105
112
|
sourceTitle
|
|
106
113
|
?.replace(/[\r\n\[\]]+/g, " ")
|