@llblab/pi-kit 0.6.0 → 0.7.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 +4 -0
- package/README.md +4 -4
- package/node_modules/@llblab/pi-actors/AGENTS.md +1 -1
- package/node_modules/@llblab/pi-actors/CHANGELOG.md +6 -0
- package/node_modules/@llblab/pi-actors/README.md +1 -1
- package/node_modules/@llblab/pi-actors/dist/lib/async-runs.d.ts +3 -0
- package/node_modules/@llblab/pi-actors/dist/lib/async-runs.js +14 -1
- package/node_modules/@llblab/pi-actors/dist/lib/command-templates.js +45 -3
- package/node_modules/@llblab/pi-actors/dist/lib/extension-runtime.js +1 -1
- package/node_modules/@llblab/pi-actors/dist/lib/observability.d.ts +16 -3
- package/node_modules/@llblab/pi-actors/dist/lib/observability.js +92 -7
- package/node_modules/@llblab/pi-actors/dist/lib/pi.d.ts +0 -1
- package/node_modules/@llblab/pi-actors/dist/lib/pi.js +15 -24
- package/node_modules/@llblab/pi-actors/dist/lib/run-delivery-lineage.d.ts +17 -0
- package/node_modules/@llblab/pi-actors/dist/lib/run-delivery-lineage.js +44 -0
- package/node_modules/@llblab/pi-actors/dist/lib/run-delivery.d.ts +4 -0
- package/node_modules/@llblab/pi-actors/dist/lib/run-delivery.js +102 -4
- package/node_modules/@llblab/pi-actors/dist/lib/run-ui-runtime.js +58 -39
- package/node_modules/@llblab/pi-actors/dist/lib/runtime.js +14 -6
- package/node_modules/@llblab/pi-actors/dist/skills/actors/SKILL.md +1 -1
- package/node_modules/@llblab/pi-actors/docs/async-runs.md +1 -1
- package/node_modules/@llblab/pi-actors/docs/coordinator-delivery.md +18 -23
- package/node_modules/@llblab/pi-actors/lib/async-runs.ts +18 -1
- package/node_modules/@llblab/pi-actors/lib/command-templates.ts +41 -3
- package/node_modules/@llblab/pi-actors/lib/extension-runtime.ts +1 -1
- package/node_modules/@llblab/pi-actors/lib/observability.ts +119 -5
- package/node_modules/@llblab/pi-actors/lib/pi.ts +15 -28
- package/node_modules/@llblab/pi-actors/lib/run-delivery-lineage.ts +68 -0
- package/node_modules/@llblab/pi-actors/lib/run-delivery.ts +120 -4
- package/node_modules/@llblab/pi-actors/lib/run-ui-runtime.ts +69 -44
- package/node_modules/@llblab/pi-actors/lib/runtime.ts +17 -6
- package/node_modules/@llblab/pi-actors/package.json +1 -1
- package/node_modules/@llblab/pi-actors/skills/actors/SKILL.md +1 -1
- package/node_modules/@llblab/pi-state-flow/AGENTS.md +33 -12
- package/node_modules/@llblab/pi-state-flow/BACKLOG.md +125 -2
- package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +87 -45
- package/node_modules/@llblab/pi-state-flow/README.md +203 -107
- package/node_modules/@llblab/pi-state-flow/docs/README.md +4 -0
- package/node_modules/@llblab/pi-state-flow/docs/architecture.md +188 -0
- package/node_modules/@llblab/pi-state-flow/docs/temporal-acceptance.md +42 -0
- package/node_modules/@llblab/pi-state-flow/index.ts +164 -2
- package/node_modules/@llblab/pi-state-flow/lib/acquisition.ts +138 -0
- package/node_modules/@llblab/pi-state-flow/lib/artifact.ts +273 -0
- package/node_modules/@llblab/pi-state-flow/lib/config.ts +48 -0
- package/node_modules/@llblab/pi-state-flow/lib/context.ts +18 -5
- package/node_modules/@llblab/pi-state-flow/lib/continuation.ts +268 -0
- package/node_modules/@llblab/pi-state-flow/lib/discovery.ts +117 -0
- package/node_modules/@llblab/pi-state-flow/lib/durable.ts +562 -0
- package/node_modules/@llblab/pi-state-flow/lib/episode.ts +24 -12
- package/node_modules/@llblab/pi-state-flow/lib/extension.ts +606 -70
- package/node_modules/@llblab/pi-state-flow/lib/git.ts +666 -0
- package/node_modules/@llblab/pi-state-flow/lib/history.ts +95 -0
- package/node_modules/@llblab/pi-state-flow/lib/json.ts +24 -0
- package/node_modules/@llblab/pi-state-flow/lib/maintenance.ts +141 -0
- package/node_modules/@llblab/pi-state-flow/lib/memory.ts +52 -0
- package/node_modules/@llblab/pi-state-flow/lib/migration.ts +88 -0
- package/node_modules/@llblab/pi-state-flow/lib/publication.ts +296 -0
- package/node_modules/@llblab/pi-state-flow/lib/recovery.ts +23 -7
- package/node_modules/@llblab/pi-state-flow/lib/rehydration.ts +79 -0
- package/node_modules/@llblab/pi-state-flow/lib/runtime.ts +264 -0
- package/node_modules/@llblab/pi-state-flow/lib/session.ts +6 -0
- package/node_modules/@llblab/pi-state-flow/lib/skills.ts +99 -7
- package/node_modules/@llblab/pi-state-flow/lib/snapshot.ts +305 -48
- package/node_modules/@llblab/pi-state-flow/lib/state.ts +74 -7
- package/node_modules/@llblab/pi-state-flow/lib/status.ts +125 -6
- package/node_modules/@llblab/pi-state-flow/lib/storage.ts +196 -0
- package/node_modules/@llblab/pi-state-flow/lib/temporal.ts +233 -0
- package/node_modules/@llblab/pi-state-flow/lib/terminal.ts +70 -24
- package/node_modules/@llblab/pi-state-flow/lib/transition.ts +254 -29
- package/node_modules/@llblab/pi-state-flow/package.json +8 -2
- package/node_modules/@llblab/pi-state-flow/skills/state-flow-memory/SKILL.md +128 -0
- package/node_modules/@llblab/pi-telegram/AGENTS.md +13 -8
- package/node_modules/@llblab/pi-telegram/BACKLOG.md +20 -3
- package/node_modules/@llblab/pi-telegram/CHANGELOG.md +13 -0
- package/node_modules/@llblab/pi-telegram/README.md +12 -8
- package/node_modules/@llblab/pi-telegram/docs/README.md +1 -0
- package/node_modules/@llblab/pi-telegram/docs/architecture.md +220 -18
- package/node_modules/@llblab/pi-telegram/docs/generative-apps.md +1 -1
- package/node_modules/@llblab/pi-telegram/docs/multi-instance-bus.md +70 -19
- package/node_modules/@llblab/pi-telegram/docs/outbound.md +6 -6
- package/node_modules/@llblab/pi-telegram/docs/public-api.md +12 -5
- package/node_modules/@llblab/pi-telegram/docs/ui-style.md +3 -1
- package/node_modules/@llblab/pi-telegram/index.ts +4 -1418
- package/node_modules/@llblab/pi-telegram/lib/agent-messages.ts +6 -3
- package/node_modules/@llblab/pi-telegram/lib/bindings.ts +28 -1
- package/node_modules/@llblab/pi-telegram/lib/bus-follower.ts +600 -135
- package/node_modules/@llblab/pi-telegram/lib/bus-leader.ts +962 -55
- package/node_modules/@llblab/pi-telegram/lib/bus.ts +350 -26
- package/node_modules/@llblab/pi-telegram/lib/channel-posts.ts +544 -0
- package/node_modules/@llblab/pi-telegram/lib/commands.ts +234 -11
- package/node_modules/@llblab/pi-telegram/lib/config.ts +177 -24
- package/node_modules/@llblab/pi-telegram/lib/extension.ts +1792 -0
- package/node_modules/@llblab/pi-telegram/lib/generative-apps.ts +20 -2
- package/node_modules/@llblab/pi-telegram/lib/journal.ts +2184 -126
- package/node_modules/@llblab/pi-telegram/lib/locks.ts +38 -1
- package/node_modules/@llblab/pi-telegram/lib/menu-settings.ts +152 -13
- package/node_modules/@llblab/pi-telegram/lib/outbound-attachments.ts +51 -10
- package/node_modules/@llblab/pi-telegram/lib/paths.ts +29 -0
- package/node_modules/@llblab/pi-telegram/lib/polling.ts +85 -17
- package/node_modules/@llblab/pi-telegram/lib/prompts.ts +5 -2
- package/node_modules/@llblab/pi-telegram/lib/queue.ts +52 -18
- package/node_modules/@llblab/pi-telegram/lib/replies.ts +2 -2
- package/node_modules/@llblab/pi-telegram/lib/routing.ts +305 -112
- package/node_modules/@llblab/pi-telegram/lib/status.ts +10 -0
- package/node_modules/@llblab/pi-telegram/lib/sync.ts +308 -39
- package/node_modules/@llblab/pi-telegram/lib/telegram-api.ts +279 -4
- package/node_modules/@llblab/pi-telegram/lib/thread-cleanup-manager.ts +664 -0
- package/node_modules/@llblab/pi-telegram/lib/thread-display.ts +226 -0
- package/node_modules/@llblab/pi-telegram/lib/thread-naming.ts +118 -0
- package/node_modules/@llblab/pi-telegram/lib/threads.ts +1686 -129
- package/node_modules/@llblab/pi-telegram/lib/updates.ts +1319 -97
- package/node_modules/@llblab/pi-telegram/lib/workspace-admission.ts +1643 -0
- package/node_modules/@llblab/pi-telegram/lib/workspace-retirement.ts +968 -0
- package/node_modules/@llblab/pi-telegram/lib/workspace-slots.ts +84 -0
- package/node_modules/@llblab/pi-telegram/package.json +1 -1
- package/node_modules/@llblab/pi-telegram/screenshot.png +0 -0
- package/node_modules/@llblab/pi-telegram/scripts/measure-bus.mjs +83 -0
- package/node_modules/@llblab/pi-telegram/scripts/measure-workspace.mjs +101 -0
- package/node_modules/@llblab/{skills → pi-telegram/skills}/show-me/SKILL.md +28 -6
- package/node_modules/@llblab/pi-telegram/skills/show-me/references/telegram-surfaces.md +43 -0
- package/node_modules/@llblab/pi-telegram/skills/telegram-bridge/references/delivery-and-threads.md +1 -1
- package/node_modules/@llblab/skills/package.json +2 -3
- package/package.json +6 -5
|
@@ -37,6 +37,7 @@ function getTelegramApiTempDir(): string {
|
|
|
37
37
|
return resolveTelegramTempDir();
|
|
38
38
|
}
|
|
39
39
|
const TELEGRAM_TEMP_FILE_MAX_AGE_MS = 24 * 60 * 60 * 1000;
|
|
40
|
+
const activeTelegramApiWorkspaceAdmissionOperationIds = new Set<string>();
|
|
40
41
|
const TELEGRAM_TEMP_SCRATCH_FILE_PATTERN =
|
|
41
42
|
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}-/u;
|
|
42
43
|
const TELEGRAM_INBOUND_FILE_MAX_BYTES = getTelegramInboundFileByteLimitFromEnv(
|
|
@@ -465,6 +466,263 @@ export interface TelegramApiClient {
|
|
|
465
466
|
) => Promise<void>;
|
|
466
467
|
}
|
|
467
468
|
|
|
469
|
+
export interface TelegramApiTargetActivityRuntime {
|
|
470
|
+
begin: (
|
|
471
|
+
method: string,
|
|
472
|
+
body: Record<string, unknown>,
|
|
473
|
+
) => () => void;
|
|
474
|
+
hasPendingTarget: (target: { chatId: number; threadId?: number }) => boolean;
|
|
475
|
+
listPendingTargets: () => { chatId: number; threadId: number }[];
|
|
476
|
+
listPendingChats: () => number[];
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
function parseTelegramApiTargetInteger(value: unknown): number | undefined {
|
|
480
|
+
const parsed = typeof value === "number" ? value :
|
|
481
|
+
typeof value === "string" && /^-?\d+$/u.test(value) ? Number(value) : undefined;
|
|
482
|
+
return parsed !== undefined && Number.isSafeInteger(parsed) ? parsed : undefined;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
export function createTelegramApiTargetActivityRuntime(): TelegramApiTargetActivityRuntime {
|
|
486
|
+
const pending = new Map<string, {
|
|
487
|
+
target: { chatId: number; threadId: number };
|
|
488
|
+
count: number;
|
|
489
|
+
}>();
|
|
490
|
+
const pendingChats = new Map<number, number>();
|
|
491
|
+
const messageScopedMethods = new Set([
|
|
492
|
+
"deleteMessage",
|
|
493
|
+
"editMessageCaption",
|
|
494
|
+
"editMessageReplyMarkup",
|
|
495
|
+
"editMessageText",
|
|
496
|
+
]);
|
|
497
|
+
return {
|
|
498
|
+
begin(method, body) {
|
|
499
|
+
const chatId = parseTelegramApiTargetInteger(body.chat_id);
|
|
500
|
+
const threadId = parseTelegramApiTargetInteger(body.message_thread_id);
|
|
501
|
+
const messageId = parseTelegramApiTargetInteger(body.message_id);
|
|
502
|
+
const chatScoped = chatId !== undefined && threadId === undefined &&
|
|
503
|
+
messageId !== undefined && messageScopedMethods.has(method);
|
|
504
|
+
if (chatId === undefined || (threadId === undefined && !chatScoped)) {
|
|
505
|
+
return () => undefined;
|
|
506
|
+
}
|
|
507
|
+
const key = threadId === undefined ? undefined : `${chatId}:${threadId}`;
|
|
508
|
+
if (key) {
|
|
509
|
+
const existing = pending.get(key);
|
|
510
|
+
if (existing) existing.count += 1;
|
|
511
|
+
else pending.set(key, { target: { chatId, threadId: threadId! }, count: 1 });
|
|
512
|
+
} else {
|
|
513
|
+
pendingChats.set(chatId, (pendingChats.get(chatId) ?? 0) + 1);
|
|
514
|
+
}
|
|
515
|
+
let completed = false;
|
|
516
|
+
return () => {
|
|
517
|
+
if (completed) return;
|
|
518
|
+
completed = true;
|
|
519
|
+
if (!key) {
|
|
520
|
+
const count = pendingChats.get(chatId);
|
|
521
|
+
if (!count || count <= 1) pendingChats.delete(chatId);
|
|
522
|
+
else pendingChats.set(chatId, count - 1);
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
const current = pending.get(key);
|
|
526
|
+
if (!current || current.count <= 1) pending.delete(key);
|
|
527
|
+
else current.count -= 1;
|
|
528
|
+
};
|
|
529
|
+
},
|
|
530
|
+
hasPendingTarget(target) {
|
|
531
|
+
return pendingChats.has(target.chatId) ||
|
|
532
|
+
(target.threadId !== undefined && pending.has(`${target.chatId}:${target.threadId}`));
|
|
533
|
+
},
|
|
534
|
+
listPendingTargets() {
|
|
535
|
+
return Array.from(pending.values(), ({ target }) => ({ ...target }));
|
|
536
|
+
},
|
|
537
|
+
listPendingChats() {
|
|
538
|
+
return Array.from(pendingChats.keys());
|
|
539
|
+
},
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
export function createTelegramApiTargetTrackingClient(
|
|
544
|
+
client: TelegramApiClient,
|
|
545
|
+
activity: TelegramApiTargetActivityRuntime,
|
|
546
|
+
): TelegramApiClient {
|
|
547
|
+
const track = async <T>(
|
|
548
|
+
method: string,
|
|
549
|
+
body: Record<string, unknown>,
|
|
550
|
+
operation: () => Promise<T>,
|
|
551
|
+
): Promise<T> => {
|
|
552
|
+
const end = activity.begin(method, body);
|
|
553
|
+
try {
|
|
554
|
+
return await operation();
|
|
555
|
+
} finally {
|
|
556
|
+
end();
|
|
557
|
+
}
|
|
558
|
+
};
|
|
559
|
+
return {
|
|
560
|
+
call: (method, body, options) => track(
|
|
561
|
+
method,
|
|
562
|
+
body,
|
|
563
|
+
() => client.call(method, body, options),
|
|
564
|
+
),
|
|
565
|
+
callMultipart: (method, fields, fileField, filePath, fileName, options) =>
|
|
566
|
+
track(method, fields, () => client.callMultipart(
|
|
567
|
+
method, fields, fileField, filePath, fileName, options,
|
|
568
|
+
)),
|
|
569
|
+
downloadFile: client.downloadFile,
|
|
570
|
+
answerCallbackQuery: client.answerCallbackQuery,
|
|
571
|
+
...(client.answerGuestQuery
|
|
572
|
+
? { answerGuestQuery: client.answerGuestQuery }
|
|
573
|
+
: {}),
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
export type TelegramApiWorkspaceAdmissionScopeLike =
|
|
578
|
+
| { kind: "target"; target: { chatId: number; threadId: number } }
|
|
579
|
+
| { kind: "chat"; chatId: number }
|
|
580
|
+
| { kind: "profile" };
|
|
581
|
+
|
|
582
|
+
export interface TelegramApiWorkspaceAdmissionLeaseLike {
|
|
583
|
+
operationId: string;
|
|
584
|
+
operationKind: string;
|
|
585
|
+
profileKey: string;
|
|
586
|
+
scope: TelegramApiWorkspaceAdmissionScopeLike;
|
|
587
|
+
owner: { processId: number; processBirthId: string };
|
|
588
|
+
acquiredAtMs: number;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
export interface TelegramApiWorkspaceAdmissionPort {
|
|
592
|
+
acquireAdmission: (input: {
|
|
593
|
+
operationId: string;
|
|
594
|
+
operationKind: string;
|
|
595
|
+
scope: TelegramApiWorkspaceAdmissionScopeLike;
|
|
596
|
+
}) =>
|
|
597
|
+
| {
|
|
598
|
+
kind: "acquired";
|
|
599
|
+
lease: TelegramApiWorkspaceAdmissionLeaseLike;
|
|
600
|
+
resumed: boolean;
|
|
601
|
+
}
|
|
602
|
+
| { kind: "blocked"; reason: "retirement-fenced" };
|
|
603
|
+
releaseAdmission: (expected: TelegramApiWorkspaceAdmissionLeaseLike) => boolean;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
export class TelegramApiWorkspaceAdmissionError extends Error {
|
|
607
|
+
readonly code: "blocked" | "unavailable" | "release-lost" | "duplicate-operation";
|
|
608
|
+
|
|
609
|
+
constructor(code: TelegramApiWorkspaceAdmissionError["code"], message: string) {
|
|
610
|
+
super(message);
|
|
611
|
+
this.name = "TelegramApiWorkspaceAdmissionError";
|
|
612
|
+
this.code = code;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
export function getTelegramApiWorkspaceAdmissionScope(
|
|
617
|
+
body: Record<string, unknown>,
|
|
618
|
+
): TelegramApiWorkspaceAdmissionScopeLike | undefined {
|
|
619
|
+
if (!("chat_id" in body)) return undefined;
|
|
620
|
+
const chatId = parseTelegramApiTargetInteger(body.chat_id);
|
|
621
|
+
if (chatId === undefined || chatId === 0) return { kind: "profile" };
|
|
622
|
+
if (!("message_thread_id" in body) || body.message_thread_id === undefined) {
|
|
623
|
+
return { kind: "chat", chatId };
|
|
624
|
+
}
|
|
625
|
+
const threadId = parseTelegramApiTargetInteger(body.message_thread_id);
|
|
626
|
+
if (threadId === undefined || threadId <= 0) return { kind: "profile" };
|
|
627
|
+
return { kind: "target", target: { chatId, threadId } };
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
export function createTelegramApiWorkspaceAdmissionClient(
|
|
631
|
+
client: TelegramApiClient,
|
|
632
|
+
admission:
|
|
633
|
+
| TelegramApiWorkspaceAdmissionPort
|
|
634
|
+
| (() => TelegramApiWorkspaceAdmissionPort | undefined),
|
|
635
|
+
options: {
|
|
636
|
+
onReleaseError?: (error: unknown, method: string) => void;
|
|
637
|
+
createOperationId?: () => string;
|
|
638
|
+
} = {},
|
|
639
|
+
): TelegramApiClient {
|
|
640
|
+
const admit = async <T>(
|
|
641
|
+
method: string,
|
|
642
|
+
body: Record<string, unknown>,
|
|
643
|
+
operation: () => Promise<T>,
|
|
644
|
+
): Promise<T> => {
|
|
645
|
+
const scope = getTelegramApiWorkspaceAdmissionScope(body);
|
|
646
|
+
if (!scope) return operation();
|
|
647
|
+
const currentAdmission =
|
|
648
|
+
typeof admission === "function" ? admission() : admission;
|
|
649
|
+
if (!currentAdmission) {
|
|
650
|
+
throw new TelegramApiWorkspaceAdmissionError(
|
|
651
|
+
"unavailable",
|
|
652
|
+
"Telegram API Workspace admission authority is unavailable.",
|
|
653
|
+
);
|
|
654
|
+
}
|
|
655
|
+
const operationId = `api:${(options.createOperationId ?? randomUUID)()}`;
|
|
656
|
+
if (activeTelegramApiWorkspaceAdmissionOperationIds.has(operationId)) {
|
|
657
|
+
throw new TelegramApiWorkspaceAdmissionError(
|
|
658
|
+
"duplicate-operation",
|
|
659
|
+
"Telegram API Workspace admission operation is already active.",
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
activeTelegramApiWorkspaceAdmissionOperationIds.add(operationId);
|
|
663
|
+
try {
|
|
664
|
+
const acquired = currentAdmission.acquireAdmission({
|
|
665
|
+
operationId,
|
|
666
|
+
operationKind: `api.${method}`,
|
|
667
|
+
scope,
|
|
668
|
+
});
|
|
669
|
+
if (acquired.kind === "blocked") {
|
|
670
|
+
throw new TelegramApiWorkspaceAdmissionError(
|
|
671
|
+
"blocked",
|
|
672
|
+
"Telegram API target is temporarily unavailable during Workspace retirement.",
|
|
673
|
+
);
|
|
674
|
+
}
|
|
675
|
+
try {
|
|
676
|
+
return await operation();
|
|
677
|
+
} finally {
|
|
678
|
+
try {
|
|
679
|
+
if (!currentAdmission.releaseAdmission(acquired.lease)) {
|
|
680
|
+
throw new TelegramApiWorkspaceAdmissionError(
|
|
681
|
+
"release-lost",
|
|
682
|
+
"Telegram API Workspace admission lease disappeared before release.",
|
|
683
|
+
);
|
|
684
|
+
}
|
|
685
|
+
} catch (error) {
|
|
686
|
+
try {
|
|
687
|
+
options.onReleaseError?.(error, method);
|
|
688
|
+
} catch {
|
|
689
|
+
// Diagnostics cannot convert an already-settled API request into replay.
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
} finally {
|
|
694
|
+
activeTelegramApiWorkspaceAdmissionOperationIds.delete(operationId);
|
|
695
|
+
}
|
|
696
|
+
};
|
|
697
|
+
return {
|
|
698
|
+
call: (method, body, callOptions) =>
|
|
699
|
+
admit(method, body, () => client.call(method, body, callOptions)),
|
|
700
|
+
callMultipart: (
|
|
701
|
+
method,
|
|
702
|
+
fields,
|
|
703
|
+
fileField,
|
|
704
|
+
filePath,
|
|
705
|
+
fileName,
|
|
706
|
+
callOptions,
|
|
707
|
+
) =>
|
|
708
|
+
admit(method, fields, () =>
|
|
709
|
+
client.callMultipart(
|
|
710
|
+
method,
|
|
711
|
+
fields,
|
|
712
|
+
fileField,
|
|
713
|
+
filePath,
|
|
714
|
+
fileName,
|
|
715
|
+
callOptions,
|
|
716
|
+
),
|
|
717
|
+
),
|
|
718
|
+
downloadFile: client.downloadFile,
|
|
719
|
+
answerCallbackQuery: client.answerCallbackQuery,
|
|
720
|
+
...(client.answerGuestQuery
|
|
721
|
+
? { answerGuestQuery: client.answerGuestQuery }
|
|
722
|
+
: {}),
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
|
|
468
726
|
export interface TelegramBridgeApiRuntimeDeps {
|
|
469
727
|
captureRequestErrorHandler?: (body: Record<string, unknown>) =>
|
|
470
728
|
((error: unknown) => Promise<void>) | undefined;
|
|
@@ -1411,7 +1669,7 @@ export function createTelegramNativeMarkdownDraftSender(deps: {
|
|
|
1411
1669
|
return deps.sendRichMessageDraft({
|
|
1412
1670
|
chat_id: chatId,
|
|
1413
1671
|
draft_id: draftId,
|
|
1414
|
-
rich_message: { markdown: text
|
|
1672
|
+
rich_message: { markdown: text },
|
|
1415
1673
|
...(options?.message_thread_id !== undefined
|
|
1416
1674
|
? { message_thread_id: options.message_thread_id }
|
|
1417
1675
|
: {}),
|
|
@@ -1446,11 +1704,28 @@ export function createDefaultTelegramBridgeApiRuntime(deps: {
|
|
|
1446
1704
|
getBotToken: () => string | undefined;
|
|
1447
1705
|
recordRuntimeEvent: TelegramBridgeApiRuntimeDeps["recordRuntimeEvent"];
|
|
1448
1706
|
captureRequestErrorHandler?: TelegramBridgeApiRuntimeDeps["captureRequestErrorHandler"];
|
|
1707
|
+
targetActivity?: TelegramApiTargetActivityRuntime;
|
|
1708
|
+
workspaceAdmission?:
|
|
1709
|
+
| TelegramApiWorkspaceAdmissionPort
|
|
1710
|
+
| (() => TelegramApiWorkspaceAdmissionPort | undefined);
|
|
1449
1711
|
}): TelegramBridgeApiRuntime {
|
|
1712
|
+
const client = createTelegramApiClient(deps.getBotToken, {
|
|
1713
|
+
recordRuntimeEvent: deps.recordRuntimeEvent,
|
|
1714
|
+
});
|
|
1715
|
+
const admittedClient = deps.workspaceAdmission
|
|
1716
|
+
? createTelegramApiWorkspaceAdmissionClient(client, deps.workspaceAdmission, {
|
|
1717
|
+
onReleaseError(error, method) {
|
|
1718
|
+
deps.recordRuntimeEvent("api", error, {
|
|
1719
|
+
phase: "workspace-admission-release",
|
|
1720
|
+
method,
|
|
1721
|
+
});
|
|
1722
|
+
},
|
|
1723
|
+
})
|
|
1724
|
+
: client;
|
|
1450
1725
|
return createTelegramBridgeApiRuntime({
|
|
1451
|
-
client:
|
|
1452
|
-
|
|
1453
|
-
|
|
1726
|
+
client: deps.targetActivity
|
|
1727
|
+
? createTelegramApiTargetTrackingClient(admittedClient, deps.targetActivity)
|
|
1728
|
+
: admittedClient,
|
|
1454
1729
|
tempDir: getTelegramApiTempDir(),
|
|
1455
1730
|
maxFileSizeBytes: TELEGRAM_INBOUND_FILE_MAX_BYTES,
|
|
1456
1731
|
tempFileMaxAgeMs: TELEGRAM_TEMP_FILE_MAX_AGE_MS,
|