@webless/agent 0.3.1 → 0.4.0
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-MMYSBSHG.js → chunk-SVWXFDV3.js} +395 -119
- package/dist/chunk-SVWXFDV3.js.map +1 -0
- package/dist/embed.cjs +403 -113
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.css +502 -235
- 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 +15 -1
- package/dist/embed.js.map +1 -1
- package/dist/index.cjs +28 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +28 -10
- 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 +389 -113
- package/dist/react.cjs.map +1 -1
- package/dist/react.css +502 -235
- package/dist/react.css.map +1 -1
- package/dist/react.d.cts +11 -6
- package/dist/react.d.ts +11 -6
- package/dist/react.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-MMYSBSHG.js.map +0 -1
package/dist/embed.cjs
CHANGED
|
@@ -178,11 +178,12 @@ function createAgentRuntimeCapability(options) {
|
|
|
178
178
|
let pendingBootstrap;
|
|
179
179
|
const bootstrap = async () => {
|
|
180
180
|
let previewGrant;
|
|
181
|
+
const previewBuildId = options.previewBuildId?.trim();
|
|
181
182
|
if (options.version === "unpublished") {
|
|
182
|
-
previewGrant = (await options.getUnpublishedPreviewGrant?.())?.trim();
|
|
183
|
-
if (!previewGrant) {
|
|
183
|
+
previewGrant = previewBuildId ? void 0 : (await options.getUnpublishedPreviewGrant?.())?.trim();
|
|
184
|
+
if (!previewGrant && !previewBuildId) {
|
|
184
185
|
throw new Error(
|
|
185
|
-
"
|
|
186
|
+
"Unpublished preview authorization is required to use the Agent Runtime preview."
|
|
186
187
|
);
|
|
187
188
|
}
|
|
188
189
|
}
|
|
@@ -192,6 +193,7 @@ function createAgentRuntimeCapability(options) {
|
|
|
192
193
|
body: JSON.stringify({
|
|
193
194
|
clientSessionId: options.visitorSessionId,
|
|
194
195
|
indexId: options.indexId,
|
|
196
|
+
...previewBuildId ? { previewBuildId } : {},
|
|
195
197
|
...previewGrant ? { previewGrant } : {},
|
|
196
198
|
version: options.version
|
|
197
199
|
}),
|
|
@@ -400,13 +402,15 @@ function emitWorkItem(item, handlers, workItems) {
|
|
|
400
402
|
handlers.onWork?.(item);
|
|
401
403
|
handlers.onStep?.(item.label, item.detail);
|
|
402
404
|
}
|
|
403
|
-
function completePlanning(handlers, workItems) {
|
|
405
|
+
function completePlanning(handlers, workItems, nextItems = []) {
|
|
404
406
|
const planning = workItems.get("planning");
|
|
405
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";
|
|
406
410
|
emitWorkItem(
|
|
407
411
|
{
|
|
408
412
|
...planning,
|
|
409
|
-
detail
|
|
413
|
+
detail,
|
|
410
414
|
state: "completed"
|
|
411
415
|
},
|
|
412
416
|
handlers,
|
|
@@ -456,11 +460,12 @@ function applyWorkEvent(event, handlers, workItems) {
|
|
|
456
460
|
return;
|
|
457
461
|
}
|
|
458
462
|
if (event.type === "actions.requested") {
|
|
459
|
-
|
|
460
|
-
for (const action of event.data.actions) {
|
|
463
|
+
const nextItems = event.data.actions.flatMap((action) => {
|
|
461
464
|
const item = requestedWorkItem(action);
|
|
462
|
-
|
|
463
|
-
}
|
|
465
|
+
return item ? [item] : [];
|
|
466
|
+
});
|
|
467
|
+
completePlanning(handlers, workItems, nextItems);
|
|
468
|
+
for (const item of nextItems) emitWorkItem(item, handlers, workItems);
|
|
464
469
|
return;
|
|
465
470
|
}
|
|
466
471
|
if (event.type === "subagent.called") {
|
|
@@ -511,7 +516,7 @@ function applyWorkEvent(event, handlers, workItems) {
|
|
|
511
516
|
);
|
|
512
517
|
}
|
|
513
518
|
var AgentSession = class {
|
|
514
|
-
constructor(indexId, version, runtimeOrigin, visitorSessionId, storeOptions, getUnpublishedPreviewGrant) {
|
|
519
|
+
constructor(indexId, version, runtimeOrigin, visitorSessionId, storeOptions, previewBuildId, getUnpublishedPreviewGrant) {
|
|
515
520
|
this.indexId = indexId;
|
|
516
521
|
this.version = version;
|
|
517
522
|
this.runtimeOrigin = runtimeOrigin;
|
|
@@ -520,6 +525,7 @@ var AgentSession = class {
|
|
|
520
525
|
this.capability = createAgentRuntimeCapability({
|
|
521
526
|
getUnpublishedPreviewGrant,
|
|
522
527
|
indexId,
|
|
528
|
+
previewBuildId,
|
|
523
529
|
runtimeOrigin,
|
|
524
530
|
version,
|
|
525
531
|
visitorSessionId
|
|
@@ -764,6 +770,7 @@ function createAgentClient(options) {
|
|
|
764
770
|
runtimeOrigin,
|
|
765
771
|
visitorSessionId,
|
|
766
772
|
storeOptions,
|
|
773
|
+
options.previewBuildId,
|
|
767
774
|
options.getUnpublishedPreviewGrant
|
|
768
775
|
);
|
|
769
776
|
return {
|
|
@@ -791,10 +798,15 @@ function createAgentClient(options) {
|
|
|
791
798
|
// src/runtime/errors.ts
|
|
792
799
|
var import_client3 = require("eve/client");
|
|
793
800
|
var TRANSIENT_AGENT_ERROR_MESSAGE = "I couldn\u2019t finish that answer. Please try again.";
|
|
801
|
+
var PREVIEW_AUTHORIZATION_ERROR_MESSAGE = "This preview could not be authorized. Open the latest preview from Webless.";
|
|
794
802
|
function isTransientRuntimeMessage(message) {
|
|
795
803
|
const normalized = message.trim().toLowerCase();
|
|
796
804
|
return normalized.includes("empty response from runtime") || normalized.includes("failed to fetch") || normalized.includes("networkerror") || normalized.includes("load failed");
|
|
797
805
|
}
|
|
806
|
+
function isPreviewAuthorizationMessage(message) {
|
|
807
|
+
const normalized = message.trim().toLowerCase();
|
|
808
|
+
return normalized.includes("unpublished preview authorization") || normalized.includes("unpublished preview grant") || normalized.includes("agent studio preview grant") || normalized.includes("preview authorization");
|
|
809
|
+
}
|
|
798
810
|
function formatAgentError(error) {
|
|
799
811
|
if (error instanceof import_client3.ClientError) {
|
|
800
812
|
if (error.status === 401 && error.code === "index_required") {
|
|
@@ -806,6 +818,9 @@ function formatAgentError(error) {
|
|
|
806
818
|
if (error.status === 409 && error.code === "session_not_active") {
|
|
807
819
|
return "Session expired \u2014 send a new message to start again.";
|
|
808
820
|
}
|
|
821
|
+
if (error.message && isPreviewAuthorizationMessage(error.message)) {
|
|
822
|
+
return PREVIEW_AUTHORIZATION_ERROR_MESSAGE;
|
|
823
|
+
}
|
|
809
824
|
if (error.status >= 500 || error.message && isTransientRuntimeMessage(error.message)) {
|
|
810
825
|
return TRANSIENT_AGENT_ERROR_MESSAGE;
|
|
811
826
|
}
|
|
@@ -815,6 +830,9 @@ function formatAgentError(error) {
|
|
|
815
830
|
return "";
|
|
816
831
|
}
|
|
817
832
|
if (error instanceof Error) {
|
|
833
|
+
if (isPreviewAuthorizationMessage(error.message)) {
|
|
834
|
+
return PREVIEW_AUTHORIZATION_ERROR_MESSAGE;
|
|
835
|
+
}
|
|
818
836
|
return isTransientRuntimeMessage(error.message) ? TRANSIENT_AGENT_ERROR_MESSAGE : error.message;
|
|
819
837
|
}
|
|
820
838
|
return TRANSIENT_AGENT_ERROR_MESSAGE;
|
|
@@ -926,6 +944,7 @@ function useAgentChat({
|
|
|
926
944
|
customerId,
|
|
927
945
|
getUnpublishedPreviewGrant,
|
|
928
946
|
indexId,
|
|
947
|
+
previewBuildId,
|
|
929
948
|
version,
|
|
930
949
|
runtimeOrigin,
|
|
931
950
|
visitorSessionId,
|
|
@@ -976,13 +995,14 @@ function useAgentChat({
|
|
|
976
995
|
customerId,
|
|
977
996
|
getUnpublishedPreviewGrant: resolveUnpublishedPreviewGrant,
|
|
978
997
|
indexId,
|
|
998
|
+
previewBuildId,
|
|
979
999
|
version,
|
|
980
1000
|
runtimeOrigin,
|
|
981
1001
|
visitorSessionId: visitorId,
|
|
982
1002
|
storageKeyPrefix: resolvedStorageKeyPrefix
|
|
983
1003
|
})
|
|
984
1004
|
);
|
|
985
|
-
const identityKey = `${customerId ?? ""}|${indexId}|${version ?? "published"}|${runtimeOrigin ?? ""}|${resolvedStorageKeyPrefix}|${visitorId}|${greeting ?? ""}`;
|
|
1005
|
+
const identityKey = `${customerId ?? ""}|${indexId}|${version ?? "published"}|${runtimeOrigin ?? ""}|${previewBuildId ?? ""}|${resolvedStorageKeyPrefix}|${visitorId}|${greeting ?? ""}`;
|
|
986
1006
|
const identityRef = (0, import_react2.useRef)(identityKey);
|
|
987
1007
|
(0, import_react2.useEffect)(() => {
|
|
988
1008
|
if (identityRef.current === identityKey) {
|
|
@@ -995,6 +1015,7 @@ function useAgentChat({
|
|
|
995
1015
|
customerId,
|
|
996
1016
|
getUnpublishedPreviewGrant: resolveUnpublishedPreviewGrant,
|
|
997
1017
|
indexId,
|
|
1018
|
+
previewBuildId,
|
|
998
1019
|
version,
|
|
999
1020
|
runtimeOrigin,
|
|
1000
1021
|
visitorSessionId: visitorId,
|
|
@@ -1011,6 +1032,7 @@ function useAgentChat({
|
|
|
1011
1032
|
identityKey,
|
|
1012
1033
|
indexId,
|
|
1013
1034
|
initialState,
|
|
1035
|
+
previewBuildId,
|
|
1014
1036
|
runtimeOrigin,
|
|
1015
1037
|
resolvedStorageKeyPrefix,
|
|
1016
1038
|
version,
|
|
@@ -1114,8 +1136,8 @@ function useAgentChat({
|
|
|
1114
1136
|
if (!message) return;
|
|
1115
1137
|
setState((prev) => ({
|
|
1116
1138
|
...prev,
|
|
1117
|
-
phase: "
|
|
1118
|
-
toolSteps: prev.toolSteps.map(
|
|
1139
|
+
phase: "error",
|
|
1140
|
+
toolSteps: prev.toolSteps.length === 1 && prev.toolSteps[0]?.kind === "planning" ? [] : prev.toolSteps.map(
|
|
1119
1141
|
(step) => step.state === "active" ? {
|
|
1120
1142
|
...step,
|
|
1121
1143
|
detail: "Couldn\u2019t complete this step",
|
|
@@ -1165,6 +1187,37 @@ function useAgentChat({
|
|
|
1165
1187
|
},
|
|
1166
1188
|
[runTurn]
|
|
1167
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]);
|
|
1168
1221
|
(0, import_react2.useEffect)(() => {
|
|
1169
1222
|
const conversation = loadPersistedAgentConversation(
|
|
1170
1223
|
resolvedStorageKeyPrefix,
|
|
@@ -1197,6 +1250,7 @@ function useAgentChat({
|
|
|
1197
1250
|
return {
|
|
1198
1251
|
state,
|
|
1199
1252
|
reset,
|
|
1253
|
+
retry,
|
|
1200
1254
|
submit,
|
|
1201
1255
|
visitorSessionId: visitorId,
|
|
1202
1256
|
sessionId: clientRef.current.getActiveSessionId()
|
|
@@ -1274,11 +1328,13 @@ var defaultAgentRailTheme = {
|
|
|
1274
1328
|
|
|
1275
1329
|
// src/react/components/AgentActivityBubble/AgentActivityBubble.tsx
|
|
1276
1330
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
1277
|
-
function workSummary(steps) {
|
|
1331
|
+
function workSummary(steps, failed, brandLabel) {
|
|
1278
1332
|
const active = [...steps].reverse().find((step) => step.state === "active");
|
|
1279
|
-
if (active?.kind === "specialist")
|
|
1333
|
+
if (active?.kind === "specialist")
|
|
1334
|
+
return `${active.label} is reviewing your question`;
|
|
1280
1335
|
if (active?.kind === "search") return "Searching this site";
|
|
1281
|
-
if (active) return
|
|
1336
|
+
if (active) return `${brandLabel} is choosing the best way to help`;
|
|
1337
|
+
if (failed) return "Couldn\u2019t complete this request";
|
|
1282
1338
|
const hasError = steps.some((step) => step.state === "error");
|
|
1283
1339
|
const specialists = steps.filter(
|
|
1284
1340
|
(step) => step.kind === "specialist" && step.state === "completed"
|
|
@@ -1288,49 +1344,122 @@ function workSummary(steps) {
|
|
|
1288
1344
|
);
|
|
1289
1345
|
if (hasError) return "Answered with available information";
|
|
1290
1346
|
if (specialists.length > 1)
|
|
1291
|
-
return `
|
|
1292
|
-
if (specialists.length === 1)
|
|
1293
|
-
|
|
1294
|
-
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
|
+
) });
|
|
1295
1392
|
}
|
|
1296
|
-
function AgentActivityBubble({
|
|
1393
|
+
function AgentActivityBubble({
|
|
1394
|
+
brandLabel = "Webless Guide",
|
|
1395
|
+
brandLogoUrl,
|
|
1396
|
+
failed = false,
|
|
1397
|
+
steps
|
|
1398
|
+
}) {
|
|
1297
1399
|
const active = steps.some((step) => step.state === "active");
|
|
1400
|
+
const delegated = steps.some((step) => step.kind === "specialist");
|
|
1298
1401
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", { className: "agent-activity-bubble", children: [
|
|
1299
1402
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "agent-activity-bubble__status", "aria-live": "polite", children: [
|
|
1300
1403
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1301
1404
|
"span",
|
|
1302
1405
|
{
|
|
1303
|
-
className: `agent-activity-bubble__pulse${active ? " is-active" : ""}`,
|
|
1406
|
+
className: `agent-activity-bubble__pulse${active ? " is-active" : failed ? " is-error" : ""}`,
|
|
1304
1407
|
"aria-hidden": "true"
|
|
1305
1408
|
}
|
|
1306
1409
|
),
|
|
1307
|
-
workSummary(steps)
|
|
1410
|
+
workSummary(steps, failed, brandLabel)
|
|
1308
1411
|
] }),
|
|
1309
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
"
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
"
|
|
1316
|
-
children:
|
|
1317
|
-
|
|
1318
|
-
|
|
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",
|
|
1319
1423
|
{
|
|
1320
|
-
className: "agent-activity-bubble__step
|
|
1321
|
-
"
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
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
|
+
)
|
|
1334
1463
|
] });
|
|
1335
1464
|
}
|
|
1336
1465
|
|
|
@@ -1469,6 +1598,29 @@ function MinimizeIcon() {
|
|
|
1469
1598
|
}
|
|
1470
1599
|
) });
|
|
1471
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
|
+
}
|
|
1472
1624
|
function ExpandIcon() {
|
|
1473
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)(
|
|
1474
1626
|
"path",
|
|
@@ -1505,10 +1657,13 @@ function AgentRail({
|
|
|
1505
1657
|
onCollapse,
|
|
1506
1658
|
onClose,
|
|
1507
1659
|
onExpandToggle,
|
|
1660
|
+
onReset,
|
|
1661
|
+
onRetry,
|
|
1508
1662
|
onSubmit,
|
|
1509
1663
|
onFollowUpSelect
|
|
1510
1664
|
}) {
|
|
1511
1665
|
const transcriptRef = (0, import_react5.useRef)(null);
|
|
1666
|
+
const welcomeTitleId = (0, import_react5.useId)();
|
|
1512
1667
|
const resolvedTheme = { ...defaultAgentRailTheme, ...theme };
|
|
1513
1668
|
const railStyle = {
|
|
1514
1669
|
"--rail-width": resolvedTheme.railMaxWidth,
|
|
@@ -1535,7 +1690,13 @@ function AgentRail({
|
|
|
1535
1690
|
(message) => message.role === "visitor"
|
|
1536
1691
|
);
|
|
1537
1692
|
const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
|
|
1538
|
-
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;
|
|
1539
1700
|
const streamingMessage = state.phase === "streaming" && state.streamingText ? {
|
|
1540
1701
|
createdAt: 0,
|
|
1541
1702
|
id: "streaming-response",
|
|
@@ -1560,6 +1721,10 @@ function AgentRail({
|
|
|
1560
1721
|
className: `agent-rail${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}`,
|
|
1561
1722
|
style: railStyle,
|
|
1562
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,
|
|
1563
1728
|
children: [
|
|
1564
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: [
|
|
1565
1730
|
onCollapse ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
@@ -1578,7 +1743,7 @@ function AgentRail({
|
|
|
1578
1743
|
className: "agent-rail__close",
|
|
1579
1744
|
"aria-label": "Close agent",
|
|
1580
1745
|
onClick: onClose,
|
|
1581
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1746
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CloseIcon, {})
|
|
1582
1747
|
}
|
|
1583
1748
|
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
|
|
1584
1749
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "agent-rail__identity", children: [
|
|
@@ -1598,75 +1763,102 @@ function AgentRail({
|
|
|
1598
1763
|
] }),
|
|
1599
1764
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "agent-rail__brand-label", children: brandLabel })
|
|
1600
1765
|
] }),
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
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
|
+
] })
|
|
1611
1789
|
] }) }),
|
|
1612
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
showActivity ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AgentActivityBubble, { steps: state.toolSteps }) : null,
|
|
1616
|
-
!expanded && showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1617
|
-
FollowUpChips,
|
|
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",
|
|
1618
1793
|
{
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
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
|
+
]
|
|
1631
1825
|
}
|
|
1632
|
-
) : null
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
FollowUpChips,
|
|
1826
|
+
) : null,
|
|
1827
|
+
transcriptMessages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message }, message.id)),
|
|
1828
|
+
showActivity ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1829
|
+
AgentActivityBubble,
|
|
1637
1830
|
{
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1831
|
+
brandLabel,
|
|
1832
|
+
brandLogoUrl,
|
|
1833
|
+
failed: state.phase === "error",
|
|
1834
|
+
steps: state.toolSteps
|
|
1642
1835
|
}
|
|
1643
|
-
)
|
|
1644
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
}
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "agent-rail__footer-note", children: poweredByLabel })
|
|
1656
|
-
] })
|
|
1657
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
|
|
1836
|
+
) : null,
|
|
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: [
|
|
1658
1848
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1659
1849
|
Composer,
|
|
1660
1850
|
{
|
|
1851
|
+
variant: expanded || mobileFullscreen ? "dock" : "default",
|
|
1661
1852
|
disabled: isBusy,
|
|
1662
1853
|
placeholder: composerPlaceholder,
|
|
1663
1854
|
onSubmit
|
|
1664
1855
|
}
|
|
1665
1856
|
),
|
|
1666
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
1667
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("
|
|
1668
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("
|
|
1669
|
-
|
|
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
|
+
] }) })
|
|
1670
1862
|
] })
|
|
1671
1863
|
]
|
|
1672
1864
|
}
|
|
@@ -1750,7 +1942,12 @@ function AssistEdgeTab({
|
|
|
1750
1942
|
label,
|
|
1751
1943
|
logoUrl,
|
|
1752
1944
|
brandColor,
|
|
1945
|
+
brandForeground,
|
|
1946
|
+
borderColor,
|
|
1753
1947
|
fontFamily,
|
|
1948
|
+
mobile = false,
|
|
1949
|
+
surfaceColor,
|
|
1950
|
+
textColor,
|
|
1754
1951
|
onOpen
|
|
1755
1952
|
}) {
|
|
1756
1953
|
const copy = VARIANT_COPY[variant];
|
|
@@ -1759,20 +1956,50 @@ function AssistEdgeTab({
|
|
|
1759
1956
|
"--tab-along": `${along}%`,
|
|
1760
1957
|
"--tab-inset": `${inset}px`,
|
|
1761
1958
|
...brandColor ? { "--as-brand": brandColor } : {},
|
|
1762
|
-
...
|
|
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 } : {}
|
|
1763
1964
|
};
|
|
1764
1965
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1765
1966
|
"button",
|
|
1766
1967
|
{
|
|
1767
1968
|
type: "button",
|
|
1768
|
-
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" : ""}`,
|
|
1769
1970
|
style,
|
|
1770
1971
|
"aria-label": `Open ${visibleLabel}`,
|
|
1771
1972
|
"aria-hidden": !visible,
|
|
1772
1973
|
tabIndex: visible ? 0 : -1,
|
|
1773
1974
|
onClick: onOpen,
|
|
1774
1975
|
children: [
|
|
1775
|
-
|
|
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: [
|
|
1776
2003
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
|
|
1777
2004
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SparklesIcon, {}),
|
|
1778
2005
|
logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
@@ -1824,6 +2051,7 @@ function AgentWidget({
|
|
|
1824
2051
|
indexId,
|
|
1825
2052
|
customerId,
|
|
1826
2053
|
getUnpublishedPreviewGrant,
|
|
2054
|
+
previewBuildId,
|
|
1827
2055
|
version,
|
|
1828
2056
|
runtimeOrigin,
|
|
1829
2057
|
placement: placementInput,
|
|
@@ -1847,10 +2075,11 @@ function AgentWidget({
|
|
|
1847
2075
|
active: pageShiftActive,
|
|
1848
2076
|
railSlotRef
|
|
1849
2077
|
});
|
|
1850
|
-
const { state, submit } = useAgentChat({
|
|
2078
|
+
const { state, reset, retry, submit } = useAgentChat({
|
|
1851
2079
|
customerId,
|
|
1852
2080
|
getUnpublishedPreviewGrant,
|
|
1853
2081
|
indexId,
|
|
2082
|
+
previewBuildId,
|
|
1854
2083
|
version,
|
|
1855
2084
|
runtimeOrigin,
|
|
1856
2085
|
greeting: branding?.greeting
|
|
@@ -1889,6 +2118,40 @@ function AgentWidget({
|
|
|
1889
2118
|
if (isMobile) setRailCollapsed(false);
|
|
1890
2119
|
await submit(message);
|
|
1891
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]);
|
|
1892
2155
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "webless-agent-root", children: [
|
|
1893
2156
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1894
2157
|
"div",
|
|
@@ -1920,19 +2183,27 @@ function AgentWidget({
|
|
|
1920
2183
|
onClose: isMobile ? () => setRailCollapsed(true) : void 0,
|
|
1921
2184
|
onExpandToggle: !isMobile ? () => setRailExpanded((current) => !current) : void 0,
|
|
1922
2185
|
onSubmit: handleSubmit,
|
|
2186
|
+
onReset: reset,
|
|
2187
|
+
onRetry: () => void retry(),
|
|
1923
2188
|
onFollowUpSelect: (label) => void handleSubmit(label)
|
|
1924
2189
|
}
|
|
1925
2190
|
)
|
|
1926
2191
|
}
|
|
1927
2192
|
),
|
|
1928
|
-
!isMobile && railExpanded && !railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2193
|
+
!railCollapsed && isMobile || !isMobile && railExpanded && !railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1929
2194
|
"button",
|
|
1930
2195
|
{
|
|
1931
2196
|
type: "button",
|
|
1932
|
-
className: "webless-agent-root__backdrop"
|
|
2197
|
+
className: `webless-agent-root__backdrop${isMobile ? " webless-agent-root__backdrop--mobile" : ""}`,
|
|
1933
2198
|
tabIndex: -1,
|
|
1934
|
-
"aria-label": "Close
|
|
1935
|
-
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
|
+
}
|
|
1936
2207
|
}
|
|
1937
2208
|
) : null
|
|
1938
2209
|
]
|
|
@@ -1949,13 +2220,31 @@ function AgentWidget({
|
|
|
1949
2220
|
label: agentName,
|
|
1950
2221
|
logoUrl: branding?.logoUrl,
|
|
1951
2222
|
brandColor: branding?.colors?.primary,
|
|
2223
|
+
brandForeground: branding?.colors?.primaryForeground,
|
|
2224
|
+
borderColor: branding?.colors?.border,
|
|
1952
2225
|
fontFamily: branding?.fontFamily,
|
|
2226
|
+
mobile: isMobile,
|
|
2227
|
+
surfaceColor: branding?.colors?.surface,
|
|
2228
|
+
textColor: branding?.colors?.text,
|
|
1953
2229
|
onOpen: () => setRailCollapsed(false)
|
|
1954
2230
|
}
|
|
1955
2231
|
) : null
|
|
1956
2232
|
] });
|
|
1957
2233
|
}
|
|
1958
2234
|
|
|
2235
|
+
// src/embed/preview-build.ts
|
|
2236
|
+
var PREVIEW_BUILD_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
|
|
2237
|
+
function readUnpublishedPreviewBuildId(href) {
|
|
2238
|
+
const source = href ?? (typeof window === "undefined" ? void 0 : window.location.href);
|
|
2239
|
+
if (!source) return void 0;
|
|
2240
|
+
try {
|
|
2241
|
+
const buildId = new URL(source).searchParams.get("v")?.trim();
|
|
2242
|
+
return buildId && PREVIEW_BUILD_ID_PATTERN.test(buildId) ? buildId : void 0;
|
|
2243
|
+
} catch {
|
|
2244
|
+
return void 0;
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
|
|
1959
2248
|
// src/embed/AgentWidget.tsx
|
|
1960
2249
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1961
2250
|
function AgentWidget2({
|
|
@@ -1968,6 +2257,7 @@ function AgentWidget2({
|
|
|
1968
2257
|
customerId: manifest.customerId,
|
|
1969
2258
|
version: manifest.version,
|
|
1970
2259
|
runtimeOrigin: manifest.runtimeOrigin,
|
|
2260
|
+
previewBuildId: manifest.version === "unpublished" ? readUnpublishedPreviewBuildId() : void 0,
|
|
1971
2261
|
placement: manifest.placement,
|
|
1972
2262
|
pageShift: manifest.pageShift,
|
|
1973
2263
|
branding: manifest.branding,
|