@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.
@@ -124,7 +124,8 @@ var DEFAULT_WIDGET_CONFIG = {
124
124
  activePreview: false,
125
125
  grouped: false,
126
126
  previewMaxLines: 3,
127
- expandable: true
127
+ expandable: true,
128
+ loadingAnimation: "none"
128
129
  },
129
130
  reasoningDisplay: {
130
131
  activePreview: false,
@@ -3236,6 +3237,62 @@ var describeToolTitle = (tool) => {
3236
3237
  }
3237
3238
  return "Using tool...";
3238
3239
  };
3240
+ var formatElapsedMs = (ms) => {
3241
+ const seconds = ms / 1e3;
3242
+ if (seconds < 0.1) return "<0.1s";
3243
+ if (seconds >= 10) return `${Math.round(seconds)}s`;
3244
+ return `${seconds.toFixed(1).replace(/\.0$/, "")}s`;
3245
+ };
3246
+ var computeToolElapsed = (tool) => {
3247
+ var _a, _b, _c;
3248
+ const durationMs = typeof tool.duration === "number" ? tool.duration : typeof tool.durationMs === "number" ? tool.durationMs : Math.max(
3249
+ 0,
3250
+ ((_a = tool.completedAt) != null ? _a : Date.now()) - ((_c = (_b = tool.startedAt) != null ? _b : tool.completedAt) != null ? _c : Date.now())
3251
+ );
3252
+ return formatElapsedMs(durationMs);
3253
+ };
3254
+ var resolveToolHeaderText = (tool, template, fallback) => {
3255
+ var _a;
3256
+ if (!template) return fallback;
3257
+ const toolName = ((_a = tool.name) == null ? void 0 : _a.trim()) || "tool";
3258
+ const duration = computeToolElapsed(tool);
3259
+ return template.replace(/\{toolName\}/g, toolName).replace(/\{duration\}/g, duration);
3260
+ };
3261
+ var parseFormattedTemplate = (template, toolName) => {
3262
+ const resolved = template.replace(/\{toolName\}/g, toolName);
3263
+ const segments = [];
3264
+ const regex = /\*\*(.+?)\*\*|\*(.+?)\*|~(.+?)~/g;
3265
+ let lastIndex = 0;
3266
+ let match;
3267
+ while ((match = regex.exec(resolved)) !== null) {
3268
+ if (match.index > lastIndex) {
3269
+ pushSegments(segments, resolved.slice(lastIndex, match.index), []);
3270
+ }
3271
+ if (match[1] !== void 0) {
3272
+ pushSegments(segments, match[1], ["bold"]);
3273
+ } else if (match[2] !== void 0) {
3274
+ pushSegments(segments, match[2], ["italic"]);
3275
+ } else if (match[3] !== void 0) {
3276
+ pushSegments(segments, match[3], ["dim"]);
3277
+ }
3278
+ lastIndex = match.index + match[0].length;
3279
+ }
3280
+ if (lastIndex < resolved.length) {
3281
+ pushSegments(segments, resolved.slice(lastIndex), []);
3282
+ }
3283
+ return segments;
3284
+ };
3285
+ var pushSegments = (segments, text, styles) => {
3286
+ const parts = text.split("{duration}");
3287
+ for (let i = 0; i < parts.length; i++) {
3288
+ if (parts[i]) {
3289
+ segments.push({ text: parts[i], styles });
3290
+ }
3291
+ if (i < parts.length - 1) {
3292
+ segments.push({ text: "{duration}", styles, isDuration: true });
3293
+ }
3294
+ }
3295
+ };
3239
3296
  var createRegexJsonParserInternal = () => {
3240
3297
  let extractedText = null;
3241
3298
  let processedLength = 0;
@@ -7853,10 +7910,16 @@ var morphMessages = (container, newContent, options = {}) => {
7853
7910
  Idiomorph.morph(container, newContent.innerHTML, {
7854
7911
  morphStyle: "innerHTML",
7855
7912
  callbacks: {
7856
- beforeNodeMorphed(oldNode, _newNode) {
7913
+ beforeNodeMorphed(oldNode, newNode) {
7857
7914
  if (!(oldNode instanceof HTMLElement)) return;
7858
7915
  if (preserveTypingAnimation) {
7859
- if (oldNode.classList.contains("persona-animate-typing") || oldNode.hasAttribute("data-preserve-animation")) {
7916
+ if (oldNode.classList.contains("persona-animate-typing")) {
7917
+ return false;
7918
+ }
7919
+ if (oldNode.hasAttribute("data-preserve-animation")) {
7920
+ if (newNode instanceof HTMLElement && !newNode.hasAttribute("data-preserve-animation")) {
7921
+ return;
7922
+ }
7860
7923
  return false;
7861
7924
  }
7862
7925
  }
@@ -10173,7 +10236,7 @@ var getToolPreviewText = (message, maxLines) => {
10173
10236
  return argsText.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).slice(0, maxLines).join("\n");
10174
10237
  };
10175
10238
  var getToolSummaryText = (message, config) => {
10176
- var _a, _b, _c, _d;
10239
+ var _a, _b, _c, _d, _e;
10177
10240
  const tool = message.toolCall;
10178
10241
  const toolDisplayConfig = (_a = config == null ? void 0 : config.features) == null ? void 0 : _a.toolCallDisplay;
10179
10242
  const collapsedMode = (_b = toolDisplayConfig == null ? void 0 : toolDisplayConfig.collapsedMode) != null ? _b : "tool-call";
@@ -10183,12 +10246,18 @@ var getToolSummaryText = (message, config) => {
10183
10246
  return { summary: defaultSummary, previewText, isActive: false };
10184
10247
  }
10185
10248
  const isActive = tool.status !== "complete";
10249
+ const toolCallConfig = (_d = config == null ? void 0 : config.toolCall) != null ? _d : {};
10186
10250
  let summary = defaultSummary;
10187
10251
  if (collapsedMode === "tool-name") {
10188
- summary = ((_d = tool.name) == null ? void 0 : _d.trim()) || defaultSummary;
10252
+ summary = ((_e = tool.name) == null ? void 0 : _e.trim()) || defaultSummary;
10189
10253
  } else if (collapsedMode === "tool-preview" && previewText) {
10190
10254
  summary = previewText;
10191
10255
  }
10256
+ if (isActive && toolCallConfig.activeTextTemplate) {
10257
+ summary = resolveToolHeaderText(tool, toolCallConfig.activeTextTemplate, summary);
10258
+ } else if (!isActive && toolCallConfig.completeTextTemplate) {
10259
+ summary = resolveToolHeaderText(tool, toolCallConfig.completeTextTemplate, summary);
10260
+ }
10192
10261
  return { summary, previewText, isActive };
10193
10262
  };
10194
10263
  var updateToolBubbleUI = (messageId, bubble, config) => {
@@ -10218,7 +10287,7 @@ var updateToolBubbleUI = (messageId, bubble, config) => {
10218
10287
  }
10219
10288
  };
10220
10289
  var createToolBubble = (message, config) => {
10221
- var _a, _b, _c, _d, _e, _f;
10290
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
10222
10291
  const tool = message.toolCall;
10223
10292
  const toolCallConfig = (_a = config == null ? void 0 : config.toolCall) != null ? _a : {};
10224
10293
  const bubble = createElement(
@@ -10286,14 +10355,23 @@ var createToolBubble = (message, config) => {
10286
10355
  if (toolCallConfig.headerTextColor) {
10287
10356
  title.style.color = toolCallConfig.headerTextColor;
10288
10357
  }
10289
- const customSummary = (_e = toolCallConfig.renderCollapsedSummary) == null ? void 0 : _e.call(toolCallConfig, {
10358
+ const startedAt = String((_d = tool.startedAt) != null ? _d : Date.now());
10359
+ const createElapsedSpan = () => {
10360
+ const span = createElement("span", "");
10361
+ span.setAttribute("data-tool-elapsed", startedAt);
10362
+ span.textContent = computeToolElapsed(tool);
10363
+ return span;
10364
+ };
10365
+ const customSummary = (_f = toolCallConfig.renderCollapsedSummary) == null ? void 0 : _f.call(toolCallConfig, {
10290
10366
  message,
10291
10367
  toolCall: tool,
10292
10368
  defaultSummary: summary,
10293
10369
  previewText,
10294
- collapsedMode: (_d = toolDisplayConfig.collapsedMode) != null ? _d : "tool-call",
10370
+ collapsedMode: (_e = toolDisplayConfig.collapsedMode) != null ? _e : "tool-call",
10295
10371
  isActive,
10296
- config: config != null ? config : {}
10372
+ config: config != null ? config : {},
10373
+ elapsed: computeToolElapsed(tool),
10374
+ createElapsedElement: createElapsedSpan
10297
10375
  });
10298
10376
  if (typeof customSummary === "string" && customSummary.trim()) {
10299
10377
  title.textContent = customSummary;
@@ -10304,6 +10382,79 @@ var createToolBubble = (message, config) => {
10304
10382
  title.textContent = summary;
10305
10383
  headerContent.appendChild(title);
10306
10384
  }
10385
+ const loadingAnimation = (_g = toolDisplayConfig.loadingAnimation) != null ? _g : "none";
10386
+ const activeTemplate = toolCallConfig.activeTextTemplate;
10387
+ const completeTemplate = toolCallConfig.completeTextTemplate;
10388
+ const currentTemplate = isActive ? activeTemplate : completeTemplate;
10389
+ const skipCustomElement = customSummary instanceof HTMLElement;
10390
+ const appendCharSpans = (container, text, startIndex) => {
10391
+ let idx = startIndex;
10392
+ for (const char of text) {
10393
+ const span = createElement("span", "persona-tool-char");
10394
+ span.style.setProperty("--char-index", String(idx));
10395
+ span.textContent = char === " " ? "\xA0" : char;
10396
+ container.appendChild(span);
10397
+ idx++;
10398
+ }
10399
+ return idx;
10400
+ };
10401
+ const renderFormattedTitle = (template, animated) => {
10402
+ var _a2;
10403
+ title.textContent = "";
10404
+ const toolName = ((_a2 = tool.name) == null ? void 0 : _a2.trim()) || "tool";
10405
+ const segments = parseFormattedTemplate(template, toolName);
10406
+ let charIndex = 0;
10407
+ for (const seg of segments) {
10408
+ const parent = seg.styles.length > 0 ? (() => {
10409
+ const w = createElement("span", seg.styles.map((s) => `persona-tool-text-${s}`).join(" "));
10410
+ title.appendChild(w);
10411
+ return w;
10412
+ })() : title;
10413
+ if (seg.isDuration && isActive) {
10414
+ parent.appendChild(createElapsedSpan());
10415
+ } else {
10416
+ const text = seg.isDuration ? computeToolElapsed(tool) : seg.text;
10417
+ if (animated) {
10418
+ charIndex = appendCharSpans(parent, text, charIndex);
10419
+ } else {
10420
+ parent.appendChild(document.createTextNode(text));
10421
+ }
10422
+ }
10423
+ }
10424
+ };
10425
+ if (!skipCustomElement) {
10426
+ if (isActive && loadingAnimation !== "none") {
10427
+ const animDuration = (_h = toolCallConfig.loadingAnimationDuration) != null ? _h : 2e3;
10428
+ title.setAttribute("data-preserve-animation", "true");
10429
+ if (loadingAnimation === "pulse") {
10430
+ title.classList.add("persona-tool-loading-pulse");
10431
+ title.style.setProperty("--persona-tool-anim-duration", `${animDuration}ms`);
10432
+ if (currentTemplate) {
10433
+ renderFormattedTitle(currentTemplate, false);
10434
+ }
10435
+ } else {
10436
+ title.classList.add(`persona-tool-loading-${loadingAnimation}`);
10437
+ title.style.setProperty("--persona-tool-anim-duration", `${animDuration}ms`);
10438
+ if (loadingAnimation === "shimmer-color") {
10439
+ if (toolCallConfig.loadingAnimationColor) {
10440
+ title.style.setProperty("--persona-tool-anim-color", toolCallConfig.loadingAnimationColor);
10441
+ }
10442
+ if (toolCallConfig.loadingAnimationSecondaryColor) {
10443
+ title.style.setProperty("--persona-tool-anim-secondary-color", toolCallConfig.loadingAnimationSecondaryColor);
10444
+ }
10445
+ }
10446
+ if (currentTemplate) {
10447
+ renderFormattedTitle(currentTemplate, true);
10448
+ } else {
10449
+ const text = title.textContent || summary;
10450
+ title.textContent = "";
10451
+ appendCharSpans(title, text, 0);
10452
+ }
10453
+ }
10454
+ } else if (currentTemplate) {
10455
+ renderFormattedTitle(currentTemplate, false);
10456
+ }
10457
+ }
10307
10458
  let toggleIcon = null;
10308
10459
  if (expandable) {
10309
10460
  toggleIcon = createElement("div", "persona-flex persona-items-center");
@@ -10328,7 +10479,7 @@ var createToolBubble = (message, config) => {
10328
10479
  collapsedPreview.style.display = "none";
10329
10480
  collapsedPreview.style.whiteSpace = "pre-wrap";
10330
10481
  if (!expanded && isActive && toolDisplayConfig.activePreview && previewText) {
10331
- const renderedPreview = (_f = toolCallConfig.renderCollapsedPreview) == null ? void 0 : _f.call(toolCallConfig, {
10482
+ const renderedPreview = (_i = toolCallConfig.renderCollapsedPreview) == null ? void 0 : _i.call(toolCallConfig, {
10332
10483
  message,
10333
10484
  toolCall: tool,
10334
10485
  defaultPreview: previewText,
@@ -13297,6 +13448,15 @@ function getClipboardImageFiles(clipboardData) {
13297
13448
  }
13298
13449
  return imageFiles;
13299
13450
  }
13451
+ function dataTransferHasFiles(dataTransfer) {
13452
+ if (!dataTransfer) return false;
13453
+ const types = dataTransfer.types;
13454
+ if (!types) return false;
13455
+ if (typeof types.contains === "function") {
13456
+ return types.contains("Files");
13457
+ }
13458
+ return Array.from(types).includes("Files");
13459
+ }
13300
13460
  function normalizePersistStateConfig(config) {
13301
13461
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
13302
13462
  if (!config) return null;
@@ -13388,8 +13548,36 @@ var buildPostprocessor = (cfg, actionManager, onResubmitRequested) => {
13388
13548
  return sanitize ? sanitize(html) : html;
13389
13549
  };
13390
13550
  };
13551
+ function buildDropOverlay(dropCfg) {
13552
+ var _a, _b, _c, _d;
13553
+ const overlay = createElement("div", "persona-attachment-drop-overlay");
13554
+ if (dropCfg == null ? void 0 : dropCfg.background) overlay.style.setProperty("--persona-drop-overlay-bg", dropCfg.background);
13555
+ if ((dropCfg == null ? void 0 : dropCfg.backdropBlur) !== void 0) overlay.style.setProperty("--persona-drop-overlay-blur", dropCfg.backdropBlur);
13556
+ if (dropCfg == null ? void 0 : dropCfg.border) overlay.style.setProperty("--persona-drop-overlay-border", dropCfg.border);
13557
+ if (dropCfg == null ? void 0 : dropCfg.borderRadius) overlay.style.setProperty("--persona-drop-overlay-radius", dropCfg.borderRadius);
13558
+ if (dropCfg == null ? void 0 : dropCfg.inset) overlay.style.setProperty("--persona-drop-overlay-inset", dropCfg.inset);
13559
+ if (dropCfg == null ? void 0 : dropCfg.labelSize) overlay.style.setProperty("--persona-drop-overlay-label-size", dropCfg.labelSize);
13560
+ if (dropCfg == null ? void 0 : dropCfg.labelColor) overlay.style.setProperty("--persona-drop-overlay-label-color", dropCfg.labelColor);
13561
+ const iconName = (_a = dropCfg == null ? void 0 : dropCfg.iconName) != null ? _a : "upload";
13562
+ const iconSize = (_b = dropCfg == null ? void 0 : dropCfg.iconSize) != null ? _b : "48px";
13563
+ const iconColor = (_c = dropCfg == null ? void 0 : dropCfg.iconColor) != null ? _c : "rgba(59, 130, 246, 0.6)";
13564
+ const iconStrokeWidth = (_d = dropCfg == null ? void 0 : dropCfg.iconStrokeWidth) != null ? _d : 0.5;
13565
+ const iconSvg = renderLucideIcon(iconName, iconSize, iconColor, iconStrokeWidth);
13566
+ if (iconSvg) overlay.appendChild(iconSvg);
13567
+ if (dropCfg == null ? void 0 : dropCfg.label) {
13568
+ const labelEl = createElement("span", "persona-drop-overlay-label");
13569
+ labelEl.textContent = dropCfg.label;
13570
+ overlay.appendChild(labelEl);
13571
+ }
13572
+ return overlay;
13573
+ }
13391
13574
  var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
13392
13575
  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;
13576
+ if (mount == null) {
13577
+ throw new Error(
13578
+ 'createAgentExperience: mount must be a non-null HTMLElement (e.g. pass document.getElementById("my-root") after the node exists).'
13579
+ );
13580
+ }
13393
13581
  if (mount.id && !mount.getAttribute("data-persona-instance")) {
13394
13582
  mount.setAttribute("data-persona-instance", mount.id);
13395
13583
  }
@@ -13793,8 +13981,22 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
13793
13981
  return composerElements.footer;
13794
13982
  },
13795
13983
  onSubmit: (text) => {
13796
- if (session && !session.isStreaming()) {
13797
- session.sendMessage(text);
13984
+ var _a2;
13985
+ if (!session || session.isStreaming()) return;
13986
+ const value = text.trim();
13987
+ const hasAttachments = (_a2 = attachmentManager == null ? void 0 : attachmentManager.hasAttachments()) != null ? _a2 : false;
13988
+ if (!value && !hasAttachments) return;
13989
+ let contentParts;
13990
+ if (hasAttachments) {
13991
+ contentParts = [];
13992
+ contentParts.push(...attachmentManager.getContentParts());
13993
+ if (value) {
13994
+ contentParts.push(createTextPart(value));
13995
+ }
13996
+ }
13997
+ session.sendMessage(value, { contentParts });
13998
+ if (hasAttachments) {
13999
+ attachmentManager.clearAttachments();
13798
14000
  }
13799
14001
  },
13800
14002
  streaming: false,
@@ -13873,6 +14075,9 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
13873
14075
  attachmentManager == null ? void 0 : attachmentManager.handleFileSelect(target.files);
13874
14076
  target.value = "";
13875
14077
  });
14078
+ const dropCfg = config.attachments.dropOverlay;
14079
+ const overlay = buildDropOverlay(dropCfg);
14080
+ container.appendChild(overlay);
13876
14081
  }
13877
14082
  const renderSlots = () => {
13878
14083
  var _a2, _b2;
@@ -14666,8 +14871,10 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14666
14871
  let lastScrollTop = 0;
14667
14872
  let scrollRAF = null;
14668
14873
  let isAutoScrolling = false;
14669
- const USER_SCROLL_THRESHOLD = 1;
14670
- const BOTTOM_THRESHOLD = 8;
14874
+ let hasPendingAutoScroll = false;
14875
+ const USER_SCROLL_THRESHOLD = 4;
14876
+ const BOTTOM_THRESHOLD = 24;
14877
+ const AUTO_SCROLL_SNAP_THRESHOLD = 80;
14671
14878
  const messageState = /* @__PURE__ */ new Map();
14672
14879
  const voiceState = {
14673
14880
  active: false,
@@ -14758,6 +14965,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14758
14965
  cancelAnimationFrame(scrollRAF);
14759
14966
  scrollRAF = null;
14760
14967
  }
14968
+ hasPendingAutoScroll = false;
14761
14969
  cancelSmoothScroll();
14762
14970
  };
14763
14971
  const syncScrollToBottomButton = () => {
@@ -14787,9 +14995,14 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14787
14995
  const scheduleAutoScroll = (force = false) => {
14788
14996
  if (!autoFollow.isFollowing()) return;
14789
14997
  if (!force && !isStreaming) return;
14790
- cancelAutoScroll();
14998
+ if (scrollRAF !== null) {
14999
+ cancelAnimationFrame(scrollRAF);
15000
+ scrollRAF = null;
15001
+ }
15002
+ hasPendingAutoScroll = true;
14791
15003
  scrollRAF = requestAnimationFrame(() => {
14792
15004
  scrollRAF = null;
15005
+ hasPendingAutoScroll = false;
14793
15006
  if (!autoFollow.isFollowing()) return;
14794
15007
  smoothScrollToBottom(getScrollableContainer(), force ? 220 : 140);
14795
15008
  });
@@ -14802,6 +15015,14 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14802
15015
  lastScrollTop = element.scrollTop;
14803
15016
  return;
14804
15017
  }
15018
+ if (Math.abs(distance) >= AUTO_SCROLL_SNAP_THRESHOLD) {
15019
+ cancelSmoothScroll();
15020
+ isAutoScrolling = true;
15021
+ element.scrollTop = target;
15022
+ lastScrollTop = element.scrollTop;
15023
+ isAutoScrolling = false;
15024
+ return;
15025
+ }
14805
15026
  cancelSmoothScroll();
14806
15027
  const startTime = performance.now();
14807
15028
  isAutoScrolling = true;
@@ -15410,9 +15631,28 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15410
15631
  }
15411
15632
  };
15412
15633
  }
15634
+ let toolElapsedTimerId = null;
15635
+ const ensureToolElapsedTimer = () => {
15636
+ if (toolElapsedTimerId != null) return;
15637
+ toolElapsedTimerId = setInterval(() => {
15638
+ const spans = messagesWrapper.querySelectorAll("[data-tool-elapsed]");
15639
+ if (spans.length === 0) {
15640
+ clearInterval(toolElapsedTimerId);
15641
+ toolElapsedTimerId = null;
15642
+ return;
15643
+ }
15644
+ const now = Date.now();
15645
+ spans.forEach((span) => {
15646
+ const startedAt = Number(span.getAttribute("data-tool-elapsed"));
15647
+ if (!startedAt) return;
15648
+ span.textContent = formatElapsedMs(now - startedAt);
15649
+ });
15650
+ }, 100);
15651
+ };
15413
15652
  session = new AgentWidgetSession(config, {
15414
15653
  onMessagesChanged(messages) {
15415
15654
  renderMessagesWithPlugins(messagesWrapper, messages, postprocess);
15655
+ ensureToolElapsedTimer();
15416
15656
  if (session) {
15417
15657
  const hasUserMessage = messages.some((msg) => msg.role === "user");
15418
15658
  if (hasUserMessage) {
@@ -16108,7 +16348,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16108
16348
  lastScrollTop,
16109
16349
  nearBottom: isElementNearBottom(body, BOTTOM_THRESHOLD),
16110
16350
  userScrollThreshold: USER_SCROLL_THRESHOLD,
16111
- isAutoScrolling,
16351
+ isAutoScrolling: isAutoScrolling || hasPendingAutoScroll,
16112
16352
  pauseOnUpwardScroll: true,
16113
16353
  pauseWhenAwayFromBottom: false,
16114
16354
  resumeRequiresDownwardScroll: true
@@ -16223,6 +16463,61 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16223
16463
  }
16224
16464
  textarea == null ? void 0 : textarea.addEventListener("keydown", handleInputEnter);
16225
16465
  textarea == null ? void 0 : textarea.addEventListener("paste", handleInputPaste);
16466
+ const ATTACHMENT_DROP_ACTIVE_CLASS = "persona-attachment-drop-active";
16467
+ let attachmentFileDragDepth = 0;
16468
+ const clearAttachmentDropVisual = () => {
16469
+ attachmentFileDragDepth = 0;
16470
+ container.classList.remove(ATTACHMENT_DROP_ACTIVE_CLASS);
16471
+ };
16472
+ const attachmentDropHandlingActive = () => {
16473
+ var _a2;
16474
+ return ((_a2 = config.attachments) == null ? void 0 : _a2.enabled) === true && attachmentManager !== null;
16475
+ };
16476
+ const handleAttachmentDragEnterCapture = (e) => {
16477
+ if (!dataTransferHasFiles(e.dataTransfer) || !attachmentDropHandlingActive()) return;
16478
+ attachmentFileDragDepth++;
16479
+ if (attachmentFileDragDepth === 1) {
16480
+ container.classList.add(ATTACHMENT_DROP_ACTIVE_CLASS);
16481
+ }
16482
+ };
16483
+ const handleAttachmentDragLeaveCapture = (e) => {
16484
+ if (!dataTransferHasFiles(e.dataTransfer) || !attachmentDropHandlingActive()) return;
16485
+ attachmentFileDragDepth--;
16486
+ if (attachmentFileDragDepth <= 0) {
16487
+ clearAttachmentDropVisual();
16488
+ }
16489
+ };
16490
+ const handleAttachmentDragOverCapture = (e) => {
16491
+ if (!dataTransferHasFiles(e.dataTransfer) || !attachmentDropHandlingActive()) return;
16492
+ e.preventDefault();
16493
+ e.dataTransfer.dropEffect = "copy";
16494
+ };
16495
+ const handleAttachmentDropCapture = (e) => {
16496
+ var _a2;
16497
+ if (!dataTransferHasFiles(e.dataTransfer) || !attachmentDropHandlingActive()) return;
16498
+ e.preventDefault();
16499
+ e.stopPropagation();
16500
+ clearAttachmentDropVisual();
16501
+ const files = Array.from((_a2 = e.dataTransfer.files) != null ? _a2 : []);
16502
+ if (files.length === 0) return;
16503
+ void attachmentManager.handleFiles(files);
16504
+ };
16505
+ const attachmentDropCapture = true;
16506
+ container.addEventListener("dragenter", handleAttachmentDragEnterCapture, attachmentDropCapture);
16507
+ container.addEventListener("dragleave", handleAttachmentDragLeaveCapture, attachmentDropCapture);
16508
+ mount.addEventListener("dragover", handleAttachmentDragOverCapture, attachmentDropCapture);
16509
+ mount.addEventListener("drop", handleAttachmentDropCapture, attachmentDropCapture);
16510
+ const ownerDoc = mount.ownerDocument;
16511
+ const handleDocDragOver = (e) => {
16512
+ if (!attachmentDropHandlingActive()) return;
16513
+ e.preventDefault();
16514
+ };
16515
+ const handleDocDrop = (e) => {
16516
+ if (!attachmentDropHandlingActive()) return;
16517
+ e.preventDefault();
16518
+ };
16519
+ ownerDoc.addEventListener("dragover", handleDocDragOver);
16520
+ ownerDoc.addEventListener("drop", handleDocDrop);
16226
16521
  destroyCallbacks.push(() => {
16227
16522
  if (composerForm) {
16228
16523
  composerForm.removeEventListener("submit", handleSubmit);
@@ -16230,6 +16525,15 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16230
16525
  textarea == null ? void 0 : textarea.removeEventListener("keydown", handleInputEnter);
16231
16526
  textarea == null ? void 0 : textarea.removeEventListener("paste", handleInputPaste);
16232
16527
  });
16528
+ destroyCallbacks.push(() => {
16529
+ container.removeEventListener("dragenter", handleAttachmentDragEnterCapture, attachmentDropCapture);
16530
+ container.removeEventListener("dragleave", handleAttachmentDragLeaveCapture, attachmentDropCapture);
16531
+ mount.removeEventListener("dragover", handleAttachmentDragOverCapture, attachmentDropCapture);
16532
+ mount.removeEventListener("drop", handleAttachmentDropCapture, attachmentDropCapture);
16533
+ ownerDoc.removeEventListener("dragover", handleDocDragOver);
16534
+ ownerDoc.removeEventListener("drop", handleDocDrop);
16535
+ clearAttachmentDropVisual();
16536
+ });
16233
16537
  destroyCallbacks.push(() => {
16234
16538
  session.cancel();
16235
16539
  });
@@ -16244,7 +16548,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16244
16548
  }
16245
16549
  const controller = {
16246
16550
  update(nextConfig) {
16247
- 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;
16551
+ 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;
16248
16552
  const previousToolCallConfig = config.toolCall;
16249
16553
  const previousMessageActions = config.messageActions;
16250
16554
  const previousLayoutMessages = (_a2 = config.layout) == null ? void 0 : _a2.messages;
@@ -17002,6 +17306,9 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17002
17306
  }
17003
17307
  });
17004
17308
  }
17309
+ if (!container.querySelector(".persona-attachment-drop-overlay")) {
17310
+ container.appendChild(buildDropOverlay(attachmentsConfig.dropOverlay));
17311
+ }
17005
17312
  } else {
17006
17313
  attachmentButtonWrapper.style.display = "";
17007
17314
  const attachmentsConfig = (_Oa = config.attachments) != null ? _Oa : {};
@@ -17024,14 +17331,15 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17024
17331
  if (attachmentManager) {
17025
17332
  attachmentManager.clearAttachments();
17026
17333
  }
17334
+ (_Ra = container.querySelector(".persona-attachment-drop-overlay")) == null ? void 0 : _Ra.remove();
17027
17335
  }
17028
- const sendButtonConfig = (_Ra = config.sendButton) != null ? _Ra : {};
17029
- const useIcon = (_Sa = sendButtonConfig.useIcon) != null ? _Sa : false;
17030
- const iconText = (_Ta = sendButtonConfig.iconText) != null ? _Ta : "\u2191";
17336
+ const sendButtonConfig = (_Sa = config.sendButton) != null ? _Sa : {};
17337
+ const useIcon = (_Ta = sendButtonConfig.useIcon) != null ? _Ta : false;
17338
+ const iconText = (_Ua = sendButtonConfig.iconText) != null ? _Ua : "\u2191";
17031
17339
  const iconName = sendButtonConfig.iconName;
17032
- const tooltipText = (_Ua = sendButtonConfig.tooltipText) != null ? _Ua : "Send message";
17033
- const showTooltip = (_Va = sendButtonConfig.showTooltip) != null ? _Va : false;
17034
- const buttonSize = (_Wa = sendButtonConfig.size) != null ? _Wa : "40px";
17340
+ const tooltipText = (_Va = sendButtonConfig.tooltipText) != null ? _Va : "Send message";
17341
+ const showTooltip = (_Wa = sendButtonConfig.showTooltip) != null ? _Wa : false;
17342
+ const buttonSize = (_Xa = sendButtonConfig.size) != null ? _Xa : "40px";
17035
17343
  const backgroundColor = sendButtonConfig.backgroundColor;
17036
17344
  const textColor = sendButtonConfig.textColor;
17037
17345
  if (useIcon) {
@@ -17068,7 +17376,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17068
17376
  sendButton.classList.add("persona-bg-persona-primary");
17069
17377
  }
17070
17378
  } else {
17071
- sendButton.textContent = (_Ya = (_Xa = config.copy) == null ? void 0 : _Xa.sendButtonLabel) != null ? _Ya : "Send";
17379
+ sendButton.textContent = (_Za = (_Ya = config.copy) == null ? void 0 : _Ya.sendButtonLabel) != null ? _Za : "Send";
17072
17380
  sendButton.style.width = "";
17073
17381
  sendButton.style.height = "";
17074
17382
  sendButton.style.minWidth = "";
@@ -17128,7 +17436,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17128
17436
  } else if (tooltip) {
17129
17437
  tooltip.style.display = "none";
17130
17438
  }
17131
- const updatedContentMaxWidth = (_Za = config.layout) == null ? void 0 : _Za.contentMaxWidth;
17439
+ const updatedContentMaxWidth = (__a = config.layout) == null ? void 0 : __a.contentMaxWidth;
17132
17440
  if (updatedContentMaxWidth) {
17133
17441
  messagesWrapper.style.maxWidth = updatedContentMaxWidth;
17134
17442
  messagesWrapper.style.marginLeft = "auto";
@@ -17160,8 +17468,8 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17160
17468
  suggestions.style.marginRight = "";
17161
17469
  }
17162
17470
  }
17163
- const statusIndicatorConfig = (__a = config.statusIndicator) != null ? __a : {};
17164
- const isVisible = (_$a = statusIndicatorConfig.visible) != null ? _$a : true;
17471
+ const statusIndicatorConfig = (_$a = config.statusIndicator) != null ? _$a : {};
17472
+ const isVisible = (_ab = statusIndicatorConfig.visible) != null ? _ab : true;
17165
17473
  statusText.style.display = isVisible ? "" : "none";
17166
17474
  if (session) {
17167
17475
  const currentStatus = session.getStatus();
@@ -17507,6 +17815,10 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17507
17815
  return session.submitNPSFeedback(rating, comment);
17508
17816
  },
17509
17817
  destroy() {
17818
+ if (toolElapsedTimerId != null) {
17819
+ clearInterval(toolElapsedTimerId);
17820
+ toolElapsedTimerId = null;
17821
+ }
17510
17822
  destroyCallbacks.forEach((cb) => cb());
17511
17823
  wrapper.remove();
17512
17824
  launcherButtonInstance == null ? void 0 : launcherButtonInstance.destroy();