@llblab/pi-telegram 0.54.2 → 0.54.4

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 CHANGED
@@ -4,6 +4,20 @@
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.54.4: Restored tabs take their Pi's name
8
+
9
+ - `Restore title`: Restoring a Pi into a routing tab ("move Pi into this tab") now renames the tab to that Pi's Thread display title, as Workspace Restore already did; previously a live-rebind Restore left the tab named `🚦 Routing`. A failed rename is recorded and never blocks the Restore.
10
+ - `Native routing tabs`: An `All` input now also adopts a generically named native tab (desktop `New Chat`) that its client created immediately before it, not only a tab named after the input (mobile). Desktop and Android clients, with user topic creation allowed or not, each end with exactly one routing tab; a client's own brief native name before the rename cannot be prevented.
11
+ - `Reclaimed leader tab`: When the leader's own tab is gone (for example after deleting every tab) and a new tab from `All` is reclaimed for it, the leader's Workspace binding now moves to that tab with its slot and name instead of gaining a second slot, and the tab is renamed to its display title instead of staying `New Chat`. Restore and labels no longer point at the deleted tab.
12
+ - `Display titles`: A Thread whose tab has no acknowledged title yet (fresh, moved or reclaimed) now shows its display-mode title, such as the directory title, in the Restore menu and after Restore, instead of falling back to its generated slot name.
13
+ - `One-shot routing menus`: Every final routing choice now deletes its menu. A live-rebind Restore left the chooser in the tab, a Workspace Restore kept it until old-Thread cleanup, which may never come, and Cancel replaced it with a notice. A restored tab stays as the Pi's Thread; a routing tab with nothing left to route is still removed. A delivered Workspace Restore answers `Restored`, not `Restore unconfirmed`, and the Restore submenu now reads `🔁 Restore a Pi into this tab:`.
14
+ - `Restore history`: An input sent from `All` now moves into the routing tab opened for it, on desktop and mobile alike: the tab starts with a silent forward of the input, its menu replies to it, and the original leaves `All` once the copy is confirmed. A Thread restored into that tab keeps the prompt it answers instead of losing it, since the Bot API files such inputs in `All` even when mobile first draws them in the tab.
15
+ - `Old tab cleanup`: After a live-rebind Restore, the old tab is deleted right after Pi finishes answering the moved input, instead of at the next paced retry, which could add up to about 30 seconds and later a full minute. Cleanup still waits for an idle session; a settled agent only wakes the waiting retry early.
16
+
17
+ ## 0.54.3: One routing tab on mobile
18
+
19
+ - `Mobile routing tab`: Sending a command or prompt from `All` in mobile Telegram no longer leaves an extra tab named after the input. The mobile client creates that native tab itself before delivering the input to `All`; the bridge now adopts it as the routing tab and renames it, instead of creating a second tab beside it. Desktop behavior is unchanged.
20
+
7
21
  ## 0.54.2: Diagnosable ownership checks and safe app cancellation
8
22
 
9
23
  - `Ownership checks`: An ownership check that cannot be verified no longer silently stops a live transport. Each such miss is recorded (`ownership-check-failed`) and polling stands down only after two consecutive tolerated misses; a confirmed loss is recorded as `ownership-lost` and stands down at once (#319).
@@ -291,6 +291,8 @@ interface TelegramLifecycleBindingDeps {
291
291
  isTurnTransportActive?: (turn: Queue.PendingTelegramTurn) => boolean;
292
292
  updateStatus: TelegramBridgeStatusUpdater;
293
293
  recordRuntimeEvent: TelegramRuntimeEventRecorder;
294
+ /** Settled-session hint for owners that wait on agent idleness, such as old-tab cleanup after a live rebind. */
295
+ onSessionSettled?: (ctx: Pi.ExtensionContext) => void;
294
296
  }
295
- export declare function registerTelegramLifecycleRuntimeHooks({ pi, publicationRuntime, activityRuntime, activityVerbosityRuntime, diagnostics, assistantOutputRuntime, sessionLifecycleRuntime, configStore, abort, typing, lifecycle, activeTurnRuntime, telegramQueueStore, modelSwitchController, previewRuntime, promptDispatchRuntime, deferredQueueDispatchRuntime, modelContextAvailabilityRuntime, disconnectOnQuit, onSessionStarted, shutdownGenerativeAppLiveSurfaces, resolveAutomaticThreadCleanupEnabled, buttonActionStore, callMultipart, sendChatAction, sendRecordVoiceAction, sendMarkdownReply, sendTextReply, dispatchNextQueuedTelegramTurn, onPromptHandedOff, answerGuestQuery, deleteMessage, sendGuestReply, editGuestReply, stopGuestPlaceholder, preparePreviewDelivery, finalizeMarkdownPreview, proactivePushTargetGetter, getAssistantRenderingMode, recordMessageOwnership, canSendAgentActivity, isSessionContextActive, isTurnTransportActive, updateStatus, recordRuntimeEvent, }: TelegramLifecycleBindingDeps): void;
297
+ export declare function registerTelegramLifecycleRuntimeHooks({ pi, publicationRuntime, activityRuntime, activityVerbosityRuntime, diagnostics, assistantOutputRuntime, sessionLifecycleRuntime, configStore, abort, typing, lifecycle, activeTurnRuntime, telegramQueueStore, modelSwitchController, previewRuntime, promptDispatchRuntime, deferredQueueDispatchRuntime, modelContextAvailabilityRuntime, disconnectOnQuit, onSessionStarted, shutdownGenerativeAppLiveSurfaces, resolveAutomaticThreadCleanupEnabled, buttonActionStore, callMultipart, sendChatAction, sendRecordVoiceAction, sendMarkdownReply, sendTextReply, dispatchNextQueuedTelegramTurn, onPromptHandedOff, answerGuestQuery, deleteMessage, sendGuestReply, editGuestReply, stopGuestPlaceholder, preparePreviewDelivery, finalizeMarkdownPreview, proactivePushTargetGetter, getAssistantRenderingMode, recordMessageOwnership, canSendAgentActivity, isSessionContextActive, isTurnTransportActive, updateStatus, recordRuntimeEvent, onSessionSettled, }: TelegramLifecycleBindingDeps): void;
296
298
  export {};
@@ -626,7 +626,7 @@ export function registerTelegramCommandsAndTools({ pi, agentDir, configStore, pe
626
626
  },
627
627
  });
628
628
  }
629
- export function registerTelegramLifecycleRuntimeHooks({ pi, publicationRuntime, activityRuntime, activityVerbosityRuntime, diagnostics, assistantOutputRuntime, sessionLifecycleRuntime, configStore, abort, typing, lifecycle, activeTurnRuntime, telegramQueueStore, modelSwitchController, previewRuntime, promptDispatchRuntime, deferredQueueDispatchRuntime, modelContextAvailabilityRuntime, disconnectOnQuit, onSessionStarted, shutdownGenerativeAppLiveSurfaces, resolveAutomaticThreadCleanupEnabled, buttonActionStore, callMultipart, sendChatAction, sendRecordVoiceAction, sendMarkdownReply, sendTextReply, dispatchNextQueuedTelegramTurn, onPromptHandedOff, answerGuestQuery, deleteMessage, sendGuestReply, editGuestReply, stopGuestPlaceholder, preparePreviewDelivery, finalizeMarkdownPreview, proactivePushTargetGetter, getAssistantRenderingMode, recordMessageOwnership, canSendAgentActivity, isSessionContextActive = () => true, isTurnTransportActive, updateStatus, recordRuntimeEvent, }) {
629
+ export function registerTelegramLifecycleRuntimeHooks({ pi, publicationRuntime, activityRuntime, activityVerbosityRuntime, diagnostics, assistantOutputRuntime, sessionLifecycleRuntime, configStore, abort, typing, lifecycle, activeTurnRuntime, telegramQueueStore, modelSwitchController, previewRuntime, promptDispatchRuntime, deferredQueueDispatchRuntime, modelContextAvailabilityRuntime, disconnectOnQuit, onSessionStarted, shutdownGenerativeAppLiveSurfaces, resolveAutomaticThreadCleanupEnabled, buttonActionStore, callMultipart, sendChatAction, sendRecordVoiceAction, sendMarkdownReply, sendTextReply, dispatchNextQueuedTelegramTurn, onPromptHandedOff, answerGuestQuery, deleteMessage, sendGuestReply, editGuestReply, stopGuestPlaceholder, preparePreviewDelivery, finalizeMarkdownPreview, proactivePushTargetGetter, getAssistantRenderingMode, recordMessageOwnership, canSendAgentActivity, isSessionContextActive = () => true, isTurnTransportActive, updateStatus, recordRuntimeEvent, onSessionSettled, }) {
630
630
  const agentEndResetter = Runtime.createTelegramAgentEndResetter({
631
631
  abort,
632
632
  typing,
@@ -1077,6 +1077,7 @@ export function registerTelegramLifecycleRuntimeHooks({ pi, publicationRuntime,
1077
1077
  agentWorkActive = false;
1078
1078
  activityRuntime.onAgentSettled();
1079
1079
  modelContextAvailabilityRuntime.reconcile();
1080
+ onSessionSettled?.(ctx);
1080
1081
  },
1081
1082
  onBeforeAgentStart: Prompts.createTelegramProactiveBeforeAgentStartHook({
1082
1083
  reconcileAvailability: modelContextAvailabilityRuntime.reconcile,
@@ -478,6 +478,13 @@ export default function (pi) {
478
478
  instanceId: telegramInstanceId,
479
479
  listRecords: threadStore.list,
480
480
  listWorkspaceBindings: threadStore.listWorkspaceBindings,
481
+ resolveAutomaticDisplayTitle(binding) {
482
+ return ThreadDisplay.resolveTelegramInitialWorkspaceDisplayName({
483
+ bindings: threadStore.listWorkspaceBindings(),
484
+ binding,
485
+ mode: Config.resolveTelegramThreadDisplayMode(configStore.get()),
486
+ });
487
+ },
481
488
  getFollowerDisplayTitle: telegramBusFollowerRegistrationState.getDisplayTitle,
482
489
  getActiveTurnTarget: activeTurnRuntime.getTarget,
483
490
  getFollowerTarget: telegramBusFollowerRegistrationState.getTarget,
@@ -2440,5 +2447,6 @@ export default function (pi) {
2440
2447
  },
2441
2448
  updateStatus,
2442
2449
  recordRuntimeEvent,
2450
+ onSessionSettled: inboundRouteRuntime.onSessionSettled,
2443
2451
  });
2444
2452
  }
@@ -57,7 +57,10 @@ export type TelegramLiveRebindCleanupIssue = {
57
57
  cleanup: ThreadReconciler.TelegramLiveRebindCleanupOutcome;
58
58
  recorded: boolean;
59
59
  };
60
- /** Default live-rebind cleanup pacing: quick early attempts, then minutely, within a 15-minute window. */
60
+ /**
61
+ * Default live-rebind cleanup pacing: quick early attempts, then minutely, within a 15-minute window. The first
62
+ * delay is not cosmetic: a leader's detached command reply still needs the released, cleanup-free row.
63
+ */
61
64
  export declare const TELEGRAM_LIVE_REBIND_CLEANUP_SCHEDULE: Readonly<{
62
65
  delaysMs: readonly number[];
63
66
  intervalMs: 60000;
@@ -100,6 +103,8 @@ export declare function createTelegramLiveRebindCoordinator(input: {
100
103
  /** Explicit staged singleton command branch; absence preserves ordinary live input behavior. */
101
104
  selectedCommand?: Bus.TelegramBusSelectedCommandInput;
102
105
  };
106
+ /** Restore moves the tab to its new owner: once applied, show that owner's title (best-effort, never blocking). */
107
+ retitle?: (isCurrent: () => boolean) => Promise<void>;
103
108
  recordRuntimeEvent?: (category: string, error: unknown, details: Record<string, unknown>) => void;
104
109
  }): {
105
110
  /** Correlation only; a later cleanup attempt rereads and revalidates the canonical row itself. */
@@ -346,6 +351,8 @@ export declare function createTelegramInboundRouteRuntime<TUpdate extends Update
346
351
  /** Commands-owned registry port for dormant scoped recipient assembly, not ordinary update replay. */
347
352
  prepareHeldCommand: ReturnType<typeof Commands.createTelegramCommandHandlerTargetRuntime<TMessage, TContext>>["prepareHeldCommand"];
348
353
  canPrepareHeldCommand: ReturnType<typeof Commands.createTelegramCommandHandlerTargetRuntime<TMessage, TContext>>["canPrepareHeldCommand"];
354
+ /** Agent-settled hint: wakes waiting leader cleanup retries early; every readiness gate is still sampled fresh. */
355
+ onSessionSettled(ctx: TContext): void;
349
356
  /** Fresh body-free recipient observation only; never reconstructs an attempt or grants cleanup. */
350
357
  observeLiveRebindLeaderWork(intent: Threads.TelegramWorkspaceLiveRebindIntent, ctx: TContext): Promise<Bus.TelegramBusLiveRebindWorkObservation | undefined>;
351
358
  /** Fresh non-destructive candidate only; no retained idle, cleanup action or deletion grant. */