@llblab/pi-kit 0.6.0 → 0.7.1

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 (129) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +4 -4
  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-state-flow/AGENTS.md +33 -12
  35. package/node_modules/@llblab/pi-state-flow/BACKLOG.md +125 -2
  36. package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +87 -45
  37. package/node_modules/@llblab/pi-state-flow/README.md +203 -107
  38. package/node_modules/@llblab/pi-state-flow/docs/README.md +4 -0
  39. package/node_modules/@llblab/pi-state-flow/docs/architecture.md +188 -0
  40. package/node_modules/@llblab/pi-state-flow/docs/temporal-acceptance.md +42 -0
  41. package/node_modules/@llblab/pi-state-flow/index.ts +164 -2
  42. package/node_modules/@llblab/pi-state-flow/lib/acquisition.ts +138 -0
  43. package/node_modules/@llblab/pi-state-flow/lib/artifact.ts +273 -0
  44. package/node_modules/@llblab/pi-state-flow/lib/config.ts +48 -0
  45. package/node_modules/@llblab/pi-state-flow/lib/context.ts +18 -5
  46. package/node_modules/@llblab/pi-state-flow/lib/continuation.ts +268 -0
  47. package/node_modules/@llblab/pi-state-flow/lib/discovery.ts +117 -0
  48. package/node_modules/@llblab/pi-state-flow/lib/durable.ts +562 -0
  49. package/node_modules/@llblab/pi-state-flow/lib/episode.ts +24 -12
  50. package/node_modules/@llblab/pi-state-flow/lib/extension.ts +606 -70
  51. package/node_modules/@llblab/pi-state-flow/lib/git.ts +666 -0
  52. package/node_modules/@llblab/pi-state-flow/lib/history.ts +95 -0
  53. package/node_modules/@llblab/pi-state-flow/lib/json.ts +24 -0
  54. package/node_modules/@llblab/pi-state-flow/lib/maintenance.ts +141 -0
  55. package/node_modules/@llblab/pi-state-flow/lib/memory.ts +52 -0
  56. package/node_modules/@llblab/pi-state-flow/lib/migration.ts +88 -0
  57. package/node_modules/@llblab/pi-state-flow/lib/publication.ts +296 -0
  58. package/node_modules/@llblab/pi-state-flow/lib/recovery.ts +23 -7
  59. package/node_modules/@llblab/pi-state-flow/lib/rehydration.ts +79 -0
  60. package/node_modules/@llblab/pi-state-flow/lib/runtime.ts +264 -0
  61. package/node_modules/@llblab/pi-state-flow/lib/session.ts +6 -0
  62. package/node_modules/@llblab/pi-state-flow/lib/skills.ts +99 -7
  63. package/node_modules/@llblab/pi-state-flow/lib/snapshot.ts +305 -48
  64. package/node_modules/@llblab/pi-state-flow/lib/state.ts +74 -7
  65. package/node_modules/@llblab/pi-state-flow/lib/status.ts +125 -6
  66. package/node_modules/@llblab/pi-state-flow/lib/storage.ts +196 -0
  67. package/node_modules/@llblab/pi-state-flow/lib/temporal.ts +233 -0
  68. package/node_modules/@llblab/pi-state-flow/lib/terminal.ts +70 -24
  69. package/node_modules/@llblab/pi-state-flow/lib/transition.ts +254 -29
  70. package/node_modules/@llblab/pi-state-flow/package.json +8 -2
  71. package/node_modules/@llblab/pi-state-flow/skills/state-flow-memory/SKILL.md +128 -0
  72. package/node_modules/@llblab/pi-telegram/AGENTS.md +14 -9
  73. package/node_modules/@llblab/pi-telegram/BACKLOG.md +23 -5
  74. package/node_modules/@llblab/pi-telegram/CHANGELOG.md +18 -0
  75. package/node_modules/@llblab/pi-telegram/README.md +13 -9
  76. package/node_modules/@llblab/pi-telegram/docs/README.md +1 -0
  77. package/node_modules/@llblab/pi-telegram/docs/architecture.md +227 -23
  78. package/node_modules/@llblab/pi-telegram/docs/generative-apps.md +1 -1
  79. package/node_modules/@llblab/pi-telegram/docs/multi-instance-bus.md +70 -19
  80. package/node_modules/@llblab/pi-telegram/docs/outbound.md +6 -6
  81. package/node_modules/@llblab/pi-telegram/docs/public-api.md +13 -6
  82. package/node_modules/@llblab/pi-telegram/docs/ui-style.md +3 -1
  83. package/node_modules/@llblab/pi-telegram/index.ts +4 -1418
  84. package/node_modules/@llblab/pi-telegram/lib/agent-messages.ts +6 -3
  85. package/node_modules/@llblab/pi-telegram/lib/bindings.ts +46 -1
  86. package/node_modules/@llblab/pi-telegram/lib/bus-api.ts +32 -19
  87. package/node_modules/@llblab/pi-telegram/lib/bus-follower.ts +600 -135
  88. package/node_modules/@llblab/pi-telegram/lib/bus-leader.ts +962 -55
  89. package/node_modules/@llblab/pi-telegram/lib/bus.ts +355 -26
  90. package/node_modules/@llblab/pi-telegram/lib/channel-posts.ts +718 -0
  91. package/node_modules/@llblab/pi-telegram/lib/commands.ts +237 -11
  92. package/node_modules/@llblab/pi-telegram/lib/config.ts +242 -26
  93. package/node_modules/@llblab/pi-telegram/lib/extension.ts +1851 -0
  94. package/node_modules/@llblab/pi-telegram/lib/generative-apps.ts +20 -2
  95. package/node_modules/@llblab/pi-telegram/lib/journal.ts +2184 -126
  96. package/node_modules/@llblab/pi-telegram/lib/locks.ts +44 -2
  97. package/node_modules/@llblab/pi-telegram/lib/menu-settings.ts +152 -13
  98. package/node_modules/@llblab/pi-telegram/lib/outbound-attachments.ts +97 -10
  99. package/node_modules/@llblab/pi-telegram/lib/paths.ts +29 -0
  100. package/node_modules/@llblab/pi-telegram/lib/polling.ts +85 -17
  101. package/node_modules/@llblab/pi-telegram/lib/preview.ts +17 -0
  102. package/node_modules/@llblab/pi-telegram/lib/prompts.ts +6 -2
  103. package/node_modules/@llblab/pi-telegram/lib/queue.ts +118 -26
  104. package/node_modules/@llblab/pi-telegram/lib/rendering.ts +4 -1
  105. package/node_modules/@llblab/pi-telegram/lib/replies.ts +21 -2
  106. package/node_modules/@llblab/pi-telegram/lib/routing.ts +344 -112
  107. package/node_modules/@llblab/pi-telegram/lib/setup.ts +44 -4
  108. package/node_modules/@llblab/pi-telegram/lib/status.ts +51 -4
  109. package/node_modules/@llblab/pi-telegram/lib/sync.ts +308 -39
  110. package/node_modules/@llblab/pi-telegram/lib/telegram-api.ts +353 -22
  111. package/node_modules/@llblab/pi-telegram/lib/thread-cleanup-manager.ts +664 -0
  112. package/node_modules/@llblab/pi-telegram/lib/thread-display.ts +226 -0
  113. package/node_modules/@llblab/pi-telegram/lib/thread-naming.ts +118 -0
  114. package/node_modules/@llblab/pi-telegram/lib/threads.ts +1686 -129
  115. package/node_modules/@llblab/pi-telegram/lib/turns.ts +7 -0
  116. package/node_modules/@llblab/pi-telegram/lib/updates.ts +1319 -97
  117. package/node_modules/@llblab/pi-telegram/lib/workspace-admission.ts +1643 -0
  118. package/node_modules/@llblab/pi-telegram/lib/workspace-retirement.ts +968 -0
  119. package/node_modules/@llblab/pi-telegram/lib/workspace-slots.ts +84 -0
  120. package/node_modules/@llblab/pi-telegram/package.json +1 -1
  121. package/node_modules/@llblab/pi-telegram/screenshot.png +0 -0
  122. package/node_modules/@llblab/pi-telegram/scripts/measure-bus.mjs +83 -0
  123. package/node_modules/@llblab/pi-telegram/scripts/measure-workspace.mjs +101 -0
  124. package/node_modules/@llblab/{skills → pi-telegram/skills}/show-me/SKILL.md +28 -6
  125. package/node_modules/@llblab/pi-telegram/skills/show-me/references/telegram-surfaces.md +43 -0
  126. package/node_modules/@llblab/pi-telegram/skills/telegram-bridge/references/delivery-and-threads.md +1 -1
  127. package/node_modules/@llblab/skills/package.json +2 -3
  128. package/package.json +6 -5
  129. /package/node_modules/@llblab/pi-telegram/lib/{logs.ts → logging.ts} +0 -0
@@ -42,6 +42,10 @@ export interface TelegramSetupDeps {
42
42
  result?: TelegramSetupUser;
43
43
  description?: string;
44
44
  }>;
45
+ /** Resolve a submitted literal token or `$NAME`/`${NAME}` reference. */
46
+ resolveBotToken?: (value: string) => string | undefined;
47
+ /** Redacted diagnostic for an unresolved or malformed token reference. */
48
+ describeBotToken?: (value: string) => string | undefined;
45
49
  persistConfig: (config: TelegramSetupConfig) => Promise<void>;
46
50
  notify: (message: string, level: "info" | "error") => void;
47
51
  startPolling: () => unknown | Promise<unknown>;
@@ -70,6 +74,8 @@ export interface TelegramSetupPromptRuntimeDeps<
70
74
  setConfig: (config: TelegramSetupConfig) => void;
71
75
  setupGuard: TelegramSetupGuard;
72
76
  getMe: TelegramSetupDeps["getMe"];
77
+ resolveBotToken?: TelegramSetupDeps["resolveBotToken"];
78
+ describeBotToken?: TelegramSetupDeps["describeBotToken"];
73
79
  persistConfig: (config: TelegramSetupConfig) => Promise<void>;
74
80
  startPolling: (ctx: TContext) => unknown | Promise<unknown>;
75
81
  updateStatus: (ctx: TContext) => void;
@@ -88,6 +94,25 @@ const TELEGRAM_BOT_TOKEN_ENV_VARS = [
88
94
  "TELEGRAM_KEY",
89
95
  ] as const;
90
96
 
97
+ /**
98
+ * Default submitted-token handling for structural callers that inject no
99
+ * reference port: plain literals pass through, while `$`-prefixed values fail
100
+ * closed instead of being sent to the Bot API as a literal token.
101
+ */
102
+ function resolveSubmittedTelegramBotToken(value: string): string | undefined {
103
+ const trimmed = value.trim();
104
+ if (!trimmed || trimmed.startsWith("$")) return undefined;
105
+ return trimmed;
106
+ }
107
+
108
+ function describeSubmittedTelegramBotToken(
109
+ value: string,
110
+ ): string | undefined {
111
+ return value.trim().startsWith("$")
112
+ ? "Telegram bot token environment reference is unavailable in this setup environment."
113
+ : undefined;
114
+ }
115
+
91
116
  function isTelegramPollingStartResult(
92
117
  value: unknown,
93
118
  ): value is TelegramPollingStartResult {
@@ -105,8 +130,8 @@ export function getTelegramBotTokenInputDefault(
105
130
  const trimmedConfigToken = configToken?.trim();
106
131
  if (trimmedConfigToken) return trimmedConfigToken;
107
132
  for (const key of TELEGRAM_BOT_TOKEN_ENV_VARS) {
108
- const value = env[key]?.trim();
109
- if (value) return value;
133
+ // Persist the originating alias rather than copying the resolved secret.
134
+ if (env[key]?.trim()) return `$${key}`;
110
135
  }
111
136
  return TELEGRAM_BOT_TOKEN_INPUT_PLACEHOLDER;
112
137
  }
@@ -135,13 +160,26 @@ export async function runTelegramSetup(
135
160
  ? await deps.promptEditor("Telegram bot token", tokenPrompt.value)
136
161
  : await deps.promptInput("Telegram bot token", tokenPrompt.value);
137
162
  if (!token) return { status: "cancelled" };
163
+ const submittedToken = token.trim();
164
+ const resolveBotToken =
165
+ deps.resolveBotToken ?? resolveSubmittedTelegramBotToken;
166
+ const describeBotToken =
167
+ deps.describeBotToken ?? describeSubmittedTelegramBotToken;
168
+ const resolvedToken = resolveBotToken(submittedToken);
138
169
  const nextConfig: TelegramSetupConfig = {
139
170
  ...deps.config,
140
- botToken: token.trim(),
171
+ botToken: submittedToken,
141
172
  };
173
+ if (!resolvedToken) {
174
+ deps.notify(
175
+ describeBotToken(submittedToken) ?? "Invalid Telegram bot token",
176
+ "error",
177
+ );
178
+ return { status: "validation-failed" };
179
+ }
142
180
  let data: Awaited<ReturnType<TelegramSetupDeps["getMe"]>>;
143
181
  try {
144
- data = await deps.getMe(nextConfig.botToken ?? "");
182
+ data = await deps.getMe(resolvedToken);
145
183
  } catch (error) {
146
184
  const message = error instanceof Error ? error.message : String(error);
147
185
  deps.notify(`Telegram API check failed: ${message}`, "error");
@@ -195,6 +233,8 @@ export function createTelegramSetupPromptRuntime<
195
233
  promptInput: (label, value) => ctx.ui.input(label, value),
196
234
  promptEditor: (label, value) => ctx.ui.editor(label, value),
197
235
  getMe: deps.getMe,
236
+ resolveBotToken: deps.resolveBotToken,
237
+ describeBotToken: deps.describeBotToken,
198
238
  persistConfig: async (config) => {
199
239
  const previousConfig = deps.getConfig();
200
240
  deps.setConfig(config);
@@ -207,6 +207,7 @@ export interface TelegramBridgeInboundWorkerState {
207
207
  phaseStartedAtMs?: number;
208
208
  currentUpdateId?: number;
209
209
  blockedReason?: string;
210
+ blockedInputCustody?: { updateId: number; kind: string };
210
211
  journalEntryCount: number;
211
212
  journalSerializedBytes: number;
212
213
  oldestAdmittedAtMs?: number;
@@ -244,6 +245,8 @@ export interface TelegramBridgeInboundWorkerState {
244
245
  export interface TelegramBridgeStatusLineState {
245
246
  hasBotToken?: boolean;
246
247
  botUsername?: string;
248
+ /** Redacted named-variable diagnostic when the stored token reference cannot resolve. */
249
+ botTokenDiagnostic?: string;
247
250
  activeProfileName?: string;
248
251
  diagnosticPaths?: { state: string; logs: string };
249
252
  allowedUserId?: number;
@@ -294,6 +297,7 @@ export interface TelegramStatusBarState {
294
297
  pollingStopReason?: string;
295
298
  paired: boolean;
296
299
  busRole?: TelegramBridgeBusRole;
300
+ followerRegistered?: boolean;
297
301
  busLifecyclePhase?: TelegramBridgeBusLifecyclePhase;
298
302
  instanceSlot?: string;
299
303
  instanceThreadName?: string;
@@ -321,10 +325,40 @@ export interface TelegramStatusRuntimeDeps<
321
325
 
322
326
  export interface TelegramBridgeStatusConfig {
323
327
  botToken?: string;
328
+ /** Caller-resolved token availability; falls back to raw presence. */
329
+ botHasToken?: boolean;
330
+ /** Caller-supplied redacted diagnostic for an unresolved token reference. */
331
+ botTokenDiagnostic?: string;
324
332
  botUsername?: string;
325
333
  allowedUserId?: number;
326
334
  }
327
335
 
336
+ /** Narrow config-store view used to project resolved bot-token availability. */
337
+ export interface TelegramBridgeStatusConfigSource {
338
+ get: () => TelegramBridgeStatusConfig;
339
+ hasBotToken?: () => boolean;
340
+ getBotTokenDiagnostic?: () => string | undefined;
341
+ }
342
+
343
+ /**
344
+ * Project a config store into the status view without moving token-reference
345
+ * resolution into this structural leaf domain.
346
+ */
347
+ export function createTelegramBridgeStatusConfigGetter(
348
+ source: TelegramBridgeStatusConfigSource,
349
+ ): () => TelegramBridgeStatusConfig {
350
+ return () => {
351
+ const config = source.get();
352
+ return {
353
+ ...config,
354
+ ...(source.hasBotToken ? { botHasToken: source.hasBotToken() } : {}),
355
+ ...(source.getBotTokenDiagnostic
356
+ ? { botTokenDiagnostic: source.getBotTokenDiagnostic() }
357
+ : {}),
358
+ };
359
+ };
360
+ }
361
+
328
362
  export interface TelegramBridgeStatusRuntimeDeps<
329
363
  TQueueItem extends { queueLane: TelegramStatusQueueLane },
330
364
  > {
@@ -677,11 +711,13 @@ export function createTelegramBridgeStatusRuntime<
677
711
  const hasPendingModelSwitch = deps.hasPendingModelSwitch();
678
712
  const activeToolExecutions = deps.getActiveToolExecutions();
679
713
  const compactionInProgress = deps.isCompactionInProgress();
714
+ const localBus = deps.getLocalBus?.();
680
715
  return {
681
- hasBotToken: !!config.botToken,
716
+ hasBotToken: config.botHasToken ?? Boolean(config.botToken),
682
717
  pollingActive: deps.isPollingActive(),
683
718
  paired: !!config.allowedUserId,
684
719
  busRole: deps.getBusRole?.(),
720
+ followerRegistered: localBus?.followerRegistered,
685
721
  busLifecyclePhase: deps.getBusLifecyclePhase?.(),
686
722
  instanceSlot: deps.getInstanceSlot?.(),
687
723
  instanceThreadName: deps.getInstanceThreadName?.(),
@@ -711,8 +747,9 @@ export function createTelegramBridgeStatusRuntime<
711
747
  ? (deps.getActiveProfileName() ?? TELEGRAM_STATUS_DEFAULT_PROFILE_NAME)
712
748
  : undefined;
713
749
  return {
714
- hasBotToken: Boolean(config.botToken),
750
+ hasBotToken: config.botHasToken ?? Boolean(config.botToken),
715
751
  botUsername: config.botUsername,
752
+ botTokenDiagnostic: config.botTokenDiagnostic,
716
753
  activeProfileName,
717
754
  diagnosticPaths: deps.getDiagnosticPaths?.(activeProfileName),
718
755
  allowedUserId: config.allowedUserId,
@@ -902,6 +939,9 @@ export function buildTelegramStatusBarText(
902
939
  if (state.error) {
903
940
  return `${label} ${theme.fg("error", "error")}`;
904
941
  }
942
+ if (state.busRole === "follower" && state.followerRegistered === false) {
943
+ return `${label} ${theme.fg("warning", "reconnecting")}${queued}`;
944
+ }
905
945
  if (state.processing) {
906
946
  const processingStatus = state.queuedStatus
907
947
  ? "active"
@@ -918,10 +958,14 @@ export function buildTelegramStatusBarText(
918
958
  }
919
959
 
920
960
  function formatTelegramBridgeBotStatus(
921
- state: Pick<TelegramBridgeStatusLineState, "hasBotToken" | "botUsername">,
961
+ state: Pick<
962
+ TelegramBridgeStatusLineState,
963
+ "hasBotToken" | "botUsername" | "botTokenDiagnostic"
964
+ >,
922
965
  ): string {
923
966
  if (state.botUsername) return `@${state.botUsername}`;
924
- return state.hasBotToken ? "unknown" : "not configured";
967
+ if (state.hasBotToken) return "unknown";
968
+ return state.botTokenDiagnostic ?? "not configured";
925
969
  }
926
970
 
927
971
  function formatTelegramStatusTarget(
@@ -1277,6 +1321,9 @@ function buildTelegramInboundWorkerDiagnosticLines(
1277
1321
  ...(worker.blockedReason
1278
1322
  ? [`- blocked reason: ${worker.blockedReason}`]
1279
1323
  : []),
1324
+ ...(worker.blockedInputCustody
1325
+ ? [`- blocked input custody: update=${worker.blockedInputCustody.updateId}, kind=${worker.blockedInputCustody.kind}`]
1326
+ : []),
1280
1327
  ...(worker.lastCompletedUpdateId !== undefined
1281
1328
  ? [
1282
1329
  `- last completed: ${worker.lastCompletedUpdateId}${worker.lastCompletedAtMs !== undefined ? ` at ${new Date(worker.lastCompletedAtMs).toISOString()}` : ""}`,