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