@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/react.cjs
CHANGED
|
@@ -162,11 +162,12 @@ function createAgentRuntimeCapability(options) {
|
|
|
162
162
|
let pendingBootstrap;
|
|
163
163
|
const bootstrap = async () => {
|
|
164
164
|
let previewGrant;
|
|
165
|
+
const previewBuildId = options.previewBuildId?.trim();
|
|
165
166
|
if (options.version === "unpublished") {
|
|
166
|
-
previewGrant = (await options.getUnpublishedPreviewGrant?.())?.trim();
|
|
167
|
-
if (!previewGrant) {
|
|
167
|
+
previewGrant = previewBuildId ? void 0 : (await options.getUnpublishedPreviewGrant?.())?.trim();
|
|
168
|
+
if (!previewGrant && !previewBuildId) {
|
|
168
169
|
throw new Error(
|
|
169
|
-
"
|
|
170
|
+
"Unpublished preview authorization is required to use the Agent Runtime preview."
|
|
170
171
|
);
|
|
171
172
|
}
|
|
172
173
|
}
|
|
@@ -176,6 +177,7 @@ function createAgentRuntimeCapability(options) {
|
|
|
176
177
|
body: JSON.stringify({
|
|
177
178
|
clientSessionId: options.visitorSessionId,
|
|
178
179
|
indexId: options.indexId,
|
|
180
|
+
...previewBuildId ? { previewBuildId } : {},
|
|
179
181
|
...previewGrant ? { previewGrant } : {},
|
|
180
182
|
version: options.version
|
|
181
183
|
}),
|
|
@@ -384,13 +386,15 @@ function emitWorkItem(item, handlers, workItems) {
|
|
|
384
386
|
handlers.onWork?.(item);
|
|
385
387
|
handlers.onStep?.(item.label, item.detail);
|
|
386
388
|
}
|
|
387
|
-
function completePlanning(handlers, workItems) {
|
|
389
|
+
function completePlanning(handlers, workItems, nextItems = []) {
|
|
388
390
|
const planning = workItems.get("planning");
|
|
389
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";
|
|
390
394
|
emitWorkItem(
|
|
391
395
|
{
|
|
392
396
|
...planning,
|
|
393
|
-
detail
|
|
397
|
+
detail,
|
|
394
398
|
state: "completed"
|
|
395
399
|
},
|
|
396
400
|
handlers,
|
|
@@ -440,11 +444,12 @@ function applyWorkEvent(event, handlers, workItems) {
|
|
|
440
444
|
return;
|
|
441
445
|
}
|
|
442
446
|
if (event.type === "actions.requested") {
|
|
443
|
-
|
|
444
|
-
for (const action of event.data.actions) {
|
|
447
|
+
const nextItems = event.data.actions.flatMap((action) => {
|
|
445
448
|
const item = requestedWorkItem(action);
|
|
446
|
-
|
|
447
|
-
}
|
|
449
|
+
return item ? [item] : [];
|
|
450
|
+
});
|
|
451
|
+
completePlanning(handlers, workItems, nextItems);
|
|
452
|
+
for (const item of nextItems) emitWorkItem(item, handlers, workItems);
|
|
448
453
|
return;
|
|
449
454
|
}
|
|
450
455
|
if (event.type === "subagent.called") {
|
|
@@ -495,7 +500,7 @@ function applyWorkEvent(event, handlers, workItems) {
|
|
|
495
500
|
);
|
|
496
501
|
}
|
|
497
502
|
var AgentSession = class {
|
|
498
|
-
constructor(indexId, version, runtimeOrigin, visitorSessionId, storeOptions, getUnpublishedPreviewGrant) {
|
|
503
|
+
constructor(indexId, version, runtimeOrigin, visitorSessionId, storeOptions, previewBuildId, getUnpublishedPreviewGrant) {
|
|
499
504
|
this.indexId = indexId;
|
|
500
505
|
this.version = version;
|
|
501
506
|
this.runtimeOrigin = runtimeOrigin;
|
|
@@ -504,6 +509,7 @@ var AgentSession = class {
|
|
|
504
509
|
this.capability = createAgentRuntimeCapability({
|
|
505
510
|
getUnpublishedPreviewGrant,
|
|
506
511
|
indexId,
|
|
512
|
+
previewBuildId,
|
|
507
513
|
runtimeOrigin,
|
|
508
514
|
version,
|
|
509
515
|
visitorSessionId
|
|
@@ -748,6 +754,7 @@ function createAgentClient(options) {
|
|
|
748
754
|
runtimeOrigin,
|
|
749
755
|
visitorSessionId,
|
|
750
756
|
storeOptions,
|
|
757
|
+
options.previewBuildId,
|
|
751
758
|
options.getUnpublishedPreviewGrant
|
|
752
759
|
);
|
|
753
760
|
return {
|
|
@@ -775,10 +782,15 @@ function createAgentClient(options) {
|
|
|
775
782
|
// src/runtime/errors.ts
|
|
776
783
|
var import_client3 = require("eve/client");
|
|
777
784
|
var TRANSIENT_AGENT_ERROR_MESSAGE = "I couldn\u2019t finish that answer. Please try again.";
|
|
785
|
+
var PREVIEW_AUTHORIZATION_ERROR_MESSAGE = "This preview could not be authorized. Open the latest preview from Webless.";
|
|
778
786
|
function isTransientRuntimeMessage(message) {
|
|
779
787
|
const normalized = message.trim().toLowerCase();
|
|
780
788
|
return normalized.includes("empty response from runtime") || normalized.includes("failed to fetch") || normalized.includes("networkerror") || normalized.includes("load failed");
|
|
781
789
|
}
|
|
790
|
+
function isPreviewAuthorizationMessage(message) {
|
|
791
|
+
const normalized = message.trim().toLowerCase();
|
|
792
|
+
return normalized.includes("unpublished preview authorization") || normalized.includes("unpublished preview grant") || normalized.includes("agent studio preview grant") || normalized.includes("preview authorization");
|
|
793
|
+
}
|
|
782
794
|
function formatAgentError(error) {
|
|
783
795
|
if (error instanceof import_client3.ClientError) {
|
|
784
796
|
if (error.status === 401 && error.code === "index_required") {
|
|
@@ -790,6 +802,9 @@ function formatAgentError(error) {
|
|
|
790
802
|
if (error.status === 409 && error.code === "session_not_active") {
|
|
791
803
|
return "Session expired \u2014 send a new message to start again.";
|
|
792
804
|
}
|
|
805
|
+
if (error.message && isPreviewAuthorizationMessage(error.message)) {
|
|
806
|
+
return PREVIEW_AUTHORIZATION_ERROR_MESSAGE;
|
|
807
|
+
}
|
|
793
808
|
if (error.status >= 500 || error.message && isTransientRuntimeMessage(error.message)) {
|
|
794
809
|
return TRANSIENT_AGENT_ERROR_MESSAGE;
|
|
795
810
|
}
|
|
@@ -799,6 +814,9 @@ function formatAgentError(error) {
|
|
|
799
814
|
return "";
|
|
800
815
|
}
|
|
801
816
|
if (error instanceof Error) {
|
|
817
|
+
if (isPreviewAuthorizationMessage(error.message)) {
|
|
818
|
+
return PREVIEW_AUTHORIZATION_ERROR_MESSAGE;
|
|
819
|
+
}
|
|
802
820
|
return isTransientRuntimeMessage(error.message) ? TRANSIENT_AGENT_ERROR_MESSAGE : error.message;
|
|
803
821
|
}
|
|
804
822
|
return TRANSIENT_AGENT_ERROR_MESSAGE;
|
|
@@ -910,6 +928,7 @@ function useAgentChat({
|
|
|
910
928
|
customerId,
|
|
911
929
|
getUnpublishedPreviewGrant,
|
|
912
930
|
indexId,
|
|
931
|
+
previewBuildId,
|
|
913
932
|
version,
|
|
914
933
|
runtimeOrigin,
|
|
915
934
|
visitorSessionId,
|
|
@@ -960,13 +979,14 @@ function useAgentChat({
|
|
|
960
979
|
customerId,
|
|
961
980
|
getUnpublishedPreviewGrant: resolveUnpublishedPreviewGrant,
|
|
962
981
|
indexId,
|
|
982
|
+
previewBuildId,
|
|
963
983
|
version,
|
|
964
984
|
runtimeOrigin,
|
|
965
985
|
visitorSessionId: visitorId,
|
|
966
986
|
storageKeyPrefix: resolvedStorageKeyPrefix
|
|
967
987
|
})
|
|
968
988
|
);
|
|
969
|
-
const identityKey = `${customerId ?? ""}|${indexId}|${version ?? "published"}|${runtimeOrigin ?? ""}|${resolvedStorageKeyPrefix}|${visitorId}|${greeting ?? ""}`;
|
|
989
|
+
const identityKey = `${customerId ?? ""}|${indexId}|${version ?? "published"}|${runtimeOrigin ?? ""}|${previewBuildId ?? ""}|${resolvedStorageKeyPrefix}|${visitorId}|${greeting ?? ""}`;
|
|
970
990
|
const identityRef = (0, import_react2.useRef)(identityKey);
|
|
971
991
|
(0, import_react2.useEffect)(() => {
|
|
972
992
|
if (identityRef.current === identityKey) {
|
|
@@ -979,6 +999,7 @@ function useAgentChat({
|
|
|
979
999
|
customerId,
|
|
980
1000
|
getUnpublishedPreviewGrant: resolveUnpublishedPreviewGrant,
|
|
981
1001
|
indexId,
|
|
1002
|
+
previewBuildId,
|
|
982
1003
|
version,
|
|
983
1004
|
runtimeOrigin,
|
|
984
1005
|
visitorSessionId: visitorId,
|
|
@@ -995,6 +1016,7 @@ function useAgentChat({
|
|
|
995
1016
|
identityKey,
|
|
996
1017
|
indexId,
|
|
997
1018
|
initialState,
|
|
1019
|
+
previewBuildId,
|
|
998
1020
|
runtimeOrigin,
|
|
999
1021
|
resolvedStorageKeyPrefix,
|
|
1000
1022
|
version,
|
|
@@ -1098,8 +1120,8 @@ function useAgentChat({
|
|
|
1098
1120
|
if (!message) return;
|
|
1099
1121
|
setState((prev) => ({
|
|
1100
1122
|
...prev,
|
|
1101
|
-
phase: "
|
|
1102
|
-
toolSteps: prev.toolSteps.map(
|
|
1123
|
+
phase: "error",
|
|
1124
|
+
toolSteps: prev.toolSteps.length === 1 && prev.toolSteps[0]?.kind === "planning" ? [] : prev.toolSteps.map(
|
|
1103
1125
|
(step) => step.state === "active" ? {
|
|
1104
1126
|
...step,
|
|
1105
1127
|
detail: "Couldn\u2019t complete this step",
|
|
@@ -1149,6 +1171,37 @@ function useAgentChat({
|
|
|
1149
1171
|
},
|
|
1150
1172
|
[runTurn]
|
|
1151
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]);
|
|
1152
1205
|
(0, import_react2.useEffect)(() => {
|
|
1153
1206
|
const conversation = loadPersistedAgentConversation(
|
|
1154
1207
|
resolvedStorageKeyPrefix,
|
|
@@ -1181,6 +1234,7 @@ function useAgentChat({
|
|
|
1181
1234
|
return {
|
|
1182
1235
|
state,
|
|
1183
1236
|
reset,
|
|
1237
|
+
retry,
|
|
1184
1238
|
submit,
|
|
1185
1239
|
visitorSessionId: visitorId,
|
|
1186
1240
|
sessionId: clientRef.current.getActiveSessionId()
|
|
@@ -1267,11 +1321,13 @@ var defaultAgentRailTheme = {
|
|
|
1267
1321
|
|
|
1268
1322
|
// src/react/components/AgentActivityBubble/AgentActivityBubble.tsx
|
|
1269
1323
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
1270
|
-
function workSummary(steps) {
|
|
1324
|
+
function workSummary(steps, failed, brandLabel) {
|
|
1271
1325
|
const active = [...steps].reverse().find((step) => step.state === "active");
|
|
1272
|
-
if (active?.kind === "specialist")
|
|
1326
|
+
if (active?.kind === "specialist")
|
|
1327
|
+
return `${active.label} is reviewing your question`;
|
|
1273
1328
|
if (active?.kind === "search") return "Searching this site";
|
|
1274
|
-
if (active) return
|
|
1329
|
+
if (active) return `${brandLabel} is choosing the best way to help`;
|
|
1330
|
+
if (failed) return "Couldn\u2019t complete this request";
|
|
1275
1331
|
const hasError = steps.some((step) => step.state === "error");
|
|
1276
1332
|
const specialists = steps.filter(
|
|
1277
1333
|
(step) => step.kind === "specialist" && step.state === "completed"
|
|
@@ -1281,49 +1337,122 @@ function workSummary(steps) {
|
|
|
1281
1337
|
);
|
|
1282
1338
|
if (hasError) return "Answered with available information";
|
|
1283
1339
|
if (specialists.length > 1)
|
|
1284
|
-
return `
|
|
1285
|
-
if (specialists.length === 1)
|
|
1286
|
-
|
|
1287
|
-
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
|
+
] });
|
|
1288
1374
|
}
|
|
1289
|
-
function
|
|
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
|
+
) });
|
|
1385
|
+
}
|
|
1386
|
+
function AgentActivityBubble({
|
|
1387
|
+
brandLabel = "Webless Guide",
|
|
1388
|
+
brandLogoUrl,
|
|
1389
|
+
failed = false,
|
|
1390
|
+
steps
|
|
1391
|
+
}) {
|
|
1290
1392
|
const active = steps.some((step) => step.state === "active");
|
|
1393
|
+
const delegated = steps.some((step) => step.kind === "specialist");
|
|
1291
1394
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", { className: "agent-activity-bubble", children: [
|
|
1292
1395
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "agent-activity-bubble__status", "aria-live": "polite", children: [
|
|
1293
1396
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1294
1397
|
"span",
|
|
1295
1398
|
{
|
|
1296
|
-
className: `agent-activity-bubble__pulse${active ? " is-active" : ""}`,
|
|
1399
|
+
className: `agent-activity-bubble__pulse${active ? " is-active" : failed ? " is-error" : ""}`,
|
|
1297
1400
|
"aria-hidden": "true"
|
|
1298
1401
|
}
|
|
1299
1402
|
),
|
|
1300
|
-
workSummary(steps)
|
|
1403
|
+
workSummary(steps, failed, brandLabel)
|
|
1301
1404
|
] }),
|
|
1302
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
"
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
"
|
|
1309
|
-
children:
|
|
1310
|
-
|
|
1311
|
-
|
|
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",
|
|
1312
1416
|
{
|
|
1313
|
-
className: "agent-activity-bubble__step
|
|
1314
|
-
"
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
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
|
+
)
|
|
1327
1456
|
] });
|
|
1328
1457
|
}
|
|
1329
1458
|
|
|
@@ -1462,6 +1591,29 @@ function MinimizeIcon() {
|
|
|
1462
1591
|
}
|
|
1463
1592
|
) });
|
|
1464
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
|
+
}
|
|
1465
1617
|
function ExpandIcon() {
|
|
1466
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)(
|
|
1467
1619
|
"path",
|
|
@@ -1498,10 +1650,13 @@ function AgentRail({
|
|
|
1498
1650
|
onCollapse,
|
|
1499
1651
|
onClose,
|
|
1500
1652
|
onExpandToggle,
|
|
1653
|
+
onReset,
|
|
1654
|
+
onRetry,
|
|
1501
1655
|
onSubmit,
|
|
1502
1656
|
onFollowUpSelect
|
|
1503
1657
|
}) {
|
|
1504
1658
|
const transcriptRef = (0, import_react5.useRef)(null);
|
|
1659
|
+
const welcomeTitleId = (0, import_react5.useId)();
|
|
1505
1660
|
const resolvedTheme = { ...defaultAgentRailTheme, ...theme };
|
|
1506
1661
|
const railStyle = {
|
|
1507
1662
|
"--rail-width": resolvedTheme.railMaxWidth,
|
|
@@ -1528,7 +1683,13 @@ function AgentRail({
|
|
|
1528
1683
|
(message) => message.role === "visitor"
|
|
1529
1684
|
);
|
|
1530
1685
|
const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
|
|
1531
|
-
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;
|
|
1532
1693
|
const streamingMessage = state.phase === "streaming" && state.streamingText ? {
|
|
1533
1694
|
createdAt: 0,
|
|
1534
1695
|
id: "streaming-response",
|
|
@@ -1553,6 +1714,10 @@ function AgentRail({
|
|
|
1553
1714
|
className: `agent-rail${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}`,
|
|
1554
1715
|
style: railStyle,
|
|
1555
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,
|
|
1556
1721
|
children: [
|
|
1557
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: [
|
|
1558
1723
|
onCollapse ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
@@ -1571,7 +1736,7 @@ function AgentRail({
|
|
|
1571
1736
|
className: "agent-rail__close",
|
|
1572
1737
|
"aria-label": "Close agent",
|
|
1573
1738
|
onClick: onClose,
|
|
1574
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1739
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CloseIcon, {})
|
|
1575
1740
|
}
|
|
1576
1741
|
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
|
|
1577
1742
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "agent-rail__identity", children: [
|
|
@@ -1591,75 +1756,102 @@ function AgentRail({
|
|
|
1591
1756
|
] }),
|
|
1592
1757
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "agent-rail__brand-label", children: brandLabel })
|
|
1593
1758
|
] }),
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
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
|
+
] })
|
|
1604
1782
|
] }) }),
|
|
1605
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
showActivity ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AgentActivityBubble, { steps: state.toolSteps }) : null,
|
|
1609
|
-
!expanded && showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1610
|
-
FollowUpChips,
|
|
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",
|
|
1611
1786
|
{
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
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
|
+
]
|
|
1635
1818
|
}
|
|
1636
|
-
)
|
|
1637
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1638
|
-
|
|
1819
|
+
) : null,
|
|
1820
|
+
transcriptMessages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message }, message.id)),
|
|
1821
|
+
showActivity ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1822
|
+
AgentActivityBubble,
|
|
1639
1823
|
{
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1824
|
+
brandLabel,
|
|
1825
|
+
brandLogoUrl,
|
|
1826
|
+
failed: state.phase === "error",
|
|
1827
|
+
steps: state.toolSteps
|
|
1644
1828
|
}
|
|
1645
|
-
)
|
|
1646
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1829
|
+
) : null,
|
|
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: [
|
|
1651
1841
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1652
1842
|
Composer,
|
|
1653
1843
|
{
|
|
1844
|
+
variant: expanded || mobileFullscreen ? "dock" : "default",
|
|
1654
1845
|
disabled: isBusy,
|
|
1655
1846
|
placeholder: composerPlaceholder,
|
|
1656
1847
|
onSubmit
|
|
1657
1848
|
}
|
|
1658
1849
|
),
|
|
1659
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
1660
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("
|
|
1661
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("
|
|
1662
|
-
|
|
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
|
+
] }) })
|
|
1663
1855
|
] })
|
|
1664
1856
|
]
|
|
1665
1857
|
}
|
|
@@ -1743,7 +1935,12 @@ function AssistEdgeTab({
|
|
|
1743
1935
|
label,
|
|
1744
1936
|
logoUrl,
|
|
1745
1937
|
brandColor,
|
|
1938
|
+
brandForeground,
|
|
1939
|
+
borderColor,
|
|
1746
1940
|
fontFamily,
|
|
1941
|
+
mobile = false,
|
|
1942
|
+
surfaceColor,
|
|
1943
|
+
textColor,
|
|
1747
1944
|
onOpen
|
|
1748
1945
|
}) {
|
|
1749
1946
|
const copy = VARIANT_COPY[variant];
|
|
@@ -1752,20 +1949,50 @@ function AssistEdgeTab({
|
|
|
1752
1949
|
"--tab-along": `${along}%`,
|
|
1753
1950
|
"--tab-inset": `${inset}px`,
|
|
1754
1951
|
...brandColor ? { "--as-brand": brandColor } : {},
|
|
1755
|
-
...
|
|
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 } : {}
|
|
1756
1957
|
};
|
|
1757
1958
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1758
1959
|
"button",
|
|
1759
1960
|
{
|
|
1760
1961
|
type: "button",
|
|
1761
|
-
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" : ""}`,
|
|
1762
1963
|
style,
|
|
1763
1964
|
"aria-label": `Open ${visibleLabel}`,
|
|
1764
1965
|
"aria-hidden": !visible,
|
|
1765
1966
|
tabIndex: visible ? 0 : -1,
|
|
1766
1967
|
onClick: onOpen,
|
|
1767
1968
|
children: [
|
|
1768
|
-
|
|
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: [
|
|
1769
1996
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
|
|
1770
1997
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SparklesIcon, {}),
|
|
1771
1998
|
logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
@@ -1817,6 +2044,7 @@ function AgentWidget({
|
|
|
1817
2044
|
indexId,
|
|
1818
2045
|
customerId,
|
|
1819
2046
|
getUnpublishedPreviewGrant,
|
|
2047
|
+
previewBuildId,
|
|
1820
2048
|
version,
|
|
1821
2049
|
runtimeOrigin,
|
|
1822
2050
|
placement: placementInput,
|
|
@@ -1840,10 +2068,11 @@ function AgentWidget({
|
|
|
1840
2068
|
active: pageShiftActive,
|
|
1841
2069
|
railSlotRef
|
|
1842
2070
|
});
|
|
1843
|
-
const { state, submit } = useAgentChat({
|
|
2071
|
+
const { state, reset, retry, submit } = useAgentChat({
|
|
1844
2072
|
customerId,
|
|
1845
2073
|
getUnpublishedPreviewGrant,
|
|
1846
2074
|
indexId,
|
|
2075
|
+
previewBuildId,
|
|
1847
2076
|
version,
|
|
1848
2077
|
runtimeOrigin,
|
|
1849
2078
|
greeting: branding?.greeting
|
|
@@ -1882,6 +2111,40 @@ function AgentWidget({
|
|
|
1882
2111
|
if (isMobile) setRailCollapsed(false);
|
|
1883
2112
|
await submit(message);
|
|
1884
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]);
|
|
1885
2148
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "webless-agent-root", children: [
|
|
1886
2149
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1887
2150
|
"div",
|
|
@@ -1913,19 +2176,27 @@ function AgentWidget({
|
|
|
1913
2176
|
onClose: isMobile ? () => setRailCollapsed(true) : void 0,
|
|
1914
2177
|
onExpandToggle: !isMobile ? () => setRailExpanded((current) => !current) : void 0,
|
|
1915
2178
|
onSubmit: handleSubmit,
|
|
2179
|
+
onReset: reset,
|
|
2180
|
+
onRetry: () => void retry(),
|
|
1916
2181
|
onFollowUpSelect: (label) => void handleSubmit(label)
|
|
1917
2182
|
}
|
|
1918
2183
|
)
|
|
1919
2184
|
}
|
|
1920
2185
|
),
|
|
1921
|
-
!isMobile && railExpanded && !railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2186
|
+
!railCollapsed && isMobile || !isMobile && railExpanded && !railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1922
2187
|
"button",
|
|
1923
2188
|
{
|
|
1924
2189
|
type: "button",
|
|
1925
|
-
className: "webless-agent-root__backdrop"
|
|
2190
|
+
className: `webless-agent-root__backdrop${isMobile ? " webless-agent-root__backdrop--mobile" : ""}`,
|
|
1926
2191
|
tabIndex: -1,
|
|
1927
|
-
"aria-label": "Close
|
|
1928
|
-
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
|
+
}
|
|
1929
2200
|
}
|
|
1930
2201
|
) : null
|
|
1931
2202
|
]
|
|
@@ -1942,7 +2213,12 @@ function AgentWidget({
|
|
|
1942
2213
|
label: agentName,
|
|
1943
2214
|
logoUrl: branding?.logoUrl,
|
|
1944
2215
|
brandColor: branding?.colors?.primary,
|
|
2216
|
+
brandForeground: branding?.colors?.primaryForeground,
|
|
2217
|
+
borderColor: branding?.colors?.border,
|
|
1945
2218
|
fontFamily: branding?.fontFamily,
|
|
2219
|
+
mobile: isMobile,
|
|
2220
|
+
surfaceColor: branding?.colors?.surface,
|
|
2221
|
+
textColor: branding?.colors?.text,
|
|
1946
2222
|
onOpen: () => setRailCollapsed(false)
|
|
1947
2223
|
}
|
|
1948
2224
|
) : null
|