@llblab/pi-kit 0.5.2 → 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.
Files changed (141) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +5 -5
  3. package/node_modules/@llblab/pi-actors/AGENTS.md +1 -1
  4. package/node_modules/@llblab/pi-actors/CHANGELOG.md +6 -0
  5. package/node_modules/@llblab/pi-actors/README.md +1 -1
  6. package/node_modules/@llblab/pi-actors/dist/lib/async-runs.d.ts +3 -0
  7. package/node_modules/@llblab/pi-actors/dist/lib/async-runs.js +14 -1
  8. package/node_modules/@llblab/pi-actors/dist/lib/command-templates.js +45 -3
  9. package/node_modules/@llblab/pi-actors/dist/lib/extension-runtime.js +1 -1
  10. package/node_modules/@llblab/pi-actors/dist/lib/observability.d.ts +16 -3
  11. package/node_modules/@llblab/pi-actors/dist/lib/observability.js +92 -7
  12. package/node_modules/@llblab/pi-actors/dist/lib/pi.d.ts +0 -1
  13. package/node_modules/@llblab/pi-actors/dist/lib/pi.js +15 -24
  14. package/node_modules/@llblab/pi-actors/dist/lib/run-delivery-lineage.d.ts +17 -0
  15. package/node_modules/@llblab/pi-actors/dist/lib/run-delivery-lineage.js +44 -0
  16. package/node_modules/@llblab/pi-actors/dist/lib/run-delivery.d.ts +4 -0
  17. package/node_modules/@llblab/pi-actors/dist/lib/run-delivery.js +102 -4
  18. package/node_modules/@llblab/pi-actors/dist/lib/run-ui-runtime.js +58 -39
  19. package/node_modules/@llblab/pi-actors/dist/lib/runtime.js +14 -6
  20. package/node_modules/@llblab/pi-actors/dist/skills/actors/SKILL.md +1 -1
  21. package/node_modules/@llblab/pi-actors/docs/async-runs.md +1 -1
  22. package/node_modules/@llblab/pi-actors/docs/coordinator-delivery.md +18 -23
  23. package/node_modules/@llblab/pi-actors/lib/async-runs.ts +18 -1
  24. package/node_modules/@llblab/pi-actors/lib/command-templates.ts +41 -3
  25. package/node_modules/@llblab/pi-actors/lib/extension-runtime.ts +1 -1
  26. package/node_modules/@llblab/pi-actors/lib/observability.ts +119 -5
  27. package/node_modules/@llblab/pi-actors/lib/pi.ts +15 -28
  28. package/node_modules/@llblab/pi-actors/lib/run-delivery-lineage.ts +68 -0
  29. package/node_modules/@llblab/pi-actors/lib/run-delivery.ts +120 -4
  30. package/node_modules/@llblab/pi-actors/lib/run-ui-runtime.ts +69 -44
  31. package/node_modules/@llblab/pi-actors/lib/runtime.ts +17 -6
  32. package/node_modules/@llblab/pi-actors/package.json +1 -1
  33. package/node_modules/@llblab/pi-actors/skills/actors/SKILL.md +1 -1
  34. package/node_modules/@llblab/pi-grow-loop/AGENTS.md +2 -2
  35. package/node_modules/@llblab/pi-grow-loop/CHANGELOG.md +4 -0
  36. package/node_modules/@llblab/pi-grow-loop/README.md +6 -6
  37. package/node_modules/@llblab/pi-grow-loop/index.ts +6 -3
  38. package/node_modules/@llblab/pi-grow-loop/package.json +1 -1
  39. package/node_modules/@llblab/pi-state-flow/AGENTS.md +33 -12
  40. package/node_modules/@llblab/pi-state-flow/BACKLOG.md +125 -2
  41. package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +87 -45
  42. package/node_modules/@llblab/pi-state-flow/README.md +203 -107
  43. package/node_modules/@llblab/pi-state-flow/docs/README.md +4 -0
  44. package/node_modules/@llblab/pi-state-flow/docs/architecture.md +188 -0
  45. package/node_modules/@llblab/pi-state-flow/docs/temporal-acceptance.md +42 -0
  46. package/node_modules/@llblab/pi-state-flow/index.ts +164 -2
  47. package/node_modules/@llblab/pi-state-flow/lib/acquisition.ts +138 -0
  48. package/node_modules/@llblab/pi-state-flow/lib/artifact.ts +273 -0
  49. package/node_modules/@llblab/pi-state-flow/lib/config.ts +48 -0
  50. package/node_modules/@llblab/pi-state-flow/lib/context.ts +18 -5
  51. package/node_modules/@llblab/pi-state-flow/lib/continuation.ts +268 -0
  52. package/node_modules/@llblab/pi-state-flow/lib/discovery.ts +117 -0
  53. package/node_modules/@llblab/pi-state-flow/lib/durable.ts +562 -0
  54. package/node_modules/@llblab/pi-state-flow/lib/episode.ts +24 -12
  55. package/node_modules/@llblab/pi-state-flow/lib/extension.ts +606 -70
  56. package/node_modules/@llblab/pi-state-flow/lib/git.ts +666 -0
  57. package/node_modules/@llblab/pi-state-flow/lib/history.ts +95 -0
  58. package/node_modules/@llblab/pi-state-flow/lib/json.ts +24 -0
  59. package/node_modules/@llblab/pi-state-flow/lib/maintenance.ts +141 -0
  60. package/node_modules/@llblab/pi-state-flow/lib/memory.ts +52 -0
  61. package/node_modules/@llblab/pi-state-flow/lib/migration.ts +88 -0
  62. package/node_modules/@llblab/pi-state-flow/lib/publication.ts +296 -0
  63. package/node_modules/@llblab/pi-state-flow/lib/recovery.ts +23 -7
  64. package/node_modules/@llblab/pi-state-flow/lib/rehydration.ts +79 -0
  65. package/node_modules/@llblab/pi-state-flow/lib/runtime.ts +264 -0
  66. package/node_modules/@llblab/pi-state-flow/lib/session.ts +6 -0
  67. package/node_modules/@llblab/pi-state-flow/lib/skills.ts +99 -7
  68. package/node_modules/@llblab/pi-state-flow/lib/snapshot.ts +305 -48
  69. package/node_modules/@llblab/pi-state-flow/lib/state.ts +74 -7
  70. package/node_modules/@llblab/pi-state-flow/lib/status.ts +125 -6
  71. package/node_modules/@llblab/pi-state-flow/lib/storage.ts +196 -0
  72. package/node_modules/@llblab/pi-state-flow/lib/temporal.ts +233 -0
  73. package/node_modules/@llblab/pi-state-flow/lib/terminal.ts +70 -24
  74. package/node_modules/@llblab/pi-state-flow/lib/transition.ts +254 -29
  75. package/node_modules/@llblab/pi-state-flow/package.json +8 -2
  76. package/node_modules/@llblab/pi-state-flow/skills/state-flow-memory/SKILL.md +128 -0
  77. package/node_modules/@llblab/pi-telegram/AGENTS.md +14 -9
  78. package/node_modules/@llblab/pi-telegram/BACKLOG.md +20 -4
  79. package/node_modules/@llblab/pi-telegram/CHANGELOG.md +22 -5
  80. package/node_modules/@llblab/pi-telegram/README.md +13 -9
  81. package/node_modules/@llblab/pi-telegram/docs/README.md +1 -0
  82. package/node_modules/@llblab/pi-telegram/docs/architecture.md +220 -18
  83. package/node_modules/@llblab/pi-telegram/docs/generative-apps.md +1 -1
  84. package/node_modules/@llblab/pi-telegram/docs/multi-instance-bus.md +70 -19
  85. package/node_modules/@llblab/pi-telegram/docs/outbound.md +13 -7
  86. package/node_modules/@llblab/pi-telegram/docs/public-api.md +13 -5
  87. package/node_modules/@llblab/pi-telegram/docs/ui-style.md +3 -1
  88. package/node_modules/@llblab/pi-telegram/index.ts +4 -1415
  89. package/node_modules/@llblab/pi-telegram/lib/activity.ts +19 -5
  90. package/node_modules/@llblab/pi-telegram/lib/agent-messages.ts +6 -3
  91. package/node_modules/@llblab/pi-telegram/lib/bindings.ts +37 -2
  92. package/node_modules/@llblab/pi-telegram/lib/bus-follower.ts +600 -135
  93. package/node_modules/@llblab/pi-telegram/lib/bus-leader.ts +962 -55
  94. package/node_modules/@llblab/pi-telegram/lib/bus.ts +350 -26
  95. package/node_modules/@llblab/pi-telegram/lib/channel-posts.ts +544 -0
  96. package/node_modules/@llblab/pi-telegram/lib/commands.ts +234 -11
  97. package/node_modules/@llblab/pi-telegram/lib/config.ts +178 -25
  98. package/node_modules/@llblab/pi-telegram/lib/delivery.ts +18 -18
  99. package/node_modules/@llblab/pi-telegram/lib/extension.ts +1792 -0
  100. package/node_modules/@llblab/pi-telegram/lib/generative-apps.ts +20 -2
  101. package/node_modules/@llblab/pi-telegram/lib/journal.ts +2184 -126
  102. package/node_modules/@llblab/pi-telegram/lib/lifecycle.ts +7 -1
  103. package/node_modules/@llblab/pi-telegram/lib/locks.ts +38 -1
  104. package/node_modules/@llblab/pi-telegram/lib/menu-settings.ts +154 -15
  105. package/node_modules/@llblab/pi-telegram/lib/outbound-attachments.ts +74 -40
  106. package/node_modules/@llblab/pi-telegram/lib/outbound-voice.ts +28 -42
  107. package/node_modules/@llblab/pi-telegram/lib/outbound.ts +18 -14
  108. package/node_modules/@llblab/pi-telegram/lib/paths.ts +29 -0
  109. package/node_modules/@llblab/pi-telegram/lib/polling.ts +85 -17
  110. package/node_modules/@llblab/pi-telegram/lib/preview.ts +115 -70
  111. package/node_modules/@llblab/pi-telegram/lib/prompts.ts +5 -2
  112. package/node_modules/@llblab/pi-telegram/lib/queue.ts +66 -22
  113. package/node_modules/@llblab/pi-telegram/lib/replies.ts +47 -39
  114. package/node_modules/@llblab/pi-telegram/lib/routing.ts +305 -112
  115. package/node_modules/@llblab/pi-telegram/lib/status.ts +10 -0
  116. package/node_modules/@llblab/pi-telegram/lib/sync.ts +308 -39
  117. package/node_modules/@llblab/pi-telegram/lib/telegram-api.ts +315 -7
  118. package/node_modules/@llblab/pi-telegram/lib/thread-cleanup-manager.ts +664 -0
  119. package/node_modules/@llblab/pi-telegram/lib/thread-display.ts +226 -0
  120. package/node_modules/@llblab/pi-telegram/lib/thread-naming.ts +118 -0
  121. package/node_modules/@llblab/pi-telegram/lib/threads.ts +1686 -129
  122. package/node_modules/@llblab/pi-telegram/lib/updates.ts +1319 -97
  123. package/node_modules/@llblab/pi-telegram/lib/workspace-admission.ts +1643 -0
  124. package/node_modules/@llblab/pi-telegram/lib/workspace-retirement.ts +968 -0
  125. package/node_modules/@llblab/pi-telegram/lib/workspace-slots.ts +84 -0
  126. package/node_modules/@llblab/pi-telegram/package.json +1 -1
  127. package/node_modules/@llblab/pi-telegram/screenshot.png +0 -0
  128. package/node_modules/@llblab/pi-telegram/scripts/measure-bus.mjs +83 -0
  129. package/node_modules/@llblab/pi-telegram/scripts/measure-workspace.mjs +101 -0
  130. package/node_modules/@llblab/{skills → pi-telegram/skills}/show-me/SKILL.md +28 -6
  131. package/node_modules/@llblab/pi-telegram/skills/show-me/references/telegram-surfaces.md +43 -0
  132. package/node_modules/@llblab/pi-telegram/skills/telegram-bridge/references/delivery-and-threads.md +1 -1
  133. package/node_modules/@llblab/skills/abcd-context/AGENTS.md +1 -0
  134. package/node_modules/@llblab/skills/abcd-context/CHANGELOG.md +6 -2
  135. package/node_modules/@llblab/skills/abcd-context/SKILL.md +1 -1
  136. package/node_modules/@llblab/skills/abcd-context/docs/validation-design.md +11 -5
  137. package/node_modules/@llblab/skills/abcd-context/scripts/_self-test.mjs +61 -0
  138. package/node_modules/@llblab/skills/abcd-context/scripts/validate-context.mjs +67 -0
  139. package/node_modules/@llblab/skills/package.json +2 -3
  140. package/node_modules/@llblab/skills/release-flow/SKILL.md +2 -4
  141. package/package.json +7 -6
@@ -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) {
@@ -804,7 +809,13 @@ export interface TelegramAssistantOutputRuntime {
804
809
  stop: () => void;
805
810
  }
806
811
 
812
+ export interface TelegramAssistantOutputPreparation {
813
+ wait: () => Promise<void>;
814
+ settle: () => void;
815
+ }
816
+
807
817
  export function createTelegramAssistantOutputRuntime<TAuthority = undefined>(deps: {
818
+ prepareSend?: (event: TelegramAssistantSegmentEvent) => TelegramAssistantOutputPreparation | undefined;
808
819
  enqueue?: TelegramActivityPublicationRuntime["enqueue"];
809
820
  captureAuthority?: () => TAuthority;
810
821
  isAuthorityActive?: (authority: TAuthority) => boolean;
@@ -843,6 +854,7 @@ export function createTelegramAssistantOutputRuntime<TAuthority = undefined>(dep
843
854
  admitted.add(key);
844
855
  const admittedGeneration = generation;
845
856
  const admittedAuthority = deps.captureAuthority?.();
857
+ const preparation = deps.prepareSend?.(event);
846
858
  const enqueue = deps.enqueue ?? ((task: () => Promise<void>) => tail.then(task));
847
859
  tail = enqueue(async () => {
848
860
  const isAdmittedAuthorityActive = () =>
@@ -853,6 +865,8 @@ export function createTelegramAssistantOutputRuntime<TAuthority = undefined>(dep
853
865
  deps.isAuthorityActive(admittedAuthority as TAuthority));
854
866
  if (!isAdmittedAuthorityActive() || !deps.canDeliver(event)) return;
855
867
  try {
868
+ if (preparation) await preparation.wait();
869
+ if (!isAdmittedAuthorityActive() || !deps.canDeliver(event)) return;
856
870
  await deps.send(
857
871
  event,
858
872
  admittedAuthority as TAuthority,
@@ -861,7 +875,7 @@ export function createTelegramAssistantOutputRuntime<TAuthority = undefined>(dep
861
875
  } catch (error) {
862
876
  deps.recordFailure?.(event, error);
863
877
  }
864
- });
878
+ }).finally(() => preparation?.settle());
865
879
  },
866
880
  waitForIdle() {
867
881
  return tail;
@@ -18,6 +18,7 @@ export interface TelegramAgentMessageRuntimeDeps<TContext, TUpdate> {
18
18
  getAllowedChatId: () => number | undefined;
19
19
  getLeaderTarget: () => TelegramTarget | undefined;
20
20
  getLeaderThreadName: () => string | undefined;
21
+ getDisplayTitle?: (target: TelegramTarget) => string | undefined;
21
22
  followerRegistry: TelegramBusFollowerRegistry;
22
23
  getContext: () => TContext | undefined;
23
24
  handleUpdate: (update: TUpdate, ctx: TContext) => Promise<void>;
@@ -39,7 +40,7 @@ export function createTelegramAgentMessageRuntime<TContext, TUpdate>(
39
40
  if (leaderTarget?.threadId) {
40
41
  targets.push({
41
42
  target: { chatId: leaderTarget.chatId, threadId: leaderTarget.threadId },
42
- threadName: deps.getLeaderThreadName(),
43
+ threadName: deps.getDisplayTitle?.(leaderTarget) ?? deps.getLeaderThreadName(),
43
44
  });
44
45
  }
45
46
  for (const follower of deps.followerRegistry.list()) {
@@ -49,7 +50,7 @@ export function createTelegramAgentMessageRuntime<TContext, TUpdate>(
49
50
  chatId: follower.target.chatId,
50
51
  threadId: follower.target.threadId,
51
52
  },
52
- threadName: follower.threadName,
53
+ threadName: deps.getDisplayTitle?.(follower.target) ?? follower.threadName,
53
54
  });
54
55
  }
55
56
  return targets;
@@ -98,8 +99,10 @@ export function createTelegramAgentMessageRuntime<TContext, TUpdate>(
98
99
  if (allowedChatId === undefined || !ctx) {
99
100
  throw new Error("Telegram agent turn routing is unavailable.");
100
101
  }
102
+ const sourceTitle = (input.sourceTarget ? deps.getDisplayTitle?.(input.sourceTarget) : undefined)
103
+ ?? input.sourceThreadName;
101
104
  const sourceLabel =
102
- input.sourceThreadName
105
+ sourceTitle
103
106
  ?.replace(/[\r\n\[\]]+/g, " ")
104
107
  .trim()
105
108
  .slice(0, 64) || "Pi";
@@ -6,6 +6,7 @@
6
6
 
7
7
  import * as Activity from "./activity.ts";
8
8
  import * as ActivityVerbosity from "./activity-verbosity.ts";
9
+ import * as ChannelPosts from "./channel-posts.ts";
9
10
  import * as CommandTemplates from "./command-templates.ts";
10
11
  import * as Commands from "./commands.ts";
11
12
  import * as Config from "./config.ts";
@@ -353,6 +354,7 @@ export function createTelegramAssistantOutputBindingRuntime<
353
354
  typeof OutboundHandlers.createTelegramAssistantOutputSender<TTransportStamp>
354
355
  >[0];
355
356
  waitForActivityIdle?: () => Promise<void>;
357
+ prepareTelegramPreview?: () => Activity.TelegramAssistantOutputPreparation | undefined;
356
358
  enqueue?: Activity.TelegramActivityPublicationRuntime["enqueue"];
357
359
  recordRuntimeEvent: TelegramRuntimeEventRecorder;
358
360
  }): TelegramAssistantOutputBindingRuntime<TTransportStamp> {
@@ -366,6 +368,7 @@ export function createTelegramAssistantOutputBindingRuntime<
366
368
  const runtime = Activity.createTelegramAssistantOutputRuntime({
367
369
  ...authority,
368
370
  enqueue: deps.enqueue,
371
+ prepareSend: (event) => event.source === "telegram" ? deps.prepareTelegramPreview?.() : undefined,
369
372
  async send(event, authority, isAuthorityActive) {
370
373
  await deps.waitForActivityIdle?.();
371
374
  if (!isAuthorityActive()) return;
@@ -496,6 +499,10 @@ interface TelegramCommandsAndToolsBindingDeps {
496
499
  stopPolling?: () => Promise<void | string>;
497
500
  recoverPollingStart?: Commands.TelegramBridgeCommandRegistrationDeps["recoverPollingStart"];
498
501
  getDisconnectThreadName?: () => string | undefined;
502
+ setRequestedThreadNameForPollingStart?: (
503
+ threadName: string | undefined,
504
+ ) => void;
505
+ validateThreadName?: Commands.TelegramBridgeCommandRegistrationDeps["validateThreadName"];
499
506
  onTransportChanged?: () => Promise<void> | void;
500
507
  getStatusLines: (
501
508
  options?: Status.TelegramBridgeStatusLineOptions,
@@ -510,6 +517,12 @@ interface TelegramCommandsAndToolsBindingDeps {
510
517
  target?: { chatId: number; threadId?: number };
511
518
  },
512
519
  ) => Promise<number | undefined>;
520
+ sendChannelMarkdownMessage: NonNullable<
521
+ OutboundAttachments.TelegramOutboundMessageToolRegistrationDeps["sendChannelMarkdownMessage"]
522
+ >;
523
+ listChannelPosts: ChannelPosts.TelegramChannelPostJournalStore["list"];
524
+ mutateChannelPost(input: { action: "edit" | "delete"; operationId: string;
525
+ mutationId: string; markdown?: string }): Promise<ChannelPosts.TelegramChannelPostRecord>;
513
526
  callMultipart: OutboundHandlers.TelegramVoiceReplySenderDeps["sendMultipart"];
514
527
  getDefaultChatId: () => number | undefined;
515
528
  getDefaultTarget?: () => OutboundAttachments.TelegramQueuedOutboundAttachmentTurnView["target"];
@@ -531,10 +544,15 @@ export function registerTelegramCommandsAndTools({
531
544
  stopPolling,
532
545
  recoverPollingStart,
533
546
  getDisconnectThreadName,
547
+ setRequestedThreadNameForPollingStart,
548
+ validateThreadName,
534
549
  onTransportChanged,
535
550
  getStatusLines,
536
551
  buttonActionStore,
537
552
  sendMarkdownReply,
553
+ sendChannelMarkdownMessage,
554
+ listChannelPosts,
555
+ mutateChannelPost,
538
556
  callMultipart,
539
557
  getDefaultChatId,
540
558
  getDefaultTarget,
@@ -554,6 +572,8 @@ export function registerTelegramCommandsAndTools({
554
572
  sendMarkdownReply,
555
573
  recordRuntimeEvent,
556
574
  });
575
+ ChannelPosts.registerTelegramChannelPostMutationTool(pi, { mutate: mutateChannelPost });
576
+ ChannelPosts.registerTelegramChannelPostListTool(pi, { list: listChannelPosts });
557
577
  OutboundAttachments.registerTelegramOutboundAttachmentTool(pi, {
558
578
  getActiveTurn: activeTurnRuntime.get,
559
579
  getDefaultChatId,
@@ -576,6 +596,7 @@ export function registerTelegramCommandsAndTools({
576
596
  ),
577
597
  sendMarkdownMessage: (chatId, markdown, options) =>
578
598
  sendMarkdownReply(chatId, undefined, markdown, options),
599
+ sendChannelMarkdownMessage,
579
600
  recordRuntimeEvent,
580
601
  });
581
602
  const queueAgentConnectionContext = (connected: boolean): void => {
@@ -634,7 +655,11 @@ export function registerTelegramCommandsAndTools({
634
655
  );
635
656
  }
636
657
  await configStore.load();
637
- configStore.setProfile(profileName, profile);
658
+ const latestProfile = configStore.getStoredConfig().profiles?.[profileName];
659
+ configStore.setProfile(profileName, {
660
+ ...profile,
661
+ threadDisplayMode: latestProfile?.threadDisplayMode,
662
+ });
638
663
  configStore.activateProfile(profileName);
639
664
  await onTransportChanged?.();
640
665
  await persistConfig(configStore.get());
@@ -668,16 +693,20 @@ export function registerTelegramCommandsAndTools({
668
693
  reloadConfig: configStore.load,
669
694
  hasBotToken: configStore.hasBotToken,
670
695
  startPolling: async (ctx, options) => {
696
+ setRequestedThreadNameForPollingStart?.(options?.requestedThreadName);
671
697
  try {
672
698
  return await lockedPollingRuntime.start(ctx, options);
673
699
  } catch (error) {
674
700
  recordRuntimeEvent("recovery", error, { phase: "polling-start" });
675
701
  throw error;
702
+ } finally {
703
+ setRequestedThreadNameForPollingStart?.(undefined);
676
704
  }
677
705
  },
678
706
  stopPolling: stopPolling ?? lockedPollingRuntime.stop,
679
707
  recoverPollingStart,
680
708
  getDisconnectThreadName,
709
+ validateThreadName,
681
710
  queueAgentConnectionContext,
682
711
  updateStatus,
683
712
  getProfileNames: () =>
@@ -778,6 +807,7 @@ interface TelegramLifecycleBindingDeps {
778
807
  Keyboard.TelegramInlineKeyboardMarkup
779
808
  >["sendGuestReply"]
780
809
  >;
810
+ preparePreviewDelivery?: Queue.TelegramAgentEndRuntimeDeps<Queue.PendingTelegramTurn>["preparePreviewDelivery"];
781
811
  finalizeMarkdownPreview: Queue.TelegramAgentEndHookRuntimeDeps<
782
812
  Queue.PendingTelegramTurn,
783
813
  Pi.ExtensionContext,
@@ -829,6 +859,7 @@ export function registerTelegramLifecycleRuntimeHooks({
829
859
  answerGuestQuery,
830
860
  deleteMessage,
831
861
  sendGuestReply,
862
+ preparePreviewDelivery,
832
863
  finalizeMarkdownPreview,
833
864
  proactivePushTargetGetter,
834
865
  getAssistantRenderingMode,
@@ -1030,6 +1061,7 @@ export function registerTelegramLifecycleRuntimeHooks({
1030
1061
  cancel: reservation.cancel,
1031
1062
  };
1032
1063
  },
1064
+ preparePreviewDelivery,
1033
1065
  preparePreviewClear: previewRuntime.prepareClear,
1034
1066
  clearPreview: previewRuntime.clear,
1035
1067
  setPreviewPendingText: previewRuntime.setPendingText,
@@ -1052,6 +1084,7 @@ export function registerTelegramLifecycleRuntimeHooks({
1052
1084
  Lifecycle.setResetTransportReplyDedup(Replies.resetTransportReplyDedup);
1053
1085
  const agentStartWithDedupReset = Lifecycle.createAgentStartDedupHook(
1054
1086
  agentLifecycleHooks.onAgentStart,
1087
+ scheduleActiveTurnDelivery,
1055
1088
  );
1056
1089
  let uiPromptActive = false;
1057
1090
  const startAgentActivityTypingLoop = (ctx: Pi.ExtensionContext): boolean => {
@@ -1187,7 +1220,8 @@ export function registerTelegramLifecycleRuntimeHooks({
1187
1220
  agentWorkActive = true;
1188
1221
  cancelPendingFinalPublication();
1189
1222
  await agentStartWithDedupReset(event, ctx);
1190
- activityRuntime.onAgentStart(activeTurnRuntime.get()?.target);
1223
+ const turn = activeTurnRuntime.get();
1224
+ activityRuntime.onAgentStart(turn?.target, turn?.replyToMessageId);
1191
1225
  startAgentActivityTypingLoop(ctx);
1192
1226
  },
1193
1227
  async onToolExecutionStart(event, ctx) {
@@ -1233,6 +1267,7 @@ export function registerTelegramLifecycleRuntimeHooks({
1233
1267
  onMessageEnd(event, ctx) {
1234
1268
  if (!isSessionContextActive(ctx)) return;
1235
1269
  if (event.message.role === "assistant") {
1270
+ previewRuntime.seal();
1236
1271
  activityRuntime.onAssistantMessageEnd(event.message.stopReason);
1237
1272
  }
1238
1273
  if (event.message.role !== "assistant" || event.message.stopReason === "toolUse" || event.message.stopReason === "aborted") return;