@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.
- package/README.md +2 -2
- package/dist/{chunk-WUUGIP4Y.js → chunk-P6ZM4BIU.js} +526 -228
- package/dist/chunk-P6ZM4BIU.js.map +1 -0
- package/dist/embed.cjs +569 -271
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.css +424 -112
- package/dist/embed.css.map +1 -1
- package/dist/embed.js +1 -1
- package/dist/react.cjs +571 -273
- package/dist/react.cjs.map +1 -1
- package/dist/react.css +424 -112
- package/dist/react.css.map +1 -1
- package/dist/react.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-WUUGIP4Y.js.map +0 -1
package/dist/embed.cjs
CHANGED
|
@@ -64,7 +64,7 @@ function submitAgentPanel(customerId, message, options) {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
// src/react/components/AgentWidget/AgentWidget.tsx
|
|
67
|
-
var
|
|
67
|
+
var import_react20 = require("react");
|
|
68
68
|
|
|
69
69
|
// src/react/page-shift.ts
|
|
70
70
|
var import_react = require("react");
|
|
@@ -4221,7 +4221,7 @@ function normalizeAgentPlacement(placement) {
|
|
|
4221
4221
|
}
|
|
4222
4222
|
|
|
4223
4223
|
// src/react/components/AgentRail/AgentRail.tsx
|
|
4224
|
-
var
|
|
4224
|
+
var import_react18 = require("react");
|
|
4225
4225
|
|
|
4226
4226
|
// src/react/types/conversation.ts
|
|
4227
4227
|
var defaultAgentRailTheme = {
|
|
@@ -4506,44 +4506,108 @@ function AgentActivityBubble({
|
|
|
4506
4506
|
// src/react/components/LearnMore/LearnMore.tsx
|
|
4507
4507
|
var import_react7 = require("react");
|
|
4508
4508
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
4509
|
+
function QuestionIcon() {
|
|
4510
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
4511
|
+
"svg",
|
|
4512
|
+
{
|
|
4513
|
+
viewBox: "0 0 24 24",
|
|
4514
|
+
width: "18",
|
|
4515
|
+
height: "18",
|
|
4516
|
+
fill: "none",
|
|
4517
|
+
stroke: "currentColor",
|
|
4518
|
+
strokeWidth: "1.5",
|
|
4519
|
+
strokeLinecap: "round",
|
|
4520
|
+
strokeLinejoin: "round",
|
|
4521
|
+
"aria-hidden": "true",
|
|
4522
|
+
children: [
|
|
4523
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z" }),
|
|
4524
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }),
|
|
4525
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 17h.01" })
|
|
4526
|
+
]
|
|
4527
|
+
}
|
|
4528
|
+
);
|
|
4529
|
+
}
|
|
4509
4530
|
function LearnMore({
|
|
4510
4531
|
results,
|
|
4511
4532
|
disabled,
|
|
4512
4533
|
onSelect
|
|
4513
4534
|
}) {
|
|
4514
4535
|
const headingId = (0, import_react7.useId)();
|
|
4536
|
+
const panelId = (0, import_react7.useId)();
|
|
4537
|
+
const [open, setOpen] = (0, import_react7.useState)(true);
|
|
4515
4538
|
const questions = [
|
|
4516
4539
|
...new Set(results.flatMap((result) => result.suggestions ?? []))
|
|
4517
4540
|
].slice(0, 3);
|
|
4518
4541
|
if (!questions.length) return null;
|
|
4519
4542
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "learn-more", "aria-labelledby": headingId, children: [
|
|
4520
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { id: headingId, className: "learn-more__heading", children:
|
|
4521
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ul", { className: "learn-more__questions", children: questions.map((question) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
4543
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { id: headingId, className: "learn-more__heading", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
4522
4544
|
"button",
|
|
4523
4545
|
{
|
|
4524
4546
|
type: "button",
|
|
4525
|
-
|
|
4526
|
-
|
|
4547
|
+
className: "learn-more__toggle",
|
|
4548
|
+
"aria-expanded": open,
|
|
4549
|
+
"aria-controls": panelId,
|
|
4550
|
+
onClick: () => setOpen((current) => !current),
|
|
4527
4551
|
children: [
|
|
4528
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children:
|
|
4552
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "Learn more" }),
|
|
4529
4553
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
4530
4554
|
"svg",
|
|
4531
4555
|
{
|
|
4532
|
-
|
|
4556
|
+
className: "learn-more__chevron",
|
|
4557
|
+
viewBox: "0 0 16 16",
|
|
4533
4558
|
fill: "none",
|
|
4534
|
-
stroke: "currentColor",
|
|
4535
|
-
strokeWidth: "1.5",
|
|
4536
4559
|
"aria-hidden": "true",
|
|
4537
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
4560
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
4561
|
+
"path",
|
|
4562
|
+
{
|
|
4563
|
+
d: "M4 6.5l4 4 4-4",
|
|
4564
|
+
stroke: "currentColor",
|
|
4565
|
+
strokeWidth: "1.6",
|
|
4566
|
+
strokeLinecap: "round",
|
|
4567
|
+
strokeLinejoin: "round"
|
|
4568
|
+
}
|
|
4569
|
+
)
|
|
4538
4570
|
}
|
|
4539
4571
|
)
|
|
4540
4572
|
]
|
|
4541
4573
|
}
|
|
4542
|
-
) },
|
|
4574
|
+
) }),
|
|
4575
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
4576
|
+
"div",
|
|
4577
|
+
{
|
|
4578
|
+
id: panelId,
|
|
4579
|
+
className: `learn-more__panel${open ? " learn-more__panel--open" : ""}`,
|
|
4580
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "learn-more__panel-inner", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ul", { className: "learn-more__questions", children: questions.map((question) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
4581
|
+
"button",
|
|
4582
|
+
{
|
|
4583
|
+
type: "button",
|
|
4584
|
+
disabled,
|
|
4585
|
+
onClick: () => onSelect(question),
|
|
4586
|
+
children: [
|
|
4587
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "learn-more__question-icon", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(QuestionIcon, {}) }),
|
|
4588
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "learn-more__question-text", children: question }),
|
|
4589
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
4590
|
+
"svg",
|
|
4591
|
+
{
|
|
4592
|
+
className: "learn-more__question-arrow",
|
|
4593
|
+
viewBox: "0 0 24 24",
|
|
4594
|
+
fill: "none",
|
|
4595
|
+
stroke: "currentColor",
|
|
4596
|
+
strokeWidth: "1.5",
|
|
4597
|
+
"aria-hidden": "true",
|
|
4598
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M4 12h16m-7-7 7 7-7 7" })
|
|
4599
|
+
}
|
|
4600
|
+
)
|
|
4601
|
+
]
|
|
4602
|
+
}
|
|
4603
|
+
) }, question)) }) })
|
|
4604
|
+
}
|
|
4605
|
+
)
|
|
4543
4606
|
] });
|
|
4544
4607
|
}
|
|
4545
4608
|
|
|
4546
4609
|
// src/react/components/SearchReferences/SearchReferences.tsx
|
|
4610
|
+
var import_react8 = require("react");
|
|
4547
4611
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
4548
4612
|
function SiteIcon() {
|
|
4549
4613
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
@@ -4564,6 +4628,27 @@ function SiteIcon() {
|
|
|
4564
4628
|
}
|
|
4565
4629
|
);
|
|
4566
4630
|
}
|
|
4631
|
+
function SourceFavicon({ url }) {
|
|
4632
|
+
const [failed, setFailed] = (0, import_react8.useState)(false);
|
|
4633
|
+
let faviconUrl = null;
|
|
4634
|
+
if (url) {
|
|
4635
|
+
try {
|
|
4636
|
+
faviconUrl = `${new URL(url).origin}/favicon.ico`;
|
|
4637
|
+
} catch {
|
|
4638
|
+
faviconUrl = null;
|
|
4639
|
+
}
|
|
4640
|
+
}
|
|
4641
|
+
if (!faviconUrl || failed) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SiteIcon, {});
|
|
4642
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
4643
|
+
"img",
|
|
4644
|
+
{
|
|
4645
|
+
src: faviconUrl,
|
|
4646
|
+
alt: "",
|
|
4647
|
+
loading: "lazy",
|
|
4648
|
+
onError: () => setFailed(true)
|
|
4649
|
+
}
|
|
4650
|
+
);
|
|
4651
|
+
}
|
|
4567
4652
|
function searchSources(results) {
|
|
4568
4653
|
const seenSources = /* @__PURE__ */ new Set();
|
|
4569
4654
|
return results.flatMap((result) => result.sources).flatMap((source) => {
|
|
@@ -4603,28 +4688,25 @@ function SearchReferences({
|
|
|
4603
4688
|
] }) : null,
|
|
4604
4689
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "search-references__list", children: sources.map((source) => {
|
|
4605
4690
|
const content = /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
4606
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "search-references__icon", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
4607
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
),
|
|
4616
|
-
source.url ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "search-references__domain", children: new URL(source.url).hostname.replace(/^www\./u, "") }) : null
|
|
4617
|
-
] }),
|
|
4691
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "search-references__icon", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SourceFavicon, { url: source.url }) }),
|
|
4692
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
4693
|
+
"span",
|
|
4694
|
+
{
|
|
4695
|
+
className: "search-references__title",
|
|
4696
|
+
title: source.title,
|
|
4697
|
+
children: source.title
|
|
4698
|
+
}
|
|
4699
|
+
),
|
|
4618
4700
|
source.url ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
4619
4701
|
"svg",
|
|
4620
4702
|
{
|
|
4621
|
-
className: "search-
|
|
4703
|
+
className: "search-references__row-arrow",
|
|
4622
4704
|
viewBox: "0 0 24 24",
|
|
4623
4705
|
fill: "none",
|
|
4624
4706
|
stroke: "currentColor",
|
|
4625
4707
|
strokeWidth: "1.5",
|
|
4626
4708
|
"aria-hidden": "true",
|
|
4627
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "
|
|
4709
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M4 12h16m-7-7 7 7-7 7" })
|
|
4628
4710
|
}
|
|
4629
4711
|
) : null
|
|
4630
4712
|
] });
|
|
@@ -4657,17 +4739,17 @@ function SearchReferences({
|
|
|
4657
4739
|
}
|
|
4658
4740
|
|
|
4659
4741
|
// src/react/components/AnswerReceiptDialog/AnswerReceiptDialog.tsx
|
|
4660
|
-
var
|
|
4742
|
+
var import_react10 = require("react");
|
|
4661
4743
|
var import_react_dom = require("react-dom");
|
|
4662
4744
|
|
|
4663
4745
|
// src/react/components/AgentRail/AgentRailOverlayContext.tsx
|
|
4664
|
-
var
|
|
4665
|
-
var AgentRailOverlayContext = (0,
|
|
4746
|
+
var import_react9 = require("react");
|
|
4747
|
+
var AgentRailOverlayContext = (0, import_react9.createContext)(null);
|
|
4666
4748
|
function useAgentRailPortalRoots() {
|
|
4667
|
-
return (0,
|
|
4749
|
+
return (0, import_react9.useContext)(AgentRailOverlayContext);
|
|
4668
4750
|
}
|
|
4669
4751
|
function useAgentRailMenuPortalRoot() {
|
|
4670
|
-
return (0,
|
|
4752
|
+
return (0, import_react9.useContext)(AgentRailOverlayContext)?.railRef ?? null;
|
|
4671
4753
|
}
|
|
4672
4754
|
|
|
4673
4755
|
// src/react/components/AnswerReceiptDialog/AnswerReceiptDialog.tsx
|
|
@@ -4692,13 +4774,13 @@ function AnswerReceiptDialog({
|
|
|
4692
4774
|
summary,
|
|
4693
4775
|
children
|
|
4694
4776
|
}) {
|
|
4695
|
-
const titleId = (0,
|
|
4777
|
+
const titleId = (0, import_react10.useId)();
|
|
4696
4778
|
const portalRoots = useAgentRailPortalRoots();
|
|
4697
4779
|
const overlayRoot = portalRoots?.overlayRef ?? null;
|
|
4698
|
-
const cardRef = (0,
|
|
4699
|
-
const closeButtonRef = (0,
|
|
4700
|
-
const previouslyFocusedRef = (0,
|
|
4701
|
-
(0,
|
|
4780
|
+
const cardRef = (0, import_react10.useRef)(null);
|
|
4781
|
+
const closeButtonRef = (0, import_react10.useRef)(null);
|
|
4782
|
+
const previouslyFocusedRef = (0, import_react10.useRef)(null);
|
|
4783
|
+
(0, import_react10.useEffect)(() => {
|
|
4702
4784
|
previouslyFocusedRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
4703
4785
|
closeButtonRef.current?.focus({ preventScroll: true });
|
|
4704
4786
|
const handleKeyDown = (event) => {
|
|
@@ -4774,7 +4856,7 @@ function AnswerReceiptDialog({
|
|
|
4774
4856
|
}
|
|
4775
4857
|
|
|
4776
4858
|
// src/react/components/Composer/Composer.tsx
|
|
4777
|
-
var
|
|
4859
|
+
var import_react11 = require("react");
|
|
4778
4860
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
4779
4861
|
var FORM_SUBMITTED_MESSAGE = "Shared my details";
|
|
4780
4862
|
function SendIcon() {
|
|
@@ -4836,21 +4918,35 @@ function Composer({
|
|
|
4836
4918
|
allowFormResume = true,
|
|
4837
4919
|
onSubmit
|
|
4838
4920
|
}) {
|
|
4839
|
-
const [value, setValue] = (0,
|
|
4840
|
-
const [draft, setDraft] = (0,
|
|
4841
|
-
const
|
|
4842
|
-
const
|
|
4843
|
-
const
|
|
4844
|
-
const
|
|
4921
|
+
const [value, setValue] = (0, import_react11.useState)("");
|
|
4922
|
+
const [draft, setDraft] = (0, import_react11.useState)(() => createDraft(form));
|
|
4923
|
+
const [multiline, setMultiline] = (0, import_react11.useState)(false);
|
|
4924
|
+
const inputRef = (0, import_react11.useRef)(null);
|
|
4925
|
+
const firstFieldRef = (0, import_react11.useRef)(null);
|
|
4926
|
+
const formRef = (0, import_react11.useRef)(null);
|
|
4927
|
+
const formId = (0, import_react11.useId)();
|
|
4845
4928
|
if (form && form.id !== draft.form?.id) setDraft(createDraft(form));
|
|
4846
4929
|
const savedForm = allowFormResume && !draft.submitted ? draft.form : null;
|
|
4847
4930
|
const activeForm = !disabled && draft.expanded ? savedForm : null;
|
|
4848
4931
|
const canSend = !disabled && Boolean(value.trim() || activeForm);
|
|
4849
|
-
(0,
|
|
4932
|
+
(0, import_react11.useEffect)(() => {
|
|
4850
4933
|
if (activeForm) firstFieldRef.current?.focus();
|
|
4851
4934
|
else if ((savedForm || draft.submitted) && !disabled)
|
|
4852
4935
|
inputRef.current?.focus();
|
|
4853
4936
|
}, [activeForm?.id, disabled, savedForm?.id, draft.submitted]);
|
|
4937
|
+
(0, import_react11.useEffect)(() => {
|
|
4938
|
+
const input = inputRef.current;
|
|
4939
|
+
if (!input) return;
|
|
4940
|
+
const check = () => {
|
|
4941
|
+
const style = window.getComputedStyle(input);
|
|
4942
|
+
const singleLine = (parseFloat(style.lineHeight) || 20) + parseFloat(style.paddingTop) + parseFloat(style.paddingBottom) + 2;
|
|
4943
|
+
setMultiline(input.offsetHeight > singleLine);
|
|
4944
|
+
};
|
|
4945
|
+
check();
|
|
4946
|
+
const observer = new ResizeObserver(check);
|
|
4947
|
+
observer.observe(input);
|
|
4948
|
+
return () => observer.disconnect();
|
|
4949
|
+
}, []);
|
|
4854
4950
|
function collapseForm() {
|
|
4855
4951
|
setDraft((current) => ({ ...current, expanded: false }));
|
|
4856
4952
|
}
|
|
@@ -4955,7 +5051,8 @@ function Composer({
|
|
|
4955
5051
|
className: [
|
|
4956
5052
|
"composer",
|
|
4957
5053
|
variant === "dock" ? "composer--dock" : "",
|
|
4958
|
-
activeForm ? "composer--form" : ""
|
|
5054
|
+
activeForm ? "composer--form" : "",
|
|
5055
|
+
multiline ? "composer--multiline" : ""
|
|
4959
5056
|
].filter(Boolean).join(" "),
|
|
4960
5057
|
onSubmit: handleSubmit,
|
|
4961
5058
|
children: [
|
|
@@ -5107,10 +5204,10 @@ function FollowUpChips({
|
|
|
5107
5204
|
}
|
|
5108
5205
|
|
|
5109
5206
|
// src/react/components/MessageBubble/MessageBubble.tsx
|
|
5110
|
-
var
|
|
5207
|
+
var import_react13 = require("react");
|
|
5111
5208
|
|
|
5112
5209
|
// src/react/components/BookingCard/BookingCard.tsx
|
|
5113
|
-
var
|
|
5210
|
+
var import_react12 = require("react");
|
|
5114
5211
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
5115
5212
|
var BOOKING_STEPS = [
|
|
5116
5213
|
{ id: "date", label: "Date" },
|
|
@@ -5165,27 +5262,27 @@ function InteractiveBookingCard({
|
|
|
5165
5262
|
offer,
|
|
5166
5263
|
onBook
|
|
5167
5264
|
}) {
|
|
5168
|
-
const fieldId = (0,
|
|
5265
|
+
const fieldId = (0, import_react12.useId)();
|
|
5169
5266
|
const defaultType = offer.eventTypes[0]?.uri ?? offer.slots[0]?.eventTypeUri ?? "";
|
|
5170
|
-
const [step, setStep] = (0,
|
|
5171
|
-
const [eventTypeUri, setEventTypeUri] = (0,
|
|
5172
|
-
const [selectedDate, setSelectedDate] = (0,
|
|
5173
|
-
const [startTime, setStartTime] = (0,
|
|
5174
|
-
const [name, setName] = (0,
|
|
5175
|
-
const [email, setEmail] = (0,
|
|
5176
|
-
const activeStepRef = (0,
|
|
5177
|
-
const previousStepRef = (0,
|
|
5267
|
+
const [step, setStep] = (0, import_react12.useState)("date");
|
|
5268
|
+
const [eventTypeUri, setEventTypeUri] = (0, import_react12.useState)(defaultType);
|
|
5269
|
+
const [selectedDate, setSelectedDate] = (0, import_react12.useState)("");
|
|
5270
|
+
const [startTime, setStartTime] = (0, import_react12.useState)("");
|
|
5271
|
+
const [name, setName] = (0, import_react12.useState)("");
|
|
5272
|
+
const [email, setEmail] = (0, import_react12.useState)("");
|
|
5273
|
+
const activeStepRef = (0, import_react12.useRef)(null);
|
|
5274
|
+
const previousStepRef = (0, import_react12.useRef)(step);
|
|
5178
5275
|
const stepIndex = BOOKING_STEPS.findIndex((item) => item.id === step);
|
|
5179
|
-
(0,
|
|
5276
|
+
(0, import_react12.useEffect)(() => {
|
|
5180
5277
|
if (previousStepRef.current === step) return;
|
|
5181
5278
|
previousStepRef.current = step;
|
|
5182
5279
|
activeStepRef.current?.scrollIntoView({ block: "nearest" });
|
|
5183
5280
|
}, [step]);
|
|
5184
|
-
const slots = (0,
|
|
5281
|
+
const slots = (0, import_react12.useMemo)(
|
|
5185
5282
|
() => bookingSlotsForEventType(offer.slots, eventTypeUri),
|
|
5186
5283
|
[eventTypeUri, offer.slots]
|
|
5187
5284
|
);
|
|
5188
|
-
const availableByDate = (0,
|
|
5285
|
+
const availableByDate = (0, import_react12.useMemo)(() => {
|
|
5189
5286
|
const next = /* @__PURE__ */ new Map();
|
|
5190
5287
|
for (const slot of slots) {
|
|
5191
5288
|
const key = slotDateKey(slot.startTime);
|
|
@@ -5193,7 +5290,7 @@ function InteractiveBookingCard({
|
|
|
5193
5290
|
}
|
|
5194
5291
|
return next;
|
|
5195
5292
|
}, [slots]);
|
|
5196
|
-
const [visibleMonth, setVisibleMonth] = (0,
|
|
5293
|
+
const [visibleMonth, setVisibleMonth] = (0, import_react12.useState)(
|
|
5197
5294
|
() => firstAvailableBookingMonth(slots)
|
|
5198
5295
|
);
|
|
5199
5296
|
function selectEventType(nextType) {
|
|
@@ -5206,7 +5303,7 @@ function InteractiveBookingCard({
|
|
|
5206
5303
|
)
|
|
5207
5304
|
);
|
|
5208
5305
|
}
|
|
5209
|
-
const daySlots = (0,
|
|
5306
|
+
const daySlots = (0, import_react12.useMemo)(
|
|
5210
5307
|
() => slots.filter((slot) => slotDateKey(slot.startTime) === selectedDate),
|
|
5211
5308
|
[selectedDate, slots]
|
|
5212
5309
|
);
|
|
@@ -5215,7 +5312,7 @@ function InteractiveBookingCard({
|
|
|
5215
5312
|
);
|
|
5216
5313
|
const selectedSample = availableByDate.get(selectedDate) ?? startTime;
|
|
5217
5314
|
const timeZone = formatSlotTimeZone(slots[0]?.startTime ?? selectedSample);
|
|
5218
|
-
const weekdays = (0,
|
|
5315
|
+
const weekdays = (0, import_react12.useMemo)(() => weekdayLabels(), []);
|
|
5219
5316
|
const cells = calendarCells(visibleMonth.year, visibleMonth.month);
|
|
5220
5317
|
const canPrevMonth = [...availableByDate.keys()].some((key) => {
|
|
5221
5318
|
const month = monthFromKey(key);
|
|
@@ -5486,6 +5583,37 @@ function InteractiveBookingCard({
|
|
|
5486
5583
|
// src/react/components/MessageBubble/MessageBubble.tsx
|
|
5487
5584
|
var import_streamdown = require("streamdown");
|
|
5488
5585
|
|
|
5586
|
+
// src/react/lib/brand-logo-display.ts
|
|
5587
|
+
var BRAND_LOGO_LAYOUT = {
|
|
5588
|
+
header: { maxHeight: 20, maxWidth: 96, square: 24 },
|
|
5589
|
+
message: { maxHeight: 18, maxWidth: 80, square: 22 },
|
|
5590
|
+
/** Bottom/mobile launcher pill orb — keep in sync with AssistEdgeTab chip CSS. */
|
|
5591
|
+
launcher: { maxHeight: 24, maxWidth: 104, square: 38 }
|
|
5592
|
+
};
|
|
5593
|
+
function isWideBrandLogo(naturalWidth, naturalHeight) {
|
|
5594
|
+
return naturalWidth > naturalHeight * 1.4;
|
|
5595
|
+
}
|
|
5596
|
+
function snapBrandLogoDisplaySize(input) {
|
|
5597
|
+
const { maxHeight, maxWidth } = BRAND_LOGO_LAYOUT[input.surface];
|
|
5598
|
+
const { naturalWidth, naturalHeight } = input;
|
|
5599
|
+
if (naturalWidth <= 0 || naturalHeight <= 0) {
|
|
5600
|
+
return { width: maxWidth, height: maxHeight, wide: false };
|
|
5601
|
+
}
|
|
5602
|
+
const wide = isWideBrandLogo(naturalWidth, naturalHeight);
|
|
5603
|
+
if (!wide) {
|
|
5604
|
+
const size = BRAND_LOGO_LAYOUT[input.surface].square;
|
|
5605
|
+
return { width: size, height: size, wide: false };
|
|
5606
|
+
}
|
|
5607
|
+
const scale = Math.min(
|
|
5608
|
+
maxHeight / naturalHeight,
|
|
5609
|
+
maxWidth / naturalWidth,
|
|
5610
|
+
1
|
|
5611
|
+
);
|
|
5612
|
+
const height = Math.max(1, Math.round(naturalHeight * scale));
|
|
5613
|
+
const width = Math.max(1, Math.round(naturalWidth * scale));
|
|
5614
|
+
return { width, height, wide: true };
|
|
5615
|
+
}
|
|
5616
|
+
|
|
5489
5617
|
// src/react/lib/resolve-message-url.ts
|
|
5490
5618
|
function resolveMessageUrl(safeUrl, baseUrl) {
|
|
5491
5619
|
if (!safeUrl || !baseUrl) return safeUrl;
|
|
@@ -5548,7 +5676,14 @@ function MessageBubble({
|
|
|
5548
5676
|
onBook
|
|
5549
5677
|
}) {
|
|
5550
5678
|
const resolvedLogoUrl = brandLogoUrl?.trim();
|
|
5551
|
-
const [failedLogoUrl, setFailedLogoUrl] = (0,
|
|
5679
|
+
const [failedLogoUrl, setFailedLogoUrl] = (0, import_react13.useState)(null);
|
|
5680
|
+
const [logoDisplay, setLogoDisplay] = (0, import_react13.useState)(null);
|
|
5681
|
+
(0, import_react13.useEffect)(() => {
|
|
5682
|
+
setFailedLogoUrl(null);
|
|
5683
|
+
}, [resolvedLogoUrl]);
|
|
5684
|
+
const activeLogoDisplay = logoDisplay?.url === resolvedLogoUrl ? logoDisplay : null;
|
|
5685
|
+
const wideLogo = activeLogoDisplay?.wide ?? false;
|
|
5686
|
+
const logoDisplaySize = activeLogoDisplay ? { height: activeLogoDisplay.height, width: activeLogoDisplay.width } : null;
|
|
5552
5687
|
const showBrandLogo = Boolean(resolvedLogoUrl) && failedLogoUrl !== resolvedLogoUrl;
|
|
5553
5688
|
const cards = message.role === "agent" ? extractToolCards(message.text) : [];
|
|
5554
5689
|
const extractedOffers = cards.filter(
|
|
@@ -5569,7 +5704,7 @@ function MessageBubble({
|
|
|
5569
5704
|
className: "message-bubble message-bubble--visitor",
|
|
5570
5705
|
"aria-label": "Message from visitor",
|
|
5571
5706
|
children: [
|
|
5572
|
-
showProvenance ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "message-bubble__speaker", children: "You
|
|
5707
|
+
showProvenance ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "message-bubble__speaker", children: "You" }) : null,
|
|
5573
5708
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "message-bubble__text", children: visitorText })
|
|
5574
5709
|
]
|
|
5575
5710
|
}
|
|
@@ -5633,20 +5768,51 @@ function MessageBubble({
|
|
|
5633
5768
|
className: "message-bubble message-bubble--agent",
|
|
5634
5769
|
"aria-label": "Message from AI assistant",
|
|
5635
5770
|
children: [
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5771
|
+
displayText || message.searchResults?.length ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "message-bubble__agent-stack", children: [
|
|
5772
|
+
showProvenance || showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "message-bubble__agent-header", children: [
|
|
5773
|
+
showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5774
|
+
"span",
|
|
5775
|
+
{
|
|
5776
|
+
className: `message-bubble__agent-avatar${wideLogo ? " message-bubble__agent-avatar--wide" : ""}`,
|
|
5777
|
+
"aria-hidden": "true",
|
|
5778
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5779
|
+
"img",
|
|
5780
|
+
{
|
|
5781
|
+
className: "as-brand-logo-img",
|
|
5782
|
+
src: resolvedLogoUrl,
|
|
5783
|
+
alt: "",
|
|
5784
|
+
decoding: "async",
|
|
5785
|
+
...logoDisplaySize ? {
|
|
5786
|
+
height: logoDisplaySize.height,
|
|
5787
|
+
width: logoDisplaySize.width
|
|
5788
|
+
} : {},
|
|
5789
|
+
onLoad: (event) => {
|
|
5790
|
+
const img = event.currentTarget;
|
|
5791
|
+
const display = snapBrandLogoDisplaySize({
|
|
5792
|
+
naturalHeight: img.naturalHeight,
|
|
5793
|
+
naturalWidth: img.naturalWidth,
|
|
5794
|
+
surface: "message"
|
|
5795
|
+
});
|
|
5796
|
+
if (!resolvedLogoUrl) return;
|
|
5797
|
+
setLogoDisplay({
|
|
5798
|
+
height: display.height,
|
|
5799
|
+
url: resolvedLogoUrl,
|
|
5800
|
+
wide: display.wide,
|
|
5801
|
+
width: display.width
|
|
5802
|
+
});
|
|
5803
|
+
},
|
|
5804
|
+
onError: () => {
|
|
5805
|
+
setFailedLogoUrl(resolvedLogoUrl ?? null);
|
|
5806
|
+
}
|
|
5807
|
+
},
|
|
5808
|
+
resolvedLogoUrl
|
|
5809
|
+
)
|
|
5645
5810
|
}
|
|
5646
|
-
|
|
5647
|
-
|
|
5811
|
+
) : null,
|
|
5812
|
+
showProvenance ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "message-bubble__speaker", children: "AI assistant" }) : null
|
|
5813
|
+
] }) : null,
|
|
5648
5814
|
agentText
|
|
5649
|
-
] }) :
|
|
5815
|
+
] }) : null,
|
|
5650
5816
|
offers.map((nextOffer, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5651
5817
|
BookingCard,
|
|
5652
5818
|
{
|
|
@@ -5663,7 +5829,7 @@ function MessageBubble({
|
|
|
5663
5829
|
}
|
|
5664
5830
|
|
|
5665
5831
|
// src/react/components/MessageActions/MessageActions.tsx
|
|
5666
|
-
var
|
|
5832
|
+
var import_react14 = require("react");
|
|
5667
5833
|
var import_react_dom2 = require("react-dom");
|
|
5668
5834
|
|
|
5669
5835
|
// src/react/lib/speech.ts
|
|
@@ -6059,26 +6225,26 @@ function MessageActions({
|
|
|
6059
6225
|
speechText
|
|
6060
6226
|
}) {
|
|
6061
6227
|
const menuPortalRoot = useAgentRailMenuPortalRoot();
|
|
6062
|
-
const [copied, setCopied] = (0,
|
|
6063
|
-
const [rating, setRating] = (0,
|
|
6064
|
-
const [menuOpen, setMenuOpen] = (0,
|
|
6065
|
-
const [menuPosition, setMenuPosition] = (0,
|
|
6066
|
-
const [speaking, setSpeaking] = (0,
|
|
6067
|
-
const [speechSupported, setSpeechSupported] = (0,
|
|
6068
|
-
const copyTimerRef = (0,
|
|
6069
|
-
const menuRef = (0,
|
|
6070
|
-
const portaledMenuRef = (0,
|
|
6071
|
-
const moreButtonRef = (0,
|
|
6228
|
+
const [copied, setCopied] = (0, import_react14.useState)(false);
|
|
6229
|
+
const [rating, setRating] = (0, import_react14.useState)(null);
|
|
6230
|
+
const [menuOpen, setMenuOpen] = (0, import_react14.useState)(false);
|
|
6231
|
+
const [menuPosition, setMenuPosition] = (0, import_react14.useState)(null);
|
|
6232
|
+
const [speaking, setSpeaking] = (0, import_react14.useState)(false);
|
|
6233
|
+
const [speechSupported, setSpeechSupported] = (0, import_react14.useState)(null);
|
|
6234
|
+
const copyTimerRef = (0, import_react14.useRef)(null);
|
|
6235
|
+
const menuRef = (0, import_react14.useRef)(null);
|
|
6236
|
+
const portaledMenuRef = (0, import_react14.useRef)(null);
|
|
6237
|
+
const moreButtonRef = (0, import_react14.useRef)(null);
|
|
6072
6238
|
const answeredLabel = formatAnsweredAt(answeredAt ?? 0);
|
|
6073
6239
|
const resolvedSpeechText = speechText ?? toSpeechText(copyText);
|
|
6074
6240
|
const canOpenReceipt = Boolean(receiptSteps) && Boolean(onOpenReceipt);
|
|
6075
6241
|
const readAloudEligible = Boolean(readAloud && resolvedSpeechText);
|
|
6076
6242
|
const canReadAloud = readAloudEligible && speechSupported === true;
|
|
6077
6243
|
const showMenu = canOpenReceipt || (speechSupported === null ? readAloudEligible : canReadAloud);
|
|
6078
|
-
(0,
|
|
6244
|
+
(0, import_react14.useLayoutEffect)(() => {
|
|
6079
6245
|
setSpeechSupported(isSpeechSupported());
|
|
6080
6246
|
}, []);
|
|
6081
|
-
(0,
|
|
6247
|
+
(0, import_react14.useLayoutEffect)(() => {
|
|
6082
6248
|
if (!menuOpen || !moreButtonRef.current || !portaledMenuRef.current) {
|
|
6083
6249
|
setMenuPosition(null);
|
|
6084
6250
|
return;
|
|
@@ -6095,7 +6261,7 @@ function MessageActions({
|
|
|
6095
6261
|
})
|
|
6096
6262
|
);
|
|
6097
6263
|
}, [menuOpen, menuPortalRoot]);
|
|
6098
|
-
(0,
|
|
6264
|
+
(0, import_react14.useEffect)(() => {
|
|
6099
6265
|
const unsubscribe = subscribeSpeechInterrupts(() => setSpeaking(false));
|
|
6100
6266
|
return () => {
|
|
6101
6267
|
unsubscribe();
|
|
@@ -6105,7 +6271,7 @@ function MessageActions({
|
|
|
6105
6271
|
stopSpeech();
|
|
6106
6272
|
};
|
|
6107
6273
|
}, []);
|
|
6108
|
-
(0,
|
|
6274
|
+
(0, import_react14.useEffect)(() => {
|
|
6109
6275
|
if (!menuOpen) return;
|
|
6110
6276
|
const handlePointerDown = (event) => {
|
|
6111
6277
|
const target = event.target;
|
|
@@ -6274,7 +6440,7 @@ function MessageActions({
|
|
|
6274
6440
|
}
|
|
6275
6441
|
|
|
6276
6442
|
// src/react/components/HumanInputCard/HumanInputCard.tsx
|
|
6277
|
-
var
|
|
6443
|
+
var import_react16 = require("react");
|
|
6278
6444
|
|
|
6279
6445
|
// src/react/components/ConfirmationCard/ConfirmationCard.tsx
|
|
6280
6446
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
@@ -6316,7 +6482,7 @@ function ConfirmationCard({
|
|
|
6316
6482
|
}
|
|
6317
6483
|
|
|
6318
6484
|
// src/react/components/ToolInputCard/ToolInputCard.tsx
|
|
6319
|
-
var
|
|
6485
|
+
var import_react15 = require("react");
|
|
6320
6486
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
6321
6487
|
function isRecord5(value) {
|
|
6322
6488
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -6647,11 +6813,11 @@ function ToolInputCard({
|
|
|
6647
6813
|
surface,
|
|
6648
6814
|
onSubmit
|
|
6649
6815
|
}) {
|
|
6650
|
-
const [values, setValues] = (0,
|
|
6816
|
+
const [values, setValues] = (0, import_react15.useState)(
|
|
6651
6817
|
() => initialValues(surface)
|
|
6652
6818
|
);
|
|
6653
|
-
const [touched, setTouched] = (0,
|
|
6654
|
-
const [submitted, setSubmitted] = (0,
|
|
6819
|
+
const [touched, setTouched] = (0, import_react15.useState)(() => /* @__PURE__ */ new Set());
|
|
6820
|
+
const [submitted, setSubmitted] = (0, import_react15.useState)(false);
|
|
6655
6821
|
const errors = Object.fromEntries(
|
|
6656
6822
|
surface.fields.map((field) => [
|
|
6657
6823
|
field.path,
|
|
@@ -6744,7 +6910,7 @@ function HumanInputCard({
|
|
|
6744
6910
|
request,
|
|
6745
6911
|
onRespond
|
|
6746
6912
|
}) {
|
|
6747
|
-
const [text3, setText] = (0,
|
|
6913
|
+
const [text3, setText] = (0, import_react16.useState)("");
|
|
6748
6914
|
const options = request.options ?? [];
|
|
6749
6915
|
const showText = request.display === "text" || request.allowFreeform && options.length === 0;
|
|
6750
6916
|
if (request.ui) {
|
|
@@ -6802,7 +6968,7 @@ function HumanInputCard({
|
|
|
6802
6968
|
}
|
|
6803
6969
|
|
|
6804
6970
|
// src/react/components/LocationConsent/LocationConsent.tsx
|
|
6805
|
-
var
|
|
6971
|
+
var import_react17 = require("react");
|
|
6806
6972
|
|
|
6807
6973
|
// src/runtime/location-consent.ts
|
|
6808
6974
|
function isLocationConsentRequest(request) {
|
|
@@ -6850,16 +7016,16 @@ function LocationConsent({
|
|
|
6850
7016
|
request,
|
|
6851
7017
|
onRespond
|
|
6852
7018
|
}) {
|
|
6853
|
-
const [preference, setPreference] = (0,
|
|
6854
|
-
const [locating, setLocating] = (0,
|
|
6855
|
-
const [error, setError] = (0,
|
|
6856
|
-
const respond = (0,
|
|
6857
|
-
const answered = (0,
|
|
7019
|
+
const [preference, setPreference] = (0, import_react17.useState)("unset");
|
|
7020
|
+
const [locating, setLocating] = (0, import_react17.useState)(false);
|
|
7021
|
+
const [error, setError] = (0, import_react17.useState)(null);
|
|
7022
|
+
const respond = (0, import_react17.useRef)(onRespond);
|
|
7023
|
+
const answered = (0, import_react17.useRef)(null);
|
|
6858
7024
|
const requestId = request?.requestId;
|
|
6859
|
-
(0,
|
|
7025
|
+
(0, import_react17.useEffect)(() => {
|
|
6860
7026
|
respond.current = onRespond;
|
|
6861
7027
|
}, [onRespond]);
|
|
6862
|
-
(0,
|
|
7028
|
+
(0, import_react17.useEffect)(() => {
|
|
6863
7029
|
if (!requestId || preference === "unset" || answered.current === requestId || !respond.current)
|
|
6864
7030
|
return;
|
|
6865
7031
|
if (preference === "off") {
|
|
@@ -7151,16 +7317,28 @@ function CloseIcon2() {
|
|
|
7151
7317
|
) });
|
|
7152
7318
|
}
|
|
7153
7319
|
function NewChatIcon() {
|
|
7154
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.
|
|
7155
|
-
|
|
7156
|
-
|
|
7157
|
-
|
|
7158
|
-
|
|
7159
|
-
|
|
7160
|
-
|
|
7161
|
-
|
|
7162
|
-
|
|
7163
|
-
|
|
7320
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
|
|
7321
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7322
|
+
"path",
|
|
7323
|
+
{
|
|
7324
|
+
d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.86L21 8",
|
|
7325
|
+
stroke: "currentColor",
|
|
7326
|
+
strokeWidth: "2",
|
|
7327
|
+
strokeLinecap: "round",
|
|
7328
|
+
strokeLinejoin: "round"
|
|
7329
|
+
}
|
|
7330
|
+
),
|
|
7331
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7332
|
+
"path",
|
|
7333
|
+
{
|
|
7334
|
+
d: "M21 3v5h-5",
|
|
7335
|
+
stroke: "currentColor",
|
|
7336
|
+
strokeWidth: "2",
|
|
7337
|
+
strokeLinecap: "round",
|
|
7338
|
+
strokeLinejoin: "round"
|
|
7339
|
+
}
|
|
7340
|
+
)
|
|
7341
|
+
] });
|
|
7164
7342
|
}
|
|
7165
7343
|
function ExpandIcon() {
|
|
7166
7344
|
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
@@ -7229,22 +7407,32 @@ function AgentRail({
|
|
|
7229
7407
|
onInputResponse,
|
|
7230
7408
|
onToolInput
|
|
7231
7409
|
}) {
|
|
7232
|
-
const railRef = (0,
|
|
7233
|
-
const overlayRef = (0,
|
|
7234
|
-
const transcriptRef = (0,
|
|
7235
|
-
const responseRef = (0,
|
|
7236
|
-
const threadRef = (0,
|
|
7237
|
-
const lastScrolledVisitorIdRef = (0,
|
|
7238
|
-
const pinnedToBottomRef = (0,
|
|
7239
|
-
const smoothScrollToLatestRef = (0,
|
|
7240
|
-
const lockedTranscriptScrollTopRef = (0,
|
|
7241
|
-
const [showJumpToLatest, setShowJumpToLatest] = (0,
|
|
7242
|
-
const [receiptOpen, setReceiptOpen] = (0,
|
|
7243
|
-
const [
|
|
7410
|
+
const railRef = (0, import_react18.useRef)(null);
|
|
7411
|
+
const overlayRef = (0, import_react18.useRef)(null);
|
|
7412
|
+
const transcriptRef = (0, import_react18.useRef)(null);
|
|
7413
|
+
const responseRef = (0, import_react18.useRef)(null);
|
|
7414
|
+
const threadRef = (0, import_react18.useRef)(null);
|
|
7415
|
+
const lastScrolledVisitorIdRef = (0, import_react18.useRef)(void 0);
|
|
7416
|
+
const pinnedToBottomRef = (0, import_react18.useRef)(true);
|
|
7417
|
+
const smoothScrollToLatestRef = (0, import_react18.useRef)(false);
|
|
7418
|
+
const lockedTranscriptScrollTopRef = (0, import_react18.useRef)(null);
|
|
7419
|
+
const [showJumpToLatest, setShowJumpToLatest] = (0, import_react18.useState)(false);
|
|
7420
|
+
const [receiptOpen, setReceiptOpen] = (0, import_react18.useState)(false);
|
|
7421
|
+
const [expandedSourcesMessageId, setExpandedSourcesMessageId] = (0, import_react18.useState)(null);
|
|
7244
7422
|
const resolvedBrandLabel = brandLabel.trim();
|
|
7245
7423
|
const resolvedBrandLogoUrl = brandLogoUrl?.trim();
|
|
7246
7424
|
const resolvedDisclaimerLabel = disclaimerLabel === void 0 ? DEFAULT_DISCLAIMER_LABEL : disclaimerLabel;
|
|
7247
|
-
const [failedLogoUrl, setFailedLogoUrl] = (0,
|
|
7425
|
+
const [failedLogoUrl, setFailedLogoUrl] = (0, import_react18.useState)(null);
|
|
7426
|
+
const [brandLogoDisplay, setBrandLogoDisplay] = (0, import_react18.useState)(null);
|
|
7427
|
+
(0, import_react18.useEffect)(() => {
|
|
7428
|
+
setFailedLogoUrl(null);
|
|
7429
|
+
}, [resolvedBrandLogoUrl]);
|
|
7430
|
+
const activeBrandLogoDisplay = brandLogoDisplay?.url === resolvedBrandLogoUrl ? brandLogoDisplay : null;
|
|
7431
|
+
const wideBrandLogo = activeBrandLogoDisplay?.wide ?? false;
|
|
7432
|
+
const brandLogoDisplaySize = activeBrandLogoDisplay ? {
|
|
7433
|
+
height: activeBrandLogoDisplay.height,
|
|
7434
|
+
width: activeBrandLogoDisplay.width
|
|
7435
|
+
} : null;
|
|
7248
7436
|
const showBrandLogo = Boolean(resolvedBrandLogoUrl) && failedLogoUrl !== resolvedBrandLogoUrl;
|
|
7249
7437
|
const resolvedColorScheme = useAgentColorScheme(colorScheme);
|
|
7250
7438
|
const railStyle = agentThemeStyle(theme, resolvedColorScheme);
|
|
@@ -7345,30 +7533,39 @@ function AgentRail({
|
|
|
7345
7533
|
...visibleVisitorToolResults
|
|
7346
7534
|
].reverse().find((result) => result.kind !== "input")?.id;
|
|
7347
7535
|
const receiptSteps = answerReceipt && state.toolSteps.length > 0 ? state.toolSteps : void 0;
|
|
7348
|
-
(0,
|
|
7349
|
-
if (state.phase !== "complete"
|
|
7536
|
+
(0, import_react18.useEffect)(() => {
|
|
7537
|
+
if (state.phase !== "complete") {
|
|
7350
7538
|
setReceiptOpen(false);
|
|
7351
7539
|
}
|
|
7352
|
-
}, [state.phase
|
|
7540
|
+
}, [state.phase]);
|
|
7541
|
+
(0, import_react18.useEffect)(() => {
|
|
7542
|
+
if (state.phase !== "complete" || !showSources) {
|
|
7543
|
+
setExpandedSourcesMessageId(null);
|
|
7544
|
+
}
|
|
7545
|
+
}, [state.phase, showSources]);
|
|
7353
7546
|
function handleSubmit(message, options) {
|
|
7354
7547
|
setReceiptOpen(false);
|
|
7548
|
+
setExpandedSourcesMessageId(null);
|
|
7355
7549
|
onSubmit?.(message, options);
|
|
7356
7550
|
}
|
|
7357
7551
|
function handleRegenerate() {
|
|
7358
7552
|
setReceiptOpen(false);
|
|
7553
|
+
setExpandedSourcesMessageId(null);
|
|
7359
7554
|
onRegenerate?.();
|
|
7360
7555
|
}
|
|
7361
7556
|
function handleReset() {
|
|
7362
7557
|
setReceiptOpen(false);
|
|
7558
|
+
setExpandedSourcesMessageId(null);
|
|
7363
7559
|
onReset?.();
|
|
7364
7560
|
}
|
|
7365
7561
|
function handleFollowUpSelect(label) {
|
|
7366
7562
|
setReceiptOpen(false);
|
|
7563
|
+
setExpandedSourcesMessageId(null);
|
|
7367
7564
|
if (onFollowUpSelect) onFollowUpSelect(label);
|
|
7368
7565
|
else onSubmit?.(label);
|
|
7369
7566
|
}
|
|
7370
7567
|
const latestVisitorId = visibleMessages[lastVisitorIndex]?.id;
|
|
7371
|
-
(0,
|
|
7568
|
+
(0, import_react18.useEffect)(() => {
|
|
7372
7569
|
const node = transcriptRef.current;
|
|
7373
7570
|
if (!node) return;
|
|
7374
7571
|
if (latestVisitorId !== lastScrolledVisitorIdRef.current) {
|
|
@@ -7398,7 +7595,7 @@ function AgentRail({
|
|
|
7398
7595
|
state.followUps,
|
|
7399
7596
|
state.journey
|
|
7400
7597
|
]);
|
|
7401
|
-
(0,
|
|
7598
|
+
(0, import_react18.useEffect)(() => {
|
|
7402
7599
|
const node = transcriptRef.current;
|
|
7403
7600
|
if (!node) return;
|
|
7404
7601
|
const handleScroll = () => {
|
|
@@ -7412,7 +7609,7 @@ function AgentRail({
|
|
|
7412
7609
|
handleScroll();
|
|
7413
7610
|
return () => node.removeEventListener("scroll", handleScroll);
|
|
7414
7611
|
}, []);
|
|
7415
|
-
(0,
|
|
7612
|
+
(0, import_react18.useEffect)(() => {
|
|
7416
7613
|
if (!receiptOpen) {
|
|
7417
7614
|
lockedTranscriptScrollTopRef.current = null;
|
|
7418
7615
|
return;
|
|
@@ -7421,8 +7618,7 @@ function AgentRail({
|
|
|
7421
7618
|
if (!node || lockedTranscriptScrollTopRef.current === null) return;
|
|
7422
7619
|
node.scrollTop = lockedTranscriptScrollTopRef.current;
|
|
7423
7620
|
}, [receiptOpen]);
|
|
7424
|
-
function openReceipt(
|
|
7425
|
-
setSourceResults(results);
|
|
7621
|
+
function openReceipt() {
|
|
7426
7622
|
const node = transcriptRef.current;
|
|
7427
7623
|
lockedTranscriptScrollTopRef.current = node?.scrollTop ?? null;
|
|
7428
7624
|
setReceiptOpen(true);
|
|
@@ -7488,17 +7684,45 @@ function AgentRail({
|
|
|
7488
7684
|
}
|
|
7489
7685
|
) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
|
|
7490
7686
|
resolvedBrandLabel || showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "agent-rail__identity", children: [
|
|
7491
|
-
showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7492
|
-
"
|
|
7687
|
+
showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7688
|
+
"span",
|
|
7493
7689
|
{
|
|
7494
|
-
className: "agent-rail__brand-
|
|
7495
|
-
|
|
7496
|
-
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
|
|
7690
|
+
className: `agent-rail__brand-mark${wideBrandLogo ? " agent-rail__brand-mark--wide" : ""}`,
|
|
7691
|
+
"aria-hidden": "true",
|
|
7692
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7693
|
+
"img",
|
|
7694
|
+
{
|
|
7695
|
+
className: "agent-rail__brand-logo as-brand-logo-img",
|
|
7696
|
+
src: resolvedBrandLogoUrl,
|
|
7697
|
+
alt: "",
|
|
7698
|
+
decoding: "async",
|
|
7699
|
+
...brandLogoDisplaySize ? {
|
|
7700
|
+
height: brandLogoDisplaySize.height,
|
|
7701
|
+
width: brandLogoDisplaySize.width
|
|
7702
|
+
} : {},
|
|
7703
|
+
onLoad: (event) => {
|
|
7704
|
+
const img = event.currentTarget;
|
|
7705
|
+
const display = snapBrandLogoDisplaySize({
|
|
7706
|
+
naturalHeight: img.naturalHeight,
|
|
7707
|
+
naturalWidth: img.naturalWidth,
|
|
7708
|
+
surface: "header"
|
|
7709
|
+
});
|
|
7710
|
+
if (!resolvedBrandLogoUrl) return;
|
|
7711
|
+
setBrandLogoDisplay({
|
|
7712
|
+
height: display.height,
|
|
7713
|
+
url: resolvedBrandLogoUrl,
|
|
7714
|
+
wide: display.wide,
|
|
7715
|
+
width: display.width
|
|
7716
|
+
});
|
|
7717
|
+
},
|
|
7718
|
+
onError: () => {
|
|
7719
|
+
setFailedLogoUrl(resolvedBrandLogoUrl ?? null);
|
|
7720
|
+
}
|
|
7721
|
+
},
|
|
7722
|
+
resolvedBrandLogoUrl
|
|
7723
|
+
)
|
|
7500
7724
|
}
|
|
7501
|
-
)
|
|
7725
|
+
) : null,
|
|
7502
7726
|
resolvedBrandLabel ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "agent-rail__brand-label", children: resolvedBrandLabel }) : null
|
|
7503
7727
|
] }) : null,
|
|
7504
7728
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "agent-rail__actions", children: [
|
|
@@ -7530,9 +7754,7 @@ function AgentRail({
|
|
|
7530
7754
|
greeting?.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7531
7755
|
MessageBubble,
|
|
7532
7756
|
{
|
|
7533
|
-
showProvenance:
|
|
7534
|
-
handoff?.page?.enabled || handoffActive
|
|
7535
|
-
),
|
|
7757
|
+
showProvenance: true,
|
|
7536
7758
|
message: greeting,
|
|
7537
7759
|
bookingDisabled: isBusy || handoffActive,
|
|
7538
7760
|
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
@@ -7575,104 +7797,138 @@ function AgentRail({
|
|
|
7575
7797
|
request.requestId
|
|
7576
7798
|
))
|
|
7577
7799
|
] }) : null,
|
|
7578
|
-
transcriptMessages.map((message, index) =>
|
|
7579
|
-
"
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
|
|
7583
|
-
|
|
7584
|
-
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
)) : null,
|
|
7591
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7592
|
-
MessageBubble,
|
|
7593
|
-
{
|
|
7594
|
-
showProvenance: Boolean(
|
|
7595
|
-
handoff?.page?.enabled || handoffActive
|
|
7596
|
-
),
|
|
7597
|
-
message,
|
|
7598
|
-
showSearchReferences: false,
|
|
7599
|
-
bookingDisabled: isBusy || handoffActive,
|
|
7600
|
-
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
7601
|
-
offer: index === transcriptMessages.length - 1 ? state.pendingOffer : void 0,
|
|
7602
|
-
onBook
|
|
7603
|
-
}
|
|
7604
|
-
),
|
|
7605
|
-
message.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "agent-rail__answer-actions", children: [
|
|
7606
|
-
index === lastAgentIndex && showMessageActions ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7607
|
-
MessageActions,
|
|
7800
|
+
transcriptMessages.map((message, index) => {
|
|
7801
|
+
const messageSourceCount = message.role === "agent" ? searchSources(message.searchResults ?? []).length : 0;
|
|
7802
|
+
const showAnswerActions = message.role === "agent" && index === lastAgentIndex && showMessageActions;
|
|
7803
|
+
const showSourcesToggle = message.role === "agent" && showSources && state.phase === "complete" && !message.streaming && messageSourceCount > 0;
|
|
7804
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
7805
|
+
"div",
|
|
7806
|
+
{
|
|
7807
|
+
ref: index === lastVisitorIndex + 1 ? responseRef : void 0,
|
|
7808
|
+
className: "agent-rail__turn-block",
|
|
7809
|
+
children: [
|
|
7810
|
+
message.role === "agent" ? message.toolResults?.map((result) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7811
|
+
VisitorToolResultView,
|
|
7608
7812
|
{
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
onFeedback: onFeedback ? (rating) => onFeedback(rating, message) : void 0
|
|
7616
|
-
}
|
|
7617
|
-
) : null,
|
|
7618
|
-
showSources && state.phase === "complete" && !message.streaming && searchSources(message.searchResults ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7619
|
-
"button",
|
|
7813
|
+
result
|
|
7814
|
+
},
|
|
7815
|
+
result.id
|
|
7816
|
+
)) : null,
|
|
7817
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7818
|
+
MessageBubble,
|
|
7620
7819
|
{
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7820
|
+
showProvenance: true,
|
|
7821
|
+
message,
|
|
7822
|
+
showSearchReferences: false,
|
|
7823
|
+
bookingDisabled: isBusy || handoffActive,
|
|
7824
|
+
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
7825
|
+
offer: index === transcriptMessages.length - 1 ? state.pendingOffer : void 0,
|
|
7826
|
+
onBook
|
|
7626
7827
|
}
|
|
7627
|
-
)
|
|
7628
|
-
|
|
7629
|
-
|
|
7630
|
-
|
|
7631
|
-
|
|
7632
|
-
|
|
7633
|
-
|
|
7634
|
-
|
|
7635
|
-
|
|
7636
|
-
|
|
7637
|
-
|
|
7638
|
-
|
|
7639
|
-
|
|
7640
|
-
|
|
7641
|
-
|
|
7642
|
-
|
|
7643
|
-
|
|
7644
|
-
|
|
7645
|
-
|
|
7646
|
-
|
|
7828
|
+
),
|
|
7829
|
+
showAnswerActions || showSourcesToggle ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "agent-rail__answer-footer", children: [
|
|
7830
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "agent-rail__answer-actions", children: [
|
|
7831
|
+
showAnswerActions ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7832
|
+
MessageActions,
|
|
7833
|
+
{
|
|
7834
|
+
answeredAt: message.createdAt,
|
|
7835
|
+
copyText: hideToolCardFences(message.text).trim() || message.text,
|
|
7836
|
+
readAloud,
|
|
7837
|
+
receiptSteps,
|
|
7838
|
+
onOpenReceipt: receiptSteps ? () => openReceipt() : void 0,
|
|
7839
|
+
onRegenerate: onRegenerate ? handleRegenerate : void 0,
|
|
7840
|
+
onFeedback: onFeedback ? (rating) => onFeedback(rating, message) : void 0
|
|
7841
|
+
}
|
|
7842
|
+
) : null,
|
|
7843
|
+
showSourcesToggle ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
7844
|
+
"button",
|
|
7845
|
+
{
|
|
7846
|
+
className: "agent-rail__sources-button",
|
|
7847
|
+
type: "button",
|
|
7848
|
+
"aria-expanded": expandedSourcesMessageId === message.id,
|
|
7849
|
+
"aria-controls": `agent-rail-sources-${message.id}`,
|
|
7850
|
+
onClick: () => setExpandedSourcesMessageId(
|
|
7851
|
+
(current) => current === message.id ? null : message.id
|
|
7852
|
+
),
|
|
7853
|
+
children: [
|
|
7854
|
+
"Explore More",
|
|
7855
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7856
|
+
"span",
|
|
7857
|
+
{
|
|
7858
|
+
className: "agent-rail__sources-button-chevron",
|
|
7859
|
+
"aria-hidden": "true",
|
|
7860
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ChevronDownIcon, {})
|
|
7861
|
+
}
|
|
7862
|
+
)
|
|
7863
|
+
]
|
|
7864
|
+
}
|
|
7865
|
+
) : null
|
|
7866
|
+
] }),
|
|
7867
|
+
showSourcesToggle ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7868
|
+
"div",
|
|
7869
|
+
{
|
|
7870
|
+
id: `agent-rail-sources-${message.id}`,
|
|
7871
|
+
className: `agent-rail__sources-panel${expandedSourcesMessageId === message.id ? " agent-rail__sources-panel--open" : ""}`,
|
|
7872
|
+
role: "region",
|
|
7873
|
+
"aria-label": "Explore More",
|
|
7874
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "agent-rail__sources-panel-inner", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7875
|
+
SearchReferences,
|
|
7876
|
+
{
|
|
7877
|
+
results: message.searchResults ?? [],
|
|
7878
|
+
mode: "sources"
|
|
7879
|
+
}
|
|
7880
|
+
) })
|
|
7881
|
+
}
|
|
7882
|
+
) : null
|
|
7883
|
+
] }) : null,
|
|
7884
|
+
message.role === "agent" && !message.streaming ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7885
|
+
SearchReferences,
|
|
7647
7886
|
{
|
|
7648
|
-
|
|
7649
|
-
|
|
7650
|
-
failed: state.phase === "error",
|
|
7651
|
-
steps: activitySteps
|
|
7887
|
+
results: message.searchResults ?? [],
|
|
7888
|
+
mode: "actions"
|
|
7652
7889
|
}
|
|
7653
7890
|
) : null,
|
|
7654
|
-
|
|
7655
|
-
|
|
7656
|
-
{
|
|
7657
|
-
result,
|
|
7658
|
-
disabled: semanticSurfaceDisabled,
|
|
7659
|
-
onToolInput
|
|
7660
|
-
},
|
|
7661
|
-
result.id
|
|
7662
|
-
)),
|
|
7663
|
-
pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7664
|
-
HumanInputCard,
|
|
7891
|
+
showAnswerActions && !handoffActive && showLearnMore ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7892
|
+
LearnMore,
|
|
7665
7893
|
{
|
|
7666
|
-
|
|
7667
|
-
|
|
7668
|
-
|
|
7669
|
-
|
|
7670
|
-
)
|
|
7671
|
-
|
|
7672
|
-
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
|
|
7894
|
+
results: message.searchResults ?? [],
|
|
7895
|
+
disabled: isBusy || !(onFollowUpSelect || onSubmit),
|
|
7896
|
+
onSelect: handleFollowUpSelect
|
|
7897
|
+
}
|
|
7898
|
+
) : null,
|
|
7899
|
+
index === lastVisitorIndex ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
7900
|
+
showActivity ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7901
|
+
AgentActivityBubble,
|
|
7902
|
+
{
|
|
7903
|
+
brandLabel: resolvedBrandLabel,
|
|
7904
|
+
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
7905
|
+
failed: state.phase === "error",
|
|
7906
|
+
steps: activitySteps
|
|
7907
|
+
}
|
|
7908
|
+
) : null,
|
|
7909
|
+
visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7910
|
+
VisitorToolResultView,
|
|
7911
|
+
{
|
|
7912
|
+
result,
|
|
7913
|
+
disabled: semanticSurfaceDisabled,
|
|
7914
|
+
onToolInput
|
|
7915
|
+
},
|
|
7916
|
+
result.id
|
|
7917
|
+
)),
|
|
7918
|
+
pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7919
|
+
HumanInputCard,
|
|
7920
|
+
{
|
|
7921
|
+
request,
|
|
7922
|
+
onRespond: onInputResponse
|
|
7923
|
+
},
|
|
7924
|
+
request.requestId
|
|
7925
|
+
))
|
|
7926
|
+
] }) : null
|
|
7927
|
+
]
|
|
7928
|
+
},
|
|
7929
|
+
message.role === "agent" && transcriptMessages[index - 1]?.role === "visitor" ? `answer-${transcriptMessages[index - 1]?.id}` : message.id
|
|
7930
|
+
);
|
|
7931
|
+
}),
|
|
7676
7932
|
waitingForBooking ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(BookingCardLoader, {}) : null,
|
|
7677
7933
|
state.error ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("section", { className: "agent-rail__error", role: "alert", children: [
|
|
7678
7934
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
|
|
@@ -7682,21 +7938,22 @@ function AgentRail({
|
|
|
7682
7938
|
onRetry ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
|
|
7683
7939
|
] }) : null
|
|
7684
7940
|
] }) }),
|
|
7685
|
-
showDisclaimerLabel ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "agent-rail__disclaimer", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { children: disclaimerLink ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7686
|
-
"a",
|
|
7687
|
-
{
|
|
7688
|
-
href: disclaimerLink,
|
|
7689
|
-
rel: "noopener noreferrer",
|
|
7690
|
-
target: "_blank",
|
|
7691
|
-
children: resolvedDisclaimerLabel
|
|
7692
|
-
}
|
|
7693
|
-
) : resolvedDisclaimerLabel }) }) : null,
|
|
7694
7941
|
handoff && (handoff.page?.enabled || handoffActive) ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "agent-rail__handoff", children: [
|
|
7695
|
-
|
|
7942
|
+
handoffStatus === "human" || handoffStatus === "queued" || handoffStatus === "requesting" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "agent-rail__handoff-dot", "aria-hidden": "true" }) : null,
|
|
7943
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7944
|
+
"p",
|
|
7945
|
+
{
|
|
7946
|
+
className: "agent-rail__handoff-status",
|
|
7947
|
+
role: "status",
|
|
7948
|
+
"aria-live": "polite",
|
|
7949
|
+
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?"
|
|
7950
|
+
}
|
|
7951
|
+
),
|
|
7696
7952
|
handoffStatus === "ai" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7697
7953
|
"button",
|
|
7698
7954
|
{
|
|
7699
7955
|
type: "button",
|
|
7956
|
+
className: "agent-rail__handoff-cta",
|
|
7700
7957
|
disabled: handoff.busy || handoff.hasPending || isBusy,
|
|
7701
7958
|
onClick: () => void handoff.start(),
|
|
7702
7959
|
children: "Talk to a person"
|
|
@@ -7706,6 +7963,7 @@ function AgentRail({
|
|
|
7706
7963
|
"button",
|
|
7707
7964
|
{
|
|
7708
7965
|
type: "button",
|
|
7966
|
+
className: "agent-rail__handoff-action",
|
|
7709
7967
|
disabled: handoff.busy || handoff.hasPending,
|
|
7710
7968
|
onClick: () => void handoff.returnToAI(),
|
|
7711
7969
|
children: "Return to AI"
|
|
@@ -7715,17 +7973,19 @@ function AgentRail({
|
|
|
7715
7973
|
"button",
|
|
7716
7974
|
{
|
|
7717
7975
|
type: "button",
|
|
7976
|
+
className: "agent-rail__handoff-action",
|
|
7718
7977
|
disabled: !handoff.canReset,
|
|
7719
7978
|
onClick: handleReset,
|
|
7720
7979
|
children: "Start a new conversation"
|
|
7721
7980
|
}
|
|
7722
7981
|
) : null,
|
|
7723
|
-
handoff.error ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("
|
|
7724
|
-
|
|
7982
|
+
handoff.error ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "agent-rail__handoff-error", role: "alert", children: [
|
|
7983
|
+
handoff.error,
|
|
7725
7984
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7726
7985
|
"button",
|
|
7727
7986
|
{
|
|
7728
7987
|
type: "button",
|
|
7988
|
+
className: "agent-rail__handoff-action",
|
|
7729
7989
|
disabled: handoff.busy,
|
|
7730
7990
|
onClick: () => void handoff.retry(),
|
|
7731
7991
|
children: "Retry"
|
|
@@ -7733,6 +7993,15 @@ function AgentRail({
|
|
|
7733
7993
|
)
|
|
7734
7994
|
] }) : null
|
|
7735
7995
|
] }) : null,
|
|
7996
|
+
showDisclaimerLabel ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "agent-rail__disclaimer", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { children: disclaimerLink ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7997
|
+
"a",
|
|
7998
|
+
{
|
|
7999
|
+
href: disclaimerLink,
|
|
8000
|
+
rel: "noopener noreferrer",
|
|
8001
|
+
target: "_blank",
|
|
8002
|
+
children: resolvedDisclaimerLabel
|
|
8003
|
+
}
|
|
8004
|
+
) : resolvedDisclaimerLabel }) }) : null,
|
|
7736
8005
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
|
|
7737
8006
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7738
8007
|
LocationConsent,
|
|
@@ -7774,19 +8043,12 @@ function AgentRail({
|
|
|
7774
8043
|
] })
|
|
7775
8044
|
] }),
|
|
7776
8045
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { ref: overlayRef, className: "agent-rail__overlay" }),
|
|
7777
|
-
receiptOpen &&
|
|
8046
|
+
receiptOpen && receiptSteps ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
7778
8047
|
AnswerReceiptDialog,
|
|
7779
8048
|
{
|
|
7780
8049
|
brandLabel: resolvedBrandLabel,
|
|
7781
8050
|
onClose: () => setReceiptOpen(false),
|
|
7782
|
-
steps: receiptSteps
|
|
7783
|
-
title: sourceResults ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
7784
|
-
"Sources",
|
|
7785
|
-
" ",
|
|
7786
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "agent-receipt-dialog__count", children: searchSources(sourceResults).length })
|
|
7787
|
-
] }) : void 0,
|
|
7788
|
-
summary: sourceResults ? "References for this answer" : void 0,
|
|
7789
|
-
children: sourceResults ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SearchReferences, { results: sourceResults, mode: "sources" }) : void 0
|
|
8051
|
+
steps: receiptSteps
|
|
7790
8052
|
}
|
|
7791
8053
|
) : null
|
|
7792
8054
|
] })
|
|
@@ -7795,7 +8057,7 @@ function AgentRail({
|
|
|
7795
8057
|
}
|
|
7796
8058
|
|
|
7797
8059
|
// src/react/components/AssistEdgeTab/AssistEdgeTab.tsx
|
|
7798
|
-
var
|
|
8060
|
+
var import_react19 = require("react");
|
|
7799
8061
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
7800
8062
|
function ChatSparkIcon() {
|
|
7801
8063
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
@@ -7872,20 +8134,47 @@ function ChatSparkIcon() {
|
|
|
7872
8134
|
}
|
|
7873
8135
|
function TabMarkIcon({
|
|
7874
8136
|
customIconUrl,
|
|
7875
|
-
logoUrl
|
|
8137
|
+
logoUrl,
|
|
8138
|
+
chip = false
|
|
7876
8139
|
}) {
|
|
7877
8140
|
const custom = customIconUrl?.trim();
|
|
7878
8141
|
const logo = logoUrl?.trim();
|
|
7879
|
-
const [customFailed, setCustomFailed] = (0,
|
|
7880
|
-
const [logoFailed, setLogoFailed] = (0,
|
|
8142
|
+
const [customFailed, setCustomFailed] = (0, import_react19.useState)(false);
|
|
8143
|
+
const [logoFailed, setLogoFailed] = (0, import_react19.useState)(false);
|
|
8144
|
+
const [markDisplay, setMarkDisplay] = (0, import_react19.useState)(null);
|
|
8145
|
+
function applyLauncherLogoSize(img, sourceUrl) {
|
|
8146
|
+
if (!chip) return;
|
|
8147
|
+
const display = snapBrandLogoDisplaySize({
|
|
8148
|
+
naturalHeight: img.naturalHeight,
|
|
8149
|
+
naturalWidth: img.naturalWidth,
|
|
8150
|
+
surface: "launcher"
|
|
8151
|
+
});
|
|
8152
|
+
setMarkDisplay({
|
|
8153
|
+
url: sourceUrl,
|
|
8154
|
+
width: display.width,
|
|
8155
|
+
height: display.height,
|
|
8156
|
+
wide: display.wide
|
|
8157
|
+
});
|
|
8158
|
+
}
|
|
8159
|
+
const chipMarkStyle = chip && markDisplay ? {
|
|
8160
|
+
width: `${markDisplay.width}px`,
|
|
8161
|
+
height: `${markDisplay.height}px`
|
|
8162
|
+
} : void 0;
|
|
7881
8163
|
if (custom && !customFailed) {
|
|
7882
8164
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
7883
8165
|
"img",
|
|
7884
8166
|
{
|
|
7885
8167
|
alt: "",
|
|
7886
8168
|
"aria-hidden": true,
|
|
7887
|
-
className: "assist-edge-tab__custom-icon"
|
|
8169
|
+
className: `assist-edge-tab__custom-icon as-brand-logo-img${chip ? " assist-edge-tab__custom-icon--chip" : ""}`,
|
|
7888
8170
|
src: custom,
|
|
8171
|
+
decoding: "async",
|
|
8172
|
+
style: markDisplay?.url === custom ? chipMarkStyle : void 0,
|
|
8173
|
+
onLoad: (event) => {
|
|
8174
|
+
if (chip) {
|
|
8175
|
+
applyLauncherLogoSize(event.currentTarget, custom);
|
|
8176
|
+
}
|
|
8177
|
+
},
|
|
7889
8178
|
onError: () => setCustomFailed(true)
|
|
7890
8179
|
}
|
|
7891
8180
|
);
|
|
@@ -7896,8 +8185,13 @@ function TabMarkIcon({
|
|
|
7896
8185
|
{
|
|
7897
8186
|
alt: "",
|
|
7898
8187
|
"aria-hidden": true,
|
|
7899
|
-
className: "assist-edge-tab__logo"
|
|
8188
|
+
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" : ""}`,
|
|
7900
8189
|
src: logo,
|
|
8190
|
+
decoding: "async",
|
|
8191
|
+
style: markDisplay?.url === logo ? chipMarkStyle : void 0,
|
|
8192
|
+
onLoad: (event) => {
|
|
8193
|
+
applyLauncherLogoSize(event.currentTarget, logo);
|
|
8194
|
+
},
|
|
7901
8195
|
onError: () => setLogoFailed(true)
|
|
7902
8196
|
}
|
|
7903
8197
|
);
|
|
@@ -7973,6 +8267,7 @@ function AssistEdgeTab({
|
|
|
7973
8267
|
"--tab-along": `${along}%`,
|
|
7974
8268
|
"--tab-inset": `${inset}px`,
|
|
7975
8269
|
...resolvedBrandColor ? { "--as-brand": resolvedBrandColor } : {},
|
|
8270
|
+
...pill && resolvedBrandColor ? { "--pill-logo-surface": resolvedBrandColor } : {},
|
|
7976
8271
|
...brandForeground ? { "--as-visitor-text": brandForeground } : {},
|
|
7977
8272
|
...resolvedBorderColor ? { "--as-border": resolvedBorderColor } : {},
|
|
7978
8273
|
...fontFamily ? { "--as-font-display": fontFamily } : {},
|
|
@@ -8005,6 +8300,7 @@ function AssistEdgeTab({
|
|
|
8005
8300
|
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
8006
8301
|
TabMarkIcon,
|
|
8007
8302
|
{
|
|
8303
|
+
chip: true,
|
|
8008
8304
|
customIconUrl,
|
|
8009
8305
|
logoUrl
|
|
8010
8306
|
},
|
|
@@ -8020,6 +8316,7 @@ function AssistEdgeTab({
|
|
|
8020
8316
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
8021
8317
|
TabMarkIcon,
|
|
8022
8318
|
{
|
|
8319
|
+
chip: true,
|
|
8023
8320
|
customIconUrl,
|
|
8024
8321
|
logoUrl
|
|
8025
8322
|
},
|
|
@@ -8037,6 +8334,7 @@ function AssistEdgeTab({
|
|
|
8037
8334
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
8038
8335
|
TabMarkIcon,
|
|
8039
8336
|
{
|
|
8337
|
+
chip: true,
|
|
8040
8338
|
customIconUrl,
|
|
8041
8339
|
logoUrl
|
|
8042
8340
|
},
|
|
@@ -8127,9 +8425,9 @@ function AgentWidget({
|
|
|
8127
8425
|
}) {
|
|
8128
8426
|
const isMobile = useIsMobile();
|
|
8129
8427
|
const placement = normalizeAgentPlacement(placementInput);
|
|
8130
|
-
const railSlotRef = (0,
|
|
8131
|
-
const [railCollapsed, setRailCollapsed] = (0,
|
|
8132
|
-
const [railExpanded, setRailExpanded] = (0,
|
|
8428
|
+
const railSlotRef = (0, import_react20.useRef)(null);
|
|
8429
|
+
const [railCollapsed, setRailCollapsed] = (0, import_react20.useState)(defaultCollapsed);
|
|
8430
|
+
const [railExpanded, setRailExpanded] = (0, import_react20.useState)(false);
|
|
8133
8431
|
const pageShiftActive = shouldApplyPageShift({
|
|
8134
8432
|
pageShift,
|
|
8135
8433
|
isMobile,
|
|
@@ -8184,7 +8482,7 @@ function AgentWidget({
|
|
|
8184
8482
|
} : {},
|
|
8185
8483
|
...branding?.colors?.border ? { border: branding.colors.border } : {}
|
|
8186
8484
|
};
|
|
8187
|
-
(0,
|
|
8485
|
+
(0, import_react20.useEffect)(() => {
|
|
8188
8486
|
if (!registerPanelController) return;
|
|
8189
8487
|
registerAgentPanelController(customerId, {
|
|
8190
8488
|
open: () => setRailCollapsed(false),
|
|
@@ -8219,7 +8517,7 @@ function AgentWidget({
|
|
|
8219
8517
|
})
|
|
8220
8518
|
);
|
|
8221
8519
|
}
|
|
8222
|
-
(0,
|
|
8520
|
+
(0, import_react20.useEffect)(() => {
|
|
8223
8521
|
if (railCollapsed) return;
|
|
8224
8522
|
const handleKeyDown = (event) => {
|
|
8225
8523
|
if (event.key === "Tab" && (isMobile || railExpanded)) {
|