@songsid/agend 2.1.4-beta.10 → 2.1.4-beta.11

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.
@@ -629,6 +629,13 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
629
629
  * and once the agent had replied once there was no sign it was still going.
630
630
  */
631
631
  static progressText(elapsedMs: number, activity?: string | null, minElapsedMs?: number): string;
632
+ /** Render elapsed time consistently in live and retained progress bubbles. */
633
+ private static formatProgressElapsed;
634
+ /** Final read-only form of a bubble that contains semantic tool history.
635
+ * Neutral wording is intentional: the same retirement primitive is used for
636
+ * normal completion, a mid-turn bubble replacement, and user cancellation,
637
+ * so claiming every retained checkpoint is "completed" would be false. */
638
+ private composeRetiredBubbleText;
632
639
  /**
633
640
  * Make a tool summary safe to paste into a channel message.
634
641
  *
@@ -5177,16 +5177,28 @@ export class FleetManager {
5177
5177
  static progressText(elapsedMs, activity, minElapsedMs = PROGRESS_MIN_ELAPSED_MS) {
5178
5178
  if (elapsedMs < minElapsedMs)
5179
5179
  return "👀 處理中…";
5180
+ const elapsed = FleetManager.formatProgressElapsed(elapsedMs);
5181
+ const detail = FleetManager.sanitizeActivity(activity);
5182
+ return detail
5183
+ ? `⏳ 處理中… (已進行 ${elapsed} · ${detail})`
5184
+ : `⏳ 處理中… (已進行 ${elapsed})`;
5185
+ }
5186
+ /** Render elapsed time consistently in live and retained progress bubbles. */
5187
+ static formatProgressElapsed(elapsedMs) {
5180
5188
  const totalSeconds = Math.floor(elapsedMs / 1000);
5181
5189
  const minutes = Math.floor(totalSeconds / 60);
5182
5190
  const seconds = totalSeconds % 60;
5183
- const elapsed = minutes >= 60
5191
+ return minutes >= 60
5184
5192
  ? `${Math.floor(minutes / 60)}h ${minutes % 60}m`
5185
5193
  : `${minutes}m ${String(seconds).padStart(2, "0")}s`;
5186
- const detail = FleetManager.sanitizeActivity(activity);
5187
- return detail
5188
- ? `⏳ 處理中… (已進行 ${elapsed} · ${detail})`
5189
- : `⏳ 處理中… (已進行 ${elapsed})`;
5194
+ }
5195
+ /** Final read-only form of a bubble that contains semantic tool history.
5196
+ * Neutral wording is intentional: the same retirement primitive is used for
5197
+ * normal completion, a mid-turn bubble replacement, and user cancellation,
5198
+ * so claiming every retained checkpoint is "completed" would be false. */
5199
+ composeRetiredBubbleText(entry) {
5200
+ const elapsed = FleetManager.formatProgressElapsed(Date.now() - (entry.startedAt ?? Date.now()));
5201
+ return `🧾 工具歷程 (記錄至 ${elapsed})\n${entry.toolProgress}`;
5190
5202
  }
5191
5203
  /**
5192
5204
  * Make a tool summary safe to paste into a channel message.
@@ -5474,8 +5486,12 @@ export class FleetManager {
5474
5486
  if (!adapter)
5475
5487
  return Promise.reject(new Error("no adapter for cancel button"));
5476
5488
  if (e.toolProgress && adapter.editMessageRemoveButtons) {
5477
- return adapter.editMessageRemoveButtons(e.chatId, e.messageId, this.composeBubbleText(e), e.threadId);
5489
+ return adapter.editMessageRemoveButtons(e.chatId, e.messageId, this.composeRetiredBubbleText(e), e.threadId);
5478
5490
  }
5491
+ // All production adapters currently implement editMessageRemoveButtons.
5492
+ // A third-party adapter without it degrades to the legacy delete behavior:
5493
+ // removing a live Cancel control is safer than retaining an actionable,
5494
+ // untracked button forever.
5479
5495
  if (adapter.deleteMessage)
5480
5496
  return adapter.deleteMessage(e.chatId, e.messageId, e.threadId);
5481
5497
  if (adapter.editMessageRemoveButtons)