@runtypelabs/persona 3.10.0 → 3.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -233,7 +233,8 @@ var DEFAULT_WIDGET_CONFIG = {
233
233
  activePreview: false,
234
234
  grouped: false,
235
235
  previewMaxLines: 3,
236
- expandable: true
236
+ expandable: true,
237
+ loadingAnimation: "none"
237
238
  },
238
239
  reasoningDisplay: {
239
240
  activePreview: false,
@@ -3345,6 +3346,62 @@ var describeToolTitle = (tool) => {
3345
3346
  }
3346
3347
  return "Using tool...";
3347
3348
  };
3349
+ var formatElapsedMs = (ms) => {
3350
+ const seconds = ms / 1e3;
3351
+ if (seconds < 0.1) return "<0.1s";
3352
+ if (seconds >= 10) return `${Math.round(seconds)}s`;
3353
+ return `${seconds.toFixed(1).replace(/\.0$/, "")}s`;
3354
+ };
3355
+ var computeToolElapsed = (tool) => {
3356
+ var _a, _b, _c;
3357
+ const durationMs = typeof tool.duration === "number" ? tool.duration : typeof tool.durationMs === "number" ? tool.durationMs : Math.max(
3358
+ 0,
3359
+ ((_a = tool.completedAt) != null ? _a : Date.now()) - ((_c = (_b = tool.startedAt) != null ? _b : tool.completedAt) != null ? _c : Date.now())
3360
+ );
3361
+ return formatElapsedMs(durationMs);
3362
+ };
3363
+ var resolveToolHeaderText = (tool, template, fallback) => {
3364
+ var _a;
3365
+ if (!template) return fallback;
3366
+ const toolName = ((_a = tool.name) == null ? void 0 : _a.trim()) || "tool";
3367
+ const duration = computeToolElapsed(tool);
3368
+ return template.replace(/\{toolName\}/g, toolName).replace(/\{duration\}/g, duration);
3369
+ };
3370
+ var parseFormattedTemplate = (template, toolName) => {
3371
+ const resolved = template.replace(/\{toolName\}/g, toolName);
3372
+ const segments = [];
3373
+ const regex = /\*\*(.+?)\*\*|\*(.+?)\*|~(.+?)~/g;
3374
+ let lastIndex = 0;
3375
+ let match;
3376
+ while ((match = regex.exec(resolved)) !== null) {
3377
+ if (match.index > lastIndex) {
3378
+ pushSegments(segments, resolved.slice(lastIndex, match.index), []);
3379
+ }
3380
+ if (match[1] !== void 0) {
3381
+ pushSegments(segments, match[1], ["bold"]);
3382
+ } else if (match[2] !== void 0) {
3383
+ pushSegments(segments, match[2], ["italic"]);
3384
+ } else if (match[3] !== void 0) {
3385
+ pushSegments(segments, match[3], ["dim"]);
3386
+ }
3387
+ lastIndex = match.index + match[0].length;
3388
+ }
3389
+ if (lastIndex < resolved.length) {
3390
+ pushSegments(segments, resolved.slice(lastIndex), []);
3391
+ }
3392
+ return segments;
3393
+ };
3394
+ var pushSegments = (segments, text, styles) => {
3395
+ const parts = text.split("{duration}");
3396
+ for (let i = 0; i < parts.length; i++) {
3397
+ if (parts[i]) {
3398
+ segments.push({ text: parts[i], styles });
3399
+ }
3400
+ if (i < parts.length - 1) {
3401
+ segments.push({ text: "{duration}", styles, isDuration: true });
3402
+ }
3403
+ }
3404
+ };
3348
3405
  var createRegexJsonParserInternal = () => {
3349
3406
  let extractedText = null;
3350
3407
  let processedLength = 0;
@@ -7962,10 +8019,16 @@ var morphMessages = (container, newContent, options = {}) => {
7962
8019
  import_idiomorph.Idiomorph.morph(container, newContent.innerHTML, {
7963
8020
  morphStyle: "innerHTML",
7964
8021
  callbacks: {
7965
- beforeNodeMorphed(oldNode, _newNode) {
8022
+ beforeNodeMorphed(oldNode, newNode) {
7966
8023
  if (!(oldNode instanceof HTMLElement)) return;
7967
8024
  if (preserveTypingAnimation) {
7968
- if (oldNode.classList.contains("persona-animate-typing") || oldNode.hasAttribute("data-preserve-animation")) {
8025
+ if (oldNode.classList.contains("persona-animate-typing")) {
8026
+ return false;
8027
+ }
8028
+ if (oldNode.hasAttribute("data-preserve-animation")) {
8029
+ if (newNode instanceof HTMLElement && !newNode.hasAttribute("data-preserve-animation")) {
8030
+ return;
8031
+ }
7969
8032
  return false;
7970
8033
  }
7971
8034
  }
@@ -10282,7 +10345,7 @@ var getToolPreviewText = (message, maxLines) => {
10282
10345
  return argsText.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).slice(0, maxLines).join("\n");
10283
10346
  };
10284
10347
  var getToolSummaryText = (message, config) => {
10285
- var _a, _b, _c, _d;
10348
+ var _a, _b, _c, _d, _e;
10286
10349
  const tool = message.toolCall;
10287
10350
  const toolDisplayConfig = (_a = config == null ? void 0 : config.features) == null ? void 0 : _a.toolCallDisplay;
10288
10351
  const collapsedMode = (_b = toolDisplayConfig == null ? void 0 : toolDisplayConfig.collapsedMode) != null ? _b : "tool-call";
@@ -10292,12 +10355,18 @@ var getToolSummaryText = (message, config) => {
10292
10355
  return { summary: defaultSummary, previewText, isActive: false };
10293
10356
  }
10294
10357
  const isActive = tool.status !== "complete";
10358
+ const toolCallConfig = (_d = config == null ? void 0 : config.toolCall) != null ? _d : {};
10295
10359
  let summary = defaultSummary;
10296
10360
  if (collapsedMode === "tool-name") {
10297
- summary = ((_d = tool.name) == null ? void 0 : _d.trim()) || defaultSummary;
10361
+ summary = ((_e = tool.name) == null ? void 0 : _e.trim()) || defaultSummary;
10298
10362
  } else if (collapsedMode === "tool-preview" && previewText) {
10299
10363
  summary = previewText;
10300
10364
  }
10365
+ if (isActive && toolCallConfig.activeTextTemplate) {
10366
+ summary = resolveToolHeaderText(tool, toolCallConfig.activeTextTemplate, summary);
10367
+ } else if (!isActive && toolCallConfig.completeTextTemplate) {
10368
+ summary = resolveToolHeaderText(tool, toolCallConfig.completeTextTemplate, summary);
10369
+ }
10301
10370
  return { summary, previewText, isActive };
10302
10371
  };
10303
10372
  var updateToolBubbleUI = (messageId, bubble, config) => {
@@ -10327,7 +10396,7 @@ var updateToolBubbleUI = (messageId, bubble, config) => {
10327
10396
  }
10328
10397
  };
10329
10398
  var createToolBubble = (message, config) => {
10330
- var _a, _b, _c, _d, _e, _f;
10399
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
10331
10400
  const tool = message.toolCall;
10332
10401
  const toolCallConfig = (_a = config == null ? void 0 : config.toolCall) != null ? _a : {};
10333
10402
  const bubble = createElement(
@@ -10395,14 +10464,23 @@ var createToolBubble = (message, config) => {
10395
10464
  if (toolCallConfig.headerTextColor) {
10396
10465
  title.style.color = toolCallConfig.headerTextColor;
10397
10466
  }
10398
- const customSummary = (_e = toolCallConfig.renderCollapsedSummary) == null ? void 0 : _e.call(toolCallConfig, {
10467
+ const startedAt = String((_d = tool.startedAt) != null ? _d : Date.now());
10468
+ const createElapsedSpan = () => {
10469
+ const span = createElement("span", "");
10470
+ span.setAttribute("data-tool-elapsed", startedAt);
10471
+ span.textContent = computeToolElapsed(tool);
10472
+ return span;
10473
+ };
10474
+ const customSummary = (_f = toolCallConfig.renderCollapsedSummary) == null ? void 0 : _f.call(toolCallConfig, {
10399
10475
  message,
10400
10476
  toolCall: tool,
10401
10477
  defaultSummary: summary,
10402
10478
  previewText,
10403
- collapsedMode: (_d = toolDisplayConfig.collapsedMode) != null ? _d : "tool-call",
10479
+ collapsedMode: (_e = toolDisplayConfig.collapsedMode) != null ? _e : "tool-call",
10404
10480
  isActive,
10405
- config: config != null ? config : {}
10481
+ config: config != null ? config : {},
10482
+ elapsed: computeToolElapsed(tool),
10483
+ createElapsedElement: createElapsedSpan
10406
10484
  });
10407
10485
  if (typeof customSummary === "string" && customSummary.trim()) {
10408
10486
  title.textContent = customSummary;
@@ -10413,6 +10491,79 @@ var createToolBubble = (message, config) => {
10413
10491
  title.textContent = summary;
10414
10492
  headerContent.appendChild(title);
10415
10493
  }
10494
+ const loadingAnimation = (_g = toolDisplayConfig.loadingAnimation) != null ? _g : "none";
10495
+ const activeTemplate = toolCallConfig.activeTextTemplate;
10496
+ const completeTemplate = toolCallConfig.completeTextTemplate;
10497
+ const currentTemplate = isActive ? activeTemplate : completeTemplate;
10498
+ const skipCustomElement = customSummary instanceof HTMLElement;
10499
+ const appendCharSpans = (container, text, startIndex) => {
10500
+ let idx = startIndex;
10501
+ for (const char of text) {
10502
+ const span = createElement("span", "persona-tool-char");
10503
+ span.style.setProperty("--char-index", String(idx));
10504
+ span.textContent = char === " " ? "\xA0" : char;
10505
+ container.appendChild(span);
10506
+ idx++;
10507
+ }
10508
+ return idx;
10509
+ };
10510
+ const renderFormattedTitle = (template, animated) => {
10511
+ var _a2;
10512
+ title.textContent = "";
10513
+ const toolName = ((_a2 = tool.name) == null ? void 0 : _a2.trim()) || "tool";
10514
+ const segments = parseFormattedTemplate(template, toolName);
10515
+ let charIndex = 0;
10516
+ for (const seg of segments) {
10517
+ const parent = seg.styles.length > 0 ? (() => {
10518
+ const w = createElement("span", seg.styles.map((s) => `persona-tool-text-${s}`).join(" "));
10519
+ title.appendChild(w);
10520
+ return w;
10521
+ })() : title;
10522
+ if (seg.isDuration && isActive) {
10523
+ parent.appendChild(createElapsedSpan());
10524
+ } else {
10525
+ const text = seg.isDuration ? computeToolElapsed(tool) : seg.text;
10526
+ if (animated) {
10527
+ charIndex = appendCharSpans(parent, text, charIndex);
10528
+ } else {
10529
+ parent.appendChild(document.createTextNode(text));
10530
+ }
10531
+ }
10532
+ }
10533
+ };
10534
+ if (!skipCustomElement) {
10535
+ if (isActive && loadingAnimation !== "none") {
10536
+ const animDuration = (_h = toolCallConfig.loadingAnimationDuration) != null ? _h : 2e3;
10537
+ title.setAttribute("data-preserve-animation", "true");
10538
+ if (loadingAnimation === "pulse") {
10539
+ title.classList.add("persona-tool-loading-pulse");
10540
+ title.style.setProperty("--persona-tool-anim-duration", `${animDuration}ms`);
10541
+ if (currentTemplate) {
10542
+ renderFormattedTitle(currentTemplate, false);
10543
+ }
10544
+ } else {
10545
+ title.classList.add(`persona-tool-loading-${loadingAnimation}`);
10546
+ title.style.setProperty("--persona-tool-anim-duration", `${animDuration}ms`);
10547
+ if (loadingAnimation === "shimmer-color") {
10548
+ if (toolCallConfig.loadingAnimationColor) {
10549
+ title.style.setProperty("--persona-tool-anim-color", toolCallConfig.loadingAnimationColor);
10550
+ }
10551
+ if (toolCallConfig.loadingAnimationSecondaryColor) {
10552
+ title.style.setProperty("--persona-tool-anim-secondary-color", toolCallConfig.loadingAnimationSecondaryColor);
10553
+ }
10554
+ }
10555
+ if (currentTemplate) {
10556
+ renderFormattedTitle(currentTemplate, true);
10557
+ } else {
10558
+ const text = title.textContent || summary;
10559
+ title.textContent = "";
10560
+ appendCharSpans(title, text, 0);
10561
+ }
10562
+ }
10563
+ } else if (currentTemplate) {
10564
+ renderFormattedTitle(currentTemplate, false);
10565
+ }
10566
+ }
10416
10567
  let toggleIcon = null;
10417
10568
  if (expandable) {
10418
10569
  toggleIcon = createElement("div", "persona-flex persona-items-center");
@@ -10437,7 +10588,7 @@ var createToolBubble = (message, config) => {
10437
10588
  collapsedPreview.style.display = "none";
10438
10589
  collapsedPreview.style.whiteSpace = "pre-wrap";
10439
10590
  if (!expanded && isActive && toolDisplayConfig.activePreview && previewText) {
10440
- const renderedPreview = (_f = toolCallConfig.renderCollapsedPreview) == null ? void 0 : _f.call(toolCallConfig, {
10591
+ const renderedPreview = (_i = toolCallConfig.renderCollapsedPreview) == null ? void 0 : _i.call(toolCallConfig, {
10441
10592
  message,
10442
10593
  toolCall: tool,
10443
10594
  defaultPreview: previewText,
@@ -13406,6 +13557,15 @@ function getClipboardImageFiles(clipboardData) {
13406
13557
  }
13407
13558
  return imageFiles;
13408
13559
  }
13560
+ function dataTransferHasFiles(dataTransfer) {
13561
+ if (!dataTransfer) return false;
13562
+ const types = dataTransfer.types;
13563
+ if (!types) return false;
13564
+ if (typeof types.contains === "function") {
13565
+ return types.contains("Files");
13566
+ }
13567
+ return Array.from(types).includes("Files");
13568
+ }
13409
13569
  function normalizePersistStateConfig(config) {
13410
13570
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
13411
13571
  if (!config) return null;
@@ -13497,8 +13657,36 @@ var buildPostprocessor = (cfg, actionManager, onResubmitRequested) => {
13497
13657
  return sanitize ? sanitize(html) : html;
13498
13658
  };
13499
13659
  };
13660
+ function buildDropOverlay(dropCfg) {
13661
+ var _a, _b, _c, _d;
13662
+ const overlay = createElement("div", "persona-attachment-drop-overlay");
13663
+ if (dropCfg == null ? void 0 : dropCfg.background) overlay.style.setProperty("--persona-drop-overlay-bg", dropCfg.background);
13664
+ if ((dropCfg == null ? void 0 : dropCfg.backdropBlur) !== void 0) overlay.style.setProperty("--persona-drop-overlay-blur", dropCfg.backdropBlur);
13665
+ if (dropCfg == null ? void 0 : dropCfg.border) overlay.style.setProperty("--persona-drop-overlay-border", dropCfg.border);
13666
+ if (dropCfg == null ? void 0 : dropCfg.borderRadius) overlay.style.setProperty("--persona-drop-overlay-radius", dropCfg.borderRadius);
13667
+ if (dropCfg == null ? void 0 : dropCfg.inset) overlay.style.setProperty("--persona-drop-overlay-inset", dropCfg.inset);
13668
+ if (dropCfg == null ? void 0 : dropCfg.labelSize) overlay.style.setProperty("--persona-drop-overlay-label-size", dropCfg.labelSize);
13669
+ if (dropCfg == null ? void 0 : dropCfg.labelColor) overlay.style.setProperty("--persona-drop-overlay-label-color", dropCfg.labelColor);
13670
+ const iconName = (_a = dropCfg == null ? void 0 : dropCfg.iconName) != null ? _a : "upload";
13671
+ const iconSize = (_b = dropCfg == null ? void 0 : dropCfg.iconSize) != null ? _b : "48px";
13672
+ const iconColor = (_c = dropCfg == null ? void 0 : dropCfg.iconColor) != null ? _c : "rgba(59, 130, 246, 0.6)";
13673
+ const iconStrokeWidth = (_d = dropCfg == null ? void 0 : dropCfg.iconStrokeWidth) != null ? _d : 0.5;
13674
+ const iconSvg = renderLucideIcon(iconName, iconSize, iconColor, iconStrokeWidth);
13675
+ if (iconSvg) overlay.appendChild(iconSvg);
13676
+ if (dropCfg == null ? void 0 : dropCfg.label) {
13677
+ const labelEl = createElement("span", "persona-drop-overlay-label");
13678
+ labelEl.textContent = dropCfg.label;
13679
+ overlay.appendChild(labelEl);
13680
+ }
13681
+ return overlay;
13682
+ }
13500
13683
  var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
13501
13684
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N;
13685
+ if (mount == null) {
13686
+ throw new Error(
13687
+ 'createAgentExperience: mount must be a non-null HTMLElement (e.g. pass document.getElementById("my-root") after the node exists).'
13688
+ );
13689
+ }
13502
13690
  if (mount.id && !mount.getAttribute("data-persona-instance")) {
13503
13691
  mount.setAttribute("data-persona-instance", mount.id);
13504
13692
  }
@@ -13902,8 +14090,22 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
13902
14090
  return composerElements.footer;
13903
14091
  },
13904
14092
  onSubmit: (text) => {
13905
- if (session && !session.isStreaming()) {
13906
- session.sendMessage(text);
14093
+ var _a2;
14094
+ if (!session || session.isStreaming()) return;
14095
+ const value = text.trim();
14096
+ const hasAttachments = (_a2 = attachmentManager == null ? void 0 : attachmentManager.hasAttachments()) != null ? _a2 : false;
14097
+ if (!value && !hasAttachments) return;
14098
+ let contentParts;
14099
+ if (hasAttachments) {
14100
+ contentParts = [];
14101
+ contentParts.push(...attachmentManager.getContentParts());
14102
+ if (value) {
14103
+ contentParts.push(createTextPart(value));
14104
+ }
14105
+ }
14106
+ session.sendMessage(value, { contentParts });
14107
+ if (hasAttachments) {
14108
+ attachmentManager.clearAttachments();
13907
14109
  }
13908
14110
  },
13909
14111
  streaming: false,
@@ -13982,6 +14184,9 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
13982
14184
  attachmentManager == null ? void 0 : attachmentManager.handleFileSelect(target.files);
13983
14185
  target.value = "";
13984
14186
  });
14187
+ const dropCfg = config.attachments.dropOverlay;
14188
+ const overlay = buildDropOverlay(dropCfg);
14189
+ container.appendChild(overlay);
13985
14190
  }
13986
14191
  const renderSlots = () => {
13987
14192
  var _a2, _b2;
@@ -14775,8 +14980,10 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14775
14980
  let lastScrollTop = 0;
14776
14981
  let scrollRAF = null;
14777
14982
  let isAutoScrolling = false;
14778
- const USER_SCROLL_THRESHOLD = 1;
14779
- const BOTTOM_THRESHOLD = 8;
14983
+ let hasPendingAutoScroll = false;
14984
+ const USER_SCROLL_THRESHOLD = 4;
14985
+ const BOTTOM_THRESHOLD = 24;
14986
+ const AUTO_SCROLL_SNAP_THRESHOLD = 80;
14780
14987
  const messageState = /* @__PURE__ */ new Map();
14781
14988
  const voiceState = {
14782
14989
  active: false,
@@ -14867,6 +15074,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14867
15074
  cancelAnimationFrame(scrollRAF);
14868
15075
  scrollRAF = null;
14869
15076
  }
15077
+ hasPendingAutoScroll = false;
14870
15078
  cancelSmoothScroll();
14871
15079
  };
14872
15080
  const syncScrollToBottomButton = () => {
@@ -14896,9 +15104,14 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14896
15104
  const scheduleAutoScroll = (force = false) => {
14897
15105
  if (!autoFollow.isFollowing()) return;
14898
15106
  if (!force && !isStreaming) return;
14899
- cancelAutoScroll();
15107
+ if (scrollRAF !== null) {
15108
+ cancelAnimationFrame(scrollRAF);
15109
+ scrollRAF = null;
15110
+ }
15111
+ hasPendingAutoScroll = true;
14900
15112
  scrollRAF = requestAnimationFrame(() => {
14901
15113
  scrollRAF = null;
15114
+ hasPendingAutoScroll = false;
14902
15115
  if (!autoFollow.isFollowing()) return;
14903
15116
  smoothScrollToBottom(getScrollableContainer(), force ? 220 : 140);
14904
15117
  });
@@ -14911,6 +15124,14 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14911
15124
  lastScrollTop = element.scrollTop;
14912
15125
  return;
14913
15126
  }
15127
+ if (Math.abs(distance) >= AUTO_SCROLL_SNAP_THRESHOLD) {
15128
+ cancelSmoothScroll();
15129
+ isAutoScrolling = true;
15130
+ element.scrollTop = target;
15131
+ lastScrollTop = element.scrollTop;
15132
+ isAutoScrolling = false;
15133
+ return;
15134
+ }
14914
15135
  cancelSmoothScroll();
14915
15136
  const startTime = performance.now();
14916
15137
  isAutoScrolling = true;
@@ -15519,9 +15740,28 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15519
15740
  }
15520
15741
  };
15521
15742
  }
15743
+ let toolElapsedTimerId = null;
15744
+ const ensureToolElapsedTimer = () => {
15745
+ if (toolElapsedTimerId != null) return;
15746
+ toolElapsedTimerId = setInterval(() => {
15747
+ const spans = messagesWrapper.querySelectorAll("[data-tool-elapsed]");
15748
+ if (spans.length === 0) {
15749
+ clearInterval(toolElapsedTimerId);
15750
+ toolElapsedTimerId = null;
15751
+ return;
15752
+ }
15753
+ const now = Date.now();
15754
+ spans.forEach((span) => {
15755
+ const startedAt = Number(span.getAttribute("data-tool-elapsed"));
15756
+ if (!startedAt) return;
15757
+ span.textContent = formatElapsedMs(now - startedAt);
15758
+ });
15759
+ }, 100);
15760
+ };
15522
15761
  session = new AgentWidgetSession(config, {
15523
15762
  onMessagesChanged(messages) {
15524
15763
  renderMessagesWithPlugins(messagesWrapper, messages, postprocess);
15764
+ ensureToolElapsedTimer();
15525
15765
  if (session) {
15526
15766
  const hasUserMessage = messages.some((msg) => msg.role === "user");
15527
15767
  if (hasUserMessage) {
@@ -16217,7 +16457,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16217
16457
  lastScrollTop,
16218
16458
  nearBottom: isElementNearBottom(body, BOTTOM_THRESHOLD),
16219
16459
  userScrollThreshold: USER_SCROLL_THRESHOLD,
16220
- isAutoScrolling,
16460
+ isAutoScrolling: isAutoScrolling || hasPendingAutoScroll,
16221
16461
  pauseOnUpwardScroll: true,
16222
16462
  pauseWhenAwayFromBottom: false,
16223
16463
  resumeRequiresDownwardScroll: true
@@ -16332,6 +16572,61 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16332
16572
  }
16333
16573
  textarea == null ? void 0 : textarea.addEventListener("keydown", handleInputEnter);
16334
16574
  textarea == null ? void 0 : textarea.addEventListener("paste", handleInputPaste);
16575
+ const ATTACHMENT_DROP_ACTIVE_CLASS = "persona-attachment-drop-active";
16576
+ let attachmentFileDragDepth = 0;
16577
+ const clearAttachmentDropVisual = () => {
16578
+ attachmentFileDragDepth = 0;
16579
+ container.classList.remove(ATTACHMENT_DROP_ACTIVE_CLASS);
16580
+ };
16581
+ const attachmentDropHandlingActive = () => {
16582
+ var _a2;
16583
+ return ((_a2 = config.attachments) == null ? void 0 : _a2.enabled) === true && attachmentManager !== null;
16584
+ };
16585
+ const handleAttachmentDragEnterCapture = (e) => {
16586
+ if (!dataTransferHasFiles(e.dataTransfer) || !attachmentDropHandlingActive()) return;
16587
+ attachmentFileDragDepth++;
16588
+ if (attachmentFileDragDepth === 1) {
16589
+ container.classList.add(ATTACHMENT_DROP_ACTIVE_CLASS);
16590
+ }
16591
+ };
16592
+ const handleAttachmentDragLeaveCapture = (e) => {
16593
+ if (!dataTransferHasFiles(e.dataTransfer) || !attachmentDropHandlingActive()) return;
16594
+ attachmentFileDragDepth--;
16595
+ if (attachmentFileDragDepth <= 0) {
16596
+ clearAttachmentDropVisual();
16597
+ }
16598
+ };
16599
+ const handleAttachmentDragOverCapture = (e) => {
16600
+ if (!dataTransferHasFiles(e.dataTransfer) || !attachmentDropHandlingActive()) return;
16601
+ e.preventDefault();
16602
+ e.dataTransfer.dropEffect = "copy";
16603
+ };
16604
+ const handleAttachmentDropCapture = (e) => {
16605
+ var _a2;
16606
+ if (!dataTransferHasFiles(e.dataTransfer) || !attachmentDropHandlingActive()) return;
16607
+ e.preventDefault();
16608
+ e.stopPropagation();
16609
+ clearAttachmentDropVisual();
16610
+ const files = Array.from((_a2 = e.dataTransfer.files) != null ? _a2 : []);
16611
+ if (files.length === 0) return;
16612
+ void attachmentManager.handleFiles(files);
16613
+ };
16614
+ const attachmentDropCapture = true;
16615
+ container.addEventListener("dragenter", handleAttachmentDragEnterCapture, attachmentDropCapture);
16616
+ container.addEventListener("dragleave", handleAttachmentDragLeaveCapture, attachmentDropCapture);
16617
+ mount.addEventListener("dragover", handleAttachmentDragOverCapture, attachmentDropCapture);
16618
+ mount.addEventListener("drop", handleAttachmentDropCapture, attachmentDropCapture);
16619
+ const ownerDoc = mount.ownerDocument;
16620
+ const handleDocDragOver = (e) => {
16621
+ if (!attachmentDropHandlingActive()) return;
16622
+ e.preventDefault();
16623
+ };
16624
+ const handleDocDrop = (e) => {
16625
+ if (!attachmentDropHandlingActive()) return;
16626
+ e.preventDefault();
16627
+ };
16628
+ ownerDoc.addEventListener("dragover", handleDocDragOver);
16629
+ ownerDoc.addEventListener("drop", handleDocDrop);
16335
16630
  destroyCallbacks.push(() => {
16336
16631
  if (composerForm) {
16337
16632
  composerForm.removeEventListener("submit", handleSubmit);
@@ -16339,6 +16634,15 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16339
16634
  textarea == null ? void 0 : textarea.removeEventListener("keydown", handleInputEnter);
16340
16635
  textarea == null ? void 0 : textarea.removeEventListener("paste", handleInputPaste);
16341
16636
  });
16637
+ destroyCallbacks.push(() => {
16638
+ container.removeEventListener("dragenter", handleAttachmentDragEnterCapture, attachmentDropCapture);
16639
+ container.removeEventListener("dragleave", handleAttachmentDragLeaveCapture, attachmentDropCapture);
16640
+ mount.removeEventListener("dragover", handleAttachmentDragOverCapture, attachmentDropCapture);
16641
+ mount.removeEventListener("drop", handleAttachmentDropCapture, attachmentDropCapture);
16642
+ ownerDoc.removeEventListener("dragover", handleDocDragOver);
16643
+ ownerDoc.removeEventListener("drop", handleDocDrop);
16644
+ clearAttachmentDropVisual();
16645
+ });
16342
16646
  destroyCallbacks.push(() => {
16343
16647
  session.cancel();
16344
16648
  });
@@ -16353,7 +16657,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16353
16657
  }
16354
16658
  const controller = {
16355
16659
  update(nextConfig) {
16356
- var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2, _q2, _r2, _s2, _t2, _u2, _v2, _w2, _x2, _y2, _z2, _A2, _B2, _C2, _D2, _E2, _F2, _G2, _H2, _I2, _J2, _K2, _L2, _M2, _N2, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a;
16660
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2, _q2, _r2, _s2, _t2, _u2, _v2, _w2, _x2, _y2, _z2, _A2, _B2, _C2, _D2, _E2, _F2, _G2, _H2, _I2, _J2, _K2, _L2, _M2, _N2, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab;
16357
16661
  const previousToolCallConfig = config.toolCall;
16358
16662
  const previousMessageActions = config.messageActions;
16359
16663
  const previousLayoutMessages = (_a2 = config.layout) == null ? void 0 : _a2.messages;
@@ -17111,6 +17415,9 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17111
17415
  }
17112
17416
  });
17113
17417
  }
17418
+ if (!container.querySelector(".persona-attachment-drop-overlay")) {
17419
+ container.appendChild(buildDropOverlay(attachmentsConfig.dropOverlay));
17420
+ }
17114
17421
  } else {
17115
17422
  attachmentButtonWrapper.style.display = "";
17116
17423
  const attachmentsConfig = (_Oa = config.attachments) != null ? _Oa : {};
@@ -17133,14 +17440,15 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17133
17440
  if (attachmentManager) {
17134
17441
  attachmentManager.clearAttachments();
17135
17442
  }
17443
+ (_Ra = container.querySelector(".persona-attachment-drop-overlay")) == null ? void 0 : _Ra.remove();
17136
17444
  }
17137
- const sendButtonConfig = (_Ra = config.sendButton) != null ? _Ra : {};
17138
- const useIcon = (_Sa = sendButtonConfig.useIcon) != null ? _Sa : false;
17139
- const iconText = (_Ta = sendButtonConfig.iconText) != null ? _Ta : "\u2191";
17445
+ const sendButtonConfig = (_Sa = config.sendButton) != null ? _Sa : {};
17446
+ const useIcon = (_Ta = sendButtonConfig.useIcon) != null ? _Ta : false;
17447
+ const iconText = (_Ua = sendButtonConfig.iconText) != null ? _Ua : "\u2191";
17140
17448
  const iconName = sendButtonConfig.iconName;
17141
- const tooltipText = (_Ua = sendButtonConfig.tooltipText) != null ? _Ua : "Send message";
17142
- const showTooltip = (_Va = sendButtonConfig.showTooltip) != null ? _Va : false;
17143
- const buttonSize = (_Wa = sendButtonConfig.size) != null ? _Wa : "40px";
17449
+ const tooltipText = (_Va = sendButtonConfig.tooltipText) != null ? _Va : "Send message";
17450
+ const showTooltip = (_Wa = sendButtonConfig.showTooltip) != null ? _Wa : false;
17451
+ const buttonSize = (_Xa = sendButtonConfig.size) != null ? _Xa : "40px";
17144
17452
  const backgroundColor = sendButtonConfig.backgroundColor;
17145
17453
  const textColor = sendButtonConfig.textColor;
17146
17454
  if (useIcon) {
@@ -17177,7 +17485,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17177
17485
  sendButton.classList.add("persona-bg-persona-primary");
17178
17486
  }
17179
17487
  } else {
17180
- sendButton.textContent = (_Ya = (_Xa = config.copy) == null ? void 0 : _Xa.sendButtonLabel) != null ? _Ya : "Send";
17488
+ sendButton.textContent = (_Za = (_Ya = config.copy) == null ? void 0 : _Ya.sendButtonLabel) != null ? _Za : "Send";
17181
17489
  sendButton.style.width = "";
17182
17490
  sendButton.style.height = "";
17183
17491
  sendButton.style.minWidth = "";
@@ -17237,7 +17545,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17237
17545
  } else if (tooltip) {
17238
17546
  tooltip.style.display = "none";
17239
17547
  }
17240
- const updatedContentMaxWidth = (_Za = config.layout) == null ? void 0 : _Za.contentMaxWidth;
17548
+ const updatedContentMaxWidth = (__a = config.layout) == null ? void 0 : __a.contentMaxWidth;
17241
17549
  if (updatedContentMaxWidth) {
17242
17550
  messagesWrapper.style.maxWidth = updatedContentMaxWidth;
17243
17551
  messagesWrapper.style.marginLeft = "auto";
@@ -17269,8 +17577,8 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17269
17577
  suggestions.style.marginRight = "";
17270
17578
  }
17271
17579
  }
17272
- const statusIndicatorConfig = (__a = config.statusIndicator) != null ? __a : {};
17273
- const isVisible = (_$a = statusIndicatorConfig.visible) != null ? _$a : true;
17580
+ const statusIndicatorConfig = (_$a = config.statusIndicator) != null ? _$a : {};
17581
+ const isVisible = (_ab = statusIndicatorConfig.visible) != null ? _ab : true;
17274
17582
  statusText.style.display = isVisible ? "" : "none";
17275
17583
  if (session) {
17276
17584
  const currentStatus = session.getStatus();
@@ -17616,6 +17924,10 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17616
17924
  return session.submitNPSFeedback(rating, comment);
17617
17925
  },
17618
17926
  destroy() {
17927
+ if (toolElapsedTimerId != null) {
17928
+ clearInterval(toolElapsedTimerId);
17929
+ toolElapsedTimerId = null;
17930
+ }
17619
17931
  destroyCallbacks.forEach((cb) => cb());
17620
17932
  wrapper.remove();
17621
17933
  launcherButtonInstance == null ? void 0 : launcherButtonInstance.destroy();