@runtypelabs/persona 4.31.0 → 4.32.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 (141) hide show
  1. package/dist/activity-ui.cjs +2 -2
  2. package/dist/activity-ui.d.cts +11 -3
  3. package/dist/activity-ui.d.ts +11 -3
  4. package/dist/activity-ui.js +1 -1
  5. package/dist/animations/glyph-cycle.d.cts +1 -1
  6. package/dist/animations/glyph-cycle.d.ts +1 -1
  7. package/dist/animations/wipe.d.cts +1 -1
  8. package/dist/animations/wipe.d.ts +1 -1
  9. package/dist/approval-ui.d.cts +2 -2
  10. package/dist/approval-ui.d.ts +2 -2
  11. package/dist/artifacts-ui.d.cts +3 -3
  12. package/dist/artifacts-ui.d.ts +3 -3
  13. package/dist/background-runtime.d.cts +1 -1
  14. package/dist/background-runtime.d.ts +1 -1
  15. package/dist/{chunk-BrptyKSq.js → chunk-B3l7TOOv.js} +1 -1
  16. package/dist/chunk-B4ecQzeK.js +2 -0
  17. package/dist/{chunk-BWCo3rCm.js → chunk-B_H0l3u2.js} +1 -1
  18. package/dist/{chunk-MdlQetfC.js → chunk-BbXc58OA.js} +1 -1
  19. package/dist/chunk-BkOYJ11B.js +1 -0
  20. package/dist/{chunk-DE0cSmku.js → chunk-BpjtKnGI.js} +1 -1
  21. package/dist/{chunk-Co4LmTFv.js → chunk-C9uOhfk5.js} +1 -1
  22. package/dist/{chunk-CHAwCqpk.js → chunk-CdpVP6LZ.js} +1 -1
  23. package/dist/{chunk-WA9UucGf.js → chunk-CumoXK3u.js} +1 -1
  24. package/dist/{chunk-BBtVdcKU.js → chunk-DM-OJt5q.js} +1 -1
  25. package/dist/{chunk-Cb7qy0c7.js → chunk-DNdeIFJ6.js} +1 -1
  26. package/dist/{chunk-VaT6xry9.js → chunk-DTGvDx8o.js} +1 -1
  27. package/dist/{chunk-ezlpsYGk.js → chunk-DVZ8ri1z.js} +1 -1
  28. package/dist/{chunk-DhedQnek.js → chunk-DgZZqy14.js} +1 -1
  29. package/dist/{chunk-C2IbR39s.js → chunk-UWMfWW2a.js} +1 -1
  30. package/dist/client-dispatch.js +1 -1
  31. package/dist/client-history.js +1 -1
  32. package/dist/codegen.cjs +1 -1
  33. package/dist/codegen.js +1 -1
  34. package/dist/composer-actions-runtime.d.cts +2 -2
  35. package/dist/composer-actions-runtime.d.ts +2 -2
  36. package/dist/{composer-input-C2_WizXV.d.cts → composer-input-dwg_o9Z-.d.cts} +1 -1
  37. package/dist/{composer-input-C2_WizXV.d.ts → composer-input-dwg_o9Z-.d.ts} +1 -1
  38. package/dist/{composer-store-BV6kTlKv.d.cts → composer-store-Dw7Zbqxr.d.cts} +1 -1
  39. package/dist/{composer-store-BV6kTlKv.d.ts → composer-store-Dw7Zbqxr.d.ts} +1 -1
  40. package/dist/{context-mention-manager-BfZzcydV.d.cts → context-mention-manager-D2p0-JH-.d.cts} +2 -2
  41. package/dist/{context-mention-manager-BfZzcydV.d.ts → context-mention-manager-D2p0-JH-.d.ts} +2 -2
  42. package/dist/context-mentions-inline.d.cts +2 -2
  43. package/dist/context-mentions-inline.d.ts +2 -2
  44. package/dist/context-mentions.d.cts +3 -3
  45. package/dist/context-mentions.d.ts +3 -3
  46. package/dist/{defaults-DiTeXyr3.d.cts → defaults-CjX0kKzb.d.cts} +1 -1
  47. package/dist/{defaults-DiTeXyr3.d.ts → defaults-CjX0kKzb.d.ts} +1 -1
  48. package/dist/dictation-runtime.d.cts +2 -2
  49. package/dist/dictation-runtime.d.ts +2 -2
  50. package/dist/event-stream-view.d.cts +1 -1
  51. package/dist/event-stream-view.d.ts +1 -1
  52. package/dist/{fallback-speech-engine-DZ6Of7VU.d.cts → fallback-speech-engine-DmF7MczI.d.cts} +1 -1
  53. package/dist/{fallback-speech-engine-DZ6Of7VU.d.ts → fallback-speech-engine-DmF7MczI.d.ts} +1 -1
  54. package/dist/{feature-preferences-BT549D_E.d.cts → feature-preferences-CVFDt9Xf.d.cts} +1 -1
  55. package/dist/{feature-preferences-BT549D_E.d.ts → feature-preferences-CVFDt9Xf.d.ts} +1 -1
  56. package/dist/forms-ui.d.cts +2 -2
  57. package/dist/forms-ui.d.ts +2 -2
  58. package/dist/{history-confirm-dialog-Cm4oK4am.d.cts → history-confirm-dialog-DJEXsTyE.d.cts} +1 -1
  59. package/dist/{history-confirm-dialog-Cm4oK4am.d.ts → history-confirm-dialog-DJEXsTyE.d.ts} +1 -1
  60. package/dist/history-shell.d.cts +6 -6
  61. package/dist/history-shell.d.ts +6 -6
  62. package/dist/history-view.d.cts +1 -1
  63. package/dist/history-view.d.ts +1 -1
  64. package/dist/index.cjs +11 -10
  65. package/dist/index.cjs.map +1 -1
  66. package/dist/index.d.cts +9 -9
  67. package/dist/index.d.ts +9 -9
  68. package/dist/index.global.js +1 -1
  69. package/dist/index.global.js.map +1 -1
  70. package/dist/index.js +23 -22
  71. package/dist/index.js.map +1 -1
  72. package/dist/launcher.global.js +1 -1
  73. package/dist/launcher.global.js.map +1 -1
  74. package/dist/{loading-label-runtime-loader-DmiPDkBu.d.cts → loading-label-runtime-loader-CPxnoaoi.d.cts} +1 -1
  75. package/dist/{loading-label-runtime-loader-DmiPDkBu.d.ts → loading-label-runtime-loader-CPxnoaoi.d.ts} +1 -1
  76. package/dist/loading-label-runtime.d.cts +1 -1
  77. package/dist/loading-label-runtime.d.ts +1 -1
  78. package/dist/{message-bubble-D0rosKuK.d.cts → message-bubble-CkZGlCLC.d.cts} +1 -1
  79. package/dist/{message-bubble-D0rosKuK.d.ts → message-bubble-CkZGlCLC.d.ts} +1 -1
  80. package/dist/preferences-runtime.d.cts +1 -1
  81. package/dist/preferences-runtime.d.ts +1 -1
  82. package/dist/{preview-DRU27q-X.d.cts → preview-DdUvoLb4.d.cts} +2 -2
  83. package/dist/{preview-DRU27q-X.d.ts → preview-DdUvoLb4.d.ts} +2 -2
  84. package/dist/{registry-DRk3VMFc.d.cts → registry-Dz4iHNST.d.cts} +1 -1
  85. package/dist/{registry-DRk3VMFc.d.ts → registry-Dz4iHNST.d.ts} +1 -1
  86. package/dist/{session-Dj4bOm5y.d.cts → session-Baxp9iRK.d.cts} +14 -8
  87. package/dist/{session-Dj4bOm5y.d.ts → session-Baxp9iRK.d.ts} +14 -8
  88. package/dist/session-reconnect.d.cts +2 -2
  89. package/dist/session-reconnect.d.ts +2 -2
  90. package/dist/smart-dom-reader.d.cts +1 -1
  91. package/dist/smart-dom-reader.d.ts +1 -1
  92. package/dist/theme-editor-preview.cjs +46 -45
  93. package/dist/theme-editor-preview.d.cts +1 -1
  94. package/dist/theme-editor-preview.d.ts +1 -1
  95. package/dist/theme-editor-preview.js +19 -18
  96. package/dist/theme-editor.cjs +1 -1
  97. package/dist/theme-editor.d.cts +2 -2
  98. package/dist/theme-editor.d.ts +2 -2
  99. package/dist/theme-editor.js +1 -1
  100. package/dist/theme-reference.cjs +1 -1
  101. package/dist/theme-reference.d.cts +2 -2
  102. package/dist/theme-reference.d.ts +2 -2
  103. package/dist/theme-reference.js +1 -1
  104. package/dist/{tool-loading-animation-D1MS5Ace.d.cts → tool-loading-animation-un3kA5Ur.d.cts} +1 -1
  105. package/dist/{tool-loading-animation-D1MS5Ace.d.ts → tool-loading-animation-un3kA5Ur.d.ts} +1 -1
  106. package/dist/{turn-activity-ui-CorwdlI0.d.cts → turn-activity-ui-BGNhtMcH.d.cts} +2 -2
  107. package/dist/{turn-activity-ui-CorwdlI0.d.ts → turn-activity-ui-BGNhtMcH.d.ts} +2 -2
  108. package/dist/turn-activity-ui.d.cts +1 -1
  109. package/dist/turn-activity-ui.d.ts +1 -1
  110. package/dist/{types-CSXHl5cN.d.cts → types-BOZHQIk0.d.cts} +8 -1
  111. package/dist/{types-CSXHl5cN.d.ts → types-BOZHQIk0.d.ts} +8 -1
  112. package/dist/voice-client-tools.d.cts +1 -1
  113. package/dist/voice-client-tools.d.ts +1 -1
  114. package/dist/voice-runtime.cjs +1 -1
  115. package/dist/voice-runtime.d.cts +2 -2
  116. package/dist/voice-runtime.d.ts +2 -2
  117. package/dist/voice-runtime.js +1 -1
  118. package/dist/voice-worklet-player.d.cts +2 -2
  119. package/dist/voice-worklet-player.d.ts +2 -2
  120. package/dist/{webmcp-runtime-entry-DpDN6k-6.d.cts → webmcp-runtime-entry-DuAG1_yF.d.cts} +1 -1
  121. package/dist/{webmcp-runtime-entry-DpDN6k-6.d.ts → webmcp-runtime-entry-DuAG1_yF.d.ts} +1 -1
  122. package/dist/webmcp-runtime.d.cts +1 -1
  123. package/dist/webmcp-runtime.d.ts +1 -1
  124. package/dist/widget.css +1 -1
  125. package/package.json +1 -1
  126. package/src/activity-ui.ts +23 -0
  127. package/src/components/disclosure-animation.ts +5 -0
  128. package/src/components/tool-bubble.ts +1 -0
  129. package/src/index-core.ts +1 -0
  130. package/src/styles/widget.css +18 -0
  131. package/src/types.ts +8 -0
  132. package/src/ui.footer-visibility.test.ts +54 -0
  133. package/src/ui.reveal-tool-call.test.ts +258 -0
  134. package/src/ui.ts +127 -5
  135. package/src/utils/brand.test.ts +50 -0
  136. package/src/utils/brand.ts +6 -2
  137. package/src/utils/tokens.ts +2 -1
  138. package/src/utils/tool-activity-summary.test.ts +8 -0
  139. package/src/utils/tool-activity-summary.ts +2 -1
  140. package/dist/chunk-B3OrH9Ng.js +0 -2
  141. package/dist/chunk-CjhA_5Jk.js +0 -1
package/src/ui.ts CHANGED
@@ -66,6 +66,7 @@ import {
66
66
  AgentWidgetContextMentionRef,
67
67
  AgentWidgetStoredDraft,
68
68
  AgentWidgetOpenConversationOptions,
69
+ AgentWidgetRevealToolCallOptions,
69
70
  AgentWidgetSuggestion,
70
71
  AgentWidgetSuggestionSource,
71
72
  AgentWidgetWelcomeIcon,
@@ -367,6 +368,8 @@ const VOICE_STATE_RESTORE_WINDOW = 30 * 1000;
367
368
  const VOICE_RESUME_NOTICE = "Tap the mic to resume your voice call";
368
369
  // Split desktop boundary; must match widget.css artifact media queries (min-width:641px).
369
370
  const ARTIFACT_SPLIT_DESKTOP_MIN = 641;
371
+ // Covers the default 160ms V5 disclosure transition.
372
+ const REVEAL_SETTLE_MS = 200;
370
373
 
371
374
  /** Marks the status region while a composer lock reason owns it. */
372
375
  const COMPOSER_REASON_ATTR = "data-persona-composer-reason";
@@ -662,6 +665,12 @@ type Controller = {
662
665
  * (launcher mode) or textarea is unavailable.
663
666
  */
664
667
  focusInput: () => boolean;
668
+ /**
669
+ * Bring a tool call into view: opens any collapsed group holding it, expands its details
670
+ * (unless `expand: false`), scrolls it to the center of the transcript and briefly marks it
671
+ * with `data-persona-revealed`. Returns false when no rendered tool bubble has that id.
672
+ */
673
+ revealToolCall: (toolCallId: string, options?: AgentWidgetRevealToolCallOptions) => boolean;
665
674
  /**
666
675
  * Programmatically resolve a pending approval.
667
676
  * @param approvalId - The approval ID to resolve
@@ -2860,8 +2869,10 @@ export const createAgentExperience = (
2860
2869
 
2861
2870
  // Check if the click/keypress is on an expand header button
2862
2871
  const headerButton = target.closest('button[data-expand-header="true"]') as HTMLElement;
2863
- if (!headerButton) return;
2872
+ if (headerButton) toggleBubbleHeader(headerButton);
2873
+ };
2864
2874
 
2875
+ const toggleBubbleHeader = (headerButton: HTMLElement) => {
2865
2876
  // Find the parent bubble element
2866
2877
  const bubble = headerButton.closest('.persona-reasoning-bubble, .persona-tool-bubble, .persona-approval-bubble') as HTMLElement;
2867
2878
  if (!bubble) return;
@@ -2874,6 +2885,12 @@ export const createAgentExperience = (
2874
2885
  // DOM grows so the resize observer cannot pull the opened details away.
2875
2886
  markReaderEngaged();
2876
2887
  pauseAutoScroll();
2888
+ const anchor = anchorState;
2889
+ if (anchor) cancelSmoothScroll();
2890
+ const finishDisclosure = anchor && activityUi?.holdScroll(
2891
+ bubble, body, anchor, measureContentHeight, setAnchorSpacerHeight,
2892
+ BOTTOM_THRESHOLD, () => anchorState === anchor
2893
+ );
2877
2894
  const bubbleType = headerButton.getAttribute('data-bubble-type');
2878
2895
  if (bubble.classList.contains("persona-activity-row")) {
2879
2896
  activityLifecycle?.manual(messageId);
@@ -2900,6 +2917,7 @@ export const createAgentExperience = (
2900
2917
  approvalDetailsExpansionState.set(messageId, !expanded);
2901
2918
  approvalUi.updateApprovalDetailsUI(messageId, bubble, config, approvalDetailsExpansionState);
2902
2919
  }
2920
+ finishDisclosure?.();
2903
2921
  // Invalidate cached wrapper so next render rebuilds with current expansion state
2904
2922
  messageCache.delete(messageId);
2905
2923
  };
@@ -2950,6 +2968,24 @@ export const createAgentExperience = (
2950
2968
  // This handles clicks even after idiomorph morphs the DOM and strips inline listeners
2951
2969
  const messageVoteState = new Map<string, "upvote" | "downvote">();
2952
2970
 
2971
+ // Reveal state belongs to the message, not its current DOM node: streaming
2972
+ // renders can morph or replace the bubble before the highlight expires.
2973
+ const revealedToolCalls = new Map<string, number>();
2974
+ let revealCenterTimer: number | undefined;
2975
+ let revealScrollGeneration = 0;
2976
+ const refreshRevealedToolCalls = () => {
2977
+ messagesWrapper.querySelectorAll<HTMLElement>(".persona-tool-bubble[data-tool-call-id]").forEach((bubble) => {
2978
+ bubble.toggleAttribute("data-persona-revealed", revealedToolCalls.has(bubble.dataset.messageId!));
2979
+ });
2980
+ };
2981
+ const clearRevealedToolCalls = () => {
2982
+ window.clearTimeout(revealCenterTimer);
2983
+ revealCenterTimer = undefined;
2984
+ revealedToolCalls.forEach((timer) => window.clearTimeout(timer));
2985
+ revealedToolCalls.clear();
2986
+ refreshRevealedToolCalls();
2987
+ };
2988
+
2953
2989
  // Read-aloud (text-to-speech) button state. The ReadAloudController in the
2954
2990
  // session is the source of truth; these mirror its last-known state so the
2955
2991
  // button visuals can be re-applied after every render/morph (which would
@@ -4050,7 +4086,11 @@ export const createAgentExperience = (
4050
4086
  body.style.cssText = '';
4051
4087
  // A plugin-owned footer is the plugin's DOM: its inline state (the home
4052
4088
  // screen's `display: none` placeholder) is not ours to reset.
4053
- if (!composerIsPluginOwned) footer.style.cssText = '';
4089
+ if (!composerIsPluginOwned) {
4090
+ footer.style.cssText = '';
4091
+ // The reset also wipes the hidden state that layout.showFooter set.
4092
+ if (config.layout?.showFooter === false) footer.style.display = 'none';
4093
+ }
4054
4094
 
4055
4095
  // Preserve the event-stream takeover across a layout-mode change. The
4056
4096
  // cssText reset above wiped the `display: none` that toggleEventStreamOn
@@ -4402,6 +4442,7 @@ export const createAgentExperience = (
4402
4442
  border-top: none !important;
4403
4443
  padding: 8px 16px 12px 16px !important;
4404
4444
  ${chatFlush ? 'background: transparent !important;' : ''}
4445
+ ${config.layout?.showFooter === false ? 'display: none !important;' : ''}
4405
4446
  `;
4406
4447
  }
4407
4448
 
@@ -5056,6 +5097,7 @@ export const createAgentExperience = (
5056
5097
  initialSpacerHeight: number;
5057
5098
  contentHeightAtAnchor: number;
5058
5099
  spacerHeight: number;
5100
+ pending: number;
5059
5101
  } | null = null;
5060
5102
  let anchorRAF: number | null = null;
5061
5103
  // Seeded send-detection so restored history doesn't read as a fresh send.
@@ -5092,6 +5134,9 @@ export const createAgentExperience = (
5092
5134
  // look at the scroll event.
5093
5135
  let readerEngagedThisTurn = false;
5094
5136
  const markReaderEngaged = () => {
5137
+ // Reader input invalidates only reveal scrolling, including its settle pass.
5138
+ // The animation checks this generation before its next scroll write.
5139
+ revealScrollGeneration++;
5095
5140
  readerEngagedThisTurn = true;
5096
5141
  revealTranscriptScrollbar();
5097
5142
  };
@@ -5708,7 +5753,7 @@ export const createAgentExperience = (
5708
5753
  // arrow pointing at nothing. Trim to what the reader's current position
5709
5754
  // actually needs plus the anti-bounce slack (shrink-only, like the drain).
5710
5755
  const trimAnchorSpacerToRest = () => {
5711
- if (!anchorState || anchorState.spacerHeight <= 0) return;
5756
+ if (!anchorState || anchorState.spacerHeight <= 0 || anchorState.pending) return;
5712
5757
  const contentHeight = measureContentHeight(anchorState.spacerHeight);
5713
5758
  const required = Math.max(
5714
5759
  0,
@@ -5788,6 +5833,7 @@ export const createAgentExperience = (
5788
5833
  });
5789
5834
 
5790
5835
  anchorState = {
5836
+ pending: 0,
5791
5837
  initialSpacerHeight: spacerHeight,
5792
5838
  contentHeightAtAnchor: contentHeight,
5793
5839
  spacerHeight
@@ -5831,6 +5877,7 @@ export const createAgentExperience = (
5831
5877
  slack: BOTTOM_THRESHOLD
5832
5878
  });
5833
5879
  anchorState = {
5880
+ pending: 0,
5834
5881
  initialSpacerHeight: spacerHeight,
5835
5882
  contentHeightAtAnchor: contentHeight,
5836
5883
  spacerHeight
@@ -5857,7 +5904,7 @@ export const createAgentExperience = (
5857
5904
  scheduleAutoScroll(!isStreaming);
5858
5905
  return;
5859
5906
  }
5860
- if (anchorState && anchorState.initialSpacerHeight > 0) {
5907
+ if (anchorState && anchorState.initialSpacerHeight > 0 && !anchorState.pending) {
5861
5908
  const currentContentHeight = body.scrollHeight - anchorState.spacerHeight;
5862
5909
  const next = computeShrunkSpacerHeight({
5863
5910
  initialSpacerHeight: anchorState.initialSpacerHeight,
@@ -7185,6 +7232,15 @@ export const createAgentExperience = (
7185
7232
  if (messages.length > 0) warmClientStream();
7186
7233
  renderMessagesWithPluginsImpl(container, messages, transform);
7187
7234
  refreshReadAloudButtons();
7235
+ if (revealedToolCalls.size > 0) {
7236
+ for (const [id, timer] of revealedToolCalls) {
7237
+ if (!messages.some((message) => message.id === id)) {
7238
+ window.clearTimeout(timer);
7239
+ revealedToolCalls.delete(id);
7240
+ }
7241
+ }
7242
+ refreshRevealedToolCalls();
7243
+ }
7188
7244
  };
7189
7245
 
7190
7246
  /**
@@ -9159,7 +9215,7 @@ export const createAgentExperience = (
9159
9215
  currentTurnAnchored = reading.anchored;
9160
9216
  anchoredMessageId = reading.anchoredId;
9161
9217
  readerEngagedThisTurn = reading.readerEngaged;
9162
- anchorState = reading.anchor ? { ...reading.anchor } : null;
9218
+ anchorState = reading.anchor ? { ...reading.anchor, pending: 0 } : null;
9163
9219
  setAnchorSpacerHeight(reading.anchor?.spacerHeight ?? 0);
9164
9220
  if (reading.following) autoFollow.resume(); else autoFollow.pause();
9165
9221
  newMessagesSincePause = reading.unread;
@@ -11427,6 +11483,8 @@ export const createAgentExperience = (
11427
11483
 
11428
11484
  view.replaceComposer(nextFooter);
11429
11485
  footer = view.composer.footer;
11486
+ // A rebuilt footer starts visible; keep honoring layout.showFooter.
11487
+ if (config.layout?.showFooter === false) footer.style.display = "none";
11430
11488
  // A plugin composer owns its own send affordance, so the built-in
11431
11489
  // send/stop swap has nothing to drive.
11432
11490
  const isDefaultFooter =
@@ -12761,6 +12819,7 @@ export const createAgentExperience = (
12761
12819
  disposeApprovalRenders();
12762
12820
  artifactsPaneUserHidden = false;
12763
12821
  activityLifecycle?.clear();
12822
+ clearRevealedToolCalls();
12764
12823
  toolExpansionState.clear();
12765
12824
  reasoningExpansionState.clear();
12766
12825
  approvalDetailsExpansionState.clear();
@@ -13164,6 +13223,68 @@ export const createAgentExperience = (
13164
13223
  textarea.focus();
13165
13224
  return true;
13166
13225
  },
13226
+ revealToolCall(toolCallId: string, options: AgentWidgetRevealToolCallOptions = {}): boolean {
13227
+ const bubble = Array.from(body.querySelectorAll<HTMLElement>(".persona-tool-bubble[data-tool-call-id]"))
13228
+ .find((el) => el.dataset.toolCallId === toolCallId);
13229
+ if (!bubble) return false;
13230
+ const ownHeader = (owner: HTMLElement) =>
13231
+ Array.from(owner.querySelectorAll<HTMLElement>('button[data-expand-header="true"]'))
13232
+ .find((header) => header.closest(".persona-tool-bubble") === owner);
13233
+ const openHeader = (header: HTMLElement | undefined) => {
13234
+ if (header?.getAttribute("aria-expanded") === "false") toggleBubbleHeader(header);
13235
+ };
13236
+ const groups: HTMLElement[] = [];
13237
+ for (let group = bubble.parentElement?.closest<HTMLElement>(".persona-tool-bubble"); group;
13238
+ group = group.parentElement?.closest<HTMLElement>(".persona-tool-bubble")) groups.unshift(group);
13239
+ groups.forEach((group) => openHeader(ownHeader(group)));
13240
+ const header = ownHeader(bubble);
13241
+ if (options.expand !== false) openHeader(header);
13242
+
13243
+ markReaderEngaged();
13244
+ // A prior jump owns a separate animation whose completion resumes follow.
13245
+ latestScroll.cancel();
13246
+ pauseAutoScroll();
13247
+ const revealGeneration = revealScrollGeneration;
13248
+ const anchor = header ?? bubble;
13249
+ const shouldContinue = () => !destroyed && revealGeneration === revealScrollGeneration && body.contains(anchor);
13250
+ const reduceMotion = typeof window.matchMedia === "function" &&
13251
+ window.matchMedia("(prefers-reduced-motion: reduce)").matches;
13252
+ const targetTop = () => {
13253
+ const raw = offsetTopWithinBody(anchor) - (body.clientHeight - anchor.offsetHeight) / 2;
13254
+ return Math.max(0, Math.min(raw, getScrollBottomOffset(body)));
13255
+ };
13256
+ const center = () => {
13257
+ if (!shouldContinue()) return;
13258
+ // Use the same programmatic-scroll tracking as automatic following so
13259
+ // centering near the bottom cannot be mistaken for reader intent.
13260
+ if (reduceMotion) {
13261
+ cancelSmoothScroll();
13262
+ isAutoScrolling = true;
13263
+ body.scrollTop = targetTop();
13264
+ lastScrollTop = body.scrollTop;
13265
+ isAutoScrolling = false;
13266
+ } else animateScrollTo(body, targetTop, REVEAL_SETTLE_MS, shouldContinue);
13267
+ };
13268
+ window.clearTimeout(revealCenterTimer);
13269
+ center();
13270
+ // Disclosure height transitions move the row after the first pass; center again once they settle.
13271
+ revealCenterTimer = window.setTimeout(() => {
13272
+ revealCenterTimer = undefined;
13273
+ center();
13274
+ }, REVEAL_SETTLE_MS);
13275
+
13276
+ const highlightMs = options.highlightMs ?? 2000;
13277
+ if (highlightMs > 0) {
13278
+ const messageId = bubble.dataset.messageId!;
13279
+ window.clearTimeout(revealedToolCalls.get(messageId));
13280
+ revealedToolCalls.set(messageId, window.setTimeout(() => {
13281
+ revealedToolCalls.delete(messageId);
13282
+ refreshRevealedToolCalls();
13283
+ }, highlightMs));
13284
+ bubble.setAttribute("data-persona-revealed", "");
13285
+ }
13286
+ return true;
13287
+ },
13167
13288
  async resolveApproval(
13168
13289
  approvalId: string,
13169
13290
  decision: 'approved' | 'denied',
@@ -13308,6 +13429,7 @@ export const createAgentExperience = (
13308
13429
  }
13309
13430
  activityLifecycle?.destroy();
13310
13431
  loadingLabelLifecycle?.destroy();
13432
+ clearRevealedToolCalls();
13311
13433
  toolExpansionState.clear();
13312
13434
  reasoningExpansionState.clear();
13313
13435
  approvalDetailsExpansionState.clear();
@@ -73,6 +73,56 @@ describe('brand derivation', () => {
73
73
  expect(theme.components?.panel?.modes?.floating?.border).toContain('var(--persona-border)');
74
74
  expect(theme.components?.panel?.shadow).toBe(theme.palette?.shadows?.xl);
75
75
  });
76
+ describe.each(['light', 'dark'] as const)('%s message presentation', (colorScheme) => {
77
+ const elevations = [
78
+ ['flat', 'none'],
79
+ ['subtle', '0 2px 8px rgba(0, 0, 0, 0.08)'],
80
+ ['raised', '0 12px 32px rgba(0, 0, 0, 0.18)'],
81
+ ] as const;
82
+ it.each(elevations)('keeps V5 prose plain with %s elevation at every density', (elevation, shadow) => {
83
+ for (const density of ['compact', 'comfortable', 'spacious'] as const) {
84
+ const config = { colorScheme, future: { v5Defaults: true }, brand: { elevation, density } };
85
+ const vars = getCssVariables(getActiveTheme(config));
86
+ expect(vars['--persona-message-assistant-shadow']).toBe('none');
87
+ expect(vars['--persona-message-assistant-border']).toBe('transparent');
88
+ expect(vars['--persona-message-assistant-padding']).toBe('0px');
89
+ // These existing surfaces still follow elevation; this is not a global
90
+ // rule that every default of `none` must opt out of brand styling.
91
+ expect(vars['--persona-message-user-shadow']).toBe(shadow);
92
+ expect(getActiveTheme(config).components.introCard?.shadow).toBe(shadow);
93
+ const v4 = getCssVariables(getActiveTheme({ ...config, future: { v5Defaults: false } }));
94
+ expect(v4['--persona-message-assistant-shadow']).toBe(shadow);
95
+ expect(v4['--persona-message-assistant-border']).not.toBe('transparent');
96
+ }
97
+ });
98
+ it.each(elevations)('lets custom padded bubbles follow %s elevation', (elevation, shadow) => {
99
+ for (const [density, padding] of [['compact', '8px'], ['comfortable', '12px'], ['spacious', '16px']] as const) {
100
+ const theme = { components: { message: { assistant: {
101
+ background: 'semantic.colors.container', padding, borderRadius: '12px',
102
+ border: 'semantic.colors.border', borderWidth: '1px', shadow: 'palette.shadows.sm',
103
+ } } } };
104
+ // Shared overrides and dark-only overrides both remain authoritative.
105
+ for (const overrides of colorScheme === 'dark' ? [{ theme }, { darkTheme: theme }] : [{ theme }]) {
106
+ const vars = getCssVariables(getActiveTheme({
107
+ colorScheme, future: { v5Defaults: true }, brand: { elevation, density }, ...overrides,
108
+ }));
109
+ expect(vars['--persona-message-assistant-shadow']).toBe(shadow);
110
+ expect(vars['--persona-message-assistant-padding']).toBe(padding);
111
+ expect(vars['--persona-message-assistant-border']).not.toBe('transparent');
112
+ expect(vars['--persona-message-assistant-border-width']).toBe('1px');
113
+ }
114
+ }
115
+ });
116
+ it('preserves explicit assistant shadows and borders over brand elevation', () => {
117
+ const vars = getCssVariables(getActiveTheme({
118
+ colorScheme, future: { v5Defaults: true }, brand: { elevation: 'raised' },
119
+ theme: { components: { message: { assistant: { shadow: '0 1px 2px red', border: '#123456' } } } },
120
+ ...(colorScheme === 'dark' ? { darkTheme: { components: { message: { assistant: { shadow: 'none', border: '#abcdef' } } } } } : {}),
121
+ }));
122
+ expect(vars['--persona-message-assistant-shadow']).toBe(colorScheme === 'dark' ? 'none' : '0 1px 2px red');
123
+ expect(vars['--persona-message-assistant-border']).toBe(colorScheme === 'dark' ? '#abcdef' : '#123456');
124
+ });
125
+ });
76
126
  it.each([false, true])('keeps neutral-derived surfaces and elevation coherent (%s)', (v5Defaults) => {
77
127
  const theme = getActiveTheme({ future: { v5Defaults }, brand: { neutral: '#161b22', radius: 'none', elevation: 'flat' } });
78
128
  const vars = getCssVariables(theme);
@@ -111,8 +111,12 @@ export const deriveBrandTheme = (brand?: BrandConfig, scheme: 'light' | 'dark' =
111
111
  const shadow = flat ? 'none' : brand.elevation === 'subtle' ? '0 2px 8px rgba(0, 0, 0, 0.08)' : '0 12px 32px rgba(0, 0, 0, 0.18)';
112
112
  const border = flat ? '1px solid var(--persona-border)' : '1px solid color-mix(in srgb, var(--persona-border) 65%, transparent)';
113
113
  theme.palette = { ...theme.palette, shadows: { sm: shadow, md: shadow, lg: shadow, xl: shadow, '2xl': shadow } };
114
- const shadows = (node: Record<string, unknown>): Record<string, unknown> => {
114
+ const shadows = (node: Record<string, unknown>, path = ''): Record<string, unknown> => {
115
115
  const overlay: Record<string, unknown> = {};
116
+ // V5 assistant defaults are unpadded prose, not a surface to elevate.
117
+ // Explicit theme tokens still win; custom bubbles can opt into the brand
118
+ // shadow scale with `palette.shadows.sm` alongside their padding/background.
119
+ if (v5Defaults && path === 'message.assistant') return overlay;
116
120
  for (const [key, value] of Object.entries(node)) {
117
121
  if (key.toLowerCase().endsWith('shadow')) {
118
122
  overlay[key] = shadow;
@@ -120,7 +124,7 @@ export const deriveBrandTheme = (brand?: BrandConfig, scheme: 'light' | 'dark' =
120
124
  if (borderKey in node) overlay[borderKey] = typeof node[borderKey] === 'string' && (node[borderKey] as string).includes('solid') ? border : flat ? 'semantic.colors.border' : 'color-mix(in srgb, var(--persona-border) 65%, transparent)';
121
125
  }
122
126
  else if (value && typeof value === 'object') {
123
- const child = shadows(value as Record<string, unknown>);
127
+ const child = shadows(value as Record<string, unknown>, path ? `${path}.${key}` : key);
124
128
  if (Object.keys(child).length) overlay[key] = child;
125
129
  }
126
130
  }
@@ -603,7 +603,8 @@ export const DEFAULT_COMPONENTS_V5: ComponentTokens = {
603
603
  },
604
604
  launcher: CIRCLE_LAUNCHER_TOKENS,
605
605
  activity: {
606
- rowHeight: "32px", labelSize: "13px", iconSize: "16px", indent: "0px",
606
+ // CSS owns contextual parent, nested, and coarse-pointer row heights.
607
+ labelSize: "13px", iconSize: "16px", indent: "0px",
607
608
  transcriptGap: "0px", responseGap: "12px",
608
609
  groupIndent: "16px", groupGap: "2px", groupPadding: "2px 0",
609
610
  bodyPadding: "4px 0", bodyFontWeight: "400", sectionGap: "8px", bodySurface: "transparent",
@@ -6,6 +6,7 @@ const tool = (name: string, extra: Partial<AgentWidgetToolCall> = {}): AgentWidg
6
6
 
7
7
  describe("semantic tool activity", () => {
8
8
  it.each([
9
+ ["search_docs", "Searched docs"], ["read_file", "Read a file"],
9
10
  ["web_search", "Searched the web"], ["web_search_preview", "Searched the web"], ["WebSearch", "Searched the web"],
10
11
  ["web_fetch", "Read a web page"], ["WebFetch", "Read a web page"],
11
12
  ["file_search", "Searched files"], ["search_files", "Searched files"], ["Glob", "Searched files"],
@@ -22,6 +23,12 @@ describe("semantic tool activity", () => {
22
23
  ["sql_db_query", "Queried the database"], ["search_gmail", "Searched email"],
23
24
  ])("maps exact alias %s", (name, label) => expect(toolActivityLabel(tool(name))).toBe(label));
24
25
 
26
+ it("summarizes documentation searches and file reads without a custom hook", () => {
27
+ expect(summarizeToolActivity([tool("search_docs"), tool("read_file")])).toBe("Searched docs, read files");
28
+ expect(summarizeToolActivity([tool("search_docs", { status: "running" }), tool("read_file", { status: "pending" })])).toBe("Searching docs, reading files");
29
+ expect(toolActivityLabel(tool("read_file", { status: "running" }))).toBe("Reading a file");
30
+ });
31
+
25
32
  it.each(["search_events", "search_nodes", "read_graph", "open_nodes", "read", "search", "git_commit", "my_web_search", "web_search_custom"])("keeps ambiguous %s generic", name => {
26
33
  expect(toolActivityLabel(tool(name))).toMatch(/^Used /);
27
34
  });
@@ -127,6 +134,7 @@ describe("semantic tool activity", () => {
127
134
  });
128
135
 
129
136
  it.each([
137
+ ["search_docs", "search"], ["read_file", "file-text"],
130
138
  ["web_search", "globe"], ["Read", "file-text"], ["edit_file", "pencil"], ["Bash", "terminal"],
131
139
  ["sql_db_query", "database"], ["search_events", "wrench"], ["my_web_search", "wrench"],
132
140
  ])("maps the completed icon for %s without guessing", (name, icon) => expect(toolActivityIcon(tool(name))).toBe(icon));
@@ -3,10 +3,11 @@ import type { AgentWidgetConfig, AgentWidgetToolCall } from "../types";
3
3
  // Exact documented names only. Ambiguous names such as search_events or
4
4
  // search_nodes need provider metadata, which tool messages do not carry.
5
5
  const categories = [
6
+ ["search_docs", "Searching docs", "Searched docs", "search"],
6
7
  ["web_search|web_search_preview|WebSearch", "Searching the web", "Searched the web", "globe"],
7
8
  ["web_fetch|WebFetch", "Reading web pages", "Read web pages", "globe", "single"],
8
9
  ["file_search|search_files|Glob", "Searching files", "Searched files", "search"],
9
- ["read_text_file|read_multiple_files|Read", "Reading files", "Read files", "file-text", "single"],
10
+ ["read_file|read_text_file|read_multiple_files|Read", "Reading files", "Read files", "file-text", "single"],
10
11
  ["write_file|edit_file|apply_patch|Write|Edit|NotebookEdit", "Editing files", "Edited files", "pencil", "single"],
11
12
  ["list_directory|list_directory_with_sizes|directory_tree", "Browsing files", "Browsed files", "folder"],
12
13
  ["Grep", "Searching code", "Searched code", "search"],
@@ -1,2 +0,0 @@
1
- import{r as e,t}from"./chunk-D5BxWOFB.js";import{t as n}from"./chunk-Bb3MaswO.js";import{a as r,c as i,d as a,f as o,g as s,h as c,i as l,l as u,o as d,p as f,r as p,s as m,t as h,u as g}from"./chunk-mEFmAbxE.js";import{i as _,n as v,r as y,t as b}from"./chunk-BGPPJ_ui.js";import{n as x}from"./chunk-Cve3IfG4.js";const S=`[data-persona-disclosure]`,C=/* @__PURE__ */ new WeakMap;function w(e){let t=e?.expansion;return{animation:t?.animation??(e?.future?.v5Defaults?`height`:`instant`),duration:Number.isFinite(t?.duration)?Math.max(0,t.duration):160,easing:t?.easing??`ease-out`}}const T=e=>{let t=Array.from(e.children);return{header:t.find(e=>e.matches(`button[data-expand-header]`)),content:t.find(e=>e.classList.contains(`persona-border-t`)),preview:t.find(e=>e.hasAttribute(`data-persona-collapsed-preview`))}},E=e=>T(e).header?.getAttribute(`aria-expanded`)===`true`,D=()=>typeof matchMedia==`function`&&matchMedia(`(prefers-reduced-motion: reduce)`).matches;function O(e){let{header:t,content:n}=T(e),r=e.getRootNode();n?.contains(r.activeElement)&&t?.focus({preventScroll:!0})}function k(e,t){let{content:n,preview:r}=T(e);n&&(t||O(e),n.inert=!t,n.style.display=t?``:`none`,r&&(r.style.display=t||!(r.textContent||r.childNodes.length)?`none`:``))}function A(e){C.get(e)?.finish()}function j(e){for(let t=e.parentElement?.closest(S);t;t=t.parentElement?.closest(S))A(t);e.querySelectorAll(S).forEach(A)}function M(e,t,n,r){let i=w(n),a=i.animation===`height`&&i.duration>0&&!D()&&e.isConnected&&typeof e.animate==`function`,o=a?r??e.getBoundingClientRect().height:0,s=a&&C.has(e)?T(e).content:void 0,c=s?getComputedStyle(s):void 0,l=c?{transform:c.transform,opacity:c.opacity}:void 0;if(j(e),A(e),k(e,t),!a)return;let{header:u,content:d,preview:f}=T(e);if(!u||!d)return;let p=e.getBoundingClientRect().height;if(o===p)return;t||(d.style.display=``,f&&(f.style.display=`none`));let m,h;try{m=e.animate([{height:`${o}px`,boxSizing:`border-box`,overflow:`hidden`},{height:`${p}px`,boxSizing:`border-box`,overflow:`hidden`}],{duration:i.duration,easing:i.easing,fill:`both`});let n=getComputedStyle(d),r={transform:n.transform||`none`,opacity:n.opacity||`1`},a={transform:`${r.transform===`none`?``:r.transform} translateY(-8px)`,opacity:`0`};h=d.animate([l??(t?a:r),t?r:a],{duration:i.duration,easing:i.easing,fill:`both`})}catch{m?.cancel(),k(e,t);return}let g,_=p,v=()=>{C.get(e)?.effect===m&&(C.delete(e),g?.disconnect(),m.onfinish=m.oncancel=null,m.cancel(),h.cancel(),k(e,t))};C.set(e,{effect:m,expanded:t,settings:JSON.stringify(i),finish:v}),m.onfinish=m.oncancel=v,t&&typeof ResizeObserver==`function`&&(g=new ResizeObserver(()=>{if(C.get(e)?.effect!==m||!e.isConnected)return;let t=m.effect,n=t?.getComputedTiming().progress;if(n==null||n<0||n>=1)return;let r=e.getBoundingClientRect().height,i=e.style.getPropertyValue(`height`),a=e.style.getPropertyPriority(`height`);e.style.setProperty(`height`,`auto`,`important`);let o=e.getBoundingClientRect().height;i?e.style.setProperty(`height`,i,a):e.style.removeProperty(`height`),o!==_&&(_=o,t.setKeyframes([{height:`${r}px`,offset:n,boxSizing:`border-box`,overflow:`hidden`},{height:`${o}px`,offset:1,boxSizing:`border-box`,overflow:`hidden`}]))}),g.observe(d),g.observe(u))}function N(e,t){let n=/* @__PURE__ */ new Set,r=/* @__PURE__ */ new Map,i=typeof matchMedia==`function`?matchMedia(`(prefers-reduced-motion: reduce)`):void 0,a=()=>n.forEach(A),o=()=>{i?.matches&&a()};i?.addEventListener?.(`change`,o);let s=()=>{let e=w(t());return e.animation===`height`&&e.duration>0&&!D()};return{prepare(i){if(r.clear(),!s()){a(),n.clear();return}let o=new Map(Array.from(e.querySelectorAll(S),e=>[e.id,e]));for(let e of i.querySelectorAll(S)){let i=o.get(e.id);if(!i)continue;n.add(i);let a=E(e),s=C.get(i);if(a!==E(i))r.set(i.id,i.getBoundingClientRect().height),a||O(i),A(i);else if(s){if(s.settings!==JSON.stringify(w(t()))||D())A(i);else if(!s.expanded){let{content:t,preview:n}=T(e);t&&(t.style.display=``,t.inert=!0),n&&(n.style.display=`none`)}}}},sync(){if(!s())a(),n.clear(),r.clear();else{for(let t of n)e.contains(t)||(A(t),n.delete(t));for(let i of e.querySelectorAll(S)){n.add(i);let e=r.get(i.id);e!==void 0&&M(i,E(i),t(),e);let a=C.get(i);a&&(a.settings!==JSON.stringify(w(t()))||D())&&A(i)}r.clear()}},clear(){e.querySelectorAll(S).forEach(A),a(),n.clear(),r.clear()},destroy(){this.clear(),i?.removeEventListener?.(`change`,o)}}}const P=new Map([[`web_search|web_search_preview|WebSearch`,`Searching the web`,`Searched the web`,`globe`],[`web_fetch|WebFetch`,`Reading web pages`,`Read web pages`,`globe`,`single`],[`file_search|search_files|Glob`,`Searching files`,`Searched files`,`search`],[`read_text_file|read_multiple_files|Read`,`Reading files`,`Read files`,`file-text`,`single`],[`write_file|edit_file|apply_patch|Write|Edit|NotebookEdit`,`Editing files`,`Edited files`,`pencil`,`single`],[`list_directory|list_directory_with_sizes|directory_tree`,`Browsing files`,`Browsed files`,`folder`],[`Grep`,`Searching code`,`Searched code`,`search`],[`shell|local_shell|bash|Bash|PowerShell|bash_code_execution`,`Running commands`,`Ran commands`,`terminal`,`single`],[`code_interpreter|code_execution`,`Running code`,`Ran code`,`code-xml`],[`browser_navigate|browser_click|browser_snapshot|browser_fill_form`,`Using the browser`,`Used the browser`,`globe`],[`computer`,`Using the computer`,`Used the computer`,`monitor`],[`image_generation`,`Generating images`,`Generated images`,`image`],[`git_status|git_diff|git_diff_staged|git_diff_unstaged|git_log|git_show`,`Checking repository changes`,`Checked repository changes`,`file-code`],[`tool_search|ToolSearch`,`Finding tools`,`Looked up tools`,`search`],[`Agent`,`Delegating work`,`Delegated work`,`bot`],[`TodoWrite|TaskCreate|TaskUpdate`,`Updating the plan`,`Updated the plan`,`clipboard`],[`sql_db_query`,`Querying the database`,`Queried the database`,`database`],[`search_gmail`,`Searching email`,`Searched email`,`mail`]].flatMap(([e,...t])=>e.split(`|`).map(e=>[e,t]))),F=e=>{let t=e.replace(/([a-z\d])([A-Z])/g,`$1 $2`).replace(/[_-]+/g,` `).replace(/\s+/g,` `).toLowerCase();return t[0].toUpperCase()+t.slice(1)},I=e=>{let t=e.name?.trim()||`tool`,n=F(t);return P.get(t)??[`Using ${n}`,`Used ${n}`]},ee=e=>I(e)[2]??`wrench`,te=(e,t)=>{let n=t.toolCall?.iconName;return(typeof n==`function`?n(e):n)??ee(e)};function ne(e,t){if(typeof t.toolCall?.iconName==`string`)return t.toolCall.iconName;let n=e.map(e=>te(e,t));return e.every((t,r)=>I(t)[0]===I(e[0])[0]&&n[r]===n[0])?n[0]:`toolbox`}const L=[[`approvalStatus`,`pending`,`Waiting for approval`],[`approvalStatus`,`denied`,`Approval denied`],[`approvalStatus`,`timeout`,`Approval expired`],[`success`,!1,`Failed`],[`interrupted`,!0,`Interrupted`],[`superseded`,!0,`Approved, ran again below`]],R=e=>e.error||L.some(([t,n])=>e[t]===n),z=e=>R(e)?F(e.name?.trim()||`tool`):I(e)[+(e.status===`complete`)],B=e=>{let t=z(e);return I(e)[3]&&!/^(read_multiple_files|apply_patch)$/.test(e.name?.trim()??``)?t.replace(/(web pages|files|commands)$/,e=>`a ${e.slice(0,-1)}`):t};function re(e,t=3){let n=e.length;if(n===0)return``;(!Number.isInteger(t)||t<0)&&(t=3);let r=/* @__PURE__ */ new Map;for(let t of e){let e=I(t)[0],n=r.get(e);(!n||n.status===`complete`&&!R(n))&&r.set(e,t)}let i=t?[...r.values()].slice(0,t).map((e,t)=>{let n=z(e);return t?n[0].toLowerCase()+n.slice(1):n}).join(`, `):n===1?`1 activity`:`${n} activities`,a=r.size-t;a>0&&t&&(i+=`, and ${a} more`);for(let[t,n,r]of L)e.some(e=>e[t]===n||n===!1&&e.error)&&(i+=` · ${r}`);return i}function ie(e){let{executionId:t,phase:n}=e.agentMetadata??{};if(e.role!==`assistant`||typeof t!=`string`||!t)return;let r=e.variant===`tool`||e.variant===`reasoning`||n===`commentary`?`progress`:n===`partial_answer`||n===`final_answer`?`final`:void 0;if(r)return{id:t,kind:r,startedAt:Date.parse(e.createdAt)}}const ae={toolCallDisplay:{variant:`row`,grouped:!0,groupedMode:`collapsible`,autoExpand:!1,iconVisibility:`always`},reasoningDisplay:{appearance:`inset`,variant:`row`,autoExpand:!1,iconVisibility:`always`}},oe=Object.entries(ae).flatMap(([e,t])=>Object.keys(t).map(t=>`features.${e}.${t}`)),se=/* @__PURE__ */ new WeakMap;function ce(e,t){return e.turnActivity??t.turnActivity?.resolveMessage?.(e)??ie(e)}const le=e=>{let t=e.toolCall,n=e.approval?.status??t.approvalStatus;return t.error||t.interrupted||t.success===!1||t.superseded||n&&n!==`approved`},ue=(e,t)=>e.toolCall?.actionTitle?.trim()||t?.toolCall?.resolveActionTitle?.(e.toolCall,e)?.trim()||void 0,de=(e,t)=>ue(e,t)||B(e.toolCall);function fe(e,t,n){let r=e.filter(e=>e.toolCall?.status!==`complete`);return t.features?.toolCallDisplay?.groupSummary===`current-action`&&r.length===1&&!e.some(le)?de(r[0],t):n}function V(e,t){if(!e.turnActivity?.enabled||t.role!==`assistant`||ce(t,e)?.kind!==`progress`)return e;let n=se.get(e);if(n)return n;let{defaultProvenance:r,suppliedPath:i}=l(),a=r(e,oe),o={...e.features};for(let t of[`toolCallDisplay`,`reasoningDisplay`]){let n={...o[t]};for(let[r,o]of Object.entries(ae[t]))!a.includes(`features.${t}.${r}`)&&i(e.preferences,`${t}.${r}`)!==`explicit`&&Object.assign(n,{[r]:o});o[t]=n}o.toolCallDisplay={...o.toolCallDisplay,groupSummary:o.toolCallDisplay?.groupSummary??(o.toolCallDisplay?.groupedMode===`stack`?`aggregate`:`current-action`)};let s={...e,features:o};return se.set(e,s),s}const pe=[`persona-w-full`,`persona-rounded-2xl`,`persona-bg-persona-surface`,`persona-border`,`persona-border-persona-message-border`,`persona-text-persona-primary`,`persona-shadow-sm`,`persona-overflow-hidden`,`persona-px-0`,`persona-py-0`],H=(e,t)=>t==null?!1:typeof t==`string`?(e.textContent=t,!0):(e.appendChild(t),!0),U=(e,n)=>{let r=t(`div`,[`persona-message-bubble`,e,...pe].join(` `));return r.id=`bubble-${n}`,r.setAttribute(`data-message-id`,n),r.setAttribute(`data-persona-disclosure`,``),r},W=e=>{let n=t(`button`,e.expandable?`persona-flex persona-w-full persona-items-center persona-justify-between persona-gap-3 persona-bg-transparent persona-px-4 persona-py-3 persona-text-left persona-cursor-pointer persona-border-none`:`persona-flex persona-w-full persona-items-center persona-justify-between persona-gap-3 persona-bg-transparent persona-px-4 persona-py-3 persona-text-left persona-cursor-default persona-border-none`);return n.type=`button`,e.expandable&&(n.setAttribute(`aria-expanded`,e.expanded?`true`:`false`),n.setAttribute(`data-expand-header`,`true`)),n.setAttribute(`data-bubble-type`,e.bubbleType),n},G=(e,t,n,r)=>{let i=r?.expansion?.chevron?.[t?`expanded`:`collapsed`]??(r?.future?.v5Defaults?t?`down`:`right`:t?`up`:`down`),a=w(r),o=e.querySelector(`svg`);if(!o){if(o=d(`chevron-right`,16,n,1.5),!o)return;e.replaceChildren(o)}o.setAttribute(`stroke`,n),e.classList.add(`persona-disclosure-chevron`),e.style.transform=`rotate(${{right:0,down:90,left:180,up:-90}[i]}deg)`,e.style.transitionDuration=`${a.animation===`height`?a.duration:0}ms`,e.style.transitionTimingFunction=a.easing},K=(e,n,r)=>{if(!r.expandable)return e.append(n),null;let i=t(`div`,`persona-flex persona-items-center`);G(i,r.expanded,r.iconColor,r.config);let a=t(`div`,r.metaGap?`persona-flex persona-items-center persona-gap-2 persona-ml-auto`:`persona-flex persona-items-center persona-ml-auto`);return a.append(i),e.append(n,a),i},q=e=>{let n=t(`div`,`persona-px-4 persona-py-3 persona-text-xs persona-leading-snug persona-text-persona-muted`);if(n.setAttribute(`data-persona-collapsed-preview`,e.previewKind),n.style.display=`none`,n.style.whiteSpace=`pre-wrap`,!e.expanded&&e.isActive&&e.activePreview&&e.previewText){let t=e.renderPreview?.();H(n,t)||(n.textContent=e.previewText),n.style.display=``}return!e.expanded&&e.isActive&&e.activeMinHeight&&(e.bubble.style.minHeight=e.activeMinHeight),n},me=e=>{e.header.setAttribute(`aria-expanded`,e.expanded?`true`:`false`),e.toggleIcon&&G(e.toggleIcon,e.expanded,e.iconColor,e.config),e.content.style.display=e.expanded?``:`none`,e.content.inert=!e.expanded,e.collapsedPreview.style.display=e.expanded?`none`:e.collapsedPreview.textContent||e.collapsedPreview.childNodes.length?``:`none`},he=(e,t,n)=>{let r=n.stateSet.has(e),i=t.querySelector(`button[data-expand-header="true"]`),a=t.querySelector(`.persona-border-t`);if(!i||!a)return;i.setAttribute(`aria-expanded`,r?`true`:`false`);let o=i.querySelector(`.persona-ml-auto`)?.querySelector(`:scope > .persona-flex.persona-items-center`);o&&G(o,r,n.iconColor,n.config),M(t,r,n.config)},ge=(e,n,r,i,a,o)=>{e.textContent=``;for(let s of c(n,r))(s.styles.length?e.appendChild(t(`span`,s.styles.map(e=>`persona-tool-text-${e}`).join(` `))):e).append(s.isDuration?i?o():a:s.text)},_e=(e,t,n,r)=>{let i=n instanceof HTMLElement;return t.textContent=typeof n==`string`&&n.trim()?n:r,e.appendChild(i?n:t),i},J=(e,t,n)=>e.split(/\r?\n/).map(e=>e.trim()).filter(Boolean).slice(t,n).join(`
2
- `);function Y(e,t,n){e&&n&&(e=V(e,n));let r=t===`tool`,i=r?`toolCallDisplay`:`reasoningDisplay`;return{...e,features:{...e?.features,[i]:{...r?y:b,...e?.future?.v5Defaults===!0?r?_:v:{},...e?.features?.[i],layout:X(e,t)}}}}function X(e,t,n){e&&n&&(e=V(e,n));let r=t===`tool`?`toolCallDisplay`:`reasoningDisplay`;return e?.features?.[r]?.layout??e?.features?.[r]?.variant??(e?.future?.v5Defaults?`row`:`card`)}function Z(e){let t=Math.max(0,Math.floor((e??0)/1e3));return t<1?`a moment`:t<60?`${t}s`:`${Math.floor(t/60)}m ${t%60}s`}function ve(e,t){let n=Number(e.getAttribute(`data-tool-elapsed`));if(!n)return;let r=t-n;e.textContent=e.classList.contains(`persona-activity-duration`)?ye(r,e.dataset.prefix):e.closest(`.persona-activity-row`)?Z(r):f(r)}const ye=(e,t=``)=>Number.isFinite(e)&&e>=1e3?t+Z(e):``;function Q(e,n,r,i,a=!1,o){let s=a||X(r,i)===`row`,c=e.querySelector(`:scope > button`),u=i===`tool`?n.toolCall:n.reasoning,f=u?.status!==`complete`,p=r.features?.toolCallDisplay?.durationDisplay;if(c&&(s||r.future?.v5Defaults)&&i===`tool`&&u&&(p===`all`||p===(a?`group`:`tools`))){let e=t(`span`,`persona-activity-duration`),{startedAt:r,completedAt:i,durationMs:a}=u;f&&r>0&&r<=Date.now()&&e.setAttribute(`data-tool-elapsed`,String(r));let o=n.toolCall?.duration??a??i-r;e.textContent=ye(f&&r!==void 0?r>0?Date.now()-r:void 0:o),c.appendChild(e)}if(!s)return e;if(e.className=`persona-message-bubble persona-${i}-bubble persona-activity-row`,e.dataset.activityKind=i,i===`tool`){let t=l().getExplicitLegacyStyle(r,`toolCall.shadow`);e.style.boxShadow=typeof t==`string`?t.trim()||`none`:`var(--persona-consumer-toolBubble-shadow, none)`}if(!c)return e;c.className=c.classList.contains(`persona-theme-padding`)?`persona-activity-header persona-theme-padding`:`persona-activity-header`;let m=n.approval?.status??n.toolCall?.approvalStatus,h=n.toolCall?.interrupted?`interrupted`:m===`denied`||m===`timeout`?`denied`:m===`pending`?`awaiting-approval`:n.toolCall?.success===!1?`error`:f?u?.status===`pending`?`pending`:`running`:`done`;e.dataset.activityState=h;let g=t(`span`,`persona-activity-icon`);g.dataset.activityIcon=h;let _=i===`reasoning`?r.features?.reasoningDisplay?.iconName:void 0,v=h===`done`?i===`reasoning`?_||`brain`:o??(a?`toolbox`:te(n.toolCall,r)):void 0;v&&v!==`check`&&(g.style.color=`inherit`);let y=d(_||(h===`pending`?`circle`:h===`awaiting-approval`?`clock`:h===`running`?`loader-circle`:h===`done`?v||`check`:`x`),16,`currentColor`,2);!y&&v&&(y=d(`square-text`,16,`currentColor`,2)),y&&g.appendChild(y),c.querySelector(`.persona-reasoning-header-icon`)?.remove();let b=i===`tool`?`toolCallDisplay`:`reasoningDisplay`,x=(a?r.features?.toolCallDisplay?.groupIconVisibility:void 0)??r.features?.[b]?.iconVisibility??(r.future?.v5Defaults?`active`:`always`);(x===`always`||x===`active`&&h!==`done`)&&c.prepend(g),c.querySelector(`:scope > div:not(.persona-ml-auto)`)?.classList.add(`persona-activity-label`),c.querySelector(`.persona-ml-auto`)?.classList.add(`persona-activity-chevron`);let S=e.querySelector(`:scope > .persona-border-t`);return S?.classList.add(`persona-activity-body`),S&&(S.id=`activity-details-${n.id}`,c.setAttribute(`aria-controls`,S.id)),e}function be(e,t,n=()=>({})){let r=t?N(t,n):void 0,i=/* @__PURE__ */ new Map,a=e=>{let t=i.get(e)??{};return i.set(e,t),t},o=e=>{clearTimeout(e.timer),e.timer=void 0};return{observe(t,r,s,c={},l){let u=r===`tool`?t.toolCall:t.reasoning;if(!u)return;let d=Y(n(),r,t).features;c={...r===`tool`?d?.toolCallDisplay:d?.reasoningDisplay,...c},!i.has(t.id)&&l!==void 0&&(s[l?`add`:`delete`](t.id),a(t.id).manual=i.get(l)?.manual);let f=a(t.id);if(!f.manual&&(u.status!==`complete`&&(o(f),f.finished=!1),!f.seen&&u.status!==`complete`&&u.chunks?.some(Boolean)&&(f.seen=!0,c.autoExpand!==!1&&s.add(t.id)),f.seen&&u.status===`complete`&&!f.finished)){if(f.finished=!0,c.autoCollapseDelay===!1)return;f.timer=setTimeout(()=>{f.timer=void 0,s.delete(t.id),e(t.id,r)},c.autoCollapseDelay??1e3)}},manual(e){let t=a(e);t.manual=!0,o(t)},prune(e){for(let[t,n]of i)e.has(t)||(o(n),i.delete(t))},prepare(e){r?.prepare(e)},sync(){r?.sync()},clear(){i.forEach(o),i.clear(),r?.clear()},destroy(){this.clear(),r?.destroy()}}}function xe(e,n,r,i,a=typeof i==`string`,o){let s=U(`persona-tool-bubble`,e.id),c=W({expandable:!0,expanded:r,bubbleType:`tool`}),l=t(`div`,``);typeof i==`string`?l.textContent=i:l.appendChild(i);let u=m(n);K(c,l,{config:n,expandable:!0,expanded:r,iconColor:u.toggleTextColor||u.headerTextColor||`currentColor`,metaGap:!0});let d=t(`div`,`persona-border-t`);return d.style.display=r?``:`none`,d.inert=!r,s.append(c,d),Q(s,e,n,`tool`,!0,o),s.dataset.personaToolGroup=`true`,w(n).animation===`height`&&(s.dataset.personaDisclosureMotion=`height`),a&&(s.dataset.activityState===`running`||s.dataset.activityState===`pending`)&&x(l,n,`tool-group`),{bubble:s,body:d}}const Se=(e,t=!1)=>e.toggleTextColor||e.headerTextColor||(t?`currentColor`:`var(--persona-primary, #171717)`),Ce=(e,t)=>{let r=(e.chunks??[]).join(``).trim();return r?J(r,-t):J(n(e.args),0,t)},we=(e,t,n)=>{let r=n?.features?.toolCallDisplay,i=X(n,`tool`)===`row`,a=r?.collapsedMode??y.collapsedMode,c=t.success===!1?t.error||`Tool failed`:Ce(t,r?.previewMaxLines??y.previewMaxLines),l=i&&a===`tool-call`?B({...t,approvalStatus:e.approval?.status??t.approvalStatus}):t.interrupted?`${t.name?.trim()||`Tool`} · Interrupted`:n?.future?.v5Defaults||i?`${t.status===`complete`?`Used`:`Using`} ${t.name?.trim()||`tool`}`:o(t),u=t.status!==`complete`,d=n?.toolCall??{},f=u&&i&&a===`tool-call`&&!le(e)?de(e,n):l;a===`tool-name`?f=t.name?.trim()||l:a===`tool-preview`&&c&&(f=c),u&&d.activeTextTemplate?f=s(t,d.activeTextTemplate,f):!u&&!t.interrupted&&d.completeTextTemplate&&(f=s(t,d.completeTextTemplate,f)),t.interrupted?f.includes(` · Interrupted`)||(f+=` · Interrupted`):t.success===!1?f+=` · Failed`:t.superseded&&(f+=` · Approved, ran again below`);let p=e.approval?.status??t.approvalStatus;return p===`pending`?f+=` · Waiting for approval`:p===`denied`?f+=` · Approval denied`:p===`timeout`&&(f+=` · Approval expired`),{summary:f,previewText:c,isActive:u}},Te=(e,t,n,r)=>{he(e,t,{stateSet:n,config:r,iconColor:Se(m(r),t.classList.contains(`persona-activity-row`))})},Ee=(r,i,a=/* @__PURE__ */ new Set)=>{i=Y(i,`tool`,r);let o=r.toolCall,s=m(i),c=U(`persona-tool-bubble`,r.id);if(s.backgroundColor&&(c.style.backgroundColor=s.backgroundColor),s.borderColor&&(c.style.borderColor=s.borderColor),s.borderWidth&&(c.style.borderWidth=s.borderWidth),s.borderRadius&&(c.style.borderRadius=s.borderRadius),c.style.boxShadow=s.shadow===void 0?`var(--persona-tool-bubble-shadow)`:s.shadow.trim()===``?`none`:s.shadow,!o)return Q(c,r,i,`tool`);let l=i.features.toolCallDisplay,u=l.expandable??y.expandable,d=u&&a.has(r.id),{summary:f,previewText:_,isActive:v}=we(r,o,i),b=W({expandable:u,expanded:d,bubbleType:`tool`});s.headerBackgroundColor&&(b.style.backgroundColor=s.headerBackgroundColor),p(b,i,`header`);let S=t(`div`,`persona-flex persona-flex-col persona-text-left`),C=t(`span`,`persona-text-xs persona-text-persona-primary`);s.headerTextColor&&(C.style.color=s.headerTextColor);let w=String(o.startedAt??Date.now()),T=()=>{let e=t(`span`,``);return v&&e.setAttribute(`data-tool-elapsed`,w),e.textContent=g(o),e},E=s.renderCollapsedSummary?.({message:r,toolCall:o,defaultSummary:f,actionTitle:ue(r,i),previewText:_,collapsedMode:l.collapsedMode??y.collapsedMode,isActive:v,config:i,elapsed:g(o),createElapsedElement:T}),D=_e(S,C,E,f),O=s.activeTextTemplate,k=o.interrupted?void 0:s.completeTextTemplate,A=v?O:k;D||(A&&ge(C,A,o.name?.trim()||`tool`,v,g(o),T),v&&x(C,i,`tool`));let j=Se(s,X(i,`tool`)===`row`),M=K(b,S,{config:i,expandable:u,expanded:d,iconColor:j,metaGap:!0}),N=q({bubble:c,previewKind:`tool`,expanded:d,isActive:v,previewText:_,activePreview:l.activePreview,activeMinHeight:l.activeMinHeight,renderPreview:()=>s.renderCollapsedPreview?.({message:r,toolCall:o,defaultPreview:_,isActive:v,config:i})});if(!u)return c.append(b,N),Q(c,r,i,`tool`);let P=t(`div`,`persona-border-t persona-border-gray-200 persona-bg-gray-50 persona-space-y-3 persona-px-4 persona-py-3`);P.style.display=d?``:`none`,s.contentBackgroundColor&&(P.style.backgroundColor=s.contentBackgroundColor),s.contentTextColor&&(P.style.color=s.contentTextColor),p(P,i,`content`);let F=i.future?.v5Defaults===!0;if(l.showToolName&&o.name&&P.appendChild(e(`div`,{className:`persona-text-xs persona-text-persona-muted${F?``:` persona-italic`}`,attrs:{"data-persona-tool-name":``},text:o.name,style:{color:F?void 0:s.contentTextColor||s.headerTextColor}})),F)h(P,r,i);else{let r=(r,i)=>{let a=t(`div`,`persona-space-y-1`),o=e(`div`,{className:`persona-text-xs persona-text-persona-muted`,text:r,style:{color:s.labelTextColor}}),c=e(`pre`,{className:`persona-whitespace-pre-wrap persona-rounded-lg persona-border persona-px-3 persona-py-2 persona-text-xs`,style:{fontSize:`0.75rem`,lineHeight:`1rem`,backgroundColor:s.codeBlockBackgroundColor??`var(--persona-container, #f3f4f6)`,borderColor:s.codeBlockBorderColor??`var(--persona-border, #e5e7eb)`,color:s.codeBlockTextColor??`var(--persona-text, #171717)`}},e(`span`,{className:`persona-activity-scroll`,text:n(i),attrs:{role:`region`,"aria-label":r}}));a.append(o,c),P.appendChild(a)};o.args!==void 0&&r(`Arguments`,o.args),o.chunks?.length&&r(`Activity`,o.chunks.join(``)),o.success===!1&&P.appendChild(e(`div`,{className:`persona-text-sm persona-whitespace-pre-wrap`,text:o.error||`Tool failed`,attrs:{"data-persona-tool-error":``}})),o.status===`complete`&&o.result!==void 0&&r(`Result`,o.result)}return me({expanded:d,header:b,toggleIcon:M,content:P,collapsedPreview:N,iconColor:j,config:i}),c.append(b,N,P),Q(c,r,i,`tool`)},De=(e,t,n,r)=>{he(e,t,{stateSet:n,config:r,iconColor:`currentColor`})},Oe=(n,r,i=/* @__PURE__ */ new Set)=>{r=Y(r,`reasoning`,n);let o=n.reasoning,s=U(`persona-reasoning-bubble`,n.id);if(!o)return Q(s,n,r,`reasoning`);let c=r.features.reasoningDisplay,l=c.expandable??b.expandable,f=l&&i.has(n.id),p=o.status!==`complete`,m=J(n.reasoning?.chunks.join(``)??``,0,c.previewMaxLines??b.previewMaxLines),h=W({expandable:l,expanded:f,bubbleType:`reasoning`}),g=t(`div`,`persona-flex persona-flex-col persona-text-left`),_=t(`span`,`persona-text-xs persona-text-persona-primary`),v=X(r,`reasoning`)===`row`;s.dataset.appearance=c.appearance??(r.future?.v5Defaults?`inset`:v?`plain`:`panel`);let y=v&&!p?`Thought for ${Z(o.durationMs??(o.completedAt-o.startedAt||void 0))}`:`Thinking...`,S=r.reasoning??{},C=String(o.startedAt??Date.now()),w=()=>{let e=t(`span`,``);return e.setAttribute(`data-tool-elapsed`,C),e.textContent=u(o),e},T=S.renderCollapsedSummary?.({message:n,reasoning:o,defaultSummary:y,previewText:m,isActive:p,config:r,elapsed:u(o),createElapsedElement:w}),E=_e(g,_,T,y),D=t(`span`,`persona-text-xs persona-text-persona-primary`);D.textContent=a(o),v||g.appendChild(D);let O=S.activeTextTemplate,k=S.completeTextTemplate,A=p?O:k;if(E||(A&&(D.style.display=`none`,ge(_,A,``,p,u(o),w)),_.style.display=!A&&!p&&!v?`none`:``,p&&x(_,r,`reasoning`)),c.iconName&&!E){let e=t(`span`,`persona-reasoning-header-icon`),n=d(c.iconName,16,`currentColor`,2);n&&(e.appendChild(n),h.appendChild(e))}let j=`currentColor`,M=K(h,g,{config:r,expandable:l,expanded:f,iconColor:j,metaGap:!1}),N=q({bubble:s,previewKind:`reasoning`,expanded:f,isActive:p,previewText:m,activePreview:c.activePreview,activeMinHeight:c.activeMinHeight,renderPreview:()=>r.reasoning?.renderCollapsedPreview?.({message:n,reasoning:o,defaultPreview:m,isActive:p,config:r})});if(!l)return s.append(h,N),Q(s,n,r,`reasoning`);let P=t(`div`,`persona-border-t persona-border-gray-200 persona-bg-gray-50 persona-px-4 persona-py-3`),F=c.maxHeight,I=e(`div`,{className:`persona-whitespace-pre-wrap`},e(`div`,{className:`persona-activity-scroll`,text:o.chunks.join(``)||(p?`Waiting for details…`:`No additional context was shared.`),style:{maxHeight:F},attrs:{tabindex:`0`,role:`region`,"aria-label":`Reasoning`}}));return P.appendChild(I),me({expanded:f,header:h,toggleIcon:M,content:P,collapsedPreview:N,iconColor:j,config:r}),s.append(h,N,P),Q(s,n,r,`reasoning`)};function ke(e){let{config:n,messages:r,tempContainer:a,streaming:o,runActivity:s,showToolCalls:c,showReasoning:u,dropCompletedToolCalls:d,dropReasoningRow:f,createMessageRow:p,activityIds:m,activityLifecycle:h,toolExpansionState:g}=e,_=i.render;if(n.turnActivity?.enabled&&_)return _(e,{group:xe,tools:ke,classify:ce,presentation:V,hasExplicitThemeStyle:l().hasExplicitThemeStyle});let v=n.features?.toolCallDisplay;if(v?.grouped){let e=[],i=[],l=v.groupBoundary===`iteration`,_=v.groupedMode===`summary`,y=()=>{i.length&&e.push(i),i=[]};r.forEach(e=>{if(e.variant===`tool`&&e.toolCall&&c){if(d&&e.toolCall.status===`complete`&&!e.toolCall.interrupted)return;let t=i[i.length-1]?.agentMetadata,n=e.agentMetadata;l&&t&&n&&(t.executionId&&n.executionId&&t.executionId!==n.executionId||t.iteration!==void 0&&n.iteration!==void 0&&t.iteration!==n.iteration)&&y(),i.push(e)}else(e.variant!==`reasoning`||u&&(e.reasoning?.status!==`complete`||!f(e.reasoning)))&&y()}),y();let b=/* @__PURE__ */ new Map;for(let e of a.children)e instanceof HTMLElement&&b.set(e.dataset.wrapperId,e);e.forEach((r,i)=>{let a=r.map(e=>b.get(e.id)).filter(e=>!!e);if(a.length<(_?1:2))return;let c=`tool-group-${r[0].id}`,u=p(c,`assistant`);u.dataset.personaToolGroupRow=`true`,(v.groupAppearance||n.future?.v5Defaults)&&(u.dataset.groupAppearance=v.groupAppearance??`inset`);let d=r.map(e=>e.toolCall),f=d.some(e=>e.interrupted),y=i===e.length-1,S=r.some(e=>s?.messageIds.has(e.id)),C={messages:r,toolCalls:d,config:n,streaming:o,isLatestGroup:y,isCurrentRunGroup:S},w=r.map(e=>e.approval?.status??e.toolCall?.approvalStatus),T=[`pending`,`denied`,`timeout`].find(e=>w.includes(e)),E=!d.some(e=>e.success===!1||e.error),D=f||!E||T,O=d.some(e=>e.status!==`complete`),k=O||!l&&o&&y&&S&&!D,A=`${r.length} tool${r.length===1?``:`s`}`,j=v.groupedMode===`collapsible`||X(n,`tool`)===`row`?re(d.map((e,t)=>({...e,approvalStatus:w[t]})),v.groupSummaryMaxItems):f?`${A} · Interrupted`:`Called ${A}`,M=fe(r,n,j),N=n.toolCall?.renderGroupedSummary?.({...C,defaultSummary:M})??M;if(a[0].before(u),v.groupedMode===`collapsible`){let e={...r[0],id:c,approval:void 0,toolCall:{id:c,status:k?`running`:`complete`,chunks:d.flatMap(e=>e.chunks??[]),success:E,interrupted:f,approvalStatus:T}};if(d.every(e=>$(e.startedAt)&&(e.status!==`complete`||$(e.completedAt)&&e.completedAt>=e.startedAt))){let t=Math.min(...d.map(e=>e.startedAt)),n=Math.max(...d.map(e=>e.completedAt??e.startedAt));O?e.toolCall.startedAt=t:e.toolCall.durationMs=n-t}m.add(c),h.observe(e,`tool`,g,v,r.find(e=>g.has(e.id))?.id??``);let t=xe(e,n,g.has(c),N,void 0,!k&&!D?ne(d,n):void 0);t.bubble.classList.add(`persona-tool-group`),t.body.dataset.personaToolGroupStack=`true`,u.appendChild(t.bubble),a.forEach((e,n)=>{Ae(e),e.style.setProperty(`--persona-activity-stagger`,`${n*40}ms`),e.classList.add(`persona-activity-group-child`),t.body.appendChild(e)});return}let P=t(`div`,`persona-tool-group persona-flex persona-w-full persona-flex-col persona-gap-2`);P.dataset.personaToolGroup=`true`;let F=t(`div`,`persona-tool-group-summary persona-text-xs persona-text-persona-muted`);if(F.id=`tool-group-summary-${r[0].id}`,H(F,N),!(N instanceof HTMLElement)&&k&&!D&&x(F,n,`tool-group`),P.appendChild(F),u.appendChild(P),_){for(let e of a)e.remove();return}let I=t(`div`,`persona-tool-group-stack persona-flex persona-flex-col`);I.id=`tool-group-stack-${r[0].id}`,I.dataset.personaToolGroupStack=`true`,P.appendChild(I),a.forEach((e,n)=>{Ae(e);let r=t(`div`,`persona-tool-group-item persona-relative`);r.dataset.personaToolGroupItem=`true`,n<a.length-1&&(r.dataset.personaToolGroupConnector=`true`),r.appendChild(e),I.appendChild(r)})})}return!1}const $=e=>e>0&&e<=Date.now(),Ae=e=>e.style.setProperty(`--persona-message-row-max-width`,`100%`);function je(e){let t=`.persona-activity-scroll`,n=e=>{let t=e.scrollHeight-e.clientHeight,n=e.clientHeight>0&&t>1;e.toggleAttribute(`data-persona-scroll-top`,n&&e.scrollTop>1),e.toggleAttribute(`data-persona-scroll-bottom`,n&&t-e.scrollTop>1),e.tabIndex=n?0:-1},r=typeof ResizeObserver>`u`?void 0:new ResizeObserver(e=>{for(let{target:t}of e)n(t)}),i=()=>{r?.disconnect(),e.querySelectorAll(t).forEach(e=>{r?.observe(e),n(e)})},a=e=>{let r=e.target;r.matches(t)&&n(r)};return e.addEventListener(`scroll`,a,!0),{sync:i,destroy(){r?.disconnect(),e.removeEventListener(`scroll`,a,!0)}}}function Me(e,t,n,r,i,a){let o=je(e),s=be((e,o)=>{i.delete(e);let s=a(e);s&&(o===`tool`?Te(e,s,n,t()):De(e,s,r,t()))},e,t);return{...s,sync(){s.sync(),o.sync()},destroy(){s.destroy(),o.destroy()},observeMessages(e,i){let a=t();for(let t of e){let e=t.variant===`tool`?`tool`:t.variant===`reasoning`?`reasoning`:null;if(!e||X(a,e,t)!==`row`)continue;let o=Y(a,e,t).features,c=e===`tool`?o?.toolCallDisplay:o?.reasoningDisplay;c?.expandable!==!1&&(i.add(t.id),s.observe(t,e,e===`tool`?n:r,c))}}}}export{Me as createActivityLifecycle,Oe as createReasoningBubble,Ee as createToolBubble,ke as groupToolRows,r as initActivityUi,i as turnUi,ve as updateActivityElapsed,De as updateReasoningBubbleUI,Te as updateToolBubbleUI};
@@ -1 +0,0 @@
1
- const e=`4.31.0`;export{e as t};