@webless/agent 0.13.0 → 0.13.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.
@@ -4753,7 +4753,7 @@ function MessageActions({
4753
4753
  }
4754
4754
 
4755
4755
  // src/react/components/AgentRail/AgentRail.tsx
4756
- import { useEffect as useEffect8, useRef as useRef8, useState as useState11 } from "react";
4756
+ import { useEffect as useEffect9, useRef as useRef8, useState as useState13 } from "react";
4757
4757
 
4758
4758
  // src/react/lib/agent-theme.ts
4759
4759
  function agentThemeStyle(theme, resolvedColorScheme) {
@@ -4998,46 +4998,110 @@ function AgentActivityBubble({
4998
4998
  }
4999
4999
 
5000
5000
  // src/react/components/LearnMore/LearnMore.tsx
5001
- import { useId } from "react";
5001
+ import { useId, useState as useState5 } from "react";
5002
5002
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
5003
+ function QuestionIcon() {
5004
+ return /* @__PURE__ */ jsxs3(
5005
+ "svg",
5006
+ {
5007
+ viewBox: "0 0 24 24",
5008
+ width: "18",
5009
+ height: "18",
5010
+ fill: "none",
5011
+ stroke: "currentColor",
5012
+ strokeWidth: "1.5",
5013
+ strokeLinecap: "round",
5014
+ strokeLinejoin: "round",
5015
+ "aria-hidden": "true",
5016
+ children: [
5017
+ /* @__PURE__ */ jsx3("path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z" }),
5018
+ /* @__PURE__ */ jsx3("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }),
5019
+ /* @__PURE__ */ jsx3("path", { d: "M12 17h.01" })
5020
+ ]
5021
+ }
5022
+ );
5023
+ }
5003
5024
  function LearnMore({
5004
5025
  results,
5005
5026
  disabled,
5006
5027
  onSelect
5007
5028
  }) {
5008
5029
  const headingId = useId();
5030
+ const panelId = useId();
5031
+ const [open, setOpen] = useState5(true);
5009
5032
  const questions = [
5010
5033
  ...new Set(results.flatMap((result) => result.suggestions ?? []))
5011
5034
  ].slice(0, 3);
5012
5035
  if (!questions.length) return null;
5013
5036
  return /* @__PURE__ */ jsxs3("section", { className: "learn-more", "aria-labelledby": headingId, children: [
5014
- /* @__PURE__ */ jsx3("h3", { id: headingId, className: "learn-more__heading", children: "Learn more" }),
5015
- /* @__PURE__ */ jsx3("ul", { className: "learn-more__questions", children: questions.map((question) => /* @__PURE__ */ jsx3("li", { children: /* @__PURE__ */ jsxs3(
5037
+ /* @__PURE__ */ jsx3("h3", { id: headingId, className: "learn-more__heading", children: /* @__PURE__ */ jsxs3(
5016
5038
  "button",
5017
5039
  {
5018
5040
  type: "button",
5019
- disabled,
5020
- onClick: () => onSelect(question),
5041
+ className: "learn-more__toggle",
5042
+ "aria-expanded": open,
5043
+ "aria-controls": panelId,
5044
+ onClick: () => setOpen((current) => !current),
5021
5045
  children: [
5022
- /* @__PURE__ */ jsx3("span", { children: question }),
5046
+ /* @__PURE__ */ jsx3("span", { children: "Learn more" }),
5023
5047
  /* @__PURE__ */ jsx3(
5024
5048
  "svg",
5025
5049
  {
5026
- viewBox: "0 0 24 24",
5050
+ className: "learn-more__chevron",
5051
+ viewBox: "0 0 16 16",
5027
5052
  fill: "none",
5028
- stroke: "currentColor",
5029
- strokeWidth: "1.5",
5030
5053
  "aria-hidden": "true",
5031
- children: /* @__PURE__ */ jsx3("path", { d: "M4 12h16m-7-7 7 7-7 7" })
5054
+ children: /* @__PURE__ */ jsx3(
5055
+ "path",
5056
+ {
5057
+ d: "M4 6.5l4 4 4-4",
5058
+ stroke: "currentColor",
5059
+ strokeWidth: "1.6",
5060
+ strokeLinecap: "round",
5061
+ strokeLinejoin: "round"
5062
+ }
5063
+ )
5032
5064
  }
5033
5065
  )
5034
5066
  ]
5035
5067
  }
5036
- ) }, question)) })
5068
+ ) }),
5069
+ /* @__PURE__ */ jsx3(
5070
+ "div",
5071
+ {
5072
+ id: panelId,
5073
+ className: `learn-more__panel${open ? " learn-more__panel--open" : ""}`,
5074
+ children: /* @__PURE__ */ jsx3("div", { className: "learn-more__panel-inner", children: /* @__PURE__ */ jsx3("ul", { className: "learn-more__questions", children: questions.map((question) => /* @__PURE__ */ jsx3("li", { children: /* @__PURE__ */ jsxs3(
5075
+ "button",
5076
+ {
5077
+ type: "button",
5078
+ disabled,
5079
+ onClick: () => onSelect(question),
5080
+ children: [
5081
+ /* @__PURE__ */ jsx3("span", { className: "learn-more__question-icon", children: /* @__PURE__ */ jsx3(QuestionIcon, {}) }),
5082
+ /* @__PURE__ */ jsx3("span", { className: "learn-more__question-text", children: question }),
5083
+ /* @__PURE__ */ jsx3(
5084
+ "svg",
5085
+ {
5086
+ className: "learn-more__question-arrow",
5087
+ viewBox: "0 0 24 24",
5088
+ fill: "none",
5089
+ stroke: "currentColor",
5090
+ strokeWidth: "1.5",
5091
+ "aria-hidden": "true",
5092
+ children: /* @__PURE__ */ jsx3("path", { d: "M4 12h16m-7-7 7 7-7 7" })
5093
+ }
5094
+ )
5095
+ ]
5096
+ }
5097
+ ) }, question)) }) })
5098
+ }
5099
+ )
5037
5100
  ] });
5038
5101
  }
5039
5102
 
5040
5103
  // src/react/components/SearchReferences/SearchReferences.tsx
5104
+ import { useState as useState6 } from "react";
5041
5105
  import { Fragment, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
5042
5106
  function SiteIcon() {
5043
5107
  return /* @__PURE__ */ jsxs4(
@@ -5058,6 +5122,27 @@ function SiteIcon() {
5058
5122
  }
5059
5123
  );
5060
5124
  }
5125
+ function SourceFavicon({ url }) {
5126
+ const [failed, setFailed] = useState6(false);
5127
+ let faviconUrl = null;
5128
+ if (url) {
5129
+ try {
5130
+ faviconUrl = `${new URL(url).origin}/favicon.ico`;
5131
+ } catch {
5132
+ faviconUrl = null;
5133
+ }
5134
+ }
5135
+ if (!faviconUrl || failed) return /* @__PURE__ */ jsx4(SiteIcon, {});
5136
+ return /* @__PURE__ */ jsx4(
5137
+ "img",
5138
+ {
5139
+ src: faviconUrl,
5140
+ alt: "",
5141
+ loading: "lazy",
5142
+ onError: () => setFailed(true)
5143
+ }
5144
+ );
5145
+ }
5061
5146
  function searchSources(results) {
5062
5147
  const seenSources = /* @__PURE__ */ new Set();
5063
5148
  return results.flatMap((result) => result.sources).flatMap((source) => {
@@ -5097,28 +5182,25 @@ function SearchReferences({
5097
5182
  ] }) : null,
5098
5183
  /* @__PURE__ */ jsx4("ul", { className: "search-references__list", children: sources.map((source) => {
5099
5184
  const content = /* @__PURE__ */ jsxs4(Fragment, { children: [
5100
- /* @__PURE__ */ jsx4("span", { className: "search-references__icon", children: /* @__PURE__ */ jsx4(SiteIcon, {}) }),
5101
- /* @__PURE__ */ jsxs4("span", { className: "search-references__copy", children: [
5102
- /* @__PURE__ */ jsx4(
5103
- "span",
5104
- {
5105
- className: "search-references__title",
5106
- title: source.title,
5107
- children: source.title
5108
- }
5109
- ),
5110
- source.url ? /* @__PURE__ */ jsx4("span", { className: "search-references__domain", children: new URL(source.url).hostname.replace(/^www\./u, "") }) : null
5111
- ] }),
5185
+ /* @__PURE__ */ jsx4("span", { className: "search-references__icon", children: /* @__PURE__ */ jsx4(SourceFavicon, { url: source.url }) }),
5186
+ /* @__PURE__ */ jsx4(
5187
+ "span",
5188
+ {
5189
+ className: "search-references__title",
5190
+ title: source.title,
5191
+ children: source.title
5192
+ }
5193
+ ),
5112
5194
  source.url ? /* @__PURE__ */ jsx4(
5113
5195
  "svg",
5114
5196
  {
5115
- className: "search-references__external",
5197
+ className: "search-references__row-arrow",
5116
5198
  viewBox: "0 0 24 24",
5117
5199
  fill: "none",
5118
5200
  stroke: "currentColor",
5119
5201
  strokeWidth: "1.5",
5120
5202
  "aria-hidden": "true",
5121
- children: /* @__PURE__ */ jsx4("path", { d: "M7 17 17 7M7 7h10v10" })
5203
+ children: /* @__PURE__ */ jsx4("path", { d: "M4 12h16m-7-7 7 7-7 7" })
5122
5204
  }
5123
5205
  ) : null
5124
5206
  ] });
@@ -5260,7 +5342,7 @@ import {
5260
5342
  useEffect as useEffect5,
5261
5343
  useId as useId3,
5262
5344
  useRef as useRef5,
5263
- useState as useState5
5345
+ useState as useState7
5264
5346
  } from "react";
5265
5347
  import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
5266
5348
  var FORM_SUBMITTED_MESSAGE = "Shared my details";
@@ -5323,8 +5405,9 @@ function Composer({
5323
5405
  allowFormResume = true,
5324
5406
  onSubmit
5325
5407
  }) {
5326
- const [value, setValue] = useState5("");
5327
- const [draft, setDraft] = useState5(() => createDraft(form));
5408
+ const [value, setValue] = useState7("");
5409
+ const [draft, setDraft] = useState7(() => createDraft(form));
5410
+ const [multiline, setMultiline] = useState7(false);
5328
5411
  const inputRef = useRef5(null);
5329
5412
  const firstFieldRef = useRef5(null);
5330
5413
  const formRef = useRef5(null);
@@ -5338,6 +5421,19 @@ function Composer({
5338
5421
  else if ((savedForm || draft.submitted) && !disabled)
5339
5422
  inputRef.current?.focus();
5340
5423
  }, [activeForm?.id, disabled, savedForm?.id, draft.submitted]);
5424
+ useEffect5(() => {
5425
+ const input = inputRef.current;
5426
+ if (!input) return;
5427
+ const check = () => {
5428
+ const style = window.getComputedStyle(input);
5429
+ const singleLine = (parseFloat(style.lineHeight) || 20) + parseFloat(style.paddingTop) + parseFloat(style.paddingBottom) + 2;
5430
+ setMultiline(input.offsetHeight > singleLine);
5431
+ };
5432
+ check();
5433
+ const observer = new ResizeObserver(check);
5434
+ observer.observe(input);
5435
+ return () => observer.disconnect();
5436
+ }, []);
5341
5437
  function collapseForm() {
5342
5438
  setDraft((current) => ({ ...current, expanded: false }));
5343
5439
  }
@@ -5442,7 +5538,8 @@ function Composer({
5442
5538
  className: [
5443
5539
  "composer",
5444
5540
  variant === "dock" ? "composer--dock" : "",
5445
- activeForm ? "composer--form" : ""
5541
+ activeForm ? "composer--form" : "",
5542
+ multiline ? "composer--multiline" : ""
5446
5543
  ].filter(Boolean).join(" "),
5447
5544
  onSubmit: handleSubmit,
5448
5545
  children: [
@@ -5594,7 +5691,7 @@ function FollowUpChips({
5594
5691
  }
5595
5692
 
5596
5693
  // src/react/components/MessageBubble/MessageBubble.tsx
5597
- import { useState as useState7 } from "react";
5694
+ import { useEffect as useEffect7, useState as useState9 } from "react";
5598
5695
 
5599
5696
  // src/react/components/BookingCard/BookingCard.tsx
5600
5697
  import {
@@ -5602,7 +5699,7 @@ import {
5602
5699
  useId as useId4,
5603
5700
  useMemo as useMemo2,
5604
5701
  useRef as useRef6,
5605
- useState as useState6
5702
+ useState as useState8
5606
5703
  } from "react";
5607
5704
  import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
5608
5705
  var BOOKING_STEPS = [
@@ -5660,12 +5757,12 @@ function InteractiveBookingCard({
5660
5757
  }) {
5661
5758
  const fieldId = useId4();
5662
5759
  const defaultType = offer.eventTypes[0]?.uri ?? offer.slots[0]?.eventTypeUri ?? "";
5663
- const [step, setStep] = useState6("date");
5664
- const [eventTypeUri, setEventTypeUri] = useState6(defaultType);
5665
- const [selectedDate, setSelectedDate] = useState6("");
5666
- const [startTime, setStartTime] = useState6("");
5667
- const [name, setName] = useState6("");
5668
- const [email, setEmail] = useState6("");
5760
+ const [step, setStep] = useState8("date");
5761
+ const [eventTypeUri, setEventTypeUri] = useState8(defaultType);
5762
+ const [selectedDate, setSelectedDate] = useState8("");
5763
+ const [startTime, setStartTime] = useState8("");
5764
+ const [name, setName] = useState8("");
5765
+ const [email, setEmail] = useState8("");
5669
5766
  const activeStepRef = useRef6(null);
5670
5767
  const previousStepRef = useRef6(step);
5671
5768
  const stepIndex = BOOKING_STEPS.findIndex((item) => item.id === step);
@@ -5686,7 +5783,7 @@ function InteractiveBookingCard({
5686
5783
  }
5687
5784
  return next;
5688
5785
  }, [slots]);
5689
- const [visibleMonth, setVisibleMonth] = useState6(
5786
+ const [visibleMonth, setVisibleMonth] = useState8(
5690
5787
  () => firstAvailableBookingMonth(slots)
5691
5788
  );
5692
5789
  function selectEventType(nextType) {
@@ -5979,6 +6076,37 @@ function InteractiveBookingCard({
5979
6076
  // src/react/components/MessageBubble/MessageBubble.tsx
5980
6077
  import { Streamdown, defaultUrlTransform } from "streamdown";
5981
6078
 
6079
+ // src/react/lib/brand-logo-display.ts
6080
+ var BRAND_LOGO_LAYOUT = {
6081
+ header: { maxHeight: 20, maxWidth: 96, square: 24 },
6082
+ message: { maxHeight: 18, maxWidth: 80, square: 22 },
6083
+ /** Bottom/mobile launcher pill orb — keep in sync with AssistEdgeTab chip CSS. */
6084
+ launcher: { maxHeight: 24, maxWidth: 104, square: 38 }
6085
+ };
6086
+ function isWideBrandLogo(naturalWidth, naturalHeight) {
6087
+ return naturalWidth > naturalHeight * 1.4;
6088
+ }
6089
+ function snapBrandLogoDisplaySize(input) {
6090
+ const { maxHeight, maxWidth } = BRAND_LOGO_LAYOUT[input.surface];
6091
+ const { naturalWidth, naturalHeight } = input;
6092
+ if (naturalWidth <= 0 || naturalHeight <= 0) {
6093
+ return { width: maxWidth, height: maxHeight, wide: false };
6094
+ }
6095
+ const wide = isWideBrandLogo(naturalWidth, naturalHeight);
6096
+ if (!wide) {
6097
+ const size = BRAND_LOGO_LAYOUT[input.surface].square;
6098
+ return { width: size, height: size, wide: false };
6099
+ }
6100
+ const scale = Math.min(
6101
+ maxHeight / naturalHeight,
6102
+ maxWidth / naturalWidth,
6103
+ 1
6104
+ );
6105
+ const height = Math.max(1, Math.round(naturalHeight * scale));
6106
+ const width = Math.max(1, Math.round(naturalWidth * scale));
6107
+ return { width, height, wide: true };
6108
+ }
6109
+
5982
6110
  // src/react/lib/resolve-message-url.ts
5983
6111
  function resolveMessageUrl(safeUrl, baseUrl) {
5984
6112
  if (!safeUrl || !baseUrl) return safeUrl;
@@ -6041,7 +6169,14 @@ function MessageBubble({
6041
6169
  onBook
6042
6170
  }) {
6043
6171
  const resolvedLogoUrl = brandLogoUrl?.trim();
6044
- const [failedLogoUrl, setFailedLogoUrl] = useState7(null);
6172
+ const [failedLogoUrl, setFailedLogoUrl] = useState9(null);
6173
+ const [logoDisplay, setLogoDisplay] = useState9(null);
6174
+ useEffect7(() => {
6175
+ setFailedLogoUrl(null);
6176
+ }, [resolvedLogoUrl]);
6177
+ const activeLogoDisplay = logoDisplay?.url === resolvedLogoUrl ? logoDisplay : null;
6178
+ const wideLogo = activeLogoDisplay?.wide ?? false;
6179
+ const logoDisplaySize = activeLogoDisplay ? { height: activeLogoDisplay.height, width: activeLogoDisplay.width } : null;
6045
6180
  const showBrandLogo = Boolean(resolvedLogoUrl) && failedLogoUrl !== resolvedLogoUrl;
6046
6181
  const cards = message.role === "agent" ? extractToolCards(message.text) : [];
6047
6182
  const extractedOffers = cards.filter(
@@ -6062,7 +6197,7 @@ function MessageBubble({
6062
6197
  className: "message-bubble message-bubble--visitor",
6063
6198
  "aria-label": "Message from visitor",
6064
6199
  children: [
6065
- showProvenance ? /* @__PURE__ */ jsx9("span", { className: "message-bubble__speaker", children: "You \xB7 Visitor" }) : null,
6200
+ showProvenance ? /* @__PURE__ */ jsx9("span", { className: "message-bubble__speaker", children: "You" }) : null,
6066
6201
  /* @__PURE__ */ jsx9("p", { className: "message-bubble__text", children: visitorText })
6067
6202
  ]
6068
6203
  }
@@ -6126,20 +6261,51 @@ function MessageBubble({
6126
6261
  className: "message-bubble message-bubble--agent",
6127
6262
  "aria-label": "Message from AI assistant",
6128
6263
  children: [
6129
- showProvenance ? /* @__PURE__ */ jsx9("span", { className: "message-bubble__speaker", children: "AI assistant" }) : null,
6130
- displayText || message.searchResults?.length ? showBrandLogo ? /* @__PURE__ */ jsxs9("div", { className: "message-bubble__agent-row", children: [
6131
- /* @__PURE__ */ jsx9("span", { className: "message-bubble__agent-avatar", "aria-hidden": "true", children: /* @__PURE__ */ jsx9(
6132
- "img",
6133
- {
6134
- src: resolvedLogoUrl,
6135
- alt: "",
6136
- onError: () => {
6137
- setFailedLogoUrl(resolvedLogoUrl ?? null);
6264
+ displayText || message.searchResults?.length ? /* @__PURE__ */ jsxs9("div", { className: "message-bubble__agent-stack", children: [
6265
+ showProvenance || showBrandLogo ? /* @__PURE__ */ jsxs9("div", { className: "message-bubble__agent-header", children: [
6266
+ showBrandLogo ? /* @__PURE__ */ jsx9(
6267
+ "span",
6268
+ {
6269
+ className: `message-bubble__agent-avatar${wideLogo ? " message-bubble__agent-avatar--wide" : ""}`,
6270
+ "aria-hidden": "true",
6271
+ children: /* @__PURE__ */ jsx9(
6272
+ "img",
6273
+ {
6274
+ className: "as-brand-logo-img",
6275
+ src: resolvedLogoUrl,
6276
+ alt: "",
6277
+ decoding: "async",
6278
+ ...logoDisplaySize ? {
6279
+ height: logoDisplaySize.height,
6280
+ width: logoDisplaySize.width
6281
+ } : {},
6282
+ onLoad: (event) => {
6283
+ const img = event.currentTarget;
6284
+ const display = snapBrandLogoDisplaySize({
6285
+ naturalHeight: img.naturalHeight,
6286
+ naturalWidth: img.naturalWidth,
6287
+ surface: "message"
6288
+ });
6289
+ if (!resolvedLogoUrl) return;
6290
+ setLogoDisplay({
6291
+ height: display.height,
6292
+ url: resolvedLogoUrl,
6293
+ wide: display.wide,
6294
+ width: display.width
6295
+ });
6296
+ },
6297
+ onError: () => {
6298
+ setFailedLogoUrl(resolvedLogoUrl ?? null);
6299
+ }
6300
+ },
6301
+ resolvedLogoUrl
6302
+ )
6138
6303
  }
6139
- }
6140
- ) }),
6304
+ ) : null,
6305
+ showProvenance ? /* @__PURE__ */ jsx9("span", { className: "message-bubble__speaker", children: "AI assistant" }) : null
6306
+ ] }) : null,
6141
6307
  agentText
6142
- ] }) : agentText : null,
6308
+ ] }) : null,
6143
6309
  offers.map((nextOffer, index) => /* @__PURE__ */ jsx9(
6144
6310
  BookingCard,
6145
6311
  {
@@ -6156,7 +6322,7 @@ function MessageBubble({
6156
6322
  }
6157
6323
 
6158
6324
  // src/react/components/HumanInputCard/HumanInputCard.tsx
6159
- import { useState as useState9 } from "react";
6325
+ import { useState as useState11 } from "react";
6160
6326
 
6161
6327
  // src/react/components/ConfirmationCard/ConfirmationCard.tsx
6162
6328
  import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
@@ -6198,7 +6364,7 @@ function ConfirmationCard({
6198
6364
  }
6199
6365
 
6200
6366
  // src/react/components/ToolInputCard/ToolInputCard.tsx
6201
- import { useState as useState8 } from "react";
6367
+ import { useState as useState10 } from "react";
6202
6368
  import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
6203
6369
  function isRecord5(value) {
6204
6370
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -6529,11 +6695,11 @@ function ToolInputCard({
6529
6695
  surface,
6530
6696
  onSubmit
6531
6697
  }) {
6532
- const [values, setValues] = useState8(
6698
+ const [values, setValues] = useState10(
6533
6699
  () => initialValues(surface)
6534
6700
  );
6535
- const [touched, setTouched] = useState8(() => /* @__PURE__ */ new Set());
6536
- const [submitted, setSubmitted] = useState8(false);
6701
+ const [touched, setTouched] = useState10(() => /* @__PURE__ */ new Set());
6702
+ const [submitted, setSubmitted] = useState10(false);
6537
6703
  const errors = Object.fromEntries(
6538
6704
  surface.fields.map((field) => [
6539
6705
  field.path,
@@ -6626,7 +6792,7 @@ function HumanInputCard({
6626
6792
  request,
6627
6793
  onRespond
6628
6794
  }) {
6629
- const [text3, setText] = useState9("");
6795
+ const [text3, setText] = useState11("");
6630
6796
  const options = request.options ?? [];
6631
6797
  const showText = request.display === "text" || request.allowFreeform && options.length === 0;
6632
6798
  if (request.ui) {
@@ -6684,7 +6850,7 @@ function HumanInputCard({
6684
6850
  }
6685
6851
 
6686
6852
  // src/react/components/LocationConsent/LocationConsent.tsx
6687
- import { useEffect as useEffect7, useRef as useRef7, useState as useState10 } from "react";
6853
+ import { useEffect as useEffect8, useRef as useRef7, useState as useState12 } from "react";
6688
6854
 
6689
6855
  // src/runtime/location-consent.ts
6690
6856
  function isLocationConsentRequest(request) {
@@ -6732,16 +6898,16 @@ function LocationConsent({
6732
6898
  request,
6733
6899
  onRespond
6734
6900
  }) {
6735
- const [preference, setPreference] = useState10("unset");
6736
- const [locating, setLocating] = useState10(false);
6737
- const [error, setError] = useState10(null);
6901
+ const [preference, setPreference] = useState12("unset");
6902
+ const [locating, setLocating] = useState12(false);
6903
+ const [error, setError] = useState12(null);
6738
6904
  const respond = useRef7(onRespond);
6739
6905
  const answered = useRef7(null);
6740
6906
  const requestId = request?.requestId;
6741
- useEffect7(() => {
6907
+ useEffect8(() => {
6742
6908
  respond.current = onRespond;
6743
6909
  }, [onRespond]);
6744
- useEffect7(() => {
6910
+ useEffect8(() => {
6745
6911
  if (!requestId || preference === "unset" || answered.current === requestId || !respond.current)
6746
6912
  return;
6747
6913
  if (preference === "off") {
@@ -7033,16 +7199,28 @@ function CloseIcon2() {
7033
7199
  ) });
7034
7200
  }
7035
7201
  function NewChatIcon() {
7036
- return /* @__PURE__ */ jsx19("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx19(
7037
- "path",
7038
- {
7039
- d: "M9.5 3.5h3v3M12.25 3.75 8 8M7 4H4.5A1.5 1.5 0 0 0 3 5.5v6A1.5 1.5 0 0 0 4.5 13h6a1.5 1.5 0 0 0 1.5-1.5V9",
7040
- stroke: "currentColor",
7041
- strokeWidth: "1.4",
7042
- strokeLinecap: "round",
7043
- strokeLinejoin: "round"
7044
- }
7045
- ) });
7202
+ return /* @__PURE__ */ jsxs18("svg", { viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
7203
+ /* @__PURE__ */ jsx19(
7204
+ "path",
7205
+ {
7206
+ d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.86L21 8",
7207
+ stroke: "currentColor",
7208
+ strokeWidth: "2",
7209
+ strokeLinecap: "round",
7210
+ strokeLinejoin: "round"
7211
+ }
7212
+ ),
7213
+ /* @__PURE__ */ jsx19(
7214
+ "path",
7215
+ {
7216
+ d: "M21 3v5h-5",
7217
+ stroke: "currentColor",
7218
+ strokeWidth: "2",
7219
+ strokeLinecap: "round",
7220
+ strokeLinejoin: "round"
7221
+ }
7222
+ )
7223
+ ] });
7046
7224
  }
7047
7225
  function ExpandIcon() {
7048
7226
  return /* @__PURE__ */ jsx19("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx19(
@@ -7120,13 +7298,23 @@ function AgentRail({
7120
7298
  const pinnedToBottomRef = useRef8(true);
7121
7299
  const smoothScrollToLatestRef = useRef8(false);
7122
7300
  const lockedTranscriptScrollTopRef = useRef8(null);
7123
- const [showJumpToLatest, setShowJumpToLatest] = useState11(false);
7124
- const [receiptOpen, setReceiptOpen] = useState11(false);
7125
- const [sourceResults, setSourceResults] = useState11(null);
7301
+ const [showJumpToLatest, setShowJumpToLatest] = useState13(false);
7302
+ const [receiptOpen, setReceiptOpen] = useState13(false);
7303
+ const [expandedSourcesMessageId, setExpandedSourcesMessageId] = useState13(null);
7126
7304
  const resolvedBrandLabel = brandLabel.trim();
7127
7305
  const resolvedBrandLogoUrl = brandLogoUrl?.trim();
7128
7306
  const resolvedDisclaimerLabel = disclaimerLabel === void 0 ? DEFAULT_DISCLAIMER_LABEL : disclaimerLabel;
7129
- const [failedLogoUrl, setFailedLogoUrl] = useState11(null);
7307
+ const [failedLogoUrl, setFailedLogoUrl] = useState13(null);
7308
+ const [brandLogoDisplay, setBrandLogoDisplay] = useState13(null);
7309
+ useEffect9(() => {
7310
+ setFailedLogoUrl(null);
7311
+ }, [resolvedBrandLogoUrl]);
7312
+ const activeBrandLogoDisplay = brandLogoDisplay?.url === resolvedBrandLogoUrl ? brandLogoDisplay : null;
7313
+ const wideBrandLogo = activeBrandLogoDisplay?.wide ?? false;
7314
+ const brandLogoDisplaySize = activeBrandLogoDisplay ? {
7315
+ height: activeBrandLogoDisplay.height,
7316
+ width: activeBrandLogoDisplay.width
7317
+ } : null;
7130
7318
  const showBrandLogo = Boolean(resolvedBrandLogoUrl) && failedLogoUrl !== resolvedBrandLogoUrl;
7131
7319
  const resolvedColorScheme = useAgentColorScheme(colorScheme);
7132
7320
  const railStyle = agentThemeStyle(theme, resolvedColorScheme);
@@ -7227,30 +7415,39 @@ function AgentRail({
7227
7415
  ...visibleVisitorToolResults
7228
7416
  ].reverse().find((result) => result.kind !== "input")?.id;
7229
7417
  const receiptSteps = answerReceipt && state.toolSteps.length > 0 ? state.toolSteps : void 0;
7230
- useEffect8(() => {
7231
- if (state.phase !== "complete" || !showSources && sourceResults) {
7418
+ useEffect9(() => {
7419
+ if (state.phase !== "complete") {
7232
7420
  setReceiptOpen(false);
7233
7421
  }
7234
- }, [state.phase, showSources, sourceResults]);
7422
+ }, [state.phase]);
7423
+ useEffect9(() => {
7424
+ if (state.phase !== "complete" || !showSources) {
7425
+ setExpandedSourcesMessageId(null);
7426
+ }
7427
+ }, [state.phase, showSources]);
7235
7428
  function handleSubmit(message, options) {
7236
7429
  setReceiptOpen(false);
7430
+ setExpandedSourcesMessageId(null);
7237
7431
  onSubmit?.(message, options);
7238
7432
  }
7239
7433
  function handleRegenerate() {
7240
7434
  setReceiptOpen(false);
7435
+ setExpandedSourcesMessageId(null);
7241
7436
  onRegenerate?.();
7242
7437
  }
7243
7438
  function handleReset() {
7244
7439
  setReceiptOpen(false);
7440
+ setExpandedSourcesMessageId(null);
7245
7441
  onReset?.();
7246
7442
  }
7247
7443
  function handleFollowUpSelect(label) {
7248
7444
  setReceiptOpen(false);
7445
+ setExpandedSourcesMessageId(null);
7249
7446
  if (onFollowUpSelect) onFollowUpSelect(label);
7250
7447
  else onSubmit?.(label);
7251
7448
  }
7252
7449
  const latestVisitorId = visibleMessages[lastVisitorIndex]?.id;
7253
- useEffect8(() => {
7450
+ useEffect9(() => {
7254
7451
  const node = transcriptRef.current;
7255
7452
  if (!node) return;
7256
7453
  if (latestVisitorId !== lastScrolledVisitorIdRef.current) {
@@ -7280,7 +7477,7 @@ function AgentRail({
7280
7477
  state.followUps,
7281
7478
  state.journey
7282
7479
  ]);
7283
- useEffect8(() => {
7480
+ useEffect9(() => {
7284
7481
  const node = transcriptRef.current;
7285
7482
  if (!node) return;
7286
7483
  const handleScroll = () => {
@@ -7294,7 +7491,7 @@ function AgentRail({
7294
7491
  handleScroll();
7295
7492
  return () => node.removeEventListener("scroll", handleScroll);
7296
7493
  }, []);
7297
- useEffect8(() => {
7494
+ useEffect9(() => {
7298
7495
  if (!receiptOpen) {
7299
7496
  lockedTranscriptScrollTopRef.current = null;
7300
7497
  return;
@@ -7303,8 +7500,7 @@ function AgentRail({
7303
7500
  if (!node || lockedTranscriptScrollTopRef.current === null) return;
7304
7501
  node.scrollTop = lockedTranscriptScrollTopRef.current;
7305
7502
  }, [receiptOpen]);
7306
- function openReceipt(results = null) {
7307
- setSourceResults(results);
7503
+ function openReceipt() {
7308
7504
  const node = transcriptRef.current;
7309
7505
  lockedTranscriptScrollTopRef.current = node?.scrollTop ?? null;
7310
7506
  setReceiptOpen(true);
@@ -7370,17 +7566,45 @@ function AgentRail({
7370
7566
  }
7371
7567
  ) : /* @__PURE__ */ jsx19("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
7372
7568
  resolvedBrandLabel || showBrandLogo ? /* @__PURE__ */ jsxs18("span", { className: "agent-rail__identity", children: [
7373
- showBrandLogo ? /* @__PURE__ */ jsx19("span", { className: "agent-rail__brand-mark", "aria-hidden": "true", children: /* @__PURE__ */ jsx19(
7374
- "img",
7569
+ showBrandLogo ? /* @__PURE__ */ jsx19(
7570
+ "span",
7375
7571
  {
7376
- className: "agent-rail__brand-logo",
7377
- src: resolvedBrandLogoUrl,
7378
- alt: "",
7379
- onError: () => {
7380
- setFailedLogoUrl(resolvedBrandLogoUrl ?? null);
7381
- }
7572
+ className: `agent-rail__brand-mark${wideBrandLogo ? " agent-rail__brand-mark--wide" : ""}`,
7573
+ "aria-hidden": "true",
7574
+ children: /* @__PURE__ */ jsx19(
7575
+ "img",
7576
+ {
7577
+ className: "agent-rail__brand-logo as-brand-logo-img",
7578
+ src: resolvedBrandLogoUrl,
7579
+ alt: "",
7580
+ decoding: "async",
7581
+ ...brandLogoDisplaySize ? {
7582
+ height: brandLogoDisplaySize.height,
7583
+ width: brandLogoDisplaySize.width
7584
+ } : {},
7585
+ onLoad: (event) => {
7586
+ const img = event.currentTarget;
7587
+ const display = snapBrandLogoDisplaySize({
7588
+ naturalHeight: img.naturalHeight,
7589
+ naturalWidth: img.naturalWidth,
7590
+ surface: "header"
7591
+ });
7592
+ if (!resolvedBrandLogoUrl) return;
7593
+ setBrandLogoDisplay({
7594
+ height: display.height,
7595
+ url: resolvedBrandLogoUrl,
7596
+ wide: display.wide,
7597
+ width: display.width
7598
+ });
7599
+ },
7600
+ onError: () => {
7601
+ setFailedLogoUrl(resolvedBrandLogoUrl ?? null);
7602
+ }
7603
+ },
7604
+ resolvedBrandLogoUrl
7605
+ )
7382
7606
  }
7383
- ) }) : null,
7607
+ ) : null,
7384
7608
  resolvedBrandLabel ? /* @__PURE__ */ jsx19("span", { className: "agent-rail__brand-label", children: resolvedBrandLabel }) : null
7385
7609
  ] }) : null,
7386
7610
  /* @__PURE__ */ jsxs18("span", { className: "agent-rail__actions", children: [
@@ -7412,9 +7636,7 @@ function AgentRail({
7412
7636
  greeting?.role === "agent" ? /* @__PURE__ */ jsx19(
7413
7637
  MessageBubble,
7414
7638
  {
7415
- showProvenance: Boolean(
7416
- handoff?.page?.enabled || handoffActive
7417
- ),
7639
+ showProvenance: true,
7418
7640
  message: greeting,
7419
7641
  bookingDisabled: isBusy || handoffActive,
7420
7642
  brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
@@ -7457,104 +7679,138 @@ function AgentRail({
7457
7679
  request.requestId
7458
7680
  ))
7459
7681
  ] }) : null,
7460
- transcriptMessages.map((message, index) => /* @__PURE__ */ jsxs18(
7461
- "div",
7462
- {
7463
- ref: index === lastVisitorIndex + 1 ? responseRef : void 0,
7464
- className: "agent-rail__turn-block",
7465
- children: [
7466
- message.role === "agent" ? message.toolResults?.map((result) => /* @__PURE__ */ jsx19(
7467
- VisitorToolResultView,
7468
- {
7469
- result
7470
- },
7471
- result.id
7472
- )) : null,
7473
- /* @__PURE__ */ jsx19(
7474
- MessageBubble,
7475
- {
7476
- showProvenance: Boolean(
7477
- handoff?.page?.enabled || handoffActive
7478
- ),
7479
- message,
7480
- showSearchReferences: false,
7481
- bookingDisabled: isBusy || handoffActive,
7482
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
7483
- offer: index === transcriptMessages.length - 1 ? state.pendingOffer : void 0,
7484
- onBook
7485
- }
7486
- ),
7487
- message.role === "agent" ? /* @__PURE__ */ jsxs18("div", { className: "agent-rail__answer-actions", children: [
7488
- index === lastAgentIndex && showMessageActions ? /* @__PURE__ */ jsx19(
7489
- MessageActions,
7682
+ transcriptMessages.map((message, index) => {
7683
+ const messageSourceCount = message.role === "agent" ? searchSources(message.searchResults ?? []).length : 0;
7684
+ const showAnswerActions = message.role === "agent" && index === lastAgentIndex && showMessageActions;
7685
+ const showSourcesToggle = message.role === "agent" && showSources && state.phase === "complete" && !message.streaming && messageSourceCount > 0;
7686
+ return /* @__PURE__ */ jsxs18(
7687
+ "div",
7688
+ {
7689
+ ref: index === lastVisitorIndex + 1 ? responseRef : void 0,
7690
+ className: "agent-rail__turn-block",
7691
+ children: [
7692
+ message.role === "agent" ? message.toolResults?.map((result) => /* @__PURE__ */ jsx19(
7693
+ VisitorToolResultView,
7490
7694
  {
7491
- answeredAt: message.createdAt,
7492
- copyText: hideToolCardFences(message.text).trim() || message.text,
7493
- readAloud,
7494
- receiptSteps,
7495
- onOpenReceipt: receiptSteps ? () => openReceipt() : void 0,
7496
- onRegenerate: onRegenerate ? handleRegenerate : void 0,
7497
- onFeedback: onFeedback ? (rating) => onFeedback(rating, message) : void 0
7498
- }
7499
- ) : null,
7500
- showSources && state.phase === "complete" && !message.streaming && searchSources(message.searchResults ?? []).length > 0 ? /* @__PURE__ */ jsx19(
7501
- "button",
7695
+ result
7696
+ },
7697
+ result.id
7698
+ )) : null,
7699
+ /* @__PURE__ */ jsx19(
7700
+ MessageBubble,
7502
7701
  {
7503
- className: "agent-rail__sources-button",
7504
- type: "button",
7505
- "aria-haspopup": "dialog",
7506
- onClick: () => openReceipt(message.searchResults ?? []),
7507
- children: "View sources"
7702
+ showProvenance: true,
7703
+ message,
7704
+ showSearchReferences: false,
7705
+ bookingDisabled: isBusy || handoffActive,
7706
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
7707
+ offer: index === transcriptMessages.length - 1 ? state.pendingOffer : void 0,
7708
+ onBook
7508
7709
  }
7509
- ) : null
7510
- ] }) : null,
7511
- message.role === "agent" && !message.streaming ? /* @__PURE__ */ jsx19(
7512
- SearchReferences,
7513
- {
7514
- results: message.searchResults ?? [],
7515
- mode: "actions"
7516
- }
7517
- ) : null,
7518
- index === lastAgentIndex && showMessageActions && message.role === "agent" && !handoffActive && showLearnMore ? /* @__PURE__ */ jsx19(
7519
- LearnMore,
7520
- {
7521
- results: message.searchResults ?? [],
7522
- disabled: isBusy || !(onFollowUpSelect || onSubmit),
7523
- onSelect: handleFollowUpSelect
7524
- }
7525
- ) : null,
7526
- index === lastVisitorIndex ? /* @__PURE__ */ jsxs18(Fragment4, { children: [
7527
- showActivity ? /* @__PURE__ */ jsx19(
7528
- AgentActivityBubble,
7710
+ ),
7711
+ showAnswerActions || showSourcesToggle ? /* @__PURE__ */ jsxs18("div", { className: "agent-rail__answer-footer", children: [
7712
+ /* @__PURE__ */ jsxs18("div", { className: "agent-rail__answer-actions", children: [
7713
+ showAnswerActions ? /* @__PURE__ */ jsx19(
7714
+ MessageActions,
7715
+ {
7716
+ answeredAt: message.createdAt,
7717
+ copyText: hideToolCardFences(message.text).trim() || message.text,
7718
+ readAloud,
7719
+ receiptSteps,
7720
+ onOpenReceipt: receiptSteps ? () => openReceipt() : void 0,
7721
+ onRegenerate: onRegenerate ? handleRegenerate : void 0,
7722
+ onFeedback: onFeedback ? (rating) => onFeedback(rating, message) : void 0
7723
+ }
7724
+ ) : null,
7725
+ showSourcesToggle ? /* @__PURE__ */ jsxs18(
7726
+ "button",
7727
+ {
7728
+ className: "agent-rail__sources-button",
7729
+ type: "button",
7730
+ "aria-expanded": expandedSourcesMessageId === message.id,
7731
+ "aria-controls": `agent-rail-sources-${message.id}`,
7732
+ onClick: () => setExpandedSourcesMessageId(
7733
+ (current) => current === message.id ? null : message.id
7734
+ ),
7735
+ children: [
7736
+ "Explore More",
7737
+ /* @__PURE__ */ jsx19(
7738
+ "span",
7739
+ {
7740
+ className: "agent-rail__sources-button-chevron",
7741
+ "aria-hidden": "true",
7742
+ children: /* @__PURE__ */ jsx19(ChevronDownIcon, {})
7743
+ }
7744
+ )
7745
+ ]
7746
+ }
7747
+ ) : null
7748
+ ] }),
7749
+ showSourcesToggle ? /* @__PURE__ */ jsx19(
7750
+ "div",
7751
+ {
7752
+ id: `agent-rail-sources-${message.id}`,
7753
+ className: `agent-rail__sources-panel${expandedSourcesMessageId === message.id ? " agent-rail__sources-panel--open" : ""}`,
7754
+ role: "region",
7755
+ "aria-label": "Explore More",
7756
+ children: /* @__PURE__ */ jsx19("div", { className: "agent-rail__sources-panel-inner", children: /* @__PURE__ */ jsx19(
7757
+ SearchReferences,
7758
+ {
7759
+ results: message.searchResults ?? [],
7760
+ mode: "sources"
7761
+ }
7762
+ ) })
7763
+ }
7764
+ ) : null
7765
+ ] }) : null,
7766
+ message.role === "agent" && !message.streaming ? /* @__PURE__ */ jsx19(
7767
+ SearchReferences,
7529
7768
  {
7530
- brandLabel: resolvedBrandLabel,
7531
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
7532
- failed: state.phase === "error",
7533
- steps: activitySteps
7769
+ results: message.searchResults ?? [],
7770
+ mode: "actions"
7534
7771
  }
7535
7772
  ) : null,
7536
- visibleVisitorToolResults.map((result) => /* @__PURE__ */ jsx19(
7537
- VisitorToolResultView,
7538
- {
7539
- result,
7540
- disabled: semanticSurfaceDisabled,
7541
- onToolInput
7542
- },
7543
- result.id
7544
- )),
7545
- pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ jsx19(
7546
- HumanInputCard,
7773
+ showAnswerActions && !handoffActive && showLearnMore ? /* @__PURE__ */ jsx19(
7774
+ LearnMore,
7547
7775
  {
7548
- request,
7549
- onRespond: onInputResponse
7550
- },
7551
- request.requestId
7552
- ))
7553
- ] }) : null
7554
- ]
7555
- },
7556
- message.role === "agent" && transcriptMessages[index - 1]?.role === "visitor" ? `answer-${transcriptMessages[index - 1]?.id}` : message.id
7557
- )),
7776
+ results: message.searchResults ?? [],
7777
+ disabled: isBusy || !(onFollowUpSelect || onSubmit),
7778
+ onSelect: handleFollowUpSelect
7779
+ }
7780
+ ) : null,
7781
+ index === lastVisitorIndex ? /* @__PURE__ */ jsxs18(Fragment4, { children: [
7782
+ showActivity ? /* @__PURE__ */ jsx19(
7783
+ AgentActivityBubble,
7784
+ {
7785
+ brandLabel: resolvedBrandLabel,
7786
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
7787
+ failed: state.phase === "error",
7788
+ steps: activitySteps
7789
+ }
7790
+ ) : null,
7791
+ visibleVisitorToolResults.map((result) => /* @__PURE__ */ jsx19(
7792
+ VisitorToolResultView,
7793
+ {
7794
+ result,
7795
+ disabled: semanticSurfaceDisabled,
7796
+ onToolInput
7797
+ },
7798
+ result.id
7799
+ )),
7800
+ pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ jsx19(
7801
+ HumanInputCard,
7802
+ {
7803
+ request,
7804
+ onRespond: onInputResponse
7805
+ },
7806
+ request.requestId
7807
+ ))
7808
+ ] }) : null
7809
+ ]
7810
+ },
7811
+ message.role === "agent" && transcriptMessages[index - 1]?.role === "visitor" ? `answer-${transcriptMessages[index - 1]?.id}` : message.id
7812
+ );
7813
+ }),
7558
7814
  waitingForBooking ? /* @__PURE__ */ jsx19(BookingCardLoader, {}) : null,
7559
7815
  state.error ? /* @__PURE__ */ jsxs18("section", { className: "agent-rail__error", role: "alert", children: [
7560
7816
  /* @__PURE__ */ jsxs18("div", { children: [
@@ -7564,21 +7820,22 @@ function AgentRail({
7564
7820
  onRetry ? /* @__PURE__ */ jsx19("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
7565
7821
  ] }) : null
7566
7822
  ] }) }),
7567
- showDisclaimerLabel ? /* @__PURE__ */ jsx19("div", { className: "agent-rail__disclaimer", children: /* @__PURE__ */ jsx19("p", { children: disclaimerLink ? /* @__PURE__ */ jsx19(
7568
- "a",
7569
- {
7570
- href: disclaimerLink,
7571
- rel: "noopener noreferrer",
7572
- target: "_blank",
7573
- children: resolvedDisclaimerLabel
7574
- }
7575
- ) : resolvedDisclaimerLabel }) }) : null,
7576
7823
  handoff && (handoff.page?.enabled || handoffActive) ? /* @__PURE__ */ jsxs18("div", { className: "agent-rail__handoff", children: [
7577
- /* @__PURE__ */ jsx19("p", { role: "status", "aria-live": "polite", children: !handoff.page ? "Checking conversation\u2026" : handoffStatus === "human" ? "Connected with support" : handoffStatus === "queued" ? "Waiting for a representative" : handoffStatus === "requesting" ? "Connecting you to support\u2026" : handoffStatus === "resolved" ? "Your conversation with support has ended" : handoffStatus === "failed" ? "We couldn\u2019t connect you to support" : "Need a person?" }),
7824
+ handoffStatus === "human" || handoffStatus === "queued" || handoffStatus === "requesting" ? /* @__PURE__ */ jsx19("span", { className: "agent-rail__handoff-dot", "aria-hidden": "true" }) : null,
7825
+ /* @__PURE__ */ jsx19(
7826
+ "p",
7827
+ {
7828
+ className: "agent-rail__handoff-status",
7829
+ role: "status",
7830
+ "aria-live": "polite",
7831
+ children: !handoff.page ? "Checking conversation\u2026" : handoffStatus === "human" ? "Connected with support" : handoffStatus === "queued" ? "Waiting for a representative" : handoffStatus === "requesting" ? "Connecting you to support\u2026" : handoffStatus === "resolved" ? "Your conversation with support has ended" : handoffStatus === "failed" ? "We couldn\u2019t connect you to support" : "Need a person?"
7832
+ }
7833
+ ),
7578
7834
  handoffStatus === "ai" ? /* @__PURE__ */ jsx19(
7579
7835
  "button",
7580
7836
  {
7581
7837
  type: "button",
7838
+ className: "agent-rail__handoff-cta",
7582
7839
  disabled: handoff.busy || handoff.hasPending || isBusy,
7583
7840
  onClick: () => void handoff.start(),
7584
7841
  children: "Talk to a person"
@@ -7588,6 +7845,7 @@ function AgentRail({
7588
7845
  "button",
7589
7846
  {
7590
7847
  type: "button",
7848
+ className: "agent-rail__handoff-action",
7591
7849
  disabled: handoff.busy || handoff.hasPending,
7592
7850
  onClick: () => void handoff.returnToAI(),
7593
7851
  children: "Return to AI"
@@ -7597,17 +7855,19 @@ function AgentRail({
7597
7855
  "button",
7598
7856
  {
7599
7857
  type: "button",
7858
+ className: "agent-rail__handoff-action",
7600
7859
  disabled: !handoff.canReset,
7601
7860
  onClick: handleReset,
7602
7861
  children: "Start a new conversation"
7603
7862
  }
7604
7863
  ) : null,
7605
- handoff.error ? /* @__PURE__ */ jsxs18("div", { role: "alert", children: [
7606
- /* @__PURE__ */ jsx19("span", { children: handoff.error }),
7864
+ handoff.error ? /* @__PURE__ */ jsxs18("span", { className: "agent-rail__handoff-error", role: "alert", children: [
7865
+ handoff.error,
7607
7866
  /* @__PURE__ */ jsx19(
7608
7867
  "button",
7609
7868
  {
7610
7869
  type: "button",
7870
+ className: "agent-rail__handoff-action",
7611
7871
  disabled: handoff.busy,
7612
7872
  onClick: () => void handoff.retry(),
7613
7873
  children: "Retry"
@@ -7615,6 +7875,15 @@ function AgentRail({
7615
7875
  )
7616
7876
  ] }) : null
7617
7877
  ] }) : null,
7878
+ showDisclaimerLabel ? /* @__PURE__ */ jsx19("div", { className: "agent-rail__disclaimer", children: /* @__PURE__ */ jsx19("p", { children: disclaimerLink ? /* @__PURE__ */ jsx19(
7879
+ "a",
7880
+ {
7881
+ href: disclaimerLink,
7882
+ rel: "noopener noreferrer",
7883
+ target: "_blank",
7884
+ children: resolvedDisclaimerLabel
7885
+ }
7886
+ ) : resolvedDisclaimerLabel }) }) : null,
7618
7887
  /* @__PURE__ */ jsxs18("div", { className: "agent-rail__composer-wrap", children: [
7619
7888
  /* @__PURE__ */ jsx19(
7620
7889
  LocationConsent,
@@ -7656,19 +7925,12 @@ function AgentRail({
7656
7925
  ] })
7657
7926
  ] }),
7658
7927
  /* @__PURE__ */ jsx19("div", { ref: overlayRef, className: "agent-rail__overlay" }),
7659
- receiptOpen && (sourceResults || receiptSteps) ? /* @__PURE__ */ jsx19(
7928
+ receiptOpen && receiptSteps ? /* @__PURE__ */ jsx19(
7660
7929
  AnswerReceiptDialog,
7661
7930
  {
7662
7931
  brandLabel: resolvedBrandLabel,
7663
7932
  onClose: () => setReceiptOpen(false),
7664
- steps: receiptSteps,
7665
- title: sourceResults ? /* @__PURE__ */ jsxs18(Fragment4, { children: [
7666
- "Sources",
7667
- " ",
7668
- /* @__PURE__ */ jsx19("span", { className: "agent-receipt-dialog__count", children: searchSources(sourceResults).length })
7669
- ] }) : void 0,
7670
- summary: sourceResults ? "References for this answer" : void 0,
7671
- children: sourceResults ? /* @__PURE__ */ jsx19(SearchReferences, { results: sourceResults, mode: "sources" }) : void 0
7933
+ steps: receiptSteps
7672
7934
  }
7673
7935
  ) : null
7674
7936
  ] })
@@ -7677,7 +7939,7 @@ function AgentRail({
7677
7939
  }
7678
7940
 
7679
7941
  // src/react/components/AssistEdgeTab/AssistEdgeTab.tsx
7680
- import { useState as useState12 } from "react";
7942
+ import { useState as useState14 } from "react";
7681
7943
  import { Fragment as Fragment5, jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
7682
7944
  function ChatSparkIcon() {
7683
7945
  return /* @__PURE__ */ jsxs19(
@@ -7754,20 +8016,47 @@ function ChatSparkIcon() {
7754
8016
  }
7755
8017
  function TabMarkIcon({
7756
8018
  customIconUrl,
7757
- logoUrl
8019
+ logoUrl,
8020
+ chip = false
7758
8021
  }) {
7759
8022
  const custom = customIconUrl?.trim();
7760
8023
  const logo = logoUrl?.trim();
7761
- const [customFailed, setCustomFailed] = useState12(false);
7762
- const [logoFailed, setLogoFailed] = useState12(false);
8024
+ const [customFailed, setCustomFailed] = useState14(false);
8025
+ const [logoFailed, setLogoFailed] = useState14(false);
8026
+ const [markDisplay, setMarkDisplay] = useState14(null);
8027
+ function applyLauncherLogoSize(img, sourceUrl) {
8028
+ if (!chip) return;
8029
+ const display = snapBrandLogoDisplaySize({
8030
+ naturalHeight: img.naturalHeight,
8031
+ naturalWidth: img.naturalWidth,
8032
+ surface: "launcher"
8033
+ });
8034
+ setMarkDisplay({
8035
+ url: sourceUrl,
8036
+ width: display.width,
8037
+ height: display.height,
8038
+ wide: display.wide
8039
+ });
8040
+ }
8041
+ const chipMarkStyle = chip && markDisplay ? {
8042
+ width: `${markDisplay.width}px`,
8043
+ height: `${markDisplay.height}px`
8044
+ } : void 0;
7763
8045
  if (custom && !customFailed) {
7764
8046
  return /* @__PURE__ */ jsx20(
7765
8047
  "img",
7766
8048
  {
7767
8049
  alt: "",
7768
8050
  "aria-hidden": true,
7769
- className: "assist-edge-tab__custom-icon",
8051
+ className: `assist-edge-tab__custom-icon as-brand-logo-img${chip ? " assist-edge-tab__custom-icon--chip" : ""}`,
7770
8052
  src: custom,
8053
+ decoding: "async",
8054
+ style: markDisplay?.url === custom ? chipMarkStyle : void 0,
8055
+ onLoad: (event) => {
8056
+ if (chip) {
8057
+ applyLauncherLogoSize(event.currentTarget, custom);
8058
+ }
8059
+ },
7771
8060
  onError: () => setCustomFailed(true)
7772
8061
  }
7773
8062
  );
@@ -7778,8 +8067,13 @@ function TabMarkIcon({
7778
8067
  {
7779
8068
  alt: "",
7780
8069
  "aria-hidden": true,
7781
- className: "assist-edge-tab__logo",
8070
+ className: `assist-edge-tab__logo as-brand-logo-img${chip ? " assist-edge-tab__logo--chip" : ""}${chip && markDisplay?.url === logo && markDisplay.wide ? " assist-edge-tab__logo--wide" : ""}`,
7782
8071
  src: logo,
8072
+ decoding: "async",
8073
+ style: markDisplay?.url === logo ? chipMarkStyle : void 0,
8074
+ onLoad: (event) => {
8075
+ applyLauncherLogoSize(event.currentTarget, logo);
8076
+ },
7783
8077
  onError: () => setLogoFailed(true)
7784
8078
  }
7785
8079
  );
@@ -7855,6 +8149,7 @@ function AssistEdgeTab({
7855
8149
  "--tab-along": `${along}%`,
7856
8150
  "--tab-inset": `${inset}px`,
7857
8151
  ...resolvedBrandColor ? { "--as-brand": resolvedBrandColor } : {},
8152
+ ...pill && resolvedBrandColor ? { "--pill-logo-surface": resolvedBrandColor } : {},
7858
8153
  ...brandForeground ? { "--as-visitor-text": brandForeground } : {},
7859
8154
  ...resolvedBorderColor ? { "--as-border": resolvedBorderColor } : {},
7860
8155
  ...fontFamily ? { "--as-font-display": fontFamily } : {},
@@ -7887,6 +8182,7 @@ function AssistEdgeTab({
7887
8182
  children: /* @__PURE__ */ jsx20(
7888
8183
  TabMarkIcon,
7889
8184
  {
8185
+ chip: true,
7890
8186
  customIconUrl,
7891
8187
  logoUrl
7892
8188
  },
@@ -7902,6 +8198,7 @@ function AssistEdgeTab({
7902
8198
  /* @__PURE__ */ jsx20("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: /* @__PURE__ */ jsx20(
7903
8199
  TabMarkIcon,
7904
8200
  {
8201
+ chip: true,
7905
8202
  customIconUrl,
7906
8203
  logoUrl
7907
8204
  },
@@ -7919,6 +8216,7 @@ function AssistEdgeTab({
7919
8216
  /* @__PURE__ */ jsx20("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: /* @__PURE__ */ jsx20(
7920
8217
  TabMarkIcon,
7921
8218
  {
8219
+ chip: true,
7922
8220
  customIconUrl,
7923
8221
  logoUrl
7924
8222
  },
@@ -7989,10 +8287,10 @@ function sendAgentAnswerFeedback(eventUrl, event) {
7989
8287
  }
7990
8288
 
7991
8289
  // src/react/components/AgentWidget/AgentWidget.tsx
7992
- import { useEffect as useEffect11, useRef as useRef9, useState as useState14 } from "react";
8290
+ import { useEffect as useEffect12, useRef as useRef9, useState as useState16 } from "react";
7993
8291
 
7994
8292
  // src/react/page-shift.ts
7995
- import { useEffect as useEffect9 } from "react";
8293
+ import { useEffect as useEffect10 } from "react";
7996
8294
  var PAGE_SHIFT_CLASS = "webless-agent-page-shift";
7997
8295
  var DEFAULT_RAIL_WIDTH_PX = 450;
7998
8296
  function shouldApplyPageShift(input) {
@@ -8044,7 +8342,7 @@ function clearPageMargin() {
8044
8342
  }
8045
8343
  function usePageShift(input) {
8046
8344
  const { active, railSlotRef } = input;
8047
- useEffect9(() => {
8345
+ useEffect10(() => {
8048
8346
  if (typeof document === "undefined") {
8049
8347
  return;
8050
8348
  }
@@ -8072,12 +8370,12 @@ function usePageShift(input) {
8072
8370
  }
8073
8371
 
8074
8372
  // src/react/hooks/useIsMobile.ts
8075
- import { useEffect as useEffect10, useState as useState13 } from "react";
8373
+ import { useEffect as useEffect11, useState as useState15 } from "react";
8076
8374
  function useIsMobile(breakpoint = 767) {
8077
- const [isMobile, setIsMobile] = useState13(
8375
+ const [isMobile, setIsMobile] = useState15(
8078
8376
  () => typeof window !== "undefined" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
8079
8377
  );
8080
- useEffect10(() => {
8378
+ useEffect11(() => {
8081
8379
  const media = window.matchMedia(`(max-width: ${breakpoint}px)`);
8082
8380
  const onChange = () => setIsMobile(media.matches);
8083
8381
  onChange();
@@ -8109,8 +8407,8 @@ function AgentWidget({
8109
8407
  const isMobile = useIsMobile();
8110
8408
  const placement = normalizeAgentPlacement(placementInput);
8111
8409
  const railSlotRef = useRef9(null);
8112
- const [railCollapsed, setRailCollapsed] = useState14(defaultCollapsed);
8113
- const [railExpanded, setRailExpanded] = useState14(false);
8410
+ const [railCollapsed, setRailCollapsed] = useState16(defaultCollapsed);
8411
+ const [railExpanded, setRailExpanded] = useState16(false);
8114
8412
  const pageShiftActive = shouldApplyPageShift({
8115
8413
  pageShift,
8116
8414
  isMobile,
@@ -8165,7 +8463,7 @@ function AgentWidget({
8165
8463
  } : {},
8166
8464
  ...branding?.colors?.border ? { border: branding.colors.border } : {}
8167
8465
  };
8168
- useEffect11(() => {
8466
+ useEffect12(() => {
8169
8467
  if (!registerPanelController) return;
8170
8468
  registerAgentPanelController(customerId, {
8171
8469
  open: () => setRailCollapsed(false),
@@ -8200,7 +8498,7 @@ function AgentWidget({
8200
8498
  })
8201
8499
  );
8202
8500
  }
8203
- useEffect11(() => {
8501
+ useEffect12(() => {
8204
8502
  if (railCollapsed) return;
8205
8503
  const handleKeyDown = (event) => {
8206
8504
  if (event.key === "Tab" && (isMobile || railExpanded)) {
@@ -8347,4 +8645,4 @@ export {
8347
8645
  sendAgentAnswerFeedback,
8348
8646
  AgentWidget
8349
8647
  };
8350
- //# sourceMappingURL=chunk-WUUGIP4Y.js.map
8648
+ //# sourceMappingURL=chunk-P6ZM4BIU.js.map