@webless/agent 0.3.2 → 0.4.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/dist/{chunk-APNF27K2.js → chunk-SVWXFDV3.js} +357 -112
- package/dist/chunk-SVWXFDV3.js.map +1 -0
- package/dist/embed.cjs +351 -106
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.css +500 -237
- package/dist/embed.css.map +1 -1
- package/dist/embed.d.cts +2 -2
- package/dist/embed.d.ts +2 -2
- package/dist/embed.js +1 -1
- package/dist/index.cjs +9 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +9 -6
- package/dist/index.js.map +1 -1
- package/dist/{manifest-oc_3zCSC.d.cts → manifest-C8l7WUf6.d.cts} +6 -1
- package/dist/{manifest-oc_3zCSC.d.ts → manifest-C8l7WUf6.d.ts} +6 -1
- package/dist/react.cjs +351 -106
- package/dist/react.cjs.map +1 -1
- package/dist/react.css +500 -237
- package/dist/react.css.map +1 -1
- package/dist/react.d.cts +6 -3
- package/dist/react.d.ts +6 -3
- package/dist/react.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-APNF27K2.js.map +0 -1
package/dist/embed.cjs
CHANGED
|
@@ -402,13 +402,15 @@ function emitWorkItem(item, handlers, workItems) {
|
|
|
402
402
|
handlers.onWork?.(item);
|
|
403
403
|
handlers.onStep?.(item.label, item.detail);
|
|
404
404
|
}
|
|
405
|
-
function completePlanning(handlers, workItems) {
|
|
405
|
+
function completePlanning(handlers, workItems, nextItems = []) {
|
|
406
406
|
const planning = workItems.get("planning");
|
|
407
407
|
if (!planning || planning.state !== "active") return;
|
|
408
|
+
const specialists = nextItems.filter((item) => item.kind === "specialist");
|
|
409
|
+
const detail = specialists.length === 1 ? `Delegating to ${specialists[0]?.label}` : specialists.length > 1 ? `Delegating to ${specialists.length} specialists` : nextItems.some((item) => item.kind === "search") ? "Using built-in Search & Discovery" : "Picked the best way to help";
|
|
408
410
|
emitWorkItem(
|
|
409
411
|
{
|
|
410
412
|
...planning,
|
|
411
|
-
detail
|
|
413
|
+
detail,
|
|
412
414
|
state: "completed"
|
|
413
415
|
},
|
|
414
416
|
handlers,
|
|
@@ -458,11 +460,12 @@ function applyWorkEvent(event, handlers, workItems) {
|
|
|
458
460
|
return;
|
|
459
461
|
}
|
|
460
462
|
if (event.type === "actions.requested") {
|
|
461
|
-
|
|
462
|
-
for (const action of event.data.actions) {
|
|
463
|
+
const nextItems = event.data.actions.flatMap((action) => {
|
|
463
464
|
const item = requestedWorkItem(action);
|
|
464
|
-
|
|
465
|
-
}
|
|
465
|
+
return item ? [item] : [];
|
|
466
|
+
});
|
|
467
|
+
completePlanning(handlers, workItems, nextItems);
|
|
468
|
+
for (const item of nextItems) emitWorkItem(item, handlers, workItems);
|
|
466
469
|
return;
|
|
467
470
|
}
|
|
468
471
|
if (event.type === "subagent.called") {
|
|
@@ -1184,6 +1187,37 @@ function useAgentChat({
|
|
|
1184
1187
|
},
|
|
1185
1188
|
[runTurn]
|
|
1186
1189
|
);
|
|
1190
|
+
const retry = (0, import_react2.useCallback)(async () => {
|
|
1191
|
+
const visitorMessage = [...state.messages].reverse().find((message) => message.role === "visitor");
|
|
1192
|
+
if (!visitorMessage) return;
|
|
1193
|
+
if (runRef.current) {
|
|
1194
|
+
runRef.current.abort();
|
|
1195
|
+
clientRef.current.cancelActive();
|
|
1196
|
+
}
|
|
1197
|
+
const controller = new AbortController();
|
|
1198
|
+
runRef.current = controller;
|
|
1199
|
+
setState((prev) => ({
|
|
1200
|
+
...prev,
|
|
1201
|
+
phase: "thinking",
|
|
1202
|
+
toolSteps: [
|
|
1203
|
+
{
|
|
1204
|
+
id: "planning",
|
|
1205
|
+
kind: "planning",
|
|
1206
|
+
label: "Understanding your question",
|
|
1207
|
+
state: "active"
|
|
1208
|
+
}
|
|
1209
|
+
],
|
|
1210
|
+
journey: null,
|
|
1211
|
+
followUps: [],
|
|
1212
|
+
streamingText: "",
|
|
1213
|
+
error: null
|
|
1214
|
+
}));
|
|
1215
|
+
await runTurn({
|
|
1216
|
+
controller,
|
|
1217
|
+
resume: false,
|
|
1218
|
+
visitorText: visitorMessage.text
|
|
1219
|
+
});
|
|
1220
|
+
}, [runTurn, state.messages]);
|
|
1187
1221
|
(0, import_react2.useEffect)(() => {
|
|
1188
1222
|
const conversation = loadPersistedAgentConversation(
|
|
1189
1223
|
resolvedStorageKeyPrefix,
|
|
@@ -1216,6 +1250,7 @@ function useAgentChat({
|
|
|
1216
1250
|
return {
|
|
1217
1251
|
state,
|
|
1218
1252
|
reset,
|
|
1253
|
+
retry,
|
|
1219
1254
|
submit,
|
|
1220
1255
|
visitorSessionId: visitorId,
|
|
1221
1256
|
sessionId: clientRef.current.getActiveSessionId()
|
|
@@ -1293,11 +1328,12 @@ var defaultAgentRailTheme = {
|
|
|
1293
1328
|
|
|
1294
1329
|
// src/react/components/AgentActivityBubble/AgentActivityBubble.tsx
|
|
1295
1330
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
1296
|
-
function workSummary(steps, failed) {
|
|
1331
|
+
function workSummary(steps, failed, brandLabel) {
|
|
1297
1332
|
const active = [...steps].reverse().find((step) => step.state === "active");
|
|
1298
|
-
if (active?.kind === "specialist")
|
|
1333
|
+
if (active?.kind === "specialist")
|
|
1334
|
+
return `${active.label} is reviewing your question`;
|
|
1299
1335
|
if (active?.kind === "search") return "Searching this site";
|
|
1300
|
-
if (active) return
|
|
1336
|
+
if (active) return `${brandLabel} is choosing the best way to help`;
|
|
1301
1337
|
if (failed) return "Couldn\u2019t complete this request";
|
|
1302
1338
|
const hasError = steps.some((step) => step.state === "error");
|
|
1303
1339
|
const specialists = steps.filter(
|
|
@@ -1308,16 +1344,60 @@ function workSummary(steps, failed) {
|
|
|
1308
1344
|
);
|
|
1309
1345
|
if (hasError) return "Answered with available information";
|
|
1310
1346
|
if (specialists.length > 1)
|
|
1311
|
-
return `
|
|
1312
|
-
if (specialists.length === 1)
|
|
1313
|
-
|
|
1314
|
-
return "
|
|
1347
|
+
return `Answer prepared with ${specialists.length} specialists`;
|
|
1348
|
+
if (specialists.length === 1)
|
|
1349
|
+
return `Answer prepared with ${specialists[0]?.label}`;
|
|
1350
|
+
if (searched) return "Answer prepared from this site";
|
|
1351
|
+
return "Answer ready";
|
|
1352
|
+
}
|
|
1353
|
+
function stepLabel(step, brandLabel) {
|
|
1354
|
+
return step.kind === "planning" ? brandLabel : step.label;
|
|
1355
|
+
}
|
|
1356
|
+
function stepDetail(step, steps) {
|
|
1357
|
+
if (step.kind !== "planning" || step.state !== "completed") {
|
|
1358
|
+
return step.detail;
|
|
1359
|
+
}
|
|
1360
|
+
const specialists = steps.filter((item) => item.kind === "specialist");
|
|
1361
|
+
if (specialists.length === 1) return `Delegated to ${specialists[0]?.label}`;
|
|
1362
|
+
if (specialists.length > 1)
|
|
1363
|
+
return `Delegated to ${specialists.length} specialists`;
|
|
1364
|
+
if (steps.some((item) => item.kind === "search"))
|
|
1365
|
+
return "Used built-in Search & Discovery";
|
|
1366
|
+
return step.detail;
|
|
1367
|
+
}
|
|
1368
|
+
function SearchIcon() {
|
|
1369
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
|
|
1370
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "7", cy: "7", r: "3.75", stroke: "currentColor", strokeWidth: "1.4" }),
|
|
1371
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1372
|
+
"path",
|
|
1373
|
+
{
|
|
1374
|
+
d: "m10 10 3 3",
|
|
1375
|
+
stroke: "currentColor",
|
|
1376
|
+
strokeWidth: "1.4",
|
|
1377
|
+
strokeLinecap: "round"
|
|
1378
|
+
}
|
|
1379
|
+
)
|
|
1380
|
+
] });
|
|
1381
|
+
}
|
|
1382
|
+
function PlanningIcon() {
|
|
1383
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1384
|
+
"path",
|
|
1385
|
+
{
|
|
1386
|
+
d: "M4 4.5h8M4 8h5.5M4 11.5h7",
|
|
1387
|
+
stroke: "currentColor",
|
|
1388
|
+
strokeWidth: "1.4",
|
|
1389
|
+
strokeLinecap: "round"
|
|
1390
|
+
}
|
|
1391
|
+
) });
|
|
1315
1392
|
}
|
|
1316
1393
|
function AgentActivityBubble({
|
|
1394
|
+
brandLabel = "Webless Guide",
|
|
1395
|
+
brandLogoUrl,
|
|
1317
1396
|
failed = false,
|
|
1318
1397
|
steps
|
|
1319
1398
|
}) {
|
|
1320
1399
|
const active = steps.some((step) => step.state === "active");
|
|
1400
|
+
const delegated = steps.some((step) => step.kind === "specialist");
|
|
1321
1401
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", { className: "agent-activity-bubble", children: [
|
|
1322
1402
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "agent-activity-bubble__status", "aria-live": "polite", children: [
|
|
1323
1403
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -1327,33 +1407,59 @@ function AgentActivityBubble({
|
|
|
1327
1407
|
"aria-hidden": "true"
|
|
1328
1408
|
}
|
|
1329
1409
|
),
|
|
1330
|
-
workSummary(steps, failed)
|
|
1410
|
+
workSummary(steps, failed, brandLabel)
|
|
1331
1411
|
] }),
|
|
1332
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
"
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
"
|
|
1339
|
-
children:
|
|
1340
|
-
|
|
1341
|
-
|
|
1412
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1413
|
+
"details",
|
|
1414
|
+
{
|
|
1415
|
+
className: "agent-activity-bubble__details",
|
|
1416
|
+
open: active || delegated,
|
|
1417
|
+
children: [
|
|
1418
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: failed ? "What happened" : active ? "Working" : "How this answer was prepared" }),
|
|
1419
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "agent-activity-bubble__steps", children: steps.map((step) => {
|
|
1420
|
+
const detail = stepDetail(step, steps);
|
|
1421
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1422
|
+
"li",
|
|
1342
1423
|
{
|
|
1343
|
-
className: "agent-activity-bubble__step
|
|
1344
|
-
"
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1424
|
+
className: "agent-activity-bubble__step",
|
|
1425
|
+
"data-kind": step.kind,
|
|
1426
|
+
"data-state": step.state,
|
|
1427
|
+
children: [
|
|
1428
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1429
|
+
"span",
|
|
1430
|
+
{
|
|
1431
|
+
className: "agent-activity-bubble__step-icon",
|
|
1432
|
+
"aria-hidden": "true",
|
|
1433
|
+
children: step.kind === "planning" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1434
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(PlanningIcon, {}),
|
|
1435
|
+
brandLogoUrl ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1436
|
+
"img",
|
|
1437
|
+
{
|
|
1438
|
+
src: brandLogoUrl,
|
|
1439
|
+
alt: "",
|
|
1440
|
+
onError: (event) => {
|
|
1441
|
+
event.currentTarget.hidden = true;
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
) : null
|
|
1445
|
+
] }) : step.kind === "search" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SearchIcon, {}) : step.label.slice(0, 1).toUpperCase()
|
|
1446
|
+
}
|
|
1447
|
+
),
|
|
1448
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__step-copy", children: [
|
|
1449
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__step-heading", children: [
|
|
1450
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: stepLabel(step, brandLabel) }),
|
|
1451
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: step.kind === "specialist" ? "Specialist" : step.kind === "search" ? "Built-in capability" : "Supervisor" })
|
|
1452
|
+
] }),
|
|
1453
|
+
detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-activity-bubble__step-detail", children: detail }) : null
|
|
1454
|
+
] })
|
|
1455
|
+
]
|
|
1456
|
+
},
|
|
1457
|
+
step.id
|
|
1458
|
+
);
|
|
1459
|
+
}) })
|
|
1460
|
+
]
|
|
1461
|
+
}
|
|
1462
|
+
)
|
|
1357
1463
|
] });
|
|
1358
1464
|
}
|
|
1359
1465
|
|
|
@@ -1492,6 +1598,29 @@ function MinimizeIcon() {
|
|
|
1492
1598
|
}
|
|
1493
1599
|
) });
|
|
1494
1600
|
}
|
|
1601
|
+
function CloseIcon() {
|
|
1602
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1603
|
+
"path",
|
|
1604
|
+
{
|
|
1605
|
+
d: "M4 4l8 8M12 4l-8 8",
|
|
1606
|
+
stroke: "currentColor",
|
|
1607
|
+
strokeWidth: "1.5",
|
|
1608
|
+
strokeLinecap: "round"
|
|
1609
|
+
}
|
|
1610
|
+
) });
|
|
1611
|
+
}
|
|
1612
|
+
function NewChatIcon() {
|
|
1613
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1614
|
+
"path",
|
|
1615
|
+
{
|
|
1616
|
+
d: "M9.5 3.5h3v3M12.25 3.75 8 8M7 4H4.5A1.5 1.5 0 0 0 3 5.5v6A1.5 1.5 0 0 0 4.5 13h6a1.5 1.5 0 0 0 1.5-1.5V9",
|
|
1617
|
+
stroke: "currentColor",
|
|
1618
|
+
strokeWidth: "1.4",
|
|
1619
|
+
strokeLinecap: "round",
|
|
1620
|
+
strokeLinejoin: "round"
|
|
1621
|
+
}
|
|
1622
|
+
) });
|
|
1623
|
+
}
|
|
1495
1624
|
function ExpandIcon() {
|
|
1496
1625
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1497
1626
|
"path",
|
|
@@ -1528,10 +1657,13 @@ function AgentRail({
|
|
|
1528
1657
|
onCollapse,
|
|
1529
1658
|
onClose,
|
|
1530
1659
|
onExpandToggle,
|
|
1660
|
+
onReset,
|
|
1661
|
+
onRetry,
|
|
1531
1662
|
onSubmit,
|
|
1532
1663
|
onFollowUpSelect
|
|
1533
1664
|
}) {
|
|
1534
1665
|
const transcriptRef = (0, import_react5.useRef)(null);
|
|
1666
|
+
const welcomeTitleId = (0, import_react5.useId)();
|
|
1535
1667
|
const resolvedTheme = { ...defaultAgentRailTheme, ...theme };
|
|
1536
1668
|
const railStyle = {
|
|
1537
1669
|
"--rail-width": resolvedTheme.railMaxWidth,
|
|
@@ -1558,7 +1690,13 @@ function AgentRail({
|
|
|
1558
1690
|
(message) => message.role === "visitor"
|
|
1559
1691
|
);
|
|
1560
1692
|
const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
|
|
1561
|
-
const
|
|
1693
|
+
const greeting = state.messages.find(
|
|
1694
|
+
(message) => message.role === "agent" && message.id === "greeting"
|
|
1695
|
+
);
|
|
1696
|
+
const visibleMessages = hasVisitorMessages2 ? state.messages.filter((message) => message.id !== "greeting") : [];
|
|
1697
|
+
const lastMessage = visibleMessages.at(-1);
|
|
1698
|
+
const completedAnswer = showActivity && state.phase === "complete" && lastMessage?.role === "agent" ? lastMessage : null;
|
|
1699
|
+
const transcriptMessages = completedAnswer ? visibleMessages.slice(0, -1) : visibleMessages;
|
|
1562
1700
|
const streamingMessage = state.phase === "streaming" && state.streamingText ? {
|
|
1563
1701
|
createdAt: 0,
|
|
1564
1702
|
id: "streaming-response",
|
|
@@ -1583,6 +1721,10 @@ function AgentRail({
|
|
|
1583
1721
|
className: `agent-rail${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}`,
|
|
1584
1722
|
style: railStyle,
|
|
1585
1723
|
"aria-label": "Agent conversation",
|
|
1724
|
+
"aria-modal": mobileFullscreen || expanded ? true : void 0,
|
|
1725
|
+
autoFocus: mobileFullscreen || expanded,
|
|
1726
|
+
role: mobileFullscreen || expanded ? "dialog" : void 0,
|
|
1727
|
+
tabIndex: mobileFullscreen || expanded ? -1 : void 0,
|
|
1586
1728
|
children: [
|
|
1587
1729
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("header", { className: "agent-rail__header", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "agent-rail__brand-row", children: [
|
|
1588
1730
|
onCollapse ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
@@ -1601,7 +1743,7 @@ function AgentRail({
|
|
|
1601
1743
|
className: "agent-rail__close",
|
|
1602
1744
|
"aria-label": "Close agent",
|
|
1603
1745
|
onClick: onClose,
|
|
1604
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1746
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CloseIcon, {})
|
|
1605
1747
|
}
|
|
1606
1748
|
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
|
|
1607
1749
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "agent-rail__identity", children: [
|
|
@@ -1621,81 +1763,102 @@ function AgentRail({
|
|
|
1621
1763
|
] }),
|
|
1622
1764
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "agent-rail__brand-label", children: brandLabel })
|
|
1623
1765
|
] }),
|
|
1624
|
-
|
|
1625
|
-
|
|
1766
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "agent-rail__actions", children: [
|
|
1767
|
+
onReset ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1768
|
+
"button",
|
|
1769
|
+
{
|
|
1770
|
+
type: "button",
|
|
1771
|
+
className: "agent-rail__new-chat",
|
|
1772
|
+
"aria-label": "Start a new conversation",
|
|
1773
|
+
disabled: !hasVisitorMessages2,
|
|
1774
|
+
onClick: onReset,
|
|
1775
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(NewChatIcon, {})
|
|
1776
|
+
}
|
|
1777
|
+
) : null,
|
|
1778
|
+
onExpandToggle ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1779
|
+
"button",
|
|
1780
|
+
{
|
|
1781
|
+
type: "button",
|
|
1782
|
+
className: "agent-rail__expand",
|
|
1783
|
+
"aria-label": expanded ? "Exit focus view" : "Open focus view",
|
|
1784
|
+
onClick: onExpandToggle,
|
|
1785
|
+
children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RestoreIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ExpandIcon, {})
|
|
1786
|
+
}
|
|
1787
|
+
) : null
|
|
1788
|
+
] })
|
|
1789
|
+
] }) }),
|
|
1790
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: transcriptRef, className: "agent-rail__transcript", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "agent-rail__thread", children: [
|
|
1791
|
+
!hasVisitorMessages2 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1792
|
+
"section",
|
|
1626
1793
|
{
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1794
|
+
className: "agent-rail__welcome",
|
|
1795
|
+
"aria-labelledby": welcomeTitleId,
|
|
1796
|
+
children: [
|
|
1797
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "agent-rail__welcome-mark", "aria-hidden": "true", children: [
|
|
1798
|
+
brandLabel.slice(0, 1).toUpperCase(),
|
|
1799
|
+
brandLogoUrl ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1800
|
+
"img",
|
|
1801
|
+
{
|
|
1802
|
+
className: "agent-rail__welcome-logo",
|
|
1803
|
+
src: brandLogoUrl,
|
|
1804
|
+
alt: "",
|
|
1805
|
+
onError: (event) => {
|
|
1806
|
+
event.currentTarget.hidden = true;
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
) : null
|
|
1810
|
+
] }),
|
|
1811
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "agent-rail__welcome-copy", children: [
|
|
1812
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { id: welcomeTitleId, children: "What can I help you find?" }),
|
|
1813
|
+
greeting?.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: greeting.text }) : null
|
|
1814
|
+
] }),
|
|
1815
|
+
showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1816
|
+
FollowUpChips,
|
|
1817
|
+
{
|
|
1818
|
+
suggestions: state.followUps,
|
|
1819
|
+
disabled: isBusy,
|
|
1820
|
+
label: "Start here",
|
|
1821
|
+
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
1822
|
+
}
|
|
1823
|
+
) }) : null
|
|
1824
|
+
]
|
|
1632
1825
|
}
|
|
1633
|
-
) :
|
|
1634
|
-
|
|
1635
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: transcriptRef, className: "agent-rail__transcript", children: [
|
|
1636
|
-
state.messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message }, message.id)),
|
|
1637
|
-
streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message: streamingMessage }) : null,
|
|
1826
|
+
) : null,
|
|
1827
|
+
transcriptMessages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message }, message.id)),
|
|
1638
1828
|
showActivity ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1639
1829
|
AgentActivityBubble,
|
|
1640
1830
|
{
|
|
1831
|
+
brandLabel,
|
|
1832
|
+
brandLogoUrl,
|
|
1641
1833
|
failed: state.phase === "error",
|
|
1642
1834
|
steps: state.toolSteps
|
|
1643
1835
|
}
|
|
1644
1836
|
) : null,
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
}
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
{
|
|
1657
|
-
role: "alert",
|
|
1658
|
-
style: { fontSize: 13, color: "var(--as-danger)", margin: 0 },
|
|
1659
|
-
children: state.error
|
|
1660
|
-
}
|
|
1661
|
-
) : null
|
|
1662
|
-
] }),
|
|
1663
|
-
expanded ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "agent-rail__dock-wrap", children: [
|
|
1664
|
-
showDockFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "agent-rail__dock-followups", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1665
|
-
FollowUpChips,
|
|
1666
|
-
{
|
|
1667
|
-
variant: "dock",
|
|
1668
|
-
suggestions: state.followUps,
|
|
1669
|
-
disabled: isBusy,
|
|
1670
|
-
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
1671
|
-
}
|
|
1672
|
-
) }) : null,
|
|
1673
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "agent-rail__dock", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1674
|
-
Composer,
|
|
1675
|
-
{
|
|
1676
|
-
variant: "dock",
|
|
1677
|
-
disabled: isBusy,
|
|
1678
|
-
placeholder: composerPlaceholder,
|
|
1679
|
-
onSubmit
|
|
1680
|
-
}
|
|
1681
|
-
) }),
|
|
1682
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "agent-rail__footer", children: [
|
|
1683
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "agent-rail__footer-disclaimer", children: "AI can make mistakes. Check important info." }),
|
|
1684
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "agent-rail__footer-note", children: poweredByLabel })
|
|
1685
|
-
] })
|
|
1686
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
|
|
1837
|
+
streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message: streamingMessage }) : null,
|
|
1838
|
+
completedAnswer ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message: completedAnswer }) : null,
|
|
1839
|
+
state.error ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: "agent-rail__error", role: "alert", children: [
|
|
1840
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
1841
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: "Something went wrong" }),
|
|
1842
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: state.error })
|
|
1843
|
+
] }),
|
|
1844
|
+
onRetry ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
|
|
1845
|
+
] }) : null
|
|
1846
|
+
] }) }),
|
|
1847
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
|
|
1687
1848
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1688
1849
|
Composer,
|
|
1689
1850
|
{
|
|
1851
|
+
variant: expanded || mobileFullscreen ? "dock" : "default",
|
|
1690
1852
|
disabled: isBusy,
|
|
1691
1853
|
placeholder: composerPlaceholder,
|
|
1692
1854
|
onSubmit
|
|
1693
1855
|
}
|
|
1694
1856
|
),
|
|
1695
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
1696
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("
|
|
1697
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("
|
|
1698
|
-
|
|
1857
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "agent-rail__footer", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { children: [
|
|
1858
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "AI can make mistakes." }),
|
|
1859
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { "aria-hidden": "true", children: " \xB7 " }),
|
|
1860
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: poweredByLabel })
|
|
1861
|
+
] }) })
|
|
1699
1862
|
] })
|
|
1700
1863
|
]
|
|
1701
1864
|
}
|
|
@@ -1779,7 +1942,12 @@ function AssistEdgeTab({
|
|
|
1779
1942
|
label,
|
|
1780
1943
|
logoUrl,
|
|
1781
1944
|
brandColor,
|
|
1945
|
+
brandForeground,
|
|
1946
|
+
borderColor,
|
|
1782
1947
|
fontFamily,
|
|
1948
|
+
mobile = false,
|
|
1949
|
+
surfaceColor,
|
|
1950
|
+
textColor,
|
|
1783
1951
|
onOpen
|
|
1784
1952
|
}) {
|
|
1785
1953
|
const copy = VARIANT_COPY[variant];
|
|
@@ -1788,20 +1956,50 @@ function AssistEdgeTab({
|
|
|
1788
1956
|
"--tab-along": `${along}%`,
|
|
1789
1957
|
"--tab-inset": `${inset}px`,
|
|
1790
1958
|
...brandColor ? { "--as-brand": brandColor } : {},
|
|
1791
|
-
...
|
|
1959
|
+
...brandForeground ? { "--as-visitor-text": brandForeground } : {},
|
|
1960
|
+
...borderColor ? { "--as-border": borderColor } : {},
|
|
1961
|
+
...fontFamily ? { "--as-font-display": fontFamily } : {},
|
|
1962
|
+
...surfaceColor ? { "--as-surface": surfaceColor } : {},
|
|
1963
|
+
...textColor ? { "--as-text": textColor } : {}
|
|
1792
1964
|
};
|
|
1793
1965
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1794
1966
|
"button",
|
|
1795
1967
|
{
|
|
1796
1968
|
type: "button",
|
|
1797
|
-
className: `assist-edge-tab assist-edge-tab--${variant} assist-edge-tab--${side}${visible ? " is-visible" : ""}`,
|
|
1969
|
+
className: `assist-edge-tab assist-edge-tab--${variant} assist-edge-tab--${side}${mobile ? " assist-edge-tab--mobile" : ""}${visible ? " is-visible" : ""}`,
|
|
1798
1970
|
style,
|
|
1799
1971
|
"aria-label": `Open ${visibleLabel}`,
|
|
1800
1972
|
"aria-hidden": !visible,
|
|
1801
1973
|
tabIndex: visible ? 0 : -1,
|
|
1802
1974
|
onClick: onOpen,
|
|
1803
1975
|
children: [
|
|
1804
|
-
|
|
1976
|
+
mobile ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1977
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1978
|
+
"span",
|
|
1979
|
+
{
|
|
1980
|
+
className: "assist-edge-tab__mark assist-edge-tab__mark--mobile",
|
|
1981
|
+
"aria-hidden": "true",
|
|
1982
|
+
children: [
|
|
1983
|
+
visibleLabel.slice(0, 1).toUpperCase(),
|
|
1984
|
+
logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1985
|
+
"img",
|
|
1986
|
+
{
|
|
1987
|
+
className: "assist-edge-tab__logo",
|
|
1988
|
+
src: logoUrl,
|
|
1989
|
+
alt: "",
|
|
1990
|
+
onError: (event) => {
|
|
1991
|
+
event.currentTarget.hidden = true;
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
) : null
|
|
1995
|
+
]
|
|
1996
|
+
}
|
|
1997
|
+
),
|
|
1998
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "assist-edge-tab__label", children: [
|
|
1999
|
+
"Ask ",
|
|
2000
|
+
visibleLabel
|
|
2001
|
+
] })
|
|
2002
|
+
] }) : variant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1805
2003
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
|
|
1806
2004
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SparklesIcon, {}),
|
|
1807
2005
|
logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
@@ -1877,7 +2075,7 @@ function AgentWidget({
|
|
|
1877
2075
|
active: pageShiftActive,
|
|
1878
2076
|
railSlotRef
|
|
1879
2077
|
});
|
|
1880
|
-
const { state, submit } = useAgentChat({
|
|
2078
|
+
const { state, reset, retry, submit } = useAgentChat({
|
|
1881
2079
|
customerId,
|
|
1882
2080
|
getUnpublishedPreviewGrant,
|
|
1883
2081
|
indexId,
|
|
@@ -1920,6 +2118,40 @@ function AgentWidget({
|
|
|
1920
2118
|
if (isMobile) setRailCollapsed(false);
|
|
1921
2119
|
await submit(message);
|
|
1922
2120
|
}
|
|
2121
|
+
(0, import_react6.useEffect)(() => {
|
|
2122
|
+
if (railCollapsed) return;
|
|
2123
|
+
const handleKeyDown = (event) => {
|
|
2124
|
+
if (event.key === "Tab" && (isMobile || railExpanded)) {
|
|
2125
|
+
const focusable = railSlotRef.current?.querySelectorAll(
|
|
2126
|
+
'button:not(:disabled), a[href], textarea:not(:disabled), input:not(:disabled), [tabindex]:not([tabindex="-1"])'
|
|
2127
|
+
);
|
|
2128
|
+
if (!focusable || focusable.length === 0) return;
|
|
2129
|
+
const first = focusable.item(0);
|
|
2130
|
+
const last = focusable.item(focusable.length - 1);
|
|
2131
|
+
const dialog = railSlotRef.current?.querySelector(".agent-rail");
|
|
2132
|
+
if (document.activeElement === dialog) {
|
|
2133
|
+
event.preventDefault();
|
|
2134
|
+
(event.shiftKey ? last : first).focus();
|
|
2135
|
+
} else if (event.shiftKey && document.activeElement === first) {
|
|
2136
|
+
event.preventDefault();
|
|
2137
|
+
last.focus();
|
|
2138
|
+
} else if (!event.shiftKey && document.activeElement === last) {
|
|
2139
|
+
event.preventDefault();
|
|
2140
|
+
first.focus();
|
|
2141
|
+
}
|
|
2142
|
+
return;
|
|
2143
|
+
}
|
|
2144
|
+
if (event.key === "Escape") {
|
|
2145
|
+
if (railExpanded) {
|
|
2146
|
+
setRailExpanded(false);
|
|
2147
|
+
return;
|
|
2148
|
+
}
|
|
2149
|
+
setRailCollapsed(true);
|
|
2150
|
+
}
|
|
2151
|
+
};
|
|
2152
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
2153
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
2154
|
+
}, [isMobile, railCollapsed, railExpanded]);
|
|
1923
2155
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "webless-agent-root", children: [
|
|
1924
2156
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1925
2157
|
"div",
|
|
@@ -1951,19 +2183,27 @@ function AgentWidget({
|
|
|
1951
2183
|
onClose: isMobile ? () => setRailCollapsed(true) : void 0,
|
|
1952
2184
|
onExpandToggle: !isMobile ? () => setRailExpanded((current) => !current) : void 0,
|
|
1953
2185
|
onSubmit: handleSubmit,
|
|
2186
|
+
onReset: reset,
|
|
2187
|
+
onRetry: () => void retry(),
|
|
1954
2188
|
onFollowUpSelect: (label) => void handleSubmit(label)
|
|
1955
2189
|
}
|
|
1956
2190
|
)
|
|
1957
2191
|
}
|
|
1958
2192
|
),
|
|
1959
|
-
!isMobile && railExpanded && !railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2193
|
+
!railCollapsed && isMobile || !isMobile && railExpanded && !railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1960
2194
|
"button",
|
|
1961
2195
|
{
|
|
1962
2196
|
type: "button",
|
|
1963
|
-
className: "webless-agent-root__backdrop"
|
|
2197
|
+
className: `webless-agent-root__backdrop${isMobile ? " webless-agent-root__backdrop--mobile" : ""}`,
|
|
1964
2198
|
tabIndex: -1,
|
|
1965
|
-
"aria-label": "Close
|
|
1966
|
-
onClick: () =>
|
|
2199
|
+
"aria-label": isMobile ? "Close agent" : "Exit focus view",
|
|
2200
|
+
onClick: () => {
|
|
2201
|
+
if (isMobile) {
|
|
2202
|
+
setRailCollapsed(true);
|
|
2203
|
+
} else {
|
|
2204
|
+
setRailExpanded(false);
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
1967
2207
|
}
|
|
1968
2208
|
) : null
|
|
1969
2209
|
]
|
|
@@ -1980,7 +2220,12 @@ function AgentWidget({
|
|
|
1980
2220
|
label: agentName,
|
|
1981
2221
|
logoUrl: branding?.logoUrl,
|
|
1982
2222
|
brandColor: branding?.colors?.primary,
|
|
2223
|
+
brandForeground: branding?.colors?.primaryForeground,
|
|
2224
|
+
borderColor: branding?.colors?.border,
|
|
1983
2225
|
fontFamily: branding?.fontFamily,
|
|
2226
|
+
mobile: isMobile,
|
|
2227
|
+
surfaceColor: branding?.colors?.surface,
|
|
2228
|
+
textColor: branding?.colors?.text,
|
|
1984
2229
|
onOpen: () => setRailCollapsed(false)
|
|
1985
2230
|
}
|
|
1986
2231
|
) : null
|