@llblab/pi-kit 0.5.1 → 0.6.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/CHANGELOG.md +8 -0
- package/README.md +3 -3
- package/node_modules/@llblab/pi-grow-loop/AGENTS.md +2 -2
- package/node_modules/@llblab/pi-grow-loop/CHANGELOG.md +4 -0
- package/node_modules/@llblab/pi-grow-loop/README.md +6 -6
- package/node_modules/@llblab/pi-grow-loop/index.ts +6 -3
- package/node_modules/@llblab/pi-grow-loop/package.json +1 -1
- package/node_modules/@llblab/pi-telegram/AGENTS.md +1 -1
- package/node_modules/@llblab/pi-telegram/CHANGELOG.md +20 -0
- package/node_modules/@llblab/pi-telegram/README.md +1 -1
- package/node_modules/@llblab/pi-telegram/docs/architecture.md +2 -2
- package/node_modules/@llblab/pi-telegram/docs/multi-instance-bus.md +4 -0
- package/node_modules/@llblab/pi-telegram/docs/outbound.md +27 -5
- package/node_modules/@llblab/pi-telegram/docs/public-api.md +1 -0
- package/node_modules/@llblab/pi-telegram/index.ts +24 -19
- package/node_modules/@llblab/pi-telegram/lib/activity-verbosity.ts +43 -25
- package/node_modules/@llblab/pi-telegram/lib/activity.ts +79 -6
- package/node_modules/@llblab/pi-telegram/lib/bindings.ts +110 -91
- package/node_modules/@llblab/pi-telegram/lib/config.ts +1 -1
- package/node_modules/@llblab/pi-telegram/lib/delivery.ts +18 -18
- package/node_modules/@llblab/pi-telegram/lib/lifecycle.ts +14 -3
- package/node_modules/@llblab/pi-telegram/lib/menu-settings.ts +2 -2
- package/node_modules/@llblab/pi-telegram/lib/outbound-attachments.ts +41 -37
- package/node_modules/@llblab/pi-telegram/lib/outbound-voice.ts +39 -42
- package/node_modules/@llblab/pi-telegram/lib/outbound.ts +28 -17
- package/node_modules/@llblab/pi-telegram/lib/preview.ts +134 -73
- package/node_modules/@llblab/pi-telegram/lib/queue.ts +113 -72
- package/node_modules/@llblab/pi-telegram/lib/replies.ts +46 -38
- package/node_modules/@llblab/pi-telegram/lib/routing.ts +192 -58
- package/node_modules/@llblab/pi-telegram/lib/telegram-api.ts +36 -3
- package/node_modules/@llblab/pi-telegram/lib/updates.ts +27 -35
- package/node_modules/@llblab/pi-telegram/package.json +1 -1
- package/node_modules/@llblab/skills/abcd-context/AGENTS.md +1 -0
- package/node_modules/@llblab/skills/abcd-context/CHANGELOG.md +6 -2
- package/node_modules/@llblab/skills/abcd-context/SKILL.md +1 -1
- package/node_modules/@llblab/skills/abcd-context/docs/validation-design.md +11 -5
- package/node_modules/@llblab/skills/abcd-context/scripts/_self-test.mjs +61 -0
- package/node_modules/@llblab/skills/abcd-context/scripts/validate-context.mjs +67 -0
- package/node_modules/@llblab/skills/package.json +1 -1
- package/node_modules/@llblab/skills/release-flow/SKILL.md +2 -4
- package/package.json +4 -4
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Owns persistent bounded thinking and tool disclosures; excludes activity normalization, assistant answer rendering, and transport authority policy
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type { TelegramActivityEvent } from "./activity.ts";
|
|
7
|
+
import type { TelegramActivityEvent, TelegramActivityPublicationRuntime } from "./activity.ts";
|
|
8
8
|
import {
|
|
9
9
|
escapeHtml,
|
|
10
10
|
renderTelegramInlineMarkdownHtml,
|
|
@@ -321,6 +321,7 @@ export function createTelegramActivityVerbosityBinding(): TelegramActivityVerbos
|
|
|
321
321
|
}
|
|
322
322
|
|
|
323
323
|
export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
|
|
324
|
+
enqueue?: TelegramActivityPublicationRuntime["enqueue"];
|
|
324
325
|
getActivityMode: () => "quiet" | "thinking" | "tools" | "verbose";
|
|
325
326
|
refreshActivityMode?: () => Promise<void>;
|
|
326
327
|
getNowMs?: () => number;
|
|
@@ -380,15 +381,20 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
|
|
|
380
381
|
};
|
|
381
382
|
const hasAuthority = (): boolean =>
|
|
382
383
|
authority !== undefined && deps.isAuthorityActive(authority);
|
|
383
|
-
const
|
|
384
|
+
const isCurrent = (acceptedGeneration: number, admittedAuthority: TAuthority | undefined): boolean =>
|
|
385
|
+
active && generation === acceptedGeneration && admittedAuthority !== undefined && deps.isAuthorityActive(admittedAuthority);
|
|
386
|
+
const ensureActivity = (
|
|
387
|
+
event: TelegramActivityEvent,
|
|
388
|
+
admittedTarget: TelegramTarget | undefined,
|
|
389
|
+
admittedAuthority: TAuthority,
|
|
390
|
+
): boolean => {
|
|
384
391
|
if (deps.getActivityMode() === "quiet") return false;
|
|
385
392
|
if (activityId === event.activityId) return hasAuthority();
|
|
386
393
|
clearActivity();
|
|
387
|
-
|
|
388
|
-
if (!resolvedTarget) return false;
|
|
394
|
+
if (!admittedTarget) return false;
|
|
389
395
|
activityId = event.activityId;
|
|
390
|
-
target =
|
|
391
|
-
authority =
|
|
396
|
+
target = admittedTarget;
|
|
397
|
+
authority = admittedAuthority;
|
|
392
398
|
return hasAuthority();
|
|
393
399
|
};
|
|
394
400
|
const closeToolBatch = () => {
|
|
@@ -398,10 +404,10 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
|
|
|
398
404
|
event: TelegramActivityEvent,
|
|
399
405
|
acceptedGeneration: number,
|
|
400
406
|
) => {
|
|
407
|
+
const admittedAuthority = authority;
|
|
401
408
|
if (
|
|
402
|
-
|
|
409
|
+
!isCurrent(acceptedGeneration, admittedAuthority) ||
|
|
403
410
|
!target ||
|
|
404
|
-
!hasAuthority() ||
|
|
405
411
|
reasoningBlocked
|
|
406
412
|
) {
|
|
407
413
|
return;
|
|
@@ -440,22 +446,24 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
|
|
|
440
446
|
parse_mode: "HTML",
|
|
441
447
|
link_preview_options: { is_disabled: true },
|
|
442
448
|
});
|
|
449
|
+
if (!isCurrent(acceptedGeneration, admittedAuthority)) return;
|
|
443
450
|
reasoningMessage = {
|
|
444
451
|
messageId: sent.message_id,
|
|
445
452
|
target: { ...target },
|
|
446
453
|
};
|
|
447
454
|
}
|
|
448
|
-
if (
|
|
455
|
+
if (!isCurrent(acceptedGeneration, admittedAuthority)) return;
|
|
449
456
|
reasoningMessageFrames += 1;
|
|
450
457
|
lastReasoningMessageChars = reasoningChars;
|
|
451
458
|
lastReasoningPublishMs = getNowMs();
|
|
452
459
|
} catch (error) {
|
|
460
|
+
if (!isCurrent(acceptedGeneration, admittedAuthority)) return;
|
|
461
|
+
reasoningBlocked = true;
|
|
453
462
|
deps.recordFailure?.(
|
|
454
463
|
canEdit ? "reasoning-edit" : "reasoning-send",
|
|
455
464
|
event,
|
|
456
465
|
error,
|
|
457
466
|
);
|
|
458
|
-
reasoningBlocked = true;
|
|
459
467
|
}
|
|
460
468
|
};
|
|
461
469
|
const publishTool = async (
|
|
@@ -463,11 +471,8 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
|
|
|
463
471
|
tool: ToolActivity,
|
|
464
472
|
acceptedGeneration: number,
|
|
465
473
|
) => {
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
!target ||
|
|
469
|
-
!hasAuthority()
|
|
470
|
-
) {
|
|
474
|
+
const admittedAuthority = authority;
|
|
475
|
+
if (!isCurrent(acceptedGeneration, admittedAuthority) || !target) {
|
|
471
476
|
return;
|
|
472
477
|
}
|
|
473
478
|
const canAppend =
|
|
@@ -495,6 +500,7 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
|
|
|
495
500
|
}),
|
|
496
501
|
});
|
|
497
502
|
} catch (error) {
|
|
503
|
+
if (!isCurrent(acceptedGeneration, admittedAuthority)) return;
|
|
498
504
|
if (
|
|
499
505
|
toolMessage.format !== "rich" ||
|
|
500
506
|
!isKnownSafeRichActivityRejection(error)
|
|
@@ -508,9 +514,10 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
|
|
|
508
514
|
parse_mode: "HTML",
|
|
509
515
|
link_preview_options: { is_disabled: true },
|
|
510
516
|
});
|
|
517
|
+
if (!isCurrent(acceptedGeneration, admittedAuthority)) return;
|
|
511
518
|
toolMessage.format = "html";
|
|
512
519
|
}
|
|
513
|
-
if (
|
|
520
|
+
if (!isCurrent(acceptedGeneration, admittedAuthority)) return;
|
|
514
521
|
toolMessage.tools = nextTools;
|
|
515
522
|
return;
|
|
516
523
|
}
|
|
@@ -528,6 +535,7 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
|
|
|
528
535
|
rich_message: renderTelegramToolActivityRichMessage([tool]),
|
|
529
536
|
});
|
|
530
537
|
} catch (error) {
|
|
538
|
+
if (!isCurrent(acceptedGeneration, admittedAuthority)) return;
|
|
531
539
|
if (!isKnownSafeRichActivityRejection(error)) throw error;
|
|
532
540
|
sent = await deps.sendMessage({
|
|
533
541
|
...body,
|
|
@@ -537,7 +545,7 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
|
|
|
537
545
|
});
|
|
538
546
|
format = "html";
|
|
539
547
|
}
|
|
540
|
-
if (
|
|
548
|
+
if (!isCurrent(acceptedGeneration, admittedAuthority)) return;
|
|
541
549
|
toolMessage = {
|
|
542
550
|
messageId: sent.message_id,
|
|
543
551
|
tools: [tool],
|
|
@@ -545,25 +553,30 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
|
|
|
545
553
|
format,
|
|
546
554
|
};
|
|
547
555
|
} catch (error) {
|
|
548
|
-
|
|
556
|
+
if (!isCurrent(acceptedGeneration, admittedAuthority)) return;
|
|
549
557
|
closeToolBatch();
|
|
558
|
+
deps.recordFailure?.(canAppend ? "tool-edit" : "tool-send", event, error);
|
|
550
559
|
}
|
|
551
560
|
};
|
|
552
561
|
const process = async (
|
|
553
562
|
event: TelegramActivityEvent,
|
|
554
563
|
acceptedGeneration: number,
|
|
564
|
+
admittedTarget: TelegramTarget | undefined,
|
|
565
|
+
admittedAuthority: TAuthority,
|
|
555
566
|
) => {
|
|
556
567
|
if (event.type === "agent-start" && deps.refreshActivityMode) {
|
|
557
568
|
try {
|
|
558
569
|
await deps.refreshActivityMode();
|
|
559
570
|
} catch (error) {
|
|
560
|
-
|
|
571
|
+
if (!isCurrent(acceptedGeneration, admittedAuthority)) return;
|
|
561
572
|
clearActivity();
|
|
562
573
|
activityId = event.activityId;
|
|
574
|
+
deps.recordFailure?.("config-refresh", event, error);
|
|
563
575
|
return;
|
|
564
576
|
}
|
|
565
577
|
}
|
|
566
|
-
if (!
|
|
578
|
+
if (!isCurrent(acceptedGeneration, admittedAuthority)) return;
|
|
579
|
+
if (!ensureActivity(event, admittedTarget, admittedAuthority)) {
|
|
567
580
|
if (
|
|
568
581
|
activityId === event.activityId &&
|
|
569
582
|
deps.getActivityMode() === "quiet"
|
|
@@ -614,6 +627,7 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
|
|
|
614
627
|
) {
|
|
615
628
|
await publishReasoning(event, acceptedGeneration);
|
|
616
629
|
}
|
|
630
|
+
if (!isCurrent(acceptedGeneration, admittedAuthority)) return;
|
|
617
631
|
reasoningBuffer = "";
|
|
618
632
|
reasoningChars = 0;
|
|
619
633
|
reasoningMessageFrames = 0;
|
|
@@ -668,7 +682,7 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
|
|
|
668
682
|
toolOrder.shift();
|
|
669
683
|
tools.delete(next.id);
|
|
670
684
|
await publishTool(event, next, acceptedGeneration);
|
|
671
|
-
if (
|
|
685
|
+
if (!isCurrent(acceptedGeneration, admittedAuthority)) return;
|
|
672
686
|
}
|
|
673
687
|
return;
|
|
674
688
|
}
|
|
@@ -680,6 +694,7 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
|
|
|
680
694
|
) {
|
|
681
695
|
await publishReasoning(event, acceptedGeneration);
|
|
682
696
|
}
|
|
697
|
+
if (!isCurrent(acceptedGeneration, admittedAuthority)) return;
|
|
683
698
|
clearActivity();
|
|
684
699
|
}
|
|
685
700
|
};
|
|
@@ -687,10 +702,13 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
|
|
|
687
702
|
accept(event) {
|
|
688
703
|
if (!active) return;
|
|
689
704
|
const acceptedGeneration = generation;
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
705
|
+
const resolvedTarget = deps.resolveTarget(event);
|
|
706
|
+
const admittedTarget = resolvedTarget ? { ...resolvedTarget } : undefined;
|
|
707
|
+
const admittedAuthority = deps.captureAuthority();
|
|
708
|
+
const enqueue = deps.enqueue ?? ((task: () => Promise<void>) => tail.then(task));
|
|
709
|
+
tail = enqueue(async () => {
|
|
710
|
+
if (!active || generation !== acceptedGeneration || !deps.isAuthorityActive(admittedAuthority)) return;
|
|
711
|
+
await process(event, acceptedGeneration, admittedTarget, admittedAuthority);
|
|
694
712
|
})
|
|
695
713
|
.catch((error) => {
|
|
696
714
|
deps.recordFailure?.("tool-send", event, error);
|
|
@@ -32,6 +32,7 @@ export interface TelegramActivityEnvelope {
|
|
|
32
32
|
sequence: number;
|
|
33
33
|
source: TelegramActivitySource;
|
|
34
34
|
target?: TelegramActivityTarget;
|
|
35
|
+
replyToMessageId?: number;
|
|
35
36
|
timestamp: number;
|
|
36
37
|
}
|
|
37
38
|
|
|
@@ -422,8 +423,8 @@ export function createTelegramActivityBridgeRuntime(deps: {
|
|
|
422
423
|
recordInputSource(source) {
|
|
423
424
|
getRuntime()?.recordInputSource(source);
|
|
424
425
|
},
|
|
425
|
-
onAgentStart(target) {
|
|
426
|
-
getRuntime()?.onAgentStart(target);
|
|
426
|
+
onAgentStart(target, replyToMessageId) {
|
|
427
|
+
getRuntime()?.onAgentStart(target, replyToMessageId);
|
|
427
428
|
},
|
|
428
429
|
onAssistantEvent(event) {
|
|
429
430
|
getRuntime()?.onAssistantEvent(event);
|
|
@@ -492,7 +493,7 @@ export type TelegramAssistantStreamEvent =
|
|
|
492
493
|
export interface TelegramActivityRuntime {
|
|
493
494
|
onSessionStart?: () => void;
|
|
494
495
|
recordInputSource: (source: TelegramActivityInputSource) => void;
|
|
495
|
-
onAgentStart: (activeTelegramTarget?: TelegramActivityTarget) => void;
|
|
496
|
+
onAgentStart: (activeTelegramTarget?: TelegramActivityTarget, replyToMessageId?: number) => void;
|
|
496
497
|
onAssistantEvent: (event: TelegramAssistantStreamEvent) => void;
|
|
497
498
|
onAssistantMessageEnd: (stopReason?: string) => void;
|
|
498
499
|
onToolStart: (event: {
|
|
@@ -549,6 +550,7 @@ export function createTelegramActivityRuntime(deps: {
|
|
|
549
550
|
let activityId: string | undefined;
|
|
550
551
|
let activitySource: TelegramActivitySource = "unknown";
|
|
551
552
|
let activityTarget: TelegramActivityTarget | undefined;
|
|
553
|
+
let activityReplyToMessageId: number | undefined;
|
|
552
554
|
let sequence = 0;
|
|
553
555
|
let pendingInputSource: TelegramActivityInputSource = "unknown";
|
|
554
556
|
let pendingAssistantSegment: PendingAssistantSegment | undefined;
|
|
@@ -584,6 +586,7 @@ export function createTelegramActivityRuntime(deps: {
|
|
|
584
586
|
sequence,
|
|
585
587
|
source: activitySource,
|
|
586
588
|
...(activityTarget ? { target: activityTarget } : {}),
|
|
589
|
+
...(activityReplyToMessageId !== undefined ? { replyToMessageId: activityReplyToMessageId } : {}),
|
|
587
590
|
timestamp: now(),
|
|
588
591
|
} as TelegramActivityEvent;
|
|
589
592
|
try {
|
|
@@ -610,6 +613,7 @@ export function createTelegramActivityRuntime(deps: {
|
|
|
610
613
|
activityId = undefined;
|
|
611
614
|
activitySource = "unknown";
|
|
612
615
|
activityTarget = undefined;
|
|
616
|
+
activityReplyToMessageId = undefined;
|
|
613
617
|
sequence = 0;
|
|
614
618
|
pendingAssistantSegment = undefined;
|
|
615
619
|
compactionInProgress = false;
|
|
@@ -627,9 +631,10 @@ export function createTelegramActivityRuntime(deps: {
|
|
|
627
631
|
recordInputSource(source) {
|
|
628
632
|
pendingInputSource = source;
|
|
629
633
|
},
|
|
630
|
-
onAgentStart(activeTelegramTarget) {
|
|
634
|
+
onAgentStart(activeTelegramTarget, replyToMessageId) {
|
|
631
635
|
abandonCompaction();
|
|
632
636
|
ensureActivity(activeTelegramTarget);
|
|
637
|
+
activityReplyToMessageId = activitySource === "telegram" ? replyToMessageId : undefined;
|
|
633
638
|
emit({ type: "agent-start" });
|
|
634
639
|
},
|
|
635
640
|
onAssistantEvent(event) {
|
|
@@ -738,6 +743,63 @@ export function createTelegramActivityRuntime(deps: {
|
|
|
738
743
|
};
|
|
739
744
|
}
|
|
740
745
|
|
|
746
|
+
// --- Ordered Bridge-Owned Publication ---
|
|
747
|
+
|
|
748
|
+
export interface TelegramActivityPublicationReservation {
|
|
749
|
+
publish: (task: () => Promise<void>) => Promise<void>;
|
|
750
|
+
cancel: () => void;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
export interface TelegramActivityPublicationRuntime {
|
|
754
|
+
enqueue: (task: () => Promise<void>) => Promise<void>;
|
|
755
|
+
reserve: () => TelegramActivityPublicationReservation;
|
|
756
|
+
reset: () => void;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
export function createTelegramActivityPublicationRuntime(): TelegramActivityPublicationRuntime {
|
|
760
|
+
let generation = 0;
|
|
761
|
+
let tail = Promise.resolve();
|
|
762
|
+
const pending = new Set<() => void>();
|
|
763
|
+
const reserve = (): TelegramActivityPublicationReservation => {
|
|
764
|
+
const admittedGeneration = generation;
|
|
765
|
+
let state: "pending" | "published" | "cancelled" = "pending";
|
|
766
|
+
let resolve!: (task: (() => Promise<void>) | undefined) => void;
|
|
767
|
+
const ready = new Promise<(() => Promise<void>) | undefined>((accept) => { resolve = accept; });
|
|
768
|
+
const cancel = () => {
|
|
769
|
+
if (state !== "pending") return;
|
|
770
|
+
state = "cancelled";
|
|
771
|
+
pending.delete(cancel);
|
|
772
|
+
resolve(undefined);
|
|
773
|
+
};
|
|
774
|
+
pending.add(cancel);
|
|
775
|
+
const result = tail.then(async () => {
|
|
776
|
+
const task = await ready;
|
|
777
|
+
if (admittedGeneration === generation && task) await task();
|
|
778
|
+
});
|
|
779
|
+
tail = result.catch(() => {});
|
|
780
|
+
return {
|
|
781
|
+
publish(task) {
|
|
782
|
+
if (state === "cancelled") return result;
|
|
783
|
+
if (state === "published") return Promise.reject(new Error("Publication reservation already published."));
|
|
784
|
+
state = "published";
|
|
785
|
+
pending.delete(cancel);
|
|
786
|
+
resolve(task);
|
|
787
|
+
return result;
|
|
788
|
+
},
|
|
789
|
+
cancel,
|
|
790
|
+
};
|
|
791
|
+
};
|
|
792
|
+
return {
|
|
793
|
+
reserve,
|
|
794
|
+
enqueue: (task) => reserve().publish(task),
|
|
795
|
+
reset() {
|
|
796
|
+
generation += 1;
|
|
797
|
+
for (const cancel of pending) cancel();
|
|
798
|
+
tail = Promise.resolve();
|
|
799
|
+
},
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
|
|
741
803
|
// --- Public Assistant Output Projection ---
|
|
742
804
|
|
|
743
805
|
export interface TelegramAssistantOutputRuntime {
|
|
@@ -747,7 +809,14 @@ export interface TelegramAssistantOutputRuntime {
|
|
|
747
809
|
stop: () => void;
|
|
748
810
|
}
|
|
749
811
|
|
|
812
|
+
export interface TelegramAssistantOutputPreparation {
|
|
813
|
+
wait: () => Promise<void>;
|
|
814
|
+
settle: () => void;
|
|
815
|
+
}
|
|
816
|
+
|
|
750
817
|
export function createTelegramAssistantOutputRuntime<TAuthority = undefined>(deps: {
|
|
818
|
+
prepareSend?: (event: TelegramAssistantSegmentEvent) => TelegramAssistantOutputPreparation | undefined;
|
|
819
|
+
enqueue?: TelegramActivityPublicationRuntime["enqueue"];
|
|
751
820
|
captureAuthority?: () => TAuthority;
|
|
752
821
|
isAuthorityActive?: (authority: TAuthority) => boolean;
|
|
753
822
|
canDeliver: (event: TelegramAssistantSegmentEvent) => boolean;
|
|
@@ -785,7 +854,9 @@ export function createTelegramAssistantOutputRuntime<TAuthority = undefined>(dep
|
|
|
785
854
|
admitted.add(key);
|
|
786
855
|
const admittedGeneration = generation;
|
|
787
856
|
const admittedAuthority = deps.captureAuthority?.();
|
|
788
|
-
|
|
857
|
+
const preparation = deps.prepareSend?.(event);
|
|
858
|
+
const enqueue = deps.enqueue ?? ((task: () => Promise<void>) => tail.then(task));
|
|
859
|
+
tail = enqueue(async () => {
|
|
789
860
|
const isAdmittedAuthorityActive = () =>
|
|
790
861
|
running &&
|
|
791
862
|
generation === admittedGeneration &&
|
|
@@ -794,6 +865,8 @@ export function createTelegramAssistantOutputRuntime<TAuthority = undefined>(dep
|
|
|
794
865
|
deps.isAuthorityActive(admittedAuthority as TAuthority));
|
|
795
866
|
if (!isAdmittedAuthorityActive() || !deps.canDeliver(event)) return;
|
|
796
867
|
try {
|
|
868
|
+
if (preparation) await preparation.wait();
|
|
869
|
+
if (!isAdmittedAuthorityActive() || !deps.canDeliver(event)) return;
|
|
797
870
|
await deps.send(
|
|
798
871
|
event,
|
|
799
872
|
admittedAuthority as TAuthority,
|
|
@@ -802,7 +875,7 @@ export function createTelegramAssistantOutputRuntime<TAuthority = undefined>(dep
|
|
|
802
875
|
} catch (error) {
|
|
803
876
|
deps.recordFailure?.(event, error);
|
|
804
877
|
}
|
|
805
|
-
});
|
|
878
|
+
}).finally(() => preparation?.settle());
|
|
806
879
|
},
|
|
807
880
|
waitForIdle() {
|
|
808
881
|
return tail;
|