@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/react.cjs
CHANGED
|
@@ -386,13 +386,15 @@ function emitWorkItem(item, handlers, workItems) {
|
|
|
386
386
|
handlers.onWork?.(item);
|
|
387
387
|
handlers.onStep?.(item.label, item.detail);
|
|
388
388
|
}
|
|
389
|
-
function completePlanning(handlers, workItems) {
|
|
389
|
+
function completePlanning(handlers, workItems, nextItems = []) {
|
|
390
390
|
const planning = workItems.get("planning");
|
|
391
391
|
if (!planning || planning.state !== "active") return;
|
|
392
|
+
const specialists = nextItems.filter((item) => item.kind === "specialist");
|
|
393
|
+
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";
|
|
392
394
|
emitWorkItem(
|
|
393
395
|
{
|
|
394
396
|
...planning,
|
|
395
|
-
detail
|
|
397
|
+
detail,
|
|
396
398
|
state: "completed"
|
|
397
399
|
},
|
|
398
400
|
handlers,
|
|
@@ -442,11 +444,12 @@ function applyWorkEvent(event, handlers, workItems) {
|
|
|
442
444
|
return;
|
|
443
445
|
}
|
|
444
446
|
if (event.type === "actions.requested") {
|
|
445
|
-
|
|
446
|
-
for (const action of event.data.actions) {
|
|
447
|
+
const nextItems = event.data.actions.flatMap((action) => {
|
|
447
448
|
const item = requestedWorkItem(action);
|
|
448
|
-
|
|
449
|
-
}
|
|
449
|
+
return item ? [item] : [];
|
|
450
|
+
});
|
|
451
|
+
completePlanning(handlers, workItems, nextItems);
|
|
452
|
+
for (const item of nextItems) emitWorkItem(item, handlers, workItems);
|
|
450
453
|
return;
|
|
451
454
|
}
|
|
452
455
|
if (event.type === "subagent.called") {
|
|
@@ -1168,6 +1171,37 @@ function useAgentChat({
|
|
|
1168
1171
|
},
|
|
1169
1172
|
[runTurn]
|
|
1170
1173
|
);
|
|
1174
|
+
const retry = (0, import_react2.useCallback)(async () => {
|
|
1175
|
+
const visitorMessage = [...state.messages].reverse().find((message) => message.role === "visitor");
|
|
1176
|
+
if (!visitorMessage) return;
|
|
1177
|
+
if (runRef.current) {
|
|
1178
|
+
runRef.current.abort();
|
|
1179
|
+
clientRef.current.cancelActive();
|
|
1180
|
+
}
|
|
1181
|
+
const controller = new AbortController();
|
|
1182
|
+
runRef.current = controller;
|
|
1183
|
+
setState((prev) => ({
|
|
1184
|
+
...prev,
|
|
1185
|
+
phase: "thinking",
|
|
1186
|
+
toolSteps: [
|
|
1187
|
+
{
|
|
1188
|
+
id: "planning",
|
|
1189
|
+
kind: "planning",
|
|
1190
|
+
label: "Understanding your question",
|
|
1191
|
+
state: "active"
|
|
1192
|
+
}
|
|
1193
|
+
],
|
|
1194
|
+
journey: null,
|
|
1195
|
+
followUps: [],
|
|
1196
|
+
streamingText: "",
|
|
1197
|
+
error: null
|
|
1198
|
+
}));
|
|
1199
|
+
await runTurn({
|
|
1200
|
+
controller,
|
|
1201
|
+
resume: false,
|
|
1202
|
+
visitorText: visitorMessage.text
|
|
1203
|
+
});
|
|
1204
|
+
}, [runTurn, state.messages]);
|
|
1171
1205
|
(0, import_react2.useEffect)(() => {
|
|
1172
1206
|
const conversation = loadPersistedAgentConversation(
|
|
1173
1207
|
resolvedStorageKeyPrefix,
|
|
@@ -1200,6 +1234,7 @@ function useAgentChat({
|
|
|
1200
1234
|
return {
|
|
1201
1235
|
state,
|
|
1202
1236
|
reset,
|
|
1237
|
+
retry,
|
|
1203
1238
|
submit,
|
|
1204
1239
|
visitorSessionId: visitorId,
|
|
1205
1240
|
sessionId: clientRef.current.getActiveSessionId()
|
|
@@ -1286,11 +1321,12 @@ var defaultAgentRailTheme = {
|
|
|
1286
1321
|
|
|
1287
1322
|
// src/react/components/AgentActivityBubble/AgentActivityBubble.tsx
|
|
1288
1323
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
1289
|
-
function workSummary(steps, failed) {
|
|
1324
|
+
function workSummary(steps, failed, brandLabel) {
|
|
1290
1325
|
const active = [...steps].reverse().find((step) => step.state === "active");
|
|
1291
|
-
if (active?.kind === "specialist")
|
|
1326
|
+
if (active?.kind === "specialist")
|
|
1327
|
+
return `${active.label} is reviewing your question`;
|
|
1292
1328
|
if (active?.kind === "search") return "Searching this site";
|
|
1293
|
-
if (active) return
|
|
1329
|
+
if (active) return `${brandLabel} is choosing the best way to help`;
|
|
1294
1330
|
if (failed) return "Couldn\u2019t complete this request";
|
|
1295
1331
|
const hasError = steps.some((step) => step.state === "error");
|
|
1296
1332
|
const specialists = steps.filter(
|
|
@@ -1301,16 +1337,60 @@ function workSummary(steps, failed) {
|
|
|
1301
1337
|
);
|
|
1302
1338
|
if (hasError) return "Answered with available information";
|
|
1303
1339
|
if (specialists.length > 1)
|
|
1304
|
-
return `
|
|
1305
|
-
if (specialists.length === 1)
|
|
1306
|
-
|
|
1307
|
-
return "
|
|
1340
|
+
return `Answer prepared with ${specialists.length} specialists`;
|
|
1341
|
+
if (specialists.length === 1)
|
|
1342
|
+
return `Answer prepared with ${specialists[0]?.label}`;
|
|
1343
|
+
if (searched) return "Answer prepared from this site";
|
|
1344
|
+
return "Answer ready";
|
|
1345
|
+
}
|
|
1346
|
+
function stepLabel(step, brandLabel) {
|
|
1347
|
+
return step.kind === "planning" ? brandLabel : step.label;
|
|
1348
|
+
}
|
|
1349
|
+
function stepDetail(step, steps) {
|
|
1350
|
+
if (step.kind !== "planning" || step.state !== "completed") {
|
|
1351
|
+
return step.detail;
|
|
1352
|
+
}
|
|
1353
|
+
const specialists = steps.filter((item) => item.kind === "specialist");
|
|
1354
|
+
if (specialists.length === 1) return `Delegated to ${specialists[0]?.label}`;
|
|
1355
|
+
if (specialists.length > 1)
|
|
1356
|
+
return `Delegated to ${specialists.length} specialists`;
|
|
1357
|
+
if (steps.some((item) => item.kind === "search"))
|
|
1358
|
+
return "Used built-in Search & Discovery";
|
|
1359
|
+
return step.detail;
|
|
1360
|
+
}
|
|
1361
|
+
function SearchIcon() {
|
|
1362
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
|
|
1363
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "7", cy: "7", r: "3.75", stroke: "currentColor", strokeWidth: "1.4" }),
|
|
1364
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1365
|
+
"path",
|
|
1366
|
+
{
|
|
1367
|
+
d: "m10 10 3 3",
|
|
1368
|
+
stroke: "currentColor",
|
|
1369
|
+
strokeWidth: "1.4",
|
|
1370
|
+
strokeLinecap: "round"
|
|
1371
|
+
}
|
|
1372
|
+
)
|
|
1373
|
+
] });
|
|
1374
|
+
}
|
|
1375
|
+
function PlanningIcon() {
|
|
1376
|
+
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)(
|
|
1377
|
+
"path",
|
|
1378
|
+
{
|
|
1379
|
+
d: "M4 4.5h8M4 8h5.5M4 11.5h7",
|
|
1380
|
+
stroke: "currentColor",
|
|
1381
|
+
strokeWidth: "1.4",
|
|
1382
|
+
strokeLinecap: "round"
|
|
1383
|
+
}
|
|
1384
|
+
) });
|
|
1308
1385
|
}
|
|
1309
1386
|
function AgentActivityBubble({
|
|
1387
|
+
brandLabel = "Webless Guide",
|
|
1388
|
+
brandLogoUrl,
|
|
1310
1389
|
failed = false,
|
|
1311
1390
|
steps
|
|
1312
1391
|
}) {
|
|
1313
1392
|
const active = steps.some((step) => step.state === "active");
|
|
1393
|
+
const delegated = steps.some((step) => step.kind === "specialist");
|
|
1314
1394
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", { className: "agent-activity-bubble", children: [
|
|
1315
1395
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "agent-activity-bubble__status", "aria-live": "polite", children: [
|
|
1316
1396
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -1320,33 +1400,59 @@ function AgentActivityBubble({
|
|
|
1320
1400
|
"aria-hidden": "true"
|
|
1321
1401
|
}
|
|
1322
1402
|
),
|
|
1323
|
-
workSummary(steps, failed)
|
|
1403
|
+
workSummary(steps, failed, brandLabel)
|
|
1324
1404
|
] }),
|
|
1325
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
"
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
"
|
|
1332
|
-
children:
|
|
1333
|
-
|
|
1334
|
-
|
|
1405
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1406
|
+
"details",
|
|
1407
|
+
{
|
|
1408
|
+
className: "agent-activity-bubble__details",
|
|
1409
|
+
open: active || delegated,
|
|
1410
|
+
children: [
|
|
1411
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: failed ? "What happened" : active ? "Working" : "How this answer was prepared" }),
|
|
1412
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "agent-activity-bubble__steps", children: steps.map((step) => {
|
|
1413
|
+
const detail = stepDetail(step, steps);
|
|
1414
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1415
|
+
"li",
|
|
1335
1416
|
{
|
|
1336
|
-
className: "agent-activity-bubble__step
|
|
1337
|
-
"
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1417
|
+
className: "agent-activity-bubble__step",
|
|
1418
|
+
"data-kind": step.kind,
|
|
1419
|
+
"data-state": step.state,
|
|
1420
|
+
children: [
|
|
1421
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1422
|
+
"span",
|
|
1423
|
+
{
|
|
1424
|
+
className: "agent-activity-bubble__step-icon",
|
|
1425
|
+
"aria-hidden": "true",
|
|
1426
|
+
children: step.kind === "planning" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1427
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(PlanningIcon, {}),
|
|
1428
|
+
brandLogoUrl ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1429
|
+
"img",
|
|
1430
|
+
{
|
|
1431
|
+
src: brandLogoUrl,
|
|
1432
|
+
alt: "",
|
|
1433
|
+
onError: (event) => {
|
|
1434
|
+
event.currentTarget.hidden = true;
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
) : null
|
|
1438
|
+
] }) : step.kind === "search" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SearchIcon, {}) : step.label.slice(0, 1).toUpperCase()
|
|
1439
|
+
}
|
|
1440
|
+
),
|
|
1441
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__step-copy", children: [
|
|
1442
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__step-heading", children: [
|
|
1443
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: stepLabel(step, brandLabel) }),
|
|
1444
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: step.kind === "specialist" ? "Specialist" : step.kind === "search" ? "Built-in capability" : "Supervisor" })
|
|
1445
|
+
] }),
|
|
1446
|
+
detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-activity-bubble__step-detail", children: detail }) : null
|
|
1447
|
+
] })
|
|
1448
|
+
]
|
|
1449
|
+
},
|
|
1450
|
+
step.id
|
|
1451
|
+
);
|
|
1452
|
+
}) })
|
|
1453
|
+
]
|
|
1454
|
+
}
|
|
1455
|
+
)
|
|
1350
1456
|
] });
|
|
1351
1457
|
}
|
|
1352
1458
|
|
|
@@ -1485,6 +1591,29 @@ function MinimizeIcon() {
|
|
|
1485
1591
|
}
|
|
1486
1592
|
) });
|
|
1487
1593
|
}
|
|
1594
|
+
function CloseIcon() {
|
|
1595
|
+
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)(
|
|
1596
|
+
"path",
|
|
1597
|
+
{
|
|
1598
|
+
d: "M4 4l8 8M12 4l-8 8",
|
|
1599
|
+
stroke: "currentColor",
|
|
1600
|
+
strokeWidth: "1.5",
|
|
1601
|
+
strokeLinecap: "round"
|
|
1602
|
+
}
|
|
1603
|
+
) });
|
|
1604
|
+
}
|
|
1605
|
+
function NewChatIcon() {
|
|
1606
|
+
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)(
|
|
1607
|
+
"path",
|
|
1608
|
+
{
|
|
1609
|
+
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",
|
|
1610
|
+
stroke: "currentColor",
|
|
1611
|
+
strokeWidth: "1.4",
|
|
1612
|
+
strokeLinecap: "round",
|
|
1613
|
+
strokeLinejoin: "round"
|
|
1614
|
+
}
|
|
1615
|
+
) });
|
|
1616
|
+
}
|
|
1488
1617
|
function ExpandIcon() {
|
|
1489
1618
|
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)(
|
|
1490
1619
|
"path",
|
|
@@ -1521,10 +1650,13 @@ function AgentRail({
|
|
|
1521
1650
|
onCollapse,
|
|
1522
1651
|
onClose,
|
|
1523
1652
|
onExpandToggle,
|
|
1653
|
+
onReset,
|
|
1654
|
+
onRetry,
|
|
1524
1655
|
onSubmit,
|
|
1525
1656
|
onFollowUpSelect
|
|
1526
1657
|
}) {
|
|
1527
1658
|
const transcriptRef = (0, import_react5.useRef)(null);
|
|
1659
|
+
const welcomeTitleId = (0, import_react5.useId)();
|
|
1528
1660
|
const resolvedTheme = { ...defaultAgentRailTheme, ...theme };
|
|
1529
1661
|
const railStyle = {
|
|
1530
1662
|
"--rail-width": resolvedTheme.railMaxWidth,
|
|
@@ -1551,7 +1683,13 @@ function AgentRail({
|
|
|
1551
1683
|
(message) => message.role === "visitor"
|
|
1552
1684
|
);
|
|
1553
1685
|
const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
|
|
1554
|
-
const
|
|
1686
|
+
const greeting = state.messages.find(
|
|
1687
|
+
(message) => message.role === "agent" && message.id === "greeting"
|
|
1688
|
+
);
|
|
1689
|
+
const visibleMessages = hasVisitorMessages2 ? state.messages.filter((message) => message.id !== "greeting") : [];
|
|
1690
|
+
const lastMessage = visibleMessages.at(-1);
|
|
1691
|
+
const completedAnswer = showActivity && state.phase === "complete" && lastMessage?.role === "agent" ? lastMessage : null;
|
|
1692
|
+
const transcriptMessages = completedAnswer ? visibleMessages.slice(0, -1) : visibleMessages;
|
|
1555
1693
|
const streamingMessage = state.phase === "streaming" && state.streamingText ? {
|
|
1556
1694
|
createdAt: 0,
|
|
1557
1695
|
id: "streaming-response",
|
|
@@ -1576,6 +1714,10 @@ function AgentRail({
|
|
|
1576
1714
|
className: `agent-rail${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}`,
|
|
1577
1715
|
style: railStyle,
|
|
1578
1716
|
"aria-label": "Agent conversation",
|
|
1717
|
+
"aria-modal": mobileFullscreen || expanded ? true : void 0,
|
|
1718
|
+
autoFocus: mobileFullscreen || expanded,
|
|
1719
|
+
role: mobileFullscreen || expanded ? "dialog" : void 0,
|
|
1720
|
+
tabIndex: mobileFullscreen || expanded ? -1 : void 0,
|
|
1579
1721
|
children: [
|
|
1580
1722
|
/* @__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: [
|
|
1581
1723
|
onCollapse ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
@@ -1594,7 +1736,7 @@ function AgentRail({
|
|
|
1594
1736
|
className: "agent-rail__close",
|
|
1595
1737
|
"aria-label": "Close agent",
|
|
1596
1738
|
onClick: onClose,
|
|
1597
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1739
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CloseIcon, {})
|
|
1598
1740
|
}
|
|
1599
1741
|
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
|
|
1600
1742
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "agent-rail__identity", children: [
|
|
@@ -1614,81 +1756,102 @@ function AgentRail({
|
|
|
1614
1756
|
] }),
|
|
1615
1757
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "agent-rail__brand-label", children: brandLabel })
|
|
1616
1758
|
] }),
|
|
1617
|
-
|
|
1618
|
-
|
|
1759
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "agent-rail__actions", children: [
|
|
1760
|
+
onReset ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1761
|
+
"button",
|
|
1762
|
+
{
|
|
1763
|
+
type: "button",
|
|
1764
|
+
className: "agent-rail__new-chat",
|
|
1765
|
+
"aria-label": "Start a new conversation",
|
|
1766
|
+
disabled: !hasVisitorMessages2,
|
|
1767
|
+
onClick: onReset,
|
|
1768
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(NewChatIcon, {})
|
|
1769
|
+
}
|
|
1770
|
+
) : null,
|
|
1771
|
+
onExpandToggle ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1772
|
+
"button",
|
|
1773
|
+
{
|
|
1774
|
+
type: "button",
|
|
1775
|
+
className: "agent-rail__expand",
|
|
1776
|
+
"aria-label": expanded ? "Exit focus view" : "Open focus view",
|
|
1777
|
+
onClick: onExpandToggle,
|
|
1778
|
+
children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RestoreIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ExpandIcon, {})
|
|
1779
|
+
}
|
|
1780
|
+
) : null
|
|
1781
|
+
] })
|
|
1782
|
+
] }) }),
|
|
1783
|
+
/* @__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: [
|
|
1784
|
+
!hasVisitorMessages2 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1785
|
+
"section",
|
|
1619
1786
|
{
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1787
|
+
className: "agent-rail__welcome",
|
|
1788
|
+
"aria-labelledby": welcomeTitleId,
|
|
1789
|
+
children: [
|
|
1790
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "agent-rail__welcome-mark", "aria-hidden": "true", children: [
|
|
1791
|
+
brandLabel.slice(0, 1).toUpperCase(),
|
|
1792
|
+
brandLogoUrl ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1793
|
+
"img",
|
|
1794
|
+
{
|
|
1795
|
+
className: "agent-rail__welcome-logo",
|
|
1796
|
+
src: brandLogoUrl,
|
|
1797
|
+
alt: "",
|
|
1798
|
+
onError: (event) => {
|
|
1799
|
+
event.currentTarget.hidden = true;
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
) : null
|
|
1803
|
+
] }),
|
|
1804
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "agent-rail__welcome-copy", children: [
|
|
1805
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { id: welcomeTitleId, children: "What can I help you find?" }),
|
|
1806
|
+
greeting?.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: greeting.text }) : null
|
|
1807
|
+
] }),
|
|
1808
|
+
showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1809
|
+
FollowUpChips,
|
|
1810
|
+
{
|
|
1811
|
+
suggestions: state.followUps,
|
|
1812
|
+
disabled: isBusy,
|
|
1813
|
+
label: "Start here",
|
|
1814
|
+
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
1815
|
+
}
|
|
1816
|
+
) }) : null
|
|
1817
|
+
]
|
|
1625
1818
|
}
|
|
1626
|
-
) :
|
|
1627
|
-
|
|
1628
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: transcriptRef, className: "agent-rail__transcript", children: [
|
|
1629
|
-
state.messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message }, message.id)),
|
|
1630
|
-
streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message: streamingMessage }) : null,
|
|
1819
|
+
) : null,
|
|
1820
|
+
transcriptMessages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message }, message.id)),
|
|
1631
1821
|
showActivity ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1632
1822
|
AgentActivityBubble,
|
|
1633
1823
|
{
|
|
1824
|
+
brandLabel,
|
|
1825
|
+
brandLogoUrl,
|
|
1634
1826
|
failed: state.phase === "error",
|
|
1635
1827
|
steps: state.toolSteps
|
|
1636
1828
|
}
|
|
1637
1829
|
) : null,
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
}
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
{
|
|
1650
|
-
role: "alert",
|
|
1651
|
-
style: { fontSize: 13, color: "var(--as-danger)", margin: 0 },
|
|
1652
|
-
children: state.error
|
|
1653
|
-
}
|
|
1654
|
-
) : null
|
|
1655
|
-
] }),
|
|
1656
|
-
expanded ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "agent-rail__dock-wrap", children: [
|
|
1657
|
-
showDockFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "agent-rail__dock-followups", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1658
|
-
FollowUpChips,
|
|
1659
|
-
{
|
|
1660
|
-
variant: "dock",
|
|
1661
|
-
suggestions: state.followUps,
|
|
1662
|
-
disabled: isBusy,
|
|
1663
|
-
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
1664
|
-
}
|
|
1665
|
-
) }) : null,
|
|
1666
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "agent-rail__dock", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1667
|
-
Composer,
|
|
1668
|
-
{
|
|
1669
|
-
variant: "dock",
|
|
1670
|
-
disabled: isBusy,
|
|
1671
|
-
placeholder: composerPlaceholder,
|
|
1672
|
-
onSubmit
|
|
1673
|
-
}
|
|
1674
|
-
) }),
|
|
1675
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "agent-rail__footer", children: [
|
|
1676
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "agent-rail__footer-disclaimer", children: "AI can make mistakes. Check important info." }),
|
|
1677
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "agent-rail__footer-note", children: poweredByLabel })
|
|
1678
|
-
] })
|
|
1679
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
|
|
1830
|
+
streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message: streamingMessage }) : null,
|
|
1831
|
+
completedAnswer ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message: completedAnswer }) : null,
|
|
1832
|
+
state.error ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: "agent-rail__error", role: "alert", children: [
|
|
1833
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
1834
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: "Something went wrong" }),
|
|
1835
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: state.error })
|
|
1836
|
+
] }),
|
|
1837
|
+
onRetry ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
|
|
1838
|
+
] }) : null
|
|
1839
|
+
] }) }),
|
|
1840
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
|
|
1680
1841
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1681
1842
|
Composer,
|
|
1682
1843
|
{
|
|
1844
|
+
variant: expanded || mobileFullscreen ? "dock" : "default",
|
|
1683
1845
|
disabled: isBusy,
|
|
1684
1846
|
placeholder: composerPlaceholder,
|
|
1685
1847
|
onSubmit
|
|
1686
1848
|
}
|
|
1687
1849
|
),
|
|
1688
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
1689
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("
|
|
1690
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("
|
|
1691
|
-
|
|
1850
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "agent-rail__footer", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { children: [
|
|
1851
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "AI can make mistakes." }),
|
|
1852
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { "aria-hidden": "true", children: " \xB7 " }),
|
|
1853
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: poweredByLabel })
|
|
1854
|
+
] }) })
|
|
1692
1855
|
] })
|
|
1693
1856
|
]
|
|
1694
1857
|
}
|
|
@@ -1772,7 +1935,12 @@ function AssistEdgeTab({
|
|
|
1772
1935
|
label,
|
|
1773
1936
|
logoUrl,
|
|
1774
1937
|
brandColor,
|
|
1938
|
+
brandForeground,
|
|
1939
|
+
borderColor,
|
|
1775
1940
|
fontFamily,
|
|
1941
|
+
mobile = false,
|
|
1942
|
+
surfaceColor,
|
|
1943
|
+
textColor,
|
|
1776
1944
|
onOpen
|
|
1777
1945
|
}) {
|
|
1778
1946
|
const copy = VARIANT_COPY[variant];
|
|
@@ -1781,20 +1949,50 @@ function AssistEdgeTab({
|
|
|
1781
1949
|
"--tab-along": `${along}%`,
|
|
1782
1950
|
"--tab-inset": `${inset}px`,
|
|
1783
1951
|
...brandColor ? { "--as-brand": brandColor } : {},
|
|
1784
|
-
...
|
|
1952
|
+
...brandForeground ? { "--as-visitor-text": brandForeground } : {},
|
|
1953
|
+
...borderColor ? { "--as-border": borderColor } : {},
|
|
1954
|
+
...fontFamily ? { "--as-font-display": fontFamily } : {},
|
|
1955
|
+
...surfaceColor ? { "--as-surface": surfaceColor } : {},
|
|
1956
|
+
...textColor ? { "--as-text": textColor } : {}
|
|
1785
1957
|
};
|
|
1786
1958
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1787
1959
|
"button",
|
|
1788
1960
|
{
|
|
1789
1961
|
type: "button",
|
|
1790
|
-
className: `assist-edge-tab assist-edge-tab--${variant} assist-edge-tab--${side}${visible ? " is-visible" : ""}`,
|
|
1962
|
+
className: `assist-edge-tab assist-edge-tab--${variant} assist-edge-tab--${side}${mobile ? " assist-edge-tab--mobile" : ""}${visible ? " is-visible" : ""}`,
|
|
1791
1963
|
style,
|
|
1792
1964
|
"aria-label": `Open ${visibleLabel}`,
|
|
1793
1965
|
"aria-hidden": !visible,
|
|
1794
1966
|
tabIndex: visible ? 0 : -1,
|
|
1795
1967
|
onClick: onOpen,
|
|
1796
1968
|
children: [
|
|
1797
|
-
|
|
1969
|
+
mobile ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1970
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1971
|
+
"span",
|
|
1972
|
+
{
|
|
1973
|
+
className: "assist-edge-tab__mark assist-edge-tab__mark--mobile",
|
|
1974
|
+
"aria-hidden": "true",
|
|
1975
|
+
children: [
|
|
1976
|
+
visibleLabel.slice(0, 1).toUpperCase(),
|
|
1977
|
+
logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1978
|
+
"img",
|
|
1979
|
+
{
|
|
1980
|
+
className: "assist-edge-tab__logo",
|
|
1981
|
+
src: logoUrl,
|
|
1982
|
+
alt: "",
|
|
1983
|
+
onError: (event) => {
|
|
1984
|
+
event.currentTarget.hidden = true;
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
) : null
|
|
1988
|
+
]
|
|
1989
|
+
}
|
|
1990
|
+
),
|
|
1991
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "assist-edge-tab__label", children: [
|
|
1992
|
+
"Ask ",
|
|
1993
|
+
visibleLabel
|
|
1994
|
+
] })
|
|
1995
|
+
] }) : variant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1798
1996
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
|
|
1799
1997
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SparklesIcon, {}),
|
|
1800
1998
|
logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
@@ -1870,7 +2068,7 @@ function AgentWidget({
|
|
|
1870
2068
|
active: pageShiftActive,
|
|
1871
2069
|
railSlotRef
|
|
1872
2070
|
});
|
|
1873
|
-
const { state, submit } = useAgentChat({
|
|
2071
|
+
const { state, reset, retry, submit } = useAgentChat({
|
|
1874
2072
|
customerId,
|
|
1875
2073
|
getUnpublishedPreviewGrant,
|
|
1876
2074
|
indexId,
|
|
@@ -1913,6 +2111,40 @@ function AgentWidget({
|
|
|
1913
2111
|
if (isMobile) setRailCollapsed(false);
|
|
1914
2112
|
await submit(message);
|
|
1915
2113
|
}
|
|
2114
|
+
(0, import_react6.useEffect)(() => {
|
|
2115
|
+
if (railCollapsed) return;
|
|
2116
|
+
const handleKeyDown = (event) => {
|
|
2117
|
+
if (event.key === "Tab" && (isMobile || railExpanded)) {
|
|
2118
|
+
const focusable = railSlotRef.current?.querySelectorAll(
|
|
2119
|
+
'button:not(:disabled), a[href], textarea:not(:disabled), input:not(:disabled), [tabindex]:not([tabindex="-1"])'
|
|
2120
|
+
);
|
|
2121
|
+
if (!focusable || focusable.length === 0) return;
|
|
2122
|
+
const first = focusable.item(0);
|
|
2123
|
+
const last = focusable.item(focusable.length - 1);
|
|
2124
|
+
const dialog = railSlotRef.current?.querySelector(".agent-rail");
|
|
2125
|
+
if (document.activeElement === dialog) {
|
|
2126
|
+
event.preventDefault();
|
|
2127
|
+
(event.shiftKey ? last : first).focus();
|
|
2128
|
+
} else if (event.shiftKey && document.activeElement === first) {
|
|
2129
|
+
event.preventDefault();
|
|
2130
|
+
last.focus();
|
|
2131
|
+
} else if (!event.shiftKey && document.activeElement === last) {
|
|
2132
|
+
event.preventDefault();
|
|
2133
|
+
first.focus();
|
|
2134
|
+
}
|
|
2135
|
+
return;
|
|
2136
|
+
}
|
|
2137
|
+
if (event.key === "Escape") {
|
|
2138
|
+
if (railExpanded) {
|
|
2139
|
+
setRailExpanded(false);
|
|
2140
|
+
return;
|
|
2141
|
+
}
|
|
2142
|
+
setRailCollapsed(true);
|
|
2143
|
+
}
|
|
2144
|
+
};
|
|
2145
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
2146
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
2147
|
+
}, [isMobile, railCollapsed, railExpanded]);
|
|
1916
2148
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "webless-agent-root", children: [
|
|
1917
2149
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1918
2150
|
"div",
|
|
@@ -1944,19 +2176,27 @@ function AgentWidget({
|
|
|
1944
2176
|
onClose: isMobile ? () => setRailCollapsed(true) : void 0,
|
|
1945
2177
|
onExpandToggle: !isMobile ? () => setRailExpanded((current) => !current) : void 0,
|
|
1946
2178
|
onSubmit: handleSubmit,
|
|
2179
|
+
onReset: reset,
|
|
2180
|
+
onRetry: () => void retry(),
|
|
1947
2181
|
onFollowUpSelect: (label) => void handleSubmit(label)
|
|
1948
2182
|
}
|
|
1949
2183
|
)
|
|
1950
2184
|
}
|
|
1951
2185
|
),
|
|
1952
|
-
!isMobile && railExpanded && !railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2186
|
+
!railCollapsed && isMobile || !isMobile && railExpanded && !railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1953
2187
|
"button",
|
|
1954
2188
|
{
|
|
1955
2189
|
type: "button",
|
|
1956
|
-
className: "webless-agent-root__backdrop"
|
|
2190
|
+
className: `webless-agent-root__backdrop${isMobile ? " webless-agent-root__backdrop--mobile" : ""}`,
|
|
1957
2191
|
tabIndex: -1,
|
|
1958
|
-
"aria-label": "Close
|
|
1959
|
-
onClick: () =>
|
|
2192
|
+
"aria-label": isMobile ? "Close agent" : "Exit focus view",
|
|
2193
|
+
onClick: () => {
|
|
2194
|
+
if (isMobile) {
|
|
2195
|
+
setRailCollapsed(true);
|
|
2196
|
+
} else {
|
|
2197
|
+
setRailExpanded(false);
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
1960
2200
|
}
|
|
1961
2201
|
) : null
|
|
1962
2202
|
]
|
|
@@ -1973,7 +2213,12 @@ function AgentWidget({
|
|
|
1973
2213
|
label: agentName,
|
|
1974
2214
|
logoUrl: branding?.logoUrl,
|
|
1975
2215
|
brandColor: branding?.colors?.primary,
|
|
2216
|
+
brandForeground: branding?.colors?.primaryForeground,
|
|
2217
|
+
borderColor: branding?.colors?.border,
|
|
1976
2218
|
fontFamily: branding?.fontFamily,
|
|
2219
|
+
mobile: isMobile,
|
|
2220
|
+
surfaceColor: branding?.colors?.surface,
|
|
2221
|
+
textColor: branding?.colors?.text,
|
|
1977
2222
|
onOpen: () => setRailCollapsed(false)
|
|
1978
2223
|
}
|
|
1979
2224
|
) : null
|