@webless/agent 0.6.11 → 0.7.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-YNF2UPGJ.js → chunk-CYI3OSWG.js} +1494 -516
- package/dist/chunk-CYI3OSWG.js.map +1 -0
- package/dist/embed.cjs +1565 -565
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.css +352 -3
- 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 +27 -2
- package/dist/embed.js.map +1 -1
- package/dist/index.cjs +53 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -1
- package/dist/{manifest-Ulpp3ffe.d.cts → manifest-BNJQfEow.d.cts} +12 -1
- package/dist/{manifest-Ulpp3ffe.d.ts → manifest-BNJQfEow.d.ts} +12 -1
- package/dist/react.cjs +1545 -560
- package/dist/react.cjs.map +1 -1
- package/dist/react.css +352 -3
- package/dist/react.css.map +1 -1
- package/dist/react.d.cts +62 -5
- package/dist/react.d.ts +62 -5
- package/dist/react.js +11 -1
- package/package.json +1 -1
- package/dist/chunk-YNF2UPGJ.js.map +0 -1
package/dist/embed.cjs
CHANGED
|
@@ -64,7 +64,7 @@ function submitAgentPanel(customerId, message, options) {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
// src/react/components/AgentWidget/AgentWidget.tsx
|
|
67
|
-
var
|
|
67
|
+
var import_react15 = require("react");
|
|
68
68
|
|
|
69
69
|
// src/react/page-shift.ts
|
|
70
70
|
var import_react = require("react");
|
|
@@ -920,6 +920,20 @@ function latestTurnEvents(events) {
|
|
|
920
920
|
}
|
|
921
921
|
return startIndex >= 0 ? events.slice(startIndex) : [];
|
|
922
922
|
}
|
|
923
|
+
function streamIndexBeforeLastTurn(input) {
|
|
924
|
+
let turnStart = -1;
|
|
925
|
+
for (let index = input.events.length - 1; index >= 0; index -= 1) {
|
|
926
|
+
if (input.events[index]?.type === "message.received") {
|
|
927
|
+
turnStart = index;
|
|
928
|
+
break;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
if (turnStart < 0) return null;
|
|
932
|
+
return Math.max(
|
|
933
|
+
0,
|
|
934
|
+
input.currentStreamIndex - (input.events.length - turnStart)
|
|
935
|
+
);
|
|
936
|
+
}
|
|
923
937
|
function renderTurn(events) {
|
|
924
938
|
let rendered = "";
|
|
925
939
|
for (const event of events) {
|
|
@@ -1104,6 +1118,40 @@ var AgentSession = class {
|
|
|
1104
1118
|
this.storeOptions
|
|
1105
1119
|
);
|
|
1106
1120
|
}
|
|
1121
|
+
async rewindBeforeLastTurn(signal) {
|
|
1122
|
+
const persisted = loadPersistedAgentSession(
|
|
1123
|
+
this.visitorSessionId,
|
|
1124
|
+
this.storeOptions
|
|
1125
|
+
);
|
|
1126
|
+
if (!persisted?.sessionId) return false;
|
|
1127
|
+
const client = this.ensureClient();
|
|
1128
|
+
const attached = client.sessions.attach(persisted.sessionId, {
|
|
1129
|
+
streamIndex: persisted.streamIndex
|
|
1130
|
+
});
|
|
1131
|
+
const snapshot = await withCapabilityRefresh(
|
|
1132
|
+
this.capability,
|
|
1133
|
+
() => attached.snapshot({ signal })
|
|
1134
|
+
);
|
|
1135
|
+
const rewindStreamIndex = streamIndexBeforeLastTurn({
|
|
1136
|
+
currentStreamIndex: snapshot.session.streamIndex,
|
|
1137
|
+
events: snapshot.events
|
|
1138
|
+
});
|
|
1139
|
+
if (rewindStreamIndex === null) return false;
|
|
1140
|
+
this.session = client.sessions.attach(persisted.sessionId, {
|
|
1141
|
+
streamIndex: rewindStreamIndex
|
|
1142
|
+
});
|
|
1143
|
+
savePersistedAgentSession(
|
|
1144
|
+
this.visitorSessionId,
|
|
1145
|
+
persisted.sessionId,
|
|
1146
|
+
rewindStreamIndex,
|
|
1147
|
+
this.storeOptions
|
|
1148
|
+
);
|
|
1149
|
+
return true;
|
|
1150
|
+
}
|
|
1151
|
+
async regenerateTurn(message, signal, handlers) {
|
|
1152
|
+
await this.rewindBeforeLastTurn(signal);
|
|
1153
|
+
return this.sendTurn(message, signal, handlers);
|
|
1154
|
+
}
|
|
1107
1155
|
ensureClient() {
|
|
1108
1156
|
const config = resolveAgentRuntimeConfig({
|
|
1109
1157
|
indexId: this.indexId,
|
|
@@ -1439,6 +1487,11 @@ function createAgentClient(options) {
|
|
|
1439
1487
|
respondOptions.signal ?? new AbortController().signal,
|
|
1440
1488
|
respondOptions.handlers
|
|
1441
1489
|
),
|
|
1490
|
+
regenerateTurn: (message, regenerateOptions) => session.regenerateTurn(
|
|
1491
|
+
message,
|
|
1492
|
+
regenerateOptions.signal ?? new AbortController().signal,
|
|
1493
|
+
regenerateOptions.handlers
|
|
1494
|
+
),
|
|
1442
1495
|
reset: () => session.reset(),
|
|
1443
1496
|
cancelActive: () => session.cancelActive(),
|
|
1444
1497
|
getActiveSessionId: () => session.getActiveSessionId()
|
|
@@ -2881,6 +2934,7 @@ function useAgentChat({
|
|
|
2881
2934
|
const {
|
|
2882
2935
|
controller,
|
|
2883
2936
|
initialText = "",
|
|
2937
|
+
regenerate: regenerate2 = false,
|
|
2884
2938
|
responses,
|
|
2885
2939
|
resume,
|
|
2886
2940
|
visitorText
|
|
@@ -2992,6 +3046,9 @@ function useAgentChat({
|
|
|
2992
3046
|
initialText,
|
|
2993
3047
|
message: visitorText,
|
|
2994
3048
|
signal
|
|
3049
|
+
}) : regenerate2 ? await clientRef.current.regenerateTurn(visitorText, {
|
|
3050
|
+
handlers,
|
|
3051
|
+
signal
|
|
2995
3052
|
}) : await clientRef.current.sendTurn(visitorText, {
|
|
2996
3053
|
handlers,
|
|
2997
3054
|
signal
|
|
@@ -3208,6 +3265,49 @@ ${outgoing}` : outgoing;
|
|
|
3208
3265
|
visitorText: visitorTurnText(visitorMessage)
|
|
3209
3266
|
});
|
|
3210
3267
|
}, [runTurn, state.messages]);
|
|
3268
|
+
const regenerate = (0, import_react2.useCallback)(async () => {
|
|
3269
|
+
let lastVisitorIndex = -1;
|
|
3270
|
+
for (let index = state.messages.length - 1; index >= 0; index -= 1) {
|
|
3271
|
+
if (state.messages[index]?.role === "visitor") {
|
|
3272
|
+
lastVisitorIndex = index;
|
|
3273
|
+
break;
|
|
3274
|
+
}
|
|
3275
|
+
}
|
|
3276
|
+
const visitorMessage = lastVisitorIndex >= 0 ? state.messages[lastVisitorIndex] : void 0;
|
|
3277
|
+
if (!visitorMessage) return null;
|
|
3278
|
+
if (runRef.current) {
|
|
3279
|
+
runRef.current.abort();
|
|
3280
|
+
clientRef.current.cancelActive();
|
|
3281
|
+
}
|
|
3282
|
+
const controller = new AbortController();
|
|
3283
|
+
runRef.current = controller;
|
|
3284
|
+
setState((prev) => ({
|
|
3285
|
+
...prev,
|
|
3286
|
+
phase: "thinking",
|
|
3287
|
+
messages: prev.messages.slice(0, lastVisitorIndex + 1),
|
|
3288
|
+
toolSteps: [
|
|
3289
|
+
{
|
|
3290
|
+
id: "planning",
|
|
3291
|
+
kind: "planning",
|
|
3292
|
+
label: "Understanding your question",
|
|
3293
|
+
state: "active"
|
|
3294
|
+
}
|
|
3295
|
+
],
|
|
3296
|
+
journey: null,
|
|
3297
|
+
followUps: [],
|
|
3298
|
+
streamingText: "",
|
|
3299
|
+
pendingOffer: null,
|
|
3300
|
+
pendingInputs: [],
|
|
3301
|
+
toolResults: [],
|
|
3302
|
+
error: null
|
|
3303
|
+
}));
|
|
3304
|
+
return await runTurn({
|
|
3305
|
+
controller,
|
|
3306
|
+
regenerate: true,
|
|
3307
|
+
resume: false,
|
|
3308
|
+
visitorText: visitorTurnText(visitorMessage)
|
|
3309
|
+
});
|
|
3310
|
+
}, [runTurn, state.messages]);
|
|
3211
3311
|
const respondToToolInput = (0, import_react2.useCallback)(
|
|
3212
3312
|
async (surface, values) => {
|
|
3213
3313
|
await submit(`${surface.title} submitted`, {
|
|
@@ -3284,6 +3384,7 @@ ${outgoing}` : outgoing;
|
|
|
3284
3384
|
state,
|
|
3285
3385
|
reset,
|
|
3286
3386
|
retry,
|
|
3387
|
+
regenerate,
|
|
3287
3388
|
respondToInput,
|
|
3288
3389
|
respondToToolInput,
|
|
3289
3390
|
submit,
|
|
@@ -3334,7 +3435,7 @@ function normalizeAgentPlacement(placement) {
|
|
|
3334
3435
|
}
|
|
3335
3436
|
|
|
3336
3437
|
// src/react/components/AgentRail/AgentRail.tsx
|
|
3337
|
-
var
|
|
3438
|
+
var import_react14 = require("react");
|
|
3338
3439
|
|
|
3339
3440
|
// src/react/types/conversation.ts
|
|
3340
3441
|
var defaultAgentRailTheme = {
|
|
@@ -3456,6 +3557,60 @@ function stepDetail(step, steps) {
|
|
|
3456
3557
|
return "Searched this site";
|
|
3457
3558
|
return step.detail;
|
|
3458
3559
|
}
|
|
3560
|
+
function AgentWorkSteps({
|
|
3561
|
+
brandLabel = "",
|
|
3562
|
+
onRetryStep,
|
|
3563
|
+
steps
|
|
3564
|
+
}) {
|
|
3565
|
+
const delegationCount = steps.filter(
|
|
3566
|
+
(step) => step.kind === "specialist"
|
|
3567
|
+
).length;
|
|
3568
|
+
const delegated = delegationCount > 0 && steps.some((step) => step.kind === "planning");
|
|
3569
|
+
const visibleSteps = steps.filter(
|
|
3570
|
+
(step) => step.kind !== "planning" || Boolean(brandLabel)
|
|
3571
|
+
);
|
|
3572
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "agent-activity-bubble__steps", children: visibleSteps.map((step) => {
|
|
3573
|
+
const detail = stepDetail(step, steps);
|
|
3574
|
+
const child = delegated && step.kind === "specialist";
|
|
3575
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
3576
|
+
"li",
|
|
3577
|
+
{
|
|
3578
|
+
className: `agent-activity-bubble__step${child ? " agent-activity-bubble__step--child" : ""}`,
|
|
3579
|
+
"data-kind": step.kind,
|
|
3580
|
+
"data-state": step.state,
|
|
3581
|
+
children: [
|
|
3582
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3583
|
+
"span",
|
|
3584
|
+
{
|
|
3585
|
+
className: "agent-activity-bubble__step-icon",
|
|
3586
|
+
"aria-hidden": "true"
|
|
3587
|
+
}
|
|
3588
|
+
),
|
|
3589
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__step-copy", children: [
|
|
3590
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-activity-bubble__step-heading", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: stepLabel(step, brandLabel) }) }),
|
|
3591
|
+
detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-activity-bubble__step-detail", children: detail }) : null,
|
|
3592
|
+
delegated && step.kind === "planning" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__delegation", children: [
|
|
3593
|
+
"Delegated ",
|
|
3594
|
+
delegationCount,
|
|
3595
|
+
" ",
|
|
3596
|
+
delegationCount === 1 ? "task" : "tasks"
|
|
3597
|
+
] }) : null,
|
|
3598
|
+
step.state === "error" && onRetryStep ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3599
|
+
"button",
|
|
3600
|
+
{
|
|
3601
|
+
type: "button",
|
|
3602
|
+
className: "agent-activity-bubble__step-retry",
|
|
3603
|
+
onClick: () => onRetryStep(step),
|
|
3604
|
+
children: "Retry"
|
|
3605
|
+
}
|
|
3606
|
+
) : null
|
|
3607
|
+
] })
|
|
3608
|
+
]
|
|
3609
|
+
},
|
|
3610
|
+
step.id
|
|
3611
|
+
);
|
|
3612
|
+
}) });
|
|
3613
|
+
}
|
|
3459
3614
|
function AgentActivityBubble({
|
|
3460
3615
|
brandLabel = "",
|
|
3461
3616
|
failed = false,
|
|
@@ -3467,14 +3622,7 @@ function AgentActivityBubble({
|
|
|
3467
3622
|
const [expandedReceiptId, setExpandedReceiptId] = (0, import_react5.useState)(
|
|
3468
3623
|
null
|
|
3469
3624
|
);
|
|
3470
|
-
const detailsOpen = active
|
|
3471
|
-
const delegationCount = steps.filter(
|
|
3472
|
-
(step) => step.kind === "specialist"
|
|
3473
|
-
).length;
|
|
3474
|
-
const delegated = delegationCount > 0 && steps.some((step) => step.kind === "planning");
|
|
3475
|
-
const visibleSteps = steps.filter(
|
|
3476
|
-
(step) => step.kind !== "planning" || Boolean(brandLabel)
|
|
3477
|
-
);
|
|
3625
|
+
const detailsOpen = !active && expandedReceiptId === receiptId;
|
|
3478
3626
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", { className: "agent-activity-bubble", children: [
|
|
3479
3627
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "agent-activity-bubble__status", "aria-live": "polite", children: [
|
|
3480
3628
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -3484,9 +3632,10 @@ function AgentActivityBubble({
|
|
|
3484
3632
|
"aria-hidden": "true"
|
|
3485
3633
|
}
|
|
3486
3634
|
),
|
|
3487
|
-
workSummary(steps, failed, brandLabel)
|
|
3635
|
+
workSummary(steps, failed, brandLabel),
|
|
3636
|
+
active ? "\u2026" : ""
|
|
3488
3637
|
] }),
|
|
3489
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "agent-activity-bubble__details", children: [
|
|
3638
|
+
!active ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "agent-activity-bubble__details", children: [
|
|
3490
3639
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3491
3640
|
"button",
|
|
3492
3641
|
{
|
|
@@ -3494,7 +3643,6 @@ function AgentActivityBubble({
|
|
|
3494
3643
|
className: "agent-activity-bubble__summary",
|
|
3495
3644
|
"aria-expanded": detailsOpen,
|
|
3496
3645
|
onClick: () => {
|
|
3497
|
-
if (active) return;
|
|
3498
3646
|
setExpandedReceiptId(
|
|
3499
3647
|
(current) => current === receiptId ? null : receiptId
|
|
3500
3648
|
);
|
|
@@ -3502,56 +3650,145 @@ function AgentActivityBubble({
|
|
|
3502
3650
|
children: "How this answer was made"
|
|
3503
3651
|
}
|
|
3504
3652
|
),
|
|
3505
|
-
detailsOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
children: [
|
|
3515
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3516
|
-
"span",
|
|
3517
|
-
{
|
|
3518
|
-
className: "agent-activity-bubble__step-icon",
|
|
3519
|
-
"aria-hidden": "true"
|
|
3520
|
-
}
|
|
3521
|
-
),
|
|
3522
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__step-copy", children: [
|
|
3523
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-activity-bubble__step-heading", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: stepLabel(step, brandLabel) }) }),
|
|
3524
|
-
detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-activity-bubble__step-detail", children: detail }) : null,
|
|
3525
|
-
delegated && step.kind === "planning" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__delegation", children: [
|
|
3526
|
-
"Delegated ",
|
|
3527
|
-
delegationCount,
|
|
3528
|
-
" ",
|
|
3529
|
-
delegationCount === 1 ? "task" : "tasks"
|
|
3530
|
-
] }) : null,
|
|
3531
|
-
step.state === "error" && onRetryStep ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3532
|
-
"button",
|
|
3533
|
-
{
|
|
3534
|
-
type: "button",
|
|
3535
|
-
className: "agent-activity-bubble__step-retry",
|
|
3536
|
-
onClick: () => onRetryStep(step),
|
|
3537
|
-
children: "Retry"
|
|
3538
|
-
}
|
|
3539
|
-
) : null
|
|
3540
|
-
] })
|
|
3541
|
-
]
|
|
3542
|
-
},
|
|
3543
|
-
step.id
|
|
3544
|
-
);
|
|
3545
|
-
}) }) : null
|
|
3546
|
-
] })
|
|
3653
|
+
detailsOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3654
|
+
AgentWorkSteps,
|
|
3655
|
+
{
|
|
3656
|
+
brandLabel,
|
|
3657
|
+
onRetryStep,
|
|
3658
|
+
steps
|
|
3659
|
+
}
|
|
3660
|
+
) : null
|
|
3661
|
+
] }) : null
|
|
3547
3662
|
] });
|
|
3548
3663
|
}
|
|
3549
3664
|
|
|
3550
|
-
// src/react/components/
|
|
3665
|
+
// src/react/components/AnswerReceiptDialog/AnswerReceiptDialog.tsx
|
|
3666
|
+
var import_react7 = require("react");
|
|
3667
|
+
var import_react_dom = require("react-dom");
|
|
3668
|
+
|
|
3669
|
+
// src/react/components/AgentRail/AgentRailOverlayContext.tsx
|
|
3551
3670
|
var import_react6 = require("react");
|
|
3671
|
+
var AgentRailOverlayContext = (0, import_react6.createContext)(null);
|
|
3672
|
+
function useAgentRailPortalRoots() {
|
|
3673
|
+
return (0, import_react6.useContext)(AgentRailOverlayContext);
|
|
3674
|
+
}
|
|
3675
|
+
function useAgentRailMenuPortalRoot() {
|
|
3676
|
+
return (0, import_react6.useContext)(AgentRailOverlayContext)?.railRef ?? null;
|
|
3677
|
+
}
|
|
3678
|
+
|
|
3679
|
+
// src/react/components/AnswerReceiptDialog/AnswerReceiptDialog.tsx
|
|
3552
3680
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
3553
|
-
|
|
3681
|
+
var FOCUSABLE_SELECTOR = 'button:not(:disabled), a[href], textarea:not(:disabled), input:not(:disabled), [tabindex]:not([tabindex="-1"])';
|
|
3682
|
+
function CloseIcon() {
|
|
3554
3683
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
3684
|
+
"path",
|
|
3685
|
+
{
|
|
3686
|
+
d: "M4 4l8 8M12 4l-8 8",
|
|
3687
|
+
stroke: "currentColor",
|
|
3688
|
+
strokeWidth: "1.5",
|
|
3689
|
+
strokeLinecap: "round"
|
|
3690
|
+
}
|
|
3691
|
+
) });
|
|
3692
|
+
}
|
|
3693
|
+
function AnswerReceiptDialog({
|
|
3694
|
+
brandLabel = "",
|
|
3695
|
+
onClose,
|
|
3696
|
+
steps
|
|
3697
|
+
}) {
|
|
3698
|
+
const portalRoots = useAgentRailPortalRoots();
|
|
3699
|
+
const overlayRoot = portalRoots?.overlayRef ?? null;
|
|
3700
|
+
const cardRef = (0, import_react7.useRef)(null);
|
|
3701
|
+
const closeButtonRef = (0, import_react7.useRef)(null);
|
|
3702
|
+
const previouslyFocusedRef = (0, import_react7.useRef)(null);
|
|
3703
|
+
(0, import_react7.useEffect)(() => {
|
|
3704
|
+
previouslyFocusedRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
3705
|
+
closeButtonRef.current?.focus({ preventScroll: true });
|
|
3706
|
+
const handleKeyDown = (event) => {
|
|
3707
|
+
if (event.key === "Escape") {
|
|
3708
|
+
event.preventDefault();
|
|
3709
|
+
event.stopPropagation();
|
|
3710
|
+
onClose();
|
|
3711
|
+
return;
|
|
3712
|
+
}
|
|
3713
|
+
if (event.key !== "Tab" || !cardRef.current) return;
|
|
3714
|
+
const focusable = cardRef.current.querySelectorAll(
|
|
3715
|
+
FOCUSABLE_SELECTOR
|
|
3716
|
+
);
|
|
3717
|
+
if (focusable.length === 0) return;
|
|
3718
|
+
const first = focusable.item(0);
|
|
3719
|
+
const last = focusable.item(focusable.length - 1);
|
|
3720
|
+
if (event.shiftKey && document.activeElement === first) {
|
|
3721
|
+
event.preventDefault();
|
|
3722
|
+
last.focus({ preventScroll: true });
|
|
3723
|
+
} else if (!event.shiftKey && document.activeElement === last) {
|
|
3724
|
+
event.preventDefault();
|
|
3725
|
+
first.focus({ preventScroll: true });
|
|
3726
|
+
}
|
|
3727
|
+
};
|
|
3728
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
3729
|
+
return () => {
|
|
3730
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
3731
|
+
previouslyFocusedRef.current?.focus({ preventScroll: true });
|
|
3732
|
+
};
|
|
3733
|
+
}, [onClose]);
|
|
3734
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "agent-receipt-dialog", children: [
|
|
3735
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
3736
|
+
"button",
|
|
3737
|
+
{
|
|
3738
|
+
type: "button",
|
|
3739
|
+
className: "agent-receipt-dialog__backdrop",
|
|
3740
|
+
"aria-label": "Close",
|
|
3741
|
+
tabIndex: -1,
|
|
3742
|
+
onClick: onClose
|
|
3743
|
+
}
|
|
3744
|
+
),
|
|
3745
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
3746
|
+
"div",
|
|
3747
|
+
{
|
|
3748
|
+
ref: cardRef,
|
|
3749
|
+
className: "agent-receipt-dialog__card",
|
|
3750
|
+
role: "dialog",
|
|
3751
|
+
"aria-modal": "true",
|
|
3752
|
+
"aria-labelledby": "agent-receipt-dialog-title",
|
|
3753
|
+
children: [
|
|
3754
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "agent-receipt-dialog__header", children: [
|
|
3755
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
3756
|
+
"p",
|
|
3757
|
+
{
|
|
3758
|
+
className: "agent-receipt-dialog__title",
|
|
3759
|
+
id: "agent-receipt-dialog-title",
|
|
3760
|
+
children: "How this answer was made"
|
|
3761
|
+
}
|
|
3762
|
+
),
|
|
3763
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
3764
|
+
"button",
|
|
3765
|
+
{
|
|
3766
|
+
ref: closeButtonRef,
|
|
3767
|
+
type: "button",
|
|
3768
|
+
className: "agent-receipt-dialog__close",
|
|
3769
|
+
"aria-label": "Close",
|
|
3770
|
+
onClick: onClose,
|
|
3771
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CloseIcon, {})
|
|
3772
|
+
}
|
|
3773
|
+
)
|
|
3774
|
+
] }),
|
|
3775
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "agent-receipt-dialog__summary", children: workSummary(steps, false, brandLabel) }),
|
|
3776
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "agent-receipt-dialog__body", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AgentWorkSteps, { brandLabel, steps }) })
|
|
3777
|
+
]
|
|
3778
|
+
}
|
|
3779
|
+
)
|
|
3780
|
+
] });
|
|
3781
|
+
if (overlayRoot?.current) {
|
|
3782
|
+
return (0, import_react_dom.createPortal)(content, overlayRoot.current);
|
|
3783
|
+
}
|
|
3784
|
+
return content;
|
|
3785
|
+
}
|
|
3786
|
+
|
|
3787
|
+
// src/react/components/Composer/Composer.tsx
|
|
3788
|
+
var import_react8 = require("react");
|
|
3789
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
3790
|
+
function SendIcon() {
|
|
3791
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3555
3792
|
"path",
|
|
3556
3793
|
{
|
|
3557
3794
|
d: "M8 12V4M8 4l-3 3M8 4l3 3",
|
|
@@ -3574,21 +3811,21 @@ function Composer({
|
|
|
3574
3811
|
form = null,
|
|
3575
3812
|
onSubmit
|
|
3576
3813
|
}) {
|
|
3577
|
-
const [value, setValue] = (0,
|
|
3578
|
-
const [values, setValues] = (0,
|
|
3814
|
+
const [value, setValue] = (0, import_react8.useState)("");
|
|
3815
|
+
const [values, setValues] = (0, import_react8.useState)(
|
|
3579
3816
|
() => emptyValues(form)
|
|
3580
3817
|
);
|
|
3581
|
-
const [blurred, setBlurred] = (0,
|
|
3582
|
-
const inputRef = (0,
|
|
3583
|
-
const firstFieldRef = (0,
|
|
3584
|
-
const formId = (0,
|
|
3818
|
+
const [blurred, setBlurred] = (0, import_react8.useState)({});
|
|
3819
|
+
const inputRef = (0, import_react8.useRef)(null);
|
|
3820
|
+
const firstFieldRef = (0, import_react8.useRef)(null);
|
|
3821
|
+
const formId = (0, import_react8.useId)();
|
|
3585
3822
|
const activeForm = form;
|
|
3586
3823
|
const canSendForm = activeForm ? isComposerFormComplete(activeForm, values) : Boolean(value.trim());
|
|
3587
|
-
(0,
|
|
3824
|
+
(0, import_react8.useEffect)(() => {
|
|
3588
3825
|
setValues(emptyValues(form));
|
|
3589
3826
|
setBlurred({});
|
|
3590
3827
|
}, [form?.id]);
|
|
3591
|
-
(0,
|
|
3828
|
+
(0, import_react8.useEffect)(() => {
|
|
3592
3829
|
if (activeForm) firstFieldRef.current?.focus();
|
|
3593
3830
|
}, [activeForm?.id]);
|
|
3594
3831
|
function submitChat() {
|
|
@@ -3623,7 +3860,7 @@ function Composer({
|
|
|
3623
3860
|
submitForm();
|
|
3624
3861
|
}
|
|
3625
3862
|
}
|
|
3626
|
-
return /* @__PURE__ */ (0,
|
|
3863
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3627
3864
|
"form",
|
|
3628
3865
|
{
|
|
3629
3866
|
className: [
|
|
@@ -3632,7 +3869,7 @@ function Composer({
|
|
|
3632
3869
|
activeForm ? "composer--form" : ""
|
|
3633
3870
|
].filter(Boolean).join(" "),
|
|
3634
3871
|
onSubmit: handleSubmit,
|
|
3635
|
-
children: activeForm ? /* @__PURE__ */ (0,
|
|
3872
|
+
children: activeForm ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "composer__sheet", role: "group", "aria-label": "Required details", children: [
|
|
3636
3873
|
activeForm.fields.map((field, index) => {
|
|
3637
3874
|
const fieldId = `${formId}-${field.id}`;
|
|
3638
3875
|
const invalid = Boolean(blurred[field.id]) && !isValidComposerFieldValue(field, values[field.id] ?? "");
|
|
@@ -3657,7 +3894,7 @@ function Composer({
|
|
|
3657
3894
|
},
|
|
3658
3895
|
onKeyDown: handleFormKeyDown
|
|
3659
3896
|
};
|
|
3660
|
-
return /* @__PURE__ */ (0,
|
|
3897
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
3661
3898
|
"div",
|
|
3662
3899
|
{
|
|
3663
3900
|
className: [
|
|
@@ -3665,9 +3902,9 @@ function Composer({
|
|
|
3665
3902
|
field.kind === "textarea" ? "composer__row--grow" : ""
|
|
3666
3903
|
].filter(Boolean).join(" "),
|
|
3667
3904
|
children: [
|
|
3668
|
-
/* @__PURE__ */ (0,
|
|
3669
|
-
/* @__PURE__ */ (0,
|
|
3670
|
-
field.kind === "textarea" ? /* @__PURE__ */ (0,
|
|
3905
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "composer__label", htmlFor: fieldId, children: [
|
|
3906
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "composer__sr-only", children: field.label }),
|
|
3907
|
+
field.kind === "textarea" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3671
3908
|
"textarea",
|
|
3672
3909
|
{
|
|
3673
3910
|
...controlProps,
|
|
@@ -3677,7 +3914,7 @@ function Composer({
|
|
|
3677
3914
|
className: "composer__control composer__control--area",
|
|
3678
3915
|
rows: 3
|
|
3679
3916
|
}
|
|
3680
|
-
) : /* @__PURE__ */ (0,
|
|
3917
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3681
3918
|
"input",
|
|
3682
3919
|
{
|
|
3683
3920
|
...controlProps,
|
|
@@ -3690,24 +3927,24 @@ function Composer({
|
|
|
3690
3927
|
}
|
|
3691
3928
|
)
|
|
3692
3929
|
] }),
|
|
3693
|
-
invalid ? /* @__PURE__ */ (0,
|
|
3930
|
+
invalid ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "composer__error", id: `${fieldId}-error`, children: field.kind === "email" ? "Enter a valid email to continue." : `Add your ${field.label.toLowerCase()} to continue.` }) : null
|
|
3694
3931
|
]
|
|
3695
3932
|
},
|
|
3696
3933
|
field.id
|
|
3697
3934
|
);
|
|
3698
3935
|
}),
|
|
3699
|
-
/* @__PURE__ */ (0,
|
|
3936
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "composer__toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3700
3937
|
"button",
|
|
3701
3938
|
{
|
|
3702
3939
|
type: "submit",
|
|
3703
3940
|
className: "composer__send",
|
|
3704
3941
|
disabled: disabled || !canSendForm,
|
|
3705
3942
|
"aria-label": "Send details",
|
|
3706
|
-
children: /* @__PURE__ */ (0,
|
|
3943
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SendIcon, {})
|
|
3707
3944
|
}
|
|
3708
3945
|
) })
|
|
3709
|
-
] }) : /* @__PURE__ */ (0,
|
|
3710
|
-
/* @__PURE__ */ (0,
|
|
3946
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "composer__field", children: [
|
|
3947
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3711
3948
|
"textarea",
|
|
3712
3949
|
{
|
|
3713
3950
|
ref: inputRef,
|
|
@@ -3722,14 +3959,14 @@ function Composer({
|
|
|
3722
3959
|
onKeyDown: handleChatKeyDown
|
|
3723
3960
|
}
|
|
3724
3961
|
),
|
|
3725
|
-
/* @__PURE__ */ (0,
|
|
3962
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3726
3963
|
"button",
|
|
3727
3964
|
{
|
|
3728
3965
|
type: "submit",
|
|
3729
3966
|
className: "composer__send",
|
|
3730
3967
|
disabled: disabled || !value.trim(),
|
|
3731
3968
|
"aria-label": "Send message",
|
|
3732
|
-
children: /* @__PURE__ */ (0,
|
|
3969
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SendIcon, {})
|
|
3733
3970
|
}
|
|
3734
3971
|
)
|
|
3735
3972
|
] })
|
|
@@ -3738,7 +3975,7 @@ function Composer({
|
|
|
3738
3975
|
}
|
|
3739
3976
|
|
|
3740
3977
|
// src/react/components/FollowUpChips/FollowUpChips.tsx
|
|
3741
|
-
var
|
|
3978
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
3742
3979
|
function FollowUpChips({
|
|
3743
3980
|
suggestions,
|
|
3744
3981
|
disabled = false,
|
|
@@ -3748,7 +3985,7 @@ function FollowUpChips({
|
|
|
3748
3985
|
}) {
|
|
3749
3986
|
if (suggestions.length === 0) return null;
|
|
3750
3987
|
if (variant === "dock") {
|
|
3751
|
-
return /* @__PURE__ */ (0,
|
|
3988
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "followups followups--dock", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "followups__scroll", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3752
3989
|
"button",
|
|
3753
3990
|
{
|
|
3754
3991
|
type: "button",
|
|
@@ -3760,9 +3997,9 @@ function FollowUpChips({
|
|
|
3760
3997
|
suggestion.id
|
|
3761
3998
|
)) }) });
|
|
3762
3999
|
}
|
|
3763
|
-
return /* @__PURE__ */ (0,
|
|
3764
|
-
/* @__PURE__ */ (0,
|
|
3765
|
-
/* @__PURE__ */ (0,
|
|
4000
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "followups", children: [
|
|
4001
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "followups__label", children: label }),
|
|
4002
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "followups__list", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3766
4003
|
"button",
|
|
3767
4004
|
{
|
|
3768
4005
|
type: "button",
|
|
@@ -3777,11 +4014,11 @@ function FollowUpChips({
|
|
|
3777
4014
|
}
|
|
3778
4015
|
|
|
3779
4016
|
// src/react/components/MessageBubble/MessageBubble.tsx
|
|
3780
|
-
var
|
|
4017
|
+
var import_react10 = require("react");
|
|
3781
4018
|
|
|
3782
4019
|
// src/react/components/BookingCard/BookingCard.tsx
|
|
3783
|
-
var
|
|
3784
|
-
var
|
|
4020
|
+
var import_react9 = require("react");
|
|
4021
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
3785
4022
|
var BOOKING_STEPS = [
|
|
3786
4023
|
{ id: "date", label: "Date" },
|
|
3787
4024
|
{ id: "time", label: "Time" },
|
|
@@ -3812,34 +4049,34 @@ function calendarCells(year, month) {
|
|
|
3812
4049
|
return cells;
|
|
3813
4050
|
}
|
|
3814
4051
|
function BookingCardLoader() {
|
|
3815
|
-
return /* @__PURE__ */ (0,
|
|
4052
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("section", { className: "booking-card", "aria-label": "Book a meeting", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) });
|
|
3816
4053
|
}
|
|
3817
4054
|
function BookingCard({
|
|
3818
4055
|
disabled = false,
|
|
3819
4056
|
offer,
|
|
3820
4057
|
onBook
|
|
3821
4058
|
}) {
|
|
3822
|
-
const fieldId = (0,
|
|
4059
|
+
const fieldId = (0, import_react9.useId)();
|
|
3823
4060
|
const defaultType = offer.eventTypes[0]?.uri ?? offer.slots[0]?.eventTypeUri ?? "";
|
|
3824
|
-
const [step, setStep] = (0,
|
|
3825
|
-
const [eventTypeUri, setEventTypeUri] = (0,
|
|
3826
|
-
const [selectedDate, setSelectedDate] = (0,
|
|
3827
|
-
const [startTime, setStartTime] = (0,
|
|
3828
|
-
const [name, setName] = (0,
|
|
3829
|
-
const [email, setEmail] = (0,
|
|
3830
|
-
const activeStepRef = (0,
|
|
3831
|
-
const previousStepRef = (0,
|
|
4061
|
+
const [step, setStep] = (0, import_react9.useState)("date");
|
|
4062
|
+
const [eventTypeUri, setEventTypeUri] = (0, import_react9.useState)(defaultType);
|
|
4063
|
+
const [selectedDate, setSelectedDate] = (0, import_react9.useState)("");
|
|
4064
|
+
const [startTime, setStartTime] = (0, import_react9.useState)("");
|
|
4065
|
+
const [name, setName] = (0, import_react9.useState)("");
|
|
4066
|
+
const [email, setEmail] = (0, import_react9.useState)("");
|
|
4067
|
+
const activeStepRef = (0, import_react9.useRef)(null);
|
|
4068
|
+
const previousStepRef = (0, import_react9.useRef)(step);
|
|
3832
4069
|
const stepIndex = BOOKING_STEPS.findIndex((item) => item.id === step);
|
|
3833
|
-
(0,
|
|
4070
|
+
(0, import_react9.useEffect)(() => {
|
|
3834
4071
|
if (previousStepRef.current === step) return;
|
|
3835
4072
|
previousStepRef.current = step;
|
|
3836
4073
|
activeStepRef.current?.scrollIntoView({ block: "nearest" });
|
|
3837
4074
|
}, [step]);
|
|
3838
|
-
const slots = (0,
|
|
4075
|
+
const slots = (0, import_react9.useMemo)(
|
|
3839
4076
|
() => bookingSlotsForEventType(offer.slots, eventTypeUri),
|
|
3840
4077
|
[eventTypeUri, offer.slots]
|
|
3841
4078
|
);
|
|
3842
|
-
const availableByDate = (0,
|
|
4079
|
+
const availableByDate = (0, import_react9.useMemo)(() => {
|
|
3843
4080
|
const next = /* @__PURE__ */ new Map();
|
|
3844
4081
|
for (const slot of slots) {
|
|
3845
4082
|
const key = slotDateKey(slot.startTime);
|
|
@@ -3847,7 +4084,7 @@ function BookingCard({
|
|
|
3847
4084
|
}
|
|
3848
4085
|
return next;
|
|
3849
4086
|
}, [slots]);
|
|
3850
|
-
const [visibleMonth, setVisibleMonth] = (0,
|
|
4087
|
+
const [visibleMonth, setVisibleMonth] = (0, import_react9.useState)(
|
|
3851
4088
|
() => firstAvailableBookingMonth(slots)
|
|
3852
4089
|
);
|
|
3853
4090
|
function selectEventType(nextType) {
|
|
@@ -3860,7 +4097,7 @@ function BookingCard({
|
|
|
3860
4097
|
)
|
|
3861
4098
|
);
|
|
3862
4099
|
}
|
|
3863
|
-
const daySlots = (0,
|
|
4100
|
+
const daySlots = (0, import_react9.useMemo)(
|
|
3864
4101
|
() => slots.filter((slot) => slotDateKey(slot.startTime) === selectedDate),
|
|
3865
4102
|
[selectedDate, slots]
|
|
3866
4103
|
);
|
|
@@ -3869,7 +4106,7 @@ function BookingCard({
|
|
|
3869
4106
|
);
|
|
3870
4107
|
const selectedSample = availableByDate.get(selectedDate) ?? startTime;
|
|
3871
4108
|
const timeZone = formatSlotTimeZone(slots[0]?.startTime ?? selectedSample);
|
|
3872
|
-
const weekdays = (0,
|
|
4109
|
+
const weekdays = (0, import_react9.useMemo)(() => weekdayLabels(), []);
|
|
3873
4110
|
const cells = calendarCells(visibleMonth.year, visibleMonth.month);
|
|
3874
4111
|
const canPrevMonth = [...availableByDate.keys()].some((key) => {
|
|
3875
4112
|
const month = monthFromKey(key);
|
|
@@ -3911,14 +4148,14 @@ function BookingCard({
|
|
|
3911
4148
|
})
|
|
3912
4149
|
});
|
|
3913
4150
|
}
|
|
3914
|
-
return /* @__PURE__ */ (0,
|
|
4151
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3915
4152
|
"section",
|
|
3916
4153
|
{
|
|
3917
4154
|
className: "booking-card",
|
|
3918
4155
|
"aria-busy": disabled || void 0,
|
|
3919
4156
|
"aria-label": "Book a meeting",
|
|
3920
|
-
children: /* @__PURE__ */ (0,
|
|
3921
|
-
/* @__PURE__ */ (0,
|
|
4157
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("form", { className: "booking-card__form", onSubmit: handleSubmit, children: [
|
|
4158
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ol", { className: "booking-card__steps", "aria-label": "Booking steps", children: BOOKING_STEPS.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
3922
4159
|
"li",
|
|
3923
4160
|
{
|
|
3924
4161
|
className: [
|
|
@@ -3928,40 +4165,40 @@ function BookingCard({
|
|
|
3928
4165
|
].filter(Boolean).join(" "),
|
|
3929
4166
|
"aria-current": index === stepIndex ? "step" : void 0,
|
|
3930
4167
|
children: [
|
|
3931
|
-
/* @__PURE__ */ (0,
|
|
3932
|
-
/* @__PURE__ */ (0,
|
|
4168
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { "aria-hidden": "true", children: index + 1 }),
|
|
4169
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: item.label })
|
|
3933
4170
|
]
|
|
3934
4171
|
},
|
|
3935
4172
|
item.id
|
|
3936
4173
|
)) }),
|
|
3937
|
-
step === "date" ? /* @__PURE__ */ (0,
|
|
3938
|
-
/* @__PURE__ */ (0,
|
|
3939
|
-
timeZone ? /* @__PURE__ */ (0,
|
|
4174
|
+
step === "date" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
|
|
4175
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__title", children: selectedType?.name || "Pick a date" }),
|
|
4176
|
+
timeZone ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "booking-card__tz", children: [
|
|
3940
4177
|
"Times in ",
|
|
3941
4178
|
timeZone
|
|
3942
4179
|
] }) : null,
|
|
3943
|
-
offer.eventTypes.length > 1 ? /* @__PURE__ */ (0,
|
|
4180
|
+
offer.eventTypes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
3944
4181
|
"label",
|
|
3945
4182
|
{
|
|
3946
4183
|
className: "booking-card__field",
|
|
3947
4184
|
htmlFor: `${fieldId}-type`,
|
|
3948
4185
|
children: [
|
|
3949
|
-
/* @__PURE__ */ (0,
|
|
3950
|
-
/* @__PURE__ */ (0,
|
|
4186
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Meeting" }),
|
|
4187
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3951
4188
|
"select",
|
|
3952
4189
|
{
|
|
3953
4190
|
id: `${fieldId}-type`,
|
|
3954
4191
|
value: eventTypeUri,
|
|
3955
4192
|
disabled,
|
|
3956
4193
|
onChange: (event) => selectEventType(event.target.value),
|
|
3957
|
-
children: offer.eventTypes.map((item) => /* @__PURE__ */ (0,
|
|
4194
|
+
children: offer.eventTypes.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: item.uri, children: item.name }, item.uri))
|
|
3958
4195
|
}
|
|
3959
4196
|
)
|
|
3960
4197
|
]
|
|
3961
4198
|
}
|
|
3962
4199
|
) : null,
|
|
3963
|
-
/* @__PURE__ */ (0,
|
|
3964
|
-
/* @__PURE__ */ (0,
|
|
4200
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__month", children: [
|
|
4201
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3965
4202
|
"button",
|
|
3966
4203
|
{
|
|
3967
4204
|
type: "button",
|
|
@@ -3972,8 +4209,8 @@ function BookingCard({
|
|
|
3972
4209
|
children: "\u2039"
|
|
3973
4210
|
}
|
|
3974
4211
|
),
|
|
3975
|
-
/* @__PURE__ */ (0,
|
|
3976
|
-
/* @__PURE__ */ (0,
|
|
4212
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__month-title", children: formatMonthTitle(visibleMonth.year, visibleMonth.month) }),
|
|
4213
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3977
4214
|
"button",
|
|
3978
4215
|
{
|
|
3979
4216
|
type: "button",
|
|
@@ -3985,9 +4222,9 @@ function BookingCard({
|
|
|
3985
4222
|
}
|
|
3986
4223
|
)
|
|
3987
4224
|
] }),
|
|
3988
|
-
/* @__PURE__ */ (0,
|
|
3989
|
-
offer.slots.length === 0 ? /* @__PURE__ */ (0,
|
|
3990
|
-
/* @__PURE__ */ (0,
|
|
4225
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "booking-card__weekdays", children: weekdays.map((label) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: label }, label)) }),
|
|
4226
|
+
offer.slots.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) : null,
|
|
4227
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3991
4228
|
"div",
|
|
3992
4229
|
{
|
|
3993
4230
|
className: "booking-card__calendar",
|
|
@@ -3995,7 +4232,7 @@ function BookingCard({
|
|
|
3995
4232
|
"aria-label": "Available dates",
|
|
3996
4233
|
children: cells.map((cell, index) => {
|
|
3997
4234
|
if (!cell) {
|
|
3998
|
-
return /* @__PURE__ */ (0,
|
|
4235
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3999
4236
|
"span",
|
|
4000
4237
|
{
|
|
4001
4238
|
className: "booking-card__day"
|
|
@@ -4005,7 +4242,7 @@ function BookingCard({
|
|
|
4005
4242
|
}
|
|
4006
4243
|
const available = availableByDate.has(cell.key);
|
|
4007
4244
|
const selected = cell.key === selectedDate;
|
|
4008
|
-
return /* @__PURE__ */ (0,
|
|
4245
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
4009
4246
|
"button",
|
|
4010
4247
|
{
|
|
4011
4248
|
type: "button",
|
|
@@ -4025,9 +4262,9 @@ function BookingCard({
|
|
|
4025
4262
|
}
|
|
4026
4263
|
)
|
|
4027
4264
|
] }, "date") : null,
|
|
4028
|
-
step === "time" ? /* @__PURE__ */ (0,
|
|
4029
|
-
/* @__PURE__ */ (0,
|
|
4030
|
-
/* @__PURE__ */ (0,
|
|
4265
|
+
step === "time" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
|
|
4266
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step-bar", children: [
|
|
4267
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
4031
4268
|
"button",
|
|
4032
4269
|
{
|
|
4033
4270
|
type: "button",
|
|
@@ -4038,15 +4275,15 @@ function BookingCard({
|
|
|
4038
4275
|
children: "\u2039"
|
|
4039
4276
|
}
|
|
4040
4277
|
),
|
|
4041
|
-
/* @__PURE__ */ (0,
|
|
4042
|
-
/* @__PURE__ */ (0,
|
|
4043
|
-
timeZone ? /* @__PURE__ */ (0,
|
|
4278
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
4279
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__title", children: selectedSample ? formatLongDate(selectedSample) : "Pick a time" }),
|
|
4280
|
+
timeZone ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "booking-card__tz", children: [
|
|
4044
4281
|
"Times in ",
|
|
4045
4282
|
timeZone
|
|
4046
4283
|
] }) : null
|
|
4047
4284
|
] })
|
|
4048
4285
|
] }),
|
|
4049
|
-
/* @__PURE__ */ (0,
|
|
4286
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "booking-card__times", children: daySlots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
4050
4287
|
"button",
|
|
4051
4288
|
{
|
|
4052
4289
|
type: "button",
|
|
@@ -4058,9 +4295,9 @@ function BookingCard({
|
|
|
4058
4295
|
slot.startTime
|
|
4059
4296
|
)) })
|
|
4060
4297
|
] }, "time") : null,
|
|
4061
|
-
step === "details" ? /* @__PURE__ */ (0,
|
|
4062
|
-
/* @__PURE__ */ (0,
|
|
4063
|
-
/* @__PURE__ */ (0,
|
|
4298
|
+
step === "details" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
|
|
4299
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step-bar", children: [
|
|
4300
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
4064
4301
|
"button",
|
|
4065
4302
|
{
|
|
4066
4303
|
type: "button",
|
|
@@ -4071,21 +4308,21 @@ function BookingCard({
|
|
|
4071
4308
|
children: "\u2039"
|
|
4072
4309
|
}
|
|
4073
4310
|
),
|
|
4074
|
-
/* @__PURE__ */ (0,
|
|
4075
|
-
/* @__PURE__ */ (0,
|
|
4076
|
-
/* @__PURE__ */ (0,
|
|
4077
|
-
selectedType?.location ? /* @__PURE__ */ (0,
|
|
4311
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
4312
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__title", children: "Enter details" }),
|
|
4313
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__tz", children: formatSlotLabel(startTime) }),
|
|
4314
|
+
selectedType?.location ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__tz", children: selectedType.location }) : null
|
|
4078
4315
|
] })
|
|
4079
4316
|
] }),
|
|
4080
|
-
/* @__PURE__ */ (0,
|
|
4081
|
-
/* @__PURE__ */ (0,
|
|
4317
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__identity", children: [
|
|
4318
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
4082
4319
|
"label",
|
|
4083
4320
|
{
|
|
4084
4321
|
className: "booking-card__field",
|
|
4085
4322
|
htmlFor: `${fieldId}-name`,
|
|
4086
4323
|
children: [
|
|
4087
|
-
/* @__PURE__ */ (0,
|
|
4088
|
-
/* @__PURE__ */ (0,
|
|
4324
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Name" }),
|
|
4325
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
4089
4326
|
"input",
|
|
4090
4327
|
{
|
|
4091
4328
|
id: `${fieldId}-name`,
|
|
@@ -4099,14 +4336,14 @@ function BookingCard({
|
|
|
4099
4336
|
]
|
|
4100
4337
|
}
|
|
4101
4338
|
),
|
|
4102
|
-
/* @__PURE__ */ (0,
|
|
4339
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
4103
4340
|
"label",
|
|
4104
4341
|
{
|
|
4105
4342
|
className: "booking-card__field",
|
|
4106
4343
|
htmlFor: `${fieldId}-email`,
|
|
4107
4344
|
children: [
|
|
4108
|
-
/* @__PURE__ */ (0,
|
|
4109
|
-
/* @__PURE__ */ (0,
|
|
4345
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Email" }),
|
|
4346
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
4110
4347
|
"input",
|
|
4111
4348
|
{
|
|
4112
4349
|
id: `${fieldId}-email`,
|
|
@@ -4122,7 +4359,7 @@ function BookingCard({
|
|
|
4122
4359
|
}
|
|
4123
4360
|
)
|
|
4124
4361
|
] }),
|
|
4125
|
-
/* @__PURE__ */ (0,
|
|
4362
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
4126
4363
|
"button",
|
|
4127
4364
|
{
|
|
4128
4365
|
type: "submit",
|
|
@@ -4140,7 +4377,7 @@ function BookingCard({
|
|
|
4140
4377
|
// src/react/components/MessageBubble/MessageBubble.tsx
|
|
4141
4378
|
var import_streamdown = require("streamdown");
|
|
4142
4379
|
var import_styles = require("streamdown/styles.css");
|
|
4143
|
-
var
|
|
4380
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
4144
4381
|
function normalizeDedupeText(text) {
|
|
4145
4382
|
return text.trim().replace(/\s+/g, " ").toLowerCase();
|
|
4146
4383
|
}
|
|
@@ -4184,7 +4421,7 @@ function MessageBubble({
|
|
|
4184
4421
|
onBook
|
|
4185
4422
|
}) {
|
|
4186
4423
|
const resolvedLogoUrl = brandLogoUrl?.trim();
|
|
4187
|
-
const [failedLogoUrl, setFailedLogoUrl] = (0,
|
|
4424
|
+
const [failedLogoUrl, setFailedLogoUrl] = (0, import_react10.useState)(null);
|
|
4188
4425
|
const showBrandLogo = Boolean(resolvedLogoUrl) && failedLogoUrl !== resolvedLogoUrl;
|
|
4189
4426
|
const cards = message.role === "agent" ? extractToolCards(message.text) : [];
|
|
4190
4427
|
const extractedOffers = cards.filter(
|
|
@@ -4197,11 +4434,11 @@ function MessageBubble({
|
|
|
4197
4434
|
offers.length > 0 ? sanitizeBookingOfferCopy(visibleText) : looksLikeBookingAvailabilityDump(visibleText) ? sanitizeBookingOfferCopy(visibleText) : visibleText || (isStreaming ? "" : message.text)
|
|
4198
4435
|
);
|
|
4199
4436
|
if (message.role === "visitor") {
|
|
4200
|
-
return /* @__PURE__ */ (0,
|
|
4437
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("article", { className: "message-bubble message-bubble--visitor", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "message-bubble__text", children: message.text }) });
|
|
4201
4438
|
}
|
|
4202
4439
|
const citations = message.citations ?? [];
|
|
4203
|
-
const agentText = /* @__PURE__ */ (0,
|
|
4204
|
-
/* @__PURE__ */ (0,
|
|
4440
|
+
const agentText = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "message-bubble__text", children: [
|
|
4441
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4205
4442
|
import_streamdown.Streamdown,
|
|
4206
4443
|
{
|
|
4207
4444
|
animated: isStreaming,
|
|
@@ -4215,8 +4452,8 @@ function MessageBubble({
|
|
|
4215
4452
|
children: displayText
|
|
4216
4453
|
}
|
|
4217
4454
|
),
|
|
4218
|
-
citations.length > 0 ? /* @__PURE__ */ (0,
|
|
4219
|
-
/* @__PURE__ */ (0,
|
|
4455
|
+
citations.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ul", { className: "message-bubble__sources", "aria-label": "Sources", children: citations.map((citation) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("a", { href: citation.url, target: "_blank", rel: "noreferrer", children: [
|
|
4456
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4220
4457
|
"span",
|
|
4221
4458
|
{
|
|
4222
4459
|
className: "message-bubble__source-icon",
|
|
@@ -4224,12 +4461,12 @@ function MessageBubble({
|
|
|
4224
4461
|
children: "\u25A6"
|
|
4225
4462
|
}
|
|
4226
4463
|
),
|
|
4227
|
-
/* @__PURE__ */ (0,
|
|
4464
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: citation.label })
|
|
4228
4465
|
] }) }, citation.id)) }) : null
|
|
4229
4466
|
] });
|
|
4230
|
-
return /* @__PURE__ */ (0,
|
|
4231
|
-
displayText ? showBrandLogo ? /* @__PURE__ */ (0,
|
|
4232
|
-
/* @__PURE__ */ (0,
|
|
4467
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("article", { className: "message-bubble message-bubble--agent", children: [
|
|
4468
|
+
displayText ? showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "message-bubble__agent-row", children: [
|
|
4469
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "message-bubble__agent-avatar", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4233
4470
|
"img",
|
|
4234
4471
|
{
|
|
4235
4472
|
src: resolvedLogoUrl,
|
|
@@ -4241,7 +4478,7 @@ function MessageBubble({
|
|
|
4241
4478
|
) }),
|
|
4242
4479
|
agentText
|
|
4243
4480
|
] }) : agentText : null,
|
|
4244
|
-
offers.map((nextOffer, index) => /* @__PURE__ */ (0,
|
|
4481
|
+
offers.map((nextOffer, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4245
4482
|
BookingCard,
|
|
4246
4483
|
{
|
|
4247
4484
|
disabled: bookingDisabled,
|
|
@@ -4253,77 +4490,564 @@ function MessageBubble({
|
|
|
4253
4490
|
] });
|
|
4254
4491
|
}
|
|
4255
4492
|
|
|
4256
|
-
// src/react/components/
|
|
4257
|
-
var
|
|
4493
|
+
// src/react/components/MessageActions/MessageActions.tsx
|
|
4494
|
+
var import_react11 = require("react");
|
|
4495
|
+
var import_react_dom2 = require("react-dom");
|
|
4258
4496
|
|
|
4259
|
-
// src/react/
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
})
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
{
|
|
4282
|
-
type: "button",
|
|
4283
|
-
className: `confirmation-card__action confirmation-card__action--${option.style ?? "default"}`,
|
|
4284
|
-
disabled,
|
|
4285
|
-
onClick: () => onRespond?.({
|
|
4286
|
-
requestId: request.requestId,
|
|
4287
|
-
optionId: option.id
|
|
4288
|
-
}),
|
|
4289
|
-
children: option.label
|
|
4290
|
-
},
|
|
4291
|
-
option.id
|
|
4292
|
-
)) })
|
|
4293
|
-
]
|
|
4294
|
-
}
|
|
4295
|
-
);
|
|
4497
|
+
// src/react/lib/speech.ts
|
|
4498
|
+
function toSpeechText(text) {
|
|
4499
|
+
let out = hideToolCardFences(text);
|
|
4500
|
+
out = out.replace(/```[\s\S]*?```/g, " ");
|
|
4501
|
+
out = out.replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1");
|
|
4502
|
+
out = out.replace(/\[([^\]]+)\]\([^)]*\)/g, "$1");
|
|
4503
|
+
out = out.replace(/^\s{0,3}#{1,6}\s+/gm, "");
|
|
4504
|
+
out = out.replace(/(\*\*|__)(.*?)\1/g, "$2");
|
|
4505
|
+
out = out.replace(/(\*|_)(.*?)\1/g, "$2");
|
|
4506
|
+
out = out.replace(/~~(.*?)~~/g, "$1");
|
|
4507
|
+
out = out.replace(/`([^`]*)`/g, "$1");
|
|
4508
|
+
out = out.replace(/^\s*>\s?/gm, "");
|
|
4509
|
+
out = out.replace(/^\s*[-*+]\s+/gm, "");
|
|
4510
|
+
out = out.replace(/^\s*\d+\.\s+/gm, "");
|
|
4511
|
+
out = out.replace(/\|/g, " ");
|
|
4512
|
+
out = out.replace(/^\s*[-:]{3,}\s*$/gm, " ");
|
|
4513
|
+
out = out.replace(/\s*\n\s*/g, ". ");
|
|
4514
|
+
out = out.replace(/(?:\.\s*){2,}/g, ". ");
|
|
4515
|
+
return out.replace(/\s{2,}/g, " ").trim();
|
|
4516
|
+
}
|
|
4517
|
+
function isSpeechSupported() {
|
|
4518
|
+
return typeof window !== "undefined" && "speechSynthesis" in window && typeof window.SpeechSynthesisUtterance === "function";
|
|
4296
4519
|
}
|
|
4297
4520
|
|
|
4298
|
-
// src/react/components/
|
|
4299
|
-
var import_react9 = require("react");
|
|
4521
|
+
// src/react/components/MessageActions/MessageActions.tsx
|
|
4300
4522
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
4301
|
-
function
|
|
4302
|
-
return
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4523
|
+
function CopyIcon() {
|
|
4524
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
|
|
4525
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4526
|
+
"rect",
|
|
4527
|
+
{
|
|
4528
|
+
x: "5.75",
|
|
4529
|
+
y: "5.75",
|
|
4530
|
+
width: "7.5",
|
|
4531
|
+
height: "7.5",
|
|
4532
|
+
rx: "1.5",
|
|
4533
|
+
stroke: "currentColor",
|
|
4534
|
+
strokeWidth: "1.5"
|
|
4535
|
+
}
|
|
4536
|
+
),
|
|
4537
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4538
|
+
"path",
|
|
4539
|
+
{
|
|
4540
|
+
d: "M10.25 5.25V4.5a1.75 1.75 0 0 0-1.75-1.75h-4A1.75 1.75 0 0 0 2.75 4.5v4c0 .97.78 1.75 1.75 1.75h.75",
|
|
4541
|
+
stroke: "currentColor",
|
|
4542
|
+
strokeWidth: "1.5"
|
|
4543
|
+
}
|
|
4544
|
+
)
|
|
4545
|
+
] });
|
|
4306
4546
|
}
|
|
4307
|
-
function
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4547
|
+
function CheckIcon() {
|
|
4548
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4549
|
+
"path",
|
|
4550
|
+
{
|
|
4551
|
+
d: "M3.5 8.5l3 3 6-7",
|
|
4552
|
+
stroke: "currentColor",
|
|
4553
|
+
strokeWidth: "1.6",
|
|
4554
|
+
strokeLinecap: "round",
|
|
4555
|
+
strokeLinejoin: "round"
|
|
4314
4556
|
}
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4557
|
+
) });
|
|
4558
|
+
}
|
|
4559
|
+
function ThumbUpIcon() {
|
|
4560
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
|
|
4561
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4562
|
+
"path",
|
|
4563
|
+
{
|
|
4564
|
+
d: "M4.67 6.67v8",
|
|
4565
|
+
stroke: "currentColor",
|
|
4566
|
+
strokeWidth: "1.5",
|
|
4567
|
+
strokeLinecap: "round"
|
|
4568
|
+
}
|
|
4569
|
+
),
|
|
4570
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4571
|
+
"path",
|
|
4572
|
+
{
|
|
4573
|
+
d: "M10 3.92 9.33 6.67h3.89a1.33 1.33 0 0 1 1.28 1.7l-1.55 5.33a1.33 1.33 0 0 1-1.28.97H2.67a1.33 1.33 0 0 1-1.34-1.34V8a1.33 1.33 0 0 1 1.34-1.33h1.84a1.33 1.33 0 0 0 1.19-.74L8 1.33a2.09 2.09 0 0 1 2 2.59Z",
|
|
4574
|
+
stroke: "currentColor",
|
|
4575
|
+
strokeWidth: "1.5",
|
|
4576
|
+
strokeLinecap: "round",
|
|
4577
|
+
strokeLinejoin: "round"
|
|
4578
|
+
}
|
|
4579
|
+
)
|
|
4580
|
+
] });
|
|
4581
|
+
}
|
|
4582
|
+
function ThumbDownIcon() {
|
|
4583
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("g", { transform: "rotate(180 8 8)", children: [
|
|
4584
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4585
|
+
"path",
|
|
4586
|
+
{
|
|
4587
|
+
d: "M4.67 6.67v8",
|
|
4588
|
+
stroke: "currentColor",
|
|
4589
|
+
strokeWidth: "1.5",
|
|
4590
|
+
strokeLinecap: "round"
|
|
4591
|
+
}
|
|
4592
|
+
),
|
|
4593
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4594
|
+
"path",
|
|
4595
|
+
{
|
|
4596
|
+
d: "M10 3.92 9.33 6.67h3.89a1.33 1.33 0 0 1 1.28 1.7l-1.55 5.33a1.33 1.33 0 0 1-1.28.97H2.67a1.33 1.33 0 0 1-1.34-1.34V8a1.33 1.33 0 0 1 1.34-1.33h1.84a1.33 1.33 0 0 0 1.19-.74L8 1.33a2.09 2.09 0 0 1 2 2.59Z",
|
|
4597
|
+
stroke: "currentColor",
|
|
4598
|
+
strokeWidth: "1.5",
|
|
4599
|
+
strokeLinecap: "round",
|
|
4600
|
+
strokeLinejoin: "round"
|
|
4601
|
+
}
|
|
4602
|
+
)
|
|
4603
|
+
] }) });
|
|
4604
|
+
}
|
|
4605
|
+
function RegenerateIcon() {
|
|
4606
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
|
|
4607
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4608
|
+
"path",
|
|
4609
|
+
{
|
|
4610
|
+
d: "M2 8a6 6 0 0 1 6-6 6.5 6.5 0 0 1 4.5 1.83L14 5.33",
|
|
4611
|
+
stroke: "currentColor",
|
|
4612
|
+
strokeWidth: "1.5",
|
|
4613
|
+
strokeLinecap: "round"
|
|
4614
|
+
}
|
|
4615
|
+
),
|
|
4616
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4617
|
+
"path",
|
|
4618
|
+
{
|
|
4619
|
+
d: "M14 2v3.33h-3.33",
|
|
4620
|
+
stroke: "currentColor",
|
|
4621
|
+
strokeWidth: "1.5",
|
|
4622
|
+
strokeLinecap: "round",
|
|
4623
|
+
strokeLinejoin: "round"
|
|
4624
|
+
}
|
|
4625
|
+
),
|
|
4626
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4627
|
+
"path",
|
|
4628
|
+
{
|
|
4629
|
+
d: "M14 8a6 6 0 0 1-6 6 6.5 6.5 0 0 1-4.5-1.83L2 10.67",
|
|
4630
|
+
stroke: "currentColor",
|
|
4631
|
+
strokeWidth: "1.5",
|
|
4632
|
+
strokeLinecap: "round"
|
|
4633
|
+
}
|
|
4634
|
+
),
|
|
4635
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4636
|
+
"path",
|
|
4637
|
+
{
|
|
4638
|
+
d: "M5.33 10.67H2V14",
|
|
4639
|
+
stroke: "currentColor",
|
|
4640
|
+
strokeWidth: "1.5",
|
|
4641
|
+
strokeLinecap: "round",
|
|
4642
|
+
strokeLinejoin: "round"
|
|
4643
|
+
}
|
|
4644
|
+
)
|
|
4645
|
+
] });
|
|
4646
|
+
}
|
|
4647
|
+
function MoreIcon() {
|
|
4648
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
|
|
4649
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "3.5", cy: "8", r: "1.15", fill: "currentColor" }),
|
|
4650
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "8", cy: "8", r: "1.15", fill: "currentColor" }),
|
|
4651
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "12.5", cy: "8", r: "1.15", fill: "currentColor" })
|
|
4652
|
+
] });
|
|
4653
|
+
}
|
|
4654
|
+
function SourcesIcon() {
|
|
4655
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
|
|
4656
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4657
|
+
"path",
|
|
4658
|
+
{
|
|
4659
|
+
d: "M8 4.5C6.9 3.4 5.3 3 3.5 3c-.4 0-.8 0-1.2.1-.3 0-.5.3-.5.6v8.1c0 .4.4.7.8.6.3-.1.7-.1 1.1-.1 1.6 0 3.2.4 4.3 1.3 1.1-.9 2.7-1.3 4.3-1.3.4 0 .8 0 1.1.1.4.1.8-.2.8-.6V3.7c0-.3-.2-.6-.5-.6-.4-.1-.8-.1-1.2-.1-1.8 0-3.4.4-4.5 1.5Z",
|
|
4660
|
+
stroke: "currentColor",
|
|
4661
|
+
strokeWidth: "1.4",
|
|
4662
|
+
strokeLinecap: "round",
|
|
4663
|
+
strokeLinejoin: "round"
|
|
4664
|
+
}
|
|
4665
|
+
),
|
|
4666
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4667
|
+
"path",
|
|
4668
|
+
{
|
|
4669
|
+
d: "M8 4.5v9",
|
|
4670
|
+
stroke: "currentColor",
|
|
4671
|
+
strokeWidth: "1.4",
|
|
4672
|
+
strokeLinecap: "round"
|
|
4673
|
+
}
|
|
4674
|
+
)
|
|
4675
|
+
] });
|
|
4676
|
+
}
|
|
4677
|
+
function ReadAloudIcon() {
|
|
4678
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
|
|
4679
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4680
|
+
"path",
|
|
4681
|
+
{
|
|
4682
|
+
d: "M8.5 3.8 5.8 6H3.5c-.6 0-1 .4-1 1v2c0 .6.4 1 1 1h2.3l2.7 2.2c.4.3 1 0 1-.5V4.3c0-.5-.6-.8-1-.5Z",
|
|
4683
|
+
stroke: "currentColor",
|
|
4684
|
+
strokeWidth: "1.4",
|
|
4685
|
+
strokeLinecap: "round",
|
|
4686
|
+
strokeLinejoin: "round"
|
|
4687
|
+
}
|
|
4688
|
+
),
|
|
4689
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4690
|
+
"path",
|
|
4691
|
+
{
|
|
4692
|
+
d: "M11 6.2c.5.5.8 1.1.8 1.8s-.3 1.3-.8 1.8M12.8 4.5c.9.8 1.4 2 1.4 3.5s-.5 2.7-1.4 3.5",
|
|
4693
|
+
stroke: "currentColor",
|
|
4694
|
+
strokeWidth: "1.4",
|
|
4695
|
+
strokeLinecap: "round"
|
|
4696
|
+
}
|
|
4697
|
+
)
|
|
4698
|
+
] });
|
|
4699
|
+
}
|
|
4700
|
+
function StopIcon() {
|
|
4701
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4702
|
+
"rect",
|
|
4703
|
+
{
|
|
4704
|
+
x: "4",
|
|
4705
|
+
y: "4",
|
|
4706
|
+
width: "8",
|
|
4707
|
+
height: "8",
|
|
4708
|
+
rx: "1.5",
|
|
4709
|
+
stroke: "currentColor",
|
|
4710
|
+
strokeWidth: "1.5"
|
|
4711
|
+
}
|
|
4712
|
+
) });
|
|
4713
|
+
}
|
|
4714
|
+
async function writeToClipboard(text) {
|
|
4715
|
+
try {
|
|
4716
|
+
await navigator.clipboard.writeText(text);
|
|
4717
|
+
} catch {
|
|
4718
|
+
const textarea = document.createElement("textarea");
|
|
4719
|
+
textarea.value = text;
|
|
4720
|
+
textarea.style.position = "fixed";
|
|
4721
|
+
textarea.style.opacity = "0";
|
|
4722
|
+
document.body.appendChild(textarea);
|
|
4723
|
+
textarea.select();
|
|
4724
|
+
document.execCommand("copy");
|
|
4725
|
+
textarea.remove();
|
|
4726
|
+
}
|
|
4727
|
+
}
|
|
4728
|
+
function formatAnsweredAt(answeredAt) {
|
|
4729
|
+
if (!answeredAt) return null;
|
|
4730
|
+
const date = new Date(answeredAt);
|
|
4731
|
+
if (Number.isNaN(date.getTime())) return null;
|
|
4732
|
+
return new Intl.DateTimeFormat(void 0, {
|
|
4733
|
+
dateStyle: "medium",
|
|
4734
|
+
timeStyle: "short"
|
|
4735
|
+
}).format(date);
|
|
4736
|
+
}
|
|
4737
|
+
function resolveMenuPosition(input) {
|
|
4738
|
+
const padding = 8;
|
|
4739
|
+
const { button, menuHeight, menuWidth, rail } = input;
|
|
4740
|
+
if (!rail) {
|
|
4741
|
+
return {
|
|
4742
|
+
left: button.left,
|
|
4743
|
+
top: button.top - menuHeight - 6
|
|
4744
|
+
};
|
|
4745
|
+
}
|
|
4746
|
+
let left = button.left - rail.left;
|
|
4747
|
+
let top = button.top - rail.top - menuHeight - 6;
|
|
4748
|
+
left = Math.min(
|
|
4749
|
+
Math.max(left, padding),
|
|
4750
|
+
rail.width - menuWidth - padding
|
|
4751
|
+
);
|
|
4752
|
+
if (top < padding) {
|
|
4753
|
+
top = button.bottom - rail.top + 6;
|
|
4754
|
+
}
|
|
4755
|
+
top = Math.min(top, rail.height - menuHeight - padding);
|
|
4756
|
+
return { left, top };
|
|
4757
|
+
}
|
|
4758
|
+
function MessageActions({
|
|
4759
|
+
answeredAt,
|
|
4760
|
+
copyText,
|
|
4761
|
+
disabled = false,
|
|
4762
|
+
onOpenReceipt,
|
|
4763
|
+
onRegenerate,
|
|
4764
|
+
onFeedback,
|
|
4765
|
+
readAloud = false,
|
|
4766
|
+
receiptSteps,
|
|
4767
|
+
speechText
|
|
4768
|
+
}) {
|
|
4769
|
+
const menuPortalRoot = useAgentRailMenuPortalRoot();
|
|
4770
|
+
const [copied, setCopied] = (0, import_react11.useState)(false);
|
|
4771
|
+
const [rating, setRating] = (0, import_react11.useState)(null);
|
|
4772
|
+
const [menuOpen, setMenuOpen] = (0, import_react11.useState)(false);
|
|
4773
|
+
const [menuPosition, setMenuPosition] = (0, import_react11.useState)(null);
|
|
4774
|
+
const [speaking, setSpeaking] = (0, import_react11.useState)(false);
|
|
4775
|
+
const copyTimerRef = (0, import_react11.useRef)(null);
|
|
4776
|
+
const menuRef = (0, import_react11.useRef)(null);
|
|
4777
|
+
const portaledMenuRef = (0, import_react11.useRef)(null);
|
|
4778
|
+
const moreButtonRef = (0, import_react11.useRef)(null);
|
|
4779
|
+
const answeredLabel = formatAnsweredAt(answeredAt ?? 0);
|
|
4780
|
+
const resolvedSpeechText = speechText ?? toSpeechText(copyText);
|
|
4781
|
+
const canReadAloud = readAloud && isSpeechSupported() && resolvedSpeechText;
|
|
4782
|
+
const showMenu = Boolean(answeredLabel) || Boolean(receiptSteps) || canReadAloud;
|
|
4783
|
+
const canOpenReceipt = Boolean(receiptSteps) && Boolean(onOpenReceipt);
|
|
4784
|
+
(0, import_react11.useLayoutEffect)(() => {
|
|
4785
|
+
if (!menuOpen || !moreButtonRef.current || !portaledMenuRef.current) {
|
|
4786
|
+
setMenuPosition(null);
|
|
4787
|
+
return;
|
|
4788
|
+
}
|
|
4789
|
+
const button = moreButtonRef.current.getBoundingClientRect();
|
|
4790
|
+
const menu2 = portaledMenuRef.current;
|
|
4791
|
+
const rail = menuPortalRoot?.current?.getBoundingClientRect() ?? null;
|
|
4792
|
+
setMenuPosition(
|
|
4793
|
+
resolveMenuPosition({
|
|
4794
|
+
button,
|
|
4795
|
+
menuHeight: menu2.offsetHeight,
|
|
4796
|
+
menuWidth: menu2.offsetWidth || 190,
|
|
4797
|
+
rail
|
|
4798
|
+
})
|
|
4799
|
+
);
|
|
4800
|
+
}, [menuOpen, menuPortalRoot]);
|
|
4801
|
+
(0, import_react11.useEffect)(
|
|
4802
|
+
() => () => {
|
|
4803
|
+
if (copyTimerRef.current !== null) {
|
|
4804
|
+
window.clearTimeout(copyTimerRef.current);
|
|
4805
|
+
}
|
|
4806
|
+
if (speaking) window.speechSynthesis.cancel();
|
|
4807
|
+
},
|
|
4808
|
+
// Cancel speech only when this answer's actions unmount.
|
|
4809
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4810
|
+
[]
|
|
4811
|
+
);
|
|
4812
|
+
(0, import_react11.useEffect)(() => {
|
|
4813
|
+
if (!menuOpen) return;
|
|
4814
|
+
const handlePointerDown = (event) => {
|
|
4815
|
+
const target = event.target;
|
|
4816
|
+
if (!menuRef.current?.contains(target) && !portaledMenuRef.current?.contains(target)) {
|
|
4817
|
+
setMenuOpen(false);
|
|
4818
|
+
}
|
|
4819
|
+
};
|
|
4820
|
+
const handleKeyDown = (event) => {
|
|
4821
|
+
if (event.key !== "Escape") return;
|
|
4822
|
+
event.preventDefault();
|
|
4823
|
+
event.stopPropagation();
|
|
4824
|
+
setMenuOpen(false);
|
|
4825
|
+
};
|
|
4826
|
+
document.addEventListener("pointerdown", handlePointerDown);
|
|
4827
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
4828
|
+
return () => {
|
|
4829
|
+
document.removeEventListener("pointerdown", handlePointerDown);
|
|
4830
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
4831
|
+
};
|
|
4832
|
+
}, [menuOpen]);
|
|
4833
|
+
function handleCopy() {
|
|
4834
|
+
void writeToClipboard(copyText);
|
|
4835
|
+
setCopied(true);
|
|
4836
|
+
if (copyTimerRef.current !== null) {
|
|
4837
|
+
window.clearTimeout(copyTimerRef.current);
|
|
4838
|
+
}
|
|
4839
|
+
copyTimerRef.current = window.setTimeout(() => setCopied(false), 1600);
|
|
4840
|
+
}
|
|
4841
|
+
function handleFeedback(next) {
|
|
4842
|
+
const resolved = rating === next ? null : next;
|
|
4843
|
+
setRating(resolved);
|
|
4844
|
+
if (resolved) onFeedback?.(resolved);
|
|
4845
|
+
}
|
|
4846
|
+
function handleReadAloud() {
|
|
4847
|
+
if (!canReadAloud) return;
|
|
4848
|
+
setMenuOpen(false);
|
|
4849
|
+
if (speaking) {
|
|
4850
|
+
window.speechSynthesis.cancel();
|
|
4851
|
+
setSpeaking(false);
|
|
4852
|
+
return;
|
|
4853
|
+
}
|
|
4854
|
+
const utterance = new SpeechSynthesisUtterance(resolvedSpeechText);
|
|
4855
|
+
utterance.onend = () => setSpeaking(false);
|
|
4856
|
+
utterance.onerror = () => setSpeaking(false);
|
|
4857
|
+
window.speechSynthesis.cancel();
|
|
4858
|
+
window.speechSynthesis.speak(utterance);
|
|
4859
|
+
setSpeaking(true);
|
|
4860
|
+
}
|
|
4861
|
+
const menu = menuOpen ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
4862
|
+
"div",
|
|
4863
|
+
{
|
|
4864
|
+
className: "agent-message-actions__menu agent-message-actions__menu--portal",
|
|
4865
|
+
ref: portaledMenuRef,
|
|
4866
|
+
role: "menu",
|
|
4867
|
+
style: menuPosition ? {
|
|
4868
|
+
left: `${menuPosition.left}px`,
|
|
4869
|
+
top: `${menuPosition.top}px`
|
|
4870
|
+
} : { visibility: "hidden" },
|
|
4871
|
+
children: [
|
|
4872
|
+
answeredLabel ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "agent-message-actions__menu-meta", children: [
|
|
4873
|
+
"Answered ",
|
|
4874
|
+
answeredLabel
|
|
4875
|
+
] }) : null,
|
|
4876
|
+
canOpenReceipt ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
4877
|
+
"button",
|
|
4878
|
+
{
|
|
4879
|
+
type: "button",
|
|
4880
|
+
className: "agent-message-actions__menu-item",
|
|
4881
|
+
role: "menuitem",
|
|
4882
|
+
onClick: () => {
|
|
4883
|
+
setMenuOpen(false);
|
|
4884
|
+
onOpenReceipt?.();
|
|
4885
|
+
},
|
|
4886
|
+
children: [
|
|
4887
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SourcesIcon, {}),
|
|
4888
|
+
"View sources"
|
|
4889
|
+
]
|
|
4890
|
+
}
|
|
4891
|
+
) : null,
|
|
4892
|
+
canReadAloud ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
4893
|
+
"button",
|
|
4894
|
+
{
|
|
4895
|
+
type: "button",
|
|
4896
|
+
className: "agent-message-actions__menu-item",
|
|
4897
|
+
role: "menuitem",
|
|
4898
|
+
onClick: handleReadAloud,
|
|
4899
|
+
children: [
|
|
4900
|
+
speaking ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StopIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ReadAloudIcon, {}),
|
|
4901
|
+
speaking ? "Stop reading" : "Read aloud"
|
|
4902
|
+
]
|
|
4903
|
+
}
|
|
4904
|
+
) : null
|
|
4905
|
+
]
|
|
4906
|
+
}
|
|
4907
|
+
) : null;
|
|
4908
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "agent-message-actions", "aria-label": "Answer actions", children: [
|
|
4909
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4910
|
+
"button",
|
|
4911
|
+
{
|
|
4912
|
+
type: "button",
|
|
4913
|
+
className: `agent-message-actions__button${copied ? " is-copied" : ""}`,
|
|
4914
|
+
"aria-label": copied ? "Copied" : "Copy answer",
|
|
4915
|
+
title: copied ? "Copied" : "Copy answer",
|
|
4916
|
+
disabled,
|
|
4917
|
+
onClick: handleCopy,
|
|
4918
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CopyIcon, {})
|
|
4919
|
+
}
|
|
4920
|
+
),
|
|
4921
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4922
|
+
"button",
|
|
4923
|
+
{
|
|
4924
|
+
type: "button",
|
|
4925
|
+
className: `agent-message-actions__button${rating === "positive" ? " is-active" : ""}`,
|
|
4926
|
+
"aria-label": "Good answer",
|
|
4927
|
+
"aria-pressed": rating === "positive",
|
|
4928
|
+
title: "Good answer",
|
|
4929
|
+
disabled,
|
|
4930
|
+
onClick: () => handleFeedback("positive"),
|
|
4931
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThumbUpIcon, {})
|
|
4932
|
+
}
|
|
4933
|
+
),
|
|
4934
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4935
|
+
"button",
|
|
4936
|
+
{
|
|
4937
|
+
type: "button",
|
|
4938
|
+
className: `agent-message-actions__button${rating === "negative" ? " is-active" : ""}`,
|
|
4939
|
+
"aria-label": "Bad answer",
|
|
4940
|
+
"aria-pressed": rating === "negative",
|
|
4941
|
+
title: "Bad answer",
|
|
4942
|
+
disabled,
|
|
4943
|
+
onClick: () => handleFeedback("negative"),
|
|
4944
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThumbDownIcon, {})
|
|
4945
|
+
}
|
|
4946
|
+
),
|
|
4947
|
+
onRegenerate ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4948
|
+
"button",
|
|
4949
|
+
{
|
|
4950
|
+
type: "button",
|
|
4951
|
+
className: "agent-message-actions__button",
|
|
4952
|
+
"aria-label": "Regenerate answer",
|
|
4953
|
+
title: "Regenerate answer",
|
|
4954
|
+
disabled,
|
|
4955
|
+
onClick: onRegenerate,
|
|
4956
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RegenerateIcon, {})
|
|
4957
|
+
}
|
|
4958
|
+
) : null,
|
|
4959
|
+
showMenu ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "agent-message-actions__more", ref: menuRef, children: [
|
|
4960
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4961
|
+
"button",
|
|
4962
|
+
{
|
|
4963
|
+
ref: moreButtonRef,
|
|
4964
|
+
type: "button",
|
|
4965
|
+
className: `agent-message-actions__button${menuOpen ? " is-menu-open" : ""}`,
|
|
4966
|
+
"aria-label": "More actions",
|
|
4967
|
+
"aria-haspopup": "menu",
|
|
4968
|
+
"aria-expanded": menuOpen,
|
|
4969
|
+
title: "More actions",
|
|
4970
|
+
disabled,
|
|
4971
|
+
onClick: () => setMenuOpen((open) => !open),
|
|
4972
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MoreIcon, {})
|
|
4973
|
+
}
|
|
4974
|
+
),
|
|
4975
|
+
menuPortalRoot?.current && menu ? (0, import_react_dom2.createPortal)(menu, menuPortalRoot.current) : menu
|
|
4976
|
+
] }) : null
|
|
4977
|
+
] });
|
|
4978
|
+
}
|
|
4979
|
+
|
|
4980
|
+
// src/react/components/HumanInputCard/HumanInputCard.tsx
|
|
4981
|
+
var import_react13 = require("react");
|
|
4982
|
+
|
|
4983
|
+
// src/react/components/ConfirmationCard/ConfirmationCard.tsx
|
|
4984
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
4985
|
+
function ConfirmationCard({
|
|
4986
|
+
disabled = false,
|
|
4987
|
+
request,
|
|
4988
|
+
onRespond
|
|
4989
|
+
}) {
|
|
4990
|
+
const options = request.options ?? [];
|
|
4991
|
+
const heading = request.kind === "tool-approval" ? "Confirm this action" : request.prompt;
|
|
4992
|
+
const prompt = request.kind === "tool-approval" ? request.prompt : void 0;
|
|
4993
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
4994
|
+
"section",
|
|
4995
|
+
{
|
|
4996
|
+
className: "confirmation-card",
|
|
4997
|
+
"aria-labelledby": `confirmation-${request.requestId}`,
|
|
4998
|
+
children: [
|
|
4999
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "confirmation-card__heading", children: [
|
|
5000
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { id: `confirmation-${request.requestId}`, children: heading }),
|
|
5001
|
+
prompt ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: prompt }) : null
|
|
5002
|
+
] }),
|
|
5003
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "confirmation-card__actions", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5004
|
+
"button",
|
|
5005
|
+
{
|
|
5006
|
+
type: "button",
|
|
5007
|
+
className: `confirmation-card__action confirmation-card__action--${option.style ?? "default"}`,
|
|
5008
|
+
disabled,
|
|
5009
|
+
onClick: () => onRespond?.({
|
|
5010
|
+
requestId: request.requestId,
|
|
5011
|
+
optionId: option.id
|
|
5012
|
+
}),
|
|
5013
|
+
children: option.label
|
|
5014
|
+
},
|
|
5015
|
+
option.id
|
|
5016
|
+
)) })
|
|
5017
|
+
]
|
|
5018
|
+
}
|
|
5019
|
+
);
|
|
5020
|
+
}
|
|
5021
|
+
|
|
5022
|
+
// src/react/components/ToolInputCard/ToolInputCard.tsx
|
|
5023
|
+
var import_react12 = require("react");
|
|
5024
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
5025
|
+
function isRecord5(value) {
|
|
5026
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
5027
|
+
}
|
|
5028
|
+
function pathSegments(path) {
|
|
5029
|
+
return path.replace(/\[(\d+)\]/gu, ".$1").split(".").filter(Boolean);
|
|
5030
|
+
}
|
|
5031
|
+
function valueAtPath(root, path) {
|
|
5032
|
+
let current = root;
|
|
5033
|
+
for (const segment of pathSegments(path)) {
|
|
5034
|
+
if (Array.isArray(current)) {
|
|
5035
|
+
const index = Number(segment);
|
|
5036
|
+
current = Number.isInteger(index) ? current[index] : void 0;
|
|
5037
|
+
continue;
|
|
5038
|
+
}
|
|
5039
|
+
current = isRecord5(current) ? current[segment] : void 0;
|
|
5040
|
+
}
|
|
5041
|
+
return current;
|
|
5042
|
+
}
|
|
5043
|
+
function initialFieldValue(field, surface) {
|
|
5044
|
+
const supplied = valueAtPath(surface.values, field.path);
|
|
5045
|
+
if (supplied !== void 0) return supplied;
|
|
5046
|
+
if (field.defaultValue !== void 0) return field.defaultValue;
|
|
5047
|
+
if (field.kind === "checkbox" || field.kind === "confirmation") return false;
|
|
5048
|
+
if (field.kind === "multi-select") return [];
|
|
5049
|
+
if (field.kind === "range") return field.min ?? 0;
|
|
5050
|
+
return "";
|
|
4327
5051
|
}
|
|
4328
5052
|
function initialValues(surface) {
|
|
4329
5053
|
return Object.fromEntries(
|
|
@@ -4421,7 +5145,7 @@ function FieldDescription({
|
|
|
4421
5145
|
field,
|
|
4422
5146
|
id
|
|
4423
5147
|
}) {
|
|
4424
|
-
return field.description ? /* @__PURE__ */ (0,
|
|
5148
|
+
return field.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id, className: "tool-input-card__description", children: field.description }) : null;
|
|
4425
5149
|
}
|
|
4426
5150
|
function ChoiceField({
|
|
4427
5151
|
field,
|
|
@@ -4440,7 +5164,7 @@ function ChoiceField({
|
|
|
4440
5164
|
const selectedIndex = options.findIndex(
|
|
4441
5165
|
(option) => valuesMatch(option.value, value)
|
|
4442
5166
|
);
|
|
4443
|
-
return /* @__PURE__ */ (0,
|
|
5167
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4444
5168
|
"select",
|
|
4445
5169
|
{
|
|
4446
5170
|
id,
|
|
@@ -4455,13 +5179,13 @@ function ChoiceField({
|
|
|
4455
5179
|
if (option) onChange(option.value);
|
|
4456
5180
|
},
|
|
4457
5181
|
children: [
|
|
4458
|
-
/* @__PURE__ */ (0,
|
|
4459
|
-
options.map((option, index) => /* @__PURE__ */ (0,
|
|
5182
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "", disabled: field.required, children: "Choose an option" }),
|
|
5183
|
+
options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: index, children: option.label }, optionKey(option)))
|
|
4460
5184
|
]
|
|
4461
5185
|
}
|
|
4462
5186
|
);
|
|
4463
5187
|
}
|
|
4464
|
-
return /* @__PURE__ */ (0,
|
|
5188
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4465
5189
|
"div",
|
|
4466
5190
|
{
|
|
4467
5191
|
className: "tool-input-card__choices",
|
|
@@ -4472,8 +5196,8 @@ function ChoiceField({
|
|
|
4472
5196
|
"aria-required": field.required,
|
|
4473
5197
|
children: options.map((option, index) => {
|
|
4474
5198
|
const checked = multiple ? selected.some((item) => valuesMatch(item, option.value)) : valuesMatch(value, option.value);
|
|
4475
|
-
return /* @__PURE__ */ (0,
|
|
4476
|
-
/* @__PURE__ */ (0,
|
|
5199
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "tool-input-card__choice", children: [
|
|
5200
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4477
5201
|
"input",
|
|
4478
5202
|
{
|
|
4479
5203
|
type: multiple ? "checkbox" : "radio",
|
|
@@ -4495,7 +5219,7 @@ function ChoiceField({
|
|
|
4495
5219
|
}
|
|
4496
5220
|
}
|
|
4497
5221
|
),
|
|
4498
|
-
/* @__PURE__ */ (0,
|
|
5222
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: option.label })
|
|
4499
5223
|
] }, optionKey(option));
|
|
4500
5224
|
})
|
|
4501
5225
|
}
|
|
@@ -4515,9 +5239,9 @@ function ToolField({
|
|
|
4515
5239
|
error ? `${id}-error` : ""
|
|
4516
5240
|
].filter(Boolean).join(" ");
|
|
4517
5241
|
if (field.kind === "checkbox" || field.kind === "confirmation") {
|
|
4518
|
-
return /* @__PURE__ */ (0,
|
|
4519
|
-
/* @__PURE__ */ (0,
|
|
4520
|
-
/* @__PURE__ */ (0,
|
|
5242
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__field", children: [
|
|
5243
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "tool-input-card__check", htmlFor: id, children: [
|
|
5244
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4521
5245
|
"input",
|
|
4522
5246
|
{
|
|
4523
5247
|
id,
|
|
@@ -4530,17 +5254,17 @@ function ToolField({
|
|
|
4530
5254
|
onChange: (event) => onChange(event.target.checked)
|
|
4531
5255
|
}
|
|
4532
5256
|
),
|
|
4533
|
-
/* @__PURE__ */ (0,
|
|
4534
|
-
/* @__PURE__ */ (0,
|
|
4535
|
-
field.description ? /* @__PURE__ */ (0,
|
|
5257
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
|
|
5258
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: field.label }),
|
|
5259
|
+
field.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-description`, children: field.description }) : null
|
|
4536
5260
|
] })
|
|
4537
5261
|
] }),
|
|
4538
|
-
error ? /* @__PURE__ */ (0,
|
|
5262
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
|
|
4539
5263
|
] });
|
|
4540
5264
|
}
|
|
4541
|
-
const label = /* @__PURE__ */ (0,
|
|
5265
|
+
const label = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { id: `${id}-label`, htmlFor: id, children: [
|
|
4542
5266
|
field.label,
|
|
4543
|
-
field.required ? /* @__PURE__ */ (0,
|
|
5267
|
+
field.required ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
|
|
4544
5268
|
] });
|
|
4545
5269
|
const common = {
|
|
4546
5270
|
id,
|
|
@@ -4552,7 +5276,7 @@ function ToolField({
|
|
|
4552
5276
|
};
|
|
4553
5277
|
let control;
|
|
4554
5278
|
if (field.kind === "select" || field.kind === "radio" || field.kind === "multi-select") {
|
|
4555
|
-
control = /* @__PURE__ */ (0,
|
|
5279
|
+
control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4556
5280
|
ChoiceField,
|
|
4557
5281
|
{
|
|
4558
5282
|
field,
|
|
@@ -4566,7 +5290,7 @@ function ToolField({
|
|
|
4566
5290
|
}
|
|
4567
5291
|
);
|
|
4568
5292
|
} else if (field.kind === "textarea" || field.kind === "json") {
|
|
4569
|
-
control = /* @__PURE__ */ (0,
|
|
5293
|
+
control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4570
5294
|
"textarea",
|
|
4571
5295
|
{
|
|
4572
5296
|
...common,
|
|
@@ -4580,8 +5304,8 @@ function ToolField({
|
|
|
4580
5304
|
);
|
|
4581
5305
|
} else if (field.kind === "range") {
|
|
4582
5306
|
const numericValue = typeof value === "number" ? value : field.min ?? 0;
|
|
4583
|
-
control = /* @__PURE__ */ (0,
|
|
4584
|
-
/* @__PURE__ */ (0,
|
|
5307
|
+
control = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__range", children: [
|
|
5308
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4585
5309
|
"input",
|
|
4586
5310
|
{
|
|
4587
5311
|
...common,
|
|
@@ -4593,11 +5317,11 @@ function ToolField({
|
|
|
4593
5317
|
onChange: (event) => onChange(Number(event.target.value))
|
|
4594
5318
|
}
|
|
4595
5319
|
),
|
|
4596
|
-
/* @__PURE__ */ (0,
|
|
5320
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("output", { htmlFor: id, children: numericValue })
|
|
4597
5321
|
] });
|
|
4598
5322
|
} else {
|
|
4599
5323
|
const type = field.kind === "date-time" ? "datetime-local" : field.kind === "calendar" ? "date" : field.kind;
|
|
4600
|
-
control = /* @__PURE__ */ (0,
|
|
5324
|
+
control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4601
5325
|
"input",
|
|
4602
5326
|
{
|
|
4603
5327
|
...common,
|
|
@@ -4615,11 +5339,11 @@ function ToolField({
|
|
|
4615
5339
|
}
|
|
4616
5340
|
);
|
|
4617
5341
|
}
|
|
4618
|
-
return /* @__PURE__ */ (0,
|
|
5342
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__field", children: [
|
|
4619
5343
|
label,
|
|
4620
|
-
/* @__PURE__ */ (0,
|
|
5344
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FieldDescription, { field, id: `${id}-description` }),
|
|
4621
5345
|
control,
|
|
4622
|
-
error ? /* @__PURE__ */ (0,
|
|
5346
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
|
|
4623
5347
|
] });
|
|
4624
5348
|
}
|
|
4625
5349
|
function ToolInputCard({
|
|
@@ -4627,11 +5351,11 @@ function ToolInputCard({
|
|
|
4627
5351
|
surface,
|
|
4628
5352
|
onSubmit
|
|
4629
5353
|
}) {
|
|
4630
|
-
const [values, setValues] = (0,
|
|
5354
|
+
const [values, setValues] = (0, import_react12.useState)(
|
|
4631
5355
|
() => initialValues(surface)
|
|
4632
5356
|
);
|
|
4633
|
-
const [touched, setTouched] = (0,
|
|
4634
|
-
const [submitted, setSubmitted] = (0,
|
|
5357
|
+
const [touched, setTouched] = (0, import_react12.useState)(() => /* @__PURE__ */ new Set());
|
|
5358
|
+
const [submitted, setSubmitted] = (0, import_react12.useState)(false);
|
|
4635
5359
|
const errors = Object.fromEntries(
|
|
4636
5360
|
surface.fields.map((field) => [
|
|
4637
5361
|
field.path,
|
|
@@ -4656,14 +5380,14 @@ function ToolInputCard({
|
|
|
4656
5380
|
onSubmit?.(surface, result);
|
|
4657
5381
|
}
|
|
4658
5382
|
if (submitted) {
|
|
4659
|
-
return /* @__PURE__ */ (0,
|
|
5383
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4660
5384
|
"section",
|
|
4661
5385
|
{
|
|
4662
5386
|
className: "tool-input-card tool-input-card--submitted",
|
|
4663
5387
|
role: "status",
|
|
4664
5388
|
children: [
|
|
4665
|
-
/* @__PURE__ */ (0,
|
|
4666
|
-
/* @__PURE__ */ (0,
|
|
5389
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-hidden": "true", children: "\u2713" }),
|
|
5390
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("strong", { children: [
|
|
4667
5391
|
surface.title,
|
|
4668
5392
|
" submitted"
|
|
4669
5393
|
] })
|
|
@@ -4671,18 +5395,18 @@ function ToolInputCard({
|
|
|
4671
5395
|
}
|
|
4672
5396
|
);
|
|
4673
5397
|
}
|
|
4674
|
-
return /* @__PURE__ */ (0,
|
|
5398
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4675
5399
|
"section",
|
|
4676
5400
|
{
|
|
4677
5401
|
className: "tool-input-card",
|
|
4678
5402
|
"aria-labelledby": `tool-input-${surface.id}`,
|
|
4679
5403
|
children: [
|
|
4680
|
-
/* @__PURE__ */ (0,
|
|
4681
|
-
/* @__PURE__ */ (0,
|
|
4682
|
-
surface.description ? /* @__PURE__ */ (0,
|
|
5404
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__heading", children: [
|
|
5405
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { id: `tool-input-${surface.id}`, children: surface.title }),
|
|
5406
|
+
surface.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { children: surface.description }) : null
|
|
4683
5407
|
] }),
|
|
4684
|
-
/* @__PURE__ */ (0,
|
|
4685
|
-
/* @__PURE__ */ (0,
|
|
5408
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("form", { noValidate: true, onSubmit: submit, children: [
|
|
5409
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "tool-input-card__fields", children: surface.fields.map((field, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4686
5410
|
ToolField,
|
|
4687
5411
|
{
|
|
4688
5412
|
disabled,
|
|
@@ -4695,8 +5419,8 @@ function ToolInputCard({
|
|
|
4695
5419
|
},
|
|
4696
5420
|
field.path
|
|
4697
5421
|
)) }),
|
|
4698
|
-
/* @__PURE__ */ (0,
|
|
4699
|
-
surface.actions?.some((action) => action.id === "reset") ? /* @__PURE__ */ (0,
|
|
5422
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__actions", children: [
|
|
5423
|
+
surface.actions?.some((action) => action.id === "reset") ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4700
5424
|
"button",
|
|
4701
5425
|
{
|
|
4702
5426
|
type: "button",
|
|
@@ -4709,7 +5433,7 @@ function ToolInputCard({
|
|
|
4709
5433
|
children: surface.actions.find((action) => action.id === "reset")?.label ?? "Clear"
|
|
4710
5434
|
}
|
|
4711
5435
|
) : null,
|
|
4712
|
-
/* @__PURE__ */ (0,
|
|
5436
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "submit", disabled, children: surface.submitLabel ?? surface.actions?.find((action) => action.id === "submit")?.label ?? "Continue" })
|
|
4713
5437
|
] })
|
|
4714
5438
|
] })
|
|
4715
5439
|
]
|
|
@@ -4718,17 +5442,17 @@ function ToolInputCard({
|
|
|
4718
5442
|
}
|
|
4719
5443
|
|
|
4720
5444
|
// src/react/components/HumanInputCard/HumanInputCard.tsx
|
|
4721
|
-
var
|
|
5445
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
4722
5446
|
function HumanInputCard({
|
|
4723
5447
|
disabled = false,
|
|
4724
5448
|
request,
|
|
4725
5449
|
onRespond
|
|
4726
5450
|
}) {
|
|
4727
|
-
const [text, setText] = (0,
|
|
5451
|
+
const [text, setText] = (0, import_react13.useState)("");
|
|
4728
5452
|
const options = request.options ?? [];
|
|
4729
5453
|
const showText = request.display === "text" || request.allowFreeform && options.length === 0;
|
|
4730
5454
|
if (request.ui) {
|
|
4731
|
-
return /* @__PURE__ */ (0,
|
|
5455
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4732
5456
|
ToolInputCard,
|
|
4733
5457
|
{
|
|
4734
5458
|
disabled,
|
|
@@ -4738,7 +5462,7 @@ function HumanInputCard({
|
|
|
4738
5462
|
);
|
|
4739
5463
|
}
|
|
4740
5464
|
if (options.length > 0) {
|
|
4741
|
-
return /* @__PURE__ */ (0,
|
|
5465
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4742
5466
|
ConfirmationCard,
|
|
4743
5467
|
{
|
|
4744
5468
|
disabled,
|
|
@@ -4753,17 +5477,17 @@ function HumanInputCard({
|
|
|
4753
5477
|
if (!value || disabled) return;
|
|
4754
5478
|
onRespond?.({ requestId: request.requestId, text: value });
|
|
4755
5479
|
}
|
|
4756
|
-
return /* @__PURE__ */ (0,
|
|
5480
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
4757
5481
|
"section",
|
|
4758
5482
|
{
|
|
4759
5483
|
className: "human-input-card",
|
|
4760
5484
|
"aria-labelledby": `human-input-${request.requestId}`,
|
|
4761
5485
|
children: [
|
|
4762
|
-
/* @__PURE__ */ (0,
|
|
4763
|
-
showText ? /* @__PURE__ */ (0,
|
|
4764
|
-
/* @__PURE__ */ (0,
|
|
4765
|
-
/* @__PURE__ */ (0,
|
|
4766
|
-
/* @__PURE__ */ (0,
|
|
5486
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "human-input-card__heading", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { id: `human-input-${request.requestId}`, children: request.prompt }) }),
|
|
5487
|
+
showText ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("form", { onSubmit: submitText, children: [
|
|
5488
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { htmlFor: `human-input-text-${request.requestId}`, children: "Response" }),
|
|
5489
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
|
|
5490
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4767
5491
|
"input",
|
|
4768
5492
|
{
|
|
4769
5493
|
id: `human-input-text-${request.requestId}`,
|
|
@@ -4772,39 +5496,39 @@ function HumanInputCard({
|
|
|
4772
5496
|
onChange: (event) => setText(event.target.value)
|
|
4773
5497
|
}
|
|
4774
5498
|
),
|
|
4775
|
-
/* @__PURE__ */ (0,
|
|
5499
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "submit", disabled: disabled || !text.trim(), children: "Send" })
|
|
4776
5500
|
] })
|
|
4777
5501
|
] }) : null,
|
|
4778
|
-
!showText && options.length === 0 ? /* @__PURE__ */ (0,
|
|
5502
|
+
!showText && options.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "human-input-card__unavailable", role: "status", children: "This request can\u2019t be answered here." }) : null
|
|
4779
5503
|
]
|
|
4780
5504
|
}
|
|
4781
5505
|
);
|
|
4782
5506
|
}
|
|
4783
5507
|
|
|
4784
5508
|
// src/react/components/CollectionResultCard/CollectionResultCard.tsx
|
|
4785
|
-
var
|
|
5509
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
4786
5510
|
function CollectionResultCard({
|
|
4787
5511
|
result
|
|
4788
5512
|
}) {
|
|
4789
5513
|
const empty = result.items.length === 0;
|
|
4790
|
-
return /* @__PURE__ */ (0,
|
|
5514
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
4791
5515
|
"section",
|
|
4792
5516
|
{
|
|
4793
5517
|
className: `collection-result-card tool-result-card tool-result-card--${result.status}`,
|
|
4794
5518
|
"aria-label": result.title,
|
|
4795
5519
|
children: [
|
|
4796
|
-
/* @__PURE__ */ (0,
|
|
4797
|
-
/* @__PURE__ */ (0,
|
|
4798
|
-
/* @__PURE__ */ (0,
|
|
5520
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "tool-result-card__heading", children: [
|
|
5521
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
|
|
5522
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("strong", { children: result.title })
|
|
4799
5523
|
] }),
|
|
4800
|
-
empty ? /* @__PURE__ */ (0,
|
|
4801
|
-
/* @__PURE__ */ (0,
|
|
4802
|
-
item.description ? /* @__PURE__ */ (0,
|
|
4803
|
-
item.details?.length ? /* @__PURE__ */ (0,
|
|
4804
|
-
/* @__PURE__ */ (0,
|
|
4805
|
-
/* @__PURE__ */ (0,
|
|
5524
|
+
empty ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "collection-result-card__empty", children: "No matching record for the email you shared." }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ul", { className: "collection-result-card__list", children: result.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("li", { children: [
|
|
5525
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "collection-result-card__item-title", children: item.title }),
|
|
5526
|
+
item.description ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: item.description }) : null,
|
|
5527
|
+
item.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dl", { children: item.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
|
|
5528
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dt", { children: detail.label }),
|
|
5529
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dd", { children: detail.value })
|
|
4806
5530
|
] }, `${detail.label}:${detail.value}`)) }) : null,
|
|
4807
|
-
item.href ? /* @__PURE__ */ (0,
|
|
5531
|
+
item.href ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("a", { href: item.href, target: "_blank", rel: "noreferrer", children: "Open record" }) : null
|
|
4808
5532
|
] }, item.title)) })
|
|
4809
5533
|
]
|
|
4810
5534
|
}
|
|
@@ -4812,26 +5536,26 @@ function CollectionResultCard({
|
|
|
4812
5536
|
}
|
|
4813
5537
|
|
|
4814
5538
|
// src/react/components/EntityResultCard/EntityResultCard.tsx
|
|
4815
|
-
var
|
|
5539
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
4816
5540
|
function EntityResultCard({
|
|
4817
5541
|
result
|
|
4818
5542
|
}) {
|
|
4819
|
-
return /* @__PURE__ */ (0,
|
|
5543
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
4820
5544
|
"section",
|
|
4821
5545
|
{
|
|
4822
5546
|
className: `entity-result-card tool-result-card tool-result-card--${result.status}`,
|
|
4823
5547
|
"aria-label": result.title,
|
|
4824
5548
|
children: [
|
|
4825
|
-
/* @__PURE__ */ (0,
|
|
4826
|
-
/* @__PURE__ */ (0,
|
|
4827
|
-
/* @__PURE__ */ (0,
|
|
5549
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "tool-result-card__heading", children: [
|
|
5550
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
|
|
5551
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("strong", { children: result.title })
|
|
4828
5552
|
] }),
|
|
4829
|
-
result.description ? /* @__PURE__ */ (0,
|
|
4830
|
-
result.details?.length ? /* @__PURE__ */ (0,
|
|
4831
|
-
/* @__PURE__ */ (0,
|
|
4832
|
-
/* @__PURE__ */ (0,
|
|
5553
|
+
result.description ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { children: result.description }) : null,
|
|
5554
|
+
result.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dl", { children: result.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
|
|
5555
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dt", { children: detail.label }),
|
|
5556
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dd", { children: detail.value })
|
|
4833
5557
|
] }, `${detail.label}:${detail.value}`)) }) : null,
|
|
4834
|
-
result.links?.length ? /* @__PURE__ */ (0,
|
|
5558
|
+
result.links?.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "tool-result-card__links", children: result.links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
4835
5559
|
"a",
|
|
4836
5560
|
{
|
|
4837
5561
|
href: link.href,
|
|
@@ -4847,24 +5571,24 @@ function EntityResultCard({
|
|
|
4847
5571
|
}
|
|
4848
5572
|
|
|
4849
5573
|
// src/react/components/SignatureResultCard/SignatureResultCard.tsx
|
|
4850
|
-
var
|
|
5574
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
4851
5575
|
function SignatureResultCard({
|
|
4852
5576
|
result
|
|
4853
5577
|
}) {
|
|
4854
5578
|
const primaryLink = result.links?.[0];
|
|
4855
|
-
return /* @__PURE__ */ (0,
|
|
5579
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
4856
5580
|
"section",
|
|
4857
5581
|
{
|
|
4858
5582
|
className: `signature-result-card tool-result-card tool-result-card--${result.status}`,
|
|
4859
5583
|
"aria-label": result.title,
|
|
4860
5584
|
children: [
|
|
4861
|
-
/* @__PURE__ */ (0,
|
|
4862
|
-
/* @__PURE__ */ (0,
|
|
4863
|
-
/* @__PURE__ */ (0,
|
|
5585
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "tool-result-card__heading", children: [
|
|
5586
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
|
|
5587
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("strong", { children: result.title })
|
|
4864
5588
|
] }),
|
|
4865
|
-
result.statusLabel ? /* @__PURE__ */ (0,
|
|
4866
|
-
result.description ? /* @__PURE__ */ (0,
|
|
4867
|
-
primaryLink ? /* @__PURE__ */ (0,
|
|
5589
|
+
result.statusLabel ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "signature-result-card__badge", children: result.statusLabel }) : null,
|
|
5590
|
+
result.description ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { children: result.description }) : null,
|
|
5591
|
+
primaryLink ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
4868
5592
|
"a",
|
|
4869
5593
|
{
|
|
4870
5594
|
className: "signature-result-card__cta",
|
|
@@ -4880,26 +5604,26 @@ function SignatureResultCard({
|
|
|
4880
5604
|
}
|
|
4881
5605
|
|
|
4882
5606
|
// src/react/components/ToolResultCard/ToolResultCard.tsx
|
|
4883
|
-
var
|
|
5607
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
4884
5608
|
function ToolResultCard({
|
|
4885
5609
|
result
|
|
4886
5610
|
}) {
|
|
4887
|
-
return /* @__PURE__ */ (0,
|
|
5611
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
4888
5612
|
"section",
|
|
4889
5613
|
{
|
|
4890
5614
|
className: `tool-result-card tool-result-card--${result.status}`,
|
|
4891
5615
|
"aria-label": result.title,
|
|
4892
5616
|
children: [
|
|
4893
|
-
/* @__PURE__ */ (0,
|
|
4894
|
-
/* @__PURE__ */ (0,
|
|
4895
|
-
/* @__PURE__ */ (0,
|
|
5617
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "tool-result-card__heading", children: [
|
|
5618
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
|
|
5619
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("strong", { children: result.title })
|
|
4896
5620
|
] }),
|
|
4897
|
-
result.description ? /* @__PURE__ */ (0,
|
|
4898
|
-
result.details?.length ? /* @__PURE__ */ (0,
|
|
4899
|
-
/* @__PURE__ */ (0,
|
|
4900
|
-
/* @__PURE__ */ (0,
|
|
5621
|
+
result.description ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { children: result.description }) : null,
|
|
5622
|
+
result.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dl", { children: result.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
|
|
5623
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dt", { children: detail.label }),
|
|
5624
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dd", { children: detail.value })
|
|
4901
5625
|
] }, `${detail.label}:${detail.value}`)) }) : null,
|
|
4902
|
-
result.links?.length ? /* @__PURE__ */ (0,
|
|
5626
|
+
result.links?.length ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "tool-result-card__links", children: result.links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
4903
5627
|
"a",
|
|
4904
5628
|
{
|
|
4905
5629
|
href: link.href,
|
|
@@ -4915,14 +5639,14 @@ function ToolResultCard({
|
|
|
4915
5639
|
}
|
|
4916
5640
|
|
|
4917
5641
|
// src/react/components/VisitorToolResultView/VisitorToolResultView.tsx
|
|
4918
|
-
var
|
|
5642
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
4919
5643
|
function VisitorToolResultView({
|
|
4920
5644
|
disabled = false,
|
|
4921
5645
|
onToolInput,
|
|
4922
5646
|
result
|
|
4923
5647
|
}) {
|
|
4924
5648
|
if (result.kind === "input") {
|
|
4925
|
-
return /* @__PURE__ */ (0,
|
|
5649
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
4926
5650
|
ToolInputCard,
|
|
4927
5651
|
{
|
|
4928
5652
|
disabled,
|
|
@@ -4932,16 +5656,16 @@ function VisitorToolResultView({
|
|
|
4932
5656
|
);
|
|
4933
5657
|
}
|
|
4934
5658
|
if (result.kind === "entity") {
|
|
4935
|
-
return /* @__PURE__ */ (0,
|
|
5659
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(EntityResultCard, { result });
|
|
4936
5660
|
}
|
|
4937
5661
|
if (result.kind === "collection") {
|
|
4938
|
-
return /* @__PURE__ */ (0,
|
|
5662
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CollectionResultCard, { result });
|
|
4939
5663
|
}
|
|
4940
5664
|
if (result.kind === "signature") {
|
|
4941
|
-
return /* @__PURE__ */ (0,
|
|
5665
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SignatureResultCard, { result });
|
|
4942
5666
|
}
|
|
4943
5667
|
if (result.kind === "summary") {
|
|
4944
|
-
return /* @__PURE__ */ (0,
|
|
5668
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolResultCard, { result });
|
|
4945
5669
|
}
|
|
4946
5670
|
return null;
|
|
4947
5671
|
}
|
|
@@ -4950,9 +5674,9 @@ function isRenderableVisitorToolResult(result) {
|
|
|
4950
5674
|
}
|
|
4951
5675
|
|
|
4952
5676
|
// src/react/components/AgentRail/AgentRail.tsx
|
|
4953
|
-
var
|
|
5677
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
4954
5678
|
function MinimizeIcon() {
|
|
4955
|
-
return /* @__PURE__ */ (0,
|
|
5679
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4956
5680
|
"path",
|
|
4957
5681
|
{
|
|
4958
5682
|
d: "M3.5 8h9",
|
|
@@ -4962,8 +5686,8 @@ function MinimizeIcon() {
|
|
|
4962
5686
|
}
|
|
4963
5687
|
) });
|
|
4964
5688
|
}
|
|
4965
|
-
function
|
|
4966
|
-
return /* @__PURE__ */ (0,
|
|
5689
|
+
function CloseIcon2() {
|
|
5690
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4967
5691
|
"path",
|
|
4968
5692
|
{
|
|
4969
5693
|
d: "M4 4l8 8M12 4l-8 8",
|
|
@@ -4974,7 +5698,7 @@ function CloseIcon() {
|
|
|
4974
5698
|
) });
|
|
4975
5699
|
}
|
|
4976
5700
|
function NewChatIcon() {
|
|
4977
|
-
return /* @__PURE__ */ (0,
|
|
5701
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4978
5702
|
"path",
|
|
4979
5703
|
{
|
|
4980
5704
|
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",
|
|
@@ -4986,7 +5710,7 @@ function NewChatIcon() {
|
|
|
4986
5710
|
) });
|
|
4987
5711
|
}
|
|
4988
5712
|
function ExpandIcon() {
|
|
4989
|
-
return /* @__PURE__ */ (0,
|
|
5713
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4990
5714
|
"path",
|
|
4991
5715
|
{
|
|
4992
5716
|
d: "M6 3.5H3.5V6M10 3.5h2.5V6M10 12.5h2.5V10M6 12.5H3.5V10",
|
|
@@ -4998,7 +5722,7 @@ function ExpandIcon() {
|
|
|
4998
5722
|
) });
|
|
4999
5723
|
}
|
|
5000
5724
|
function RestoreIcon() {
|
|
5001
|
-
return /* @__PURE__ */ (0,
|
|
5725
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
5002
5726
|
"path",
|
|
5003
5727
|
{
|
|
5004
5728
|
d: "M5.5 5.5H3.5V7.5M10.5 5.5h2V7.5M10.5 10.5h2V8.5M5.5 10.5H3.5V8.5",
|
|
@@ -5009,6 +5733,19 @@ function RestoreIcon() {
|
|
|
5009
5733
|
}
|
|
5010
5734
|
) });
|
|
5011
5735
|
}
|
|
5736
|
+
function ChevronDownIcon() {
|
|
5737
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
5738
|
+
"path",
|
|
5739
|
+
{
|
|
5740
|
+
d: "M4 6.5l4 4 4-4",
|
|
5741
|
+
stroke: "currentColor",
|
|
5742
|
+
strokeWidth: "1.6",
|
|
5743
|
+
strokeLinecap: "round",
|
|
5744
|
+
strokeLinejoin: "round"
|
|
5745
|
+
}
|
|
5746
|
+
) });
|
|
5747
|
+
}
|
|
5748
|
+
var DEFAULT_DISCLAIMER_LABEL = "Agent can make mistakes. Check important info.";
|
|
5012
5749
|
function AgentRail({
|
|
5013
5750
|
state,
|
|
5014
5751
|
theme,
|
|
@@ -5016,6 +5753,9 @@ function AgentRail({
|
|
|
5016
5753
|
brandLabel = "",
|
|
5017
5754
|
brandLogoUrl,
|
|
5018
5755
|
poweredByLabel = "Powered by Webless",
|
|
5756
|
+
disclaimerLabel,
|
|
5757
|
+
answerReceipt = false,
|
|
5758
|
+
readAloud = false,
|
|
5019
5759
|
composerPlaceholder = "Ask anything\u2026",
|
|
5020
5760
|
mobileFullscreen = false,
|
|
5021
5761
|
expanded = false,
|
|
@@ -5024,16 +5764,26 @@ function AgentRail({
|
|
|
5024
5764
|
onExpandToggle,
|
|
5025
5765
|
onReset,
|
|
5026
5766
|
onRetry,
|
|
5767
|
+
onRegenerate,
|
|
5768
|
+
onFeedback,
|
|
5027
5769
|
onSubmit,
|
|
5028
5770
|
onFollowUpSelect,
|
|
5029
5771
|
onBook,
|
|
5030
5772
|
onInputResponse,
|
|
5031
5773
|
onToolInput
|
|
5032
5774
|
}) {
|
|
5033
|
-
const
|
|
5775
|
+
const railRef = (0, import_react14.useRef)(null);
|
|
5776
|
+
const overlayRef = (0, import_react14.useRef)(null);
|
|
5777
|
+
const transcriptRef = (0, import_react14.useRef)(null);
|
|
5778
|
+
const pinnedToBottomRef = (0, import_react14.useRef)(true);
|
|
5779
|
+
const smoothScrollToLatestRef = (0, import_react14.useRef)(false);
|
|
5780
|
+
const lockedTranscriptScrollTopRef = (0, import_react14.useRef)(null);
|
|
5781
|
+
const [showJumpToLatest, setShowJumpToLatest] = (0, import_react14.useState)(false);
|
|
5782
|
+
const [receiptOpen, setReceiptOpen] = (0, import_react14.useState)(false);
|
|
5034
5783
|
const resolvedBrandLabel = brandLabel.trim();
|
|
5035
5784
|
const resolvedBrandLogoUrl = brandLogoUrl?.trim();
|
|
5036
|
-
const
|
|
5785
|
+
const resolvedDisclaimerLabel = disclaimerLabel === void 0 ? DEFAULT_DISCLAIMER_LABEL : disclaimerLabel;
|
|
5786
|
+
const [failedLogoUrl, setFailedLogoUrl] = (0, import_react14.useState)(null);
|
|
5037
5787
|
const showBrandLogo = Boolean(resolvedBrandLogoUrl) && failedLogoUrl !== resolvedBrandLogoUrl;
|
|
5038
5788
|
const resolvedColorScheme = useAgentColorScheme(colorScheme);
|
|
5039
5789
|
const brandedTheme = { ...defaultAgentRailTheme, ...theme };
|
|
@@ -5084,10 +5834,15 @@ function AgentRail({
|
|
|
5084
5834
|
);
|
|
5085
5835
|
const activeVisitorToolInput = [...visitorToolResults].reverse().find((result) => result.kind === "input");
|
|
5086
5836
|
const visibleVisitorToolResults = activeVisitorToolInput ? [activeVisitorToolInput] : visitorToolResults;
|
|
5087
|
-
const
|
|
5837
|
+
const activityActive = state.toolSteps.some((step) => step.state === "active");
|
|
5838
|
+
const showActivity = state.toolSteps.length > 0 && visibleVisitorToolResults.length === 0 && pendingInputRequests.length === 0 && !state.pendingOffer && activityActive;
|
|
5088
5839
|
const hasVisitorMessages2 = state.messages.some(
|
|
5089
5840
|
(message) => message.role === "visitor"
|
|
5090
5841
|
);
|
|
5842
|
+
const hasAgentResponseAfterVisitor = state.messages.some(
|
|
5843
|
+
(message) => message.role === "agent" && message.id !== "greeting"
|
|
5844
|
+
);
|
|
5845
|
+
const showDisclaimerLabel = Boolean(resolvedDisclaimerLabel) && hasVisitorMessages2 && (hasAgentResponseAfterVisitor || state.phase === "streaming" && Boolean(state.streamingText));
|
|
5091
5846
|
const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
|
|
5092
5847
|
const greeting = state.messages.find(
|
|
5093
5848
|
(message) => message.role === "agent" && message.id === "greeting"
|
|
@@ -5109,6 +5864,7 @@ function AgentRail({
|
|
|
5109
5864
|
}
|
|
5110
5865
|
}
|
|
5111
5866
|
const lastIsAgent = lastMessage?.role === "agent";
|
|
5867
|
+
const showMessageActions = state.phase === "complete" && lastIsAgent && hasVisitorMessages2;
|
|
5112
5868
|
const streamingMessage = state.phase === "streaming" && state.streamingText && !lastIsAgent ? {
|
|
5113
5869
|
createdAt: 0,
|
|
5114
5870
|
id: "streaming-response",
|
|
@@ -5135,10 +5891,36 @@ function AgentRail({
|
|
|
5135
5891
|
hasPendingConfirmation,
|
|
5136
5892
|
enabled: lastIsAgent && !isBusy
|
|
5137
5893
|
});
|
|
5138
|
-
|
|
5894
|
+
const receiptSteps = answerReceipt && state.toolSteps.length > 0 ? state.toolSteps : void 0;
|
|
5895
|
+
(0, import_react14.useEffect)(() => {
|
|
5896
|
+
if (state.phase !== "complete") {
|
|
5897
|
+
setReceiptOpen(false);
|
|
5898
|
+
}
|
|
5899
|
+
}, [state.phase]);
|
|
5900
|
+
function handleSubmit(message) {
|
|
5901
|
+
setReceiptOpen(false);
|
|
5902
|
+
onSubmit?.(message);
|
|
5903
|
+
}
|
|
5904
|
+
function handleRegenerate() {
|
|
5905
|
+
setReceiptOpen(false);
|
|
5906
|
+
onRegenerate?.();
|
|
5907
|
+
}
|
|
5908
|
+
function handleReset() {
|
|
5909
|
+
setReceiptOpen(false);
|
|
5910
|
+
onReset?.();
|
|
5911
|
+
}
|
|
5912
|
+
function handleFollowUpSelect(label) {
|
|
5913
|
+
setReceiptOpen(false);
|
|
5914
|
+
onFollowUpSelect?.(label);
|
|
5915
|
+
}
|
|
5916
|
+
(0, import_react14.useEffect)(() => {
|
|
5139
5917
|
const node = transcriptRef.current;
|
|
5140
5918
|
if (!node) return;
|
|
5141
|
-
|
|
5919
|
+
const lastMessage2 = state.messages.at(-1);
|
|
5920
|
+
const visitorJustSent = lastMessage2?.role === "visitor";
|
|
5921
|
+
if (pinnedToBottomRef.current || visitorJustSent) {
|
|
5922
|
+
node.scrollTop = node.scrollHeight;
|
|
5923
|
+
}
|
|
5142
5924
|
}, [
|
|
5143
5925
|
state.messages,
|
|
5144
5926
|
state.toolSteps,
|
|
@@ -5146,10 +5928,75 @@ function AgentRail({
|
|
|
5146
5928
|
state.followUps,
|
|
5147
5929
|
state.journey
|
|
5148
5930
|
]);
|
|
5149
|
-
|
|
5931
|
+
(0, import_react14.useEffect)(() => {
|
|
5932
|
+
const node = transcriptRef.current;
|
|
5933
|
+
if (!node) return;
|
|
5934
|
+
const handleScroll = () => {
|
|
5935
|
+
if (node.clientHeight === 0) return;
|
|
5936
|
+
const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;
|
|
5937
|
+
const pinned = distanceFromBottom < 48 || smoothScrollToLatestRef.current;
|
|
5938
|
+
pinnedToBottomRef.current = pinned;
|
|
5939
|
+
setShowJumpToLatest(!pinned);
|
|
5940
|
+
};
|
|
5941
|
+
node.addEventListener("scroll", handleScroll, { passive: true });
|
|
5942
|
+
handleScroll();
|
|
5943
|
+
return () => node.removeEventListener("scroll", handleScroll);
|
|
5944
|
+
}, []);
|
|
5945
|
+
(0, import_react14.useEffect)(() => {
|
|
5946
|
+
const node = transcriptRef.current;
|
|
5947
|
+
if (!node) return;
|
|
5948
|
+
const observer = new ResizeObserver(() => {
|
|
5949
|
+
if (node.clientHeight === 0) return;
|
|
5950
|
+
if (pinnedToBottomRef.current) {
|
|
5951
|
+
node.scrollTo({ top: node.scrollHeight, behavior: "instant" });
|
|
5952
|
+
}
|
|
5953
|
+
});
|
|
5954
|
+
observer.observe(node);
|
|
5955
|
+
return () => observer.disconnect();
|
|
5956
|
+
}, []);
|
|
5957
|
+
(0, import_react14.useEffect)(() => {
|
|
5958
|
+
if (!receiptOpen) {
|
|
5959
|
+
lockedTranscriptScrollTopRef.current = null;
|
|
5960
|
+
return;
|
|
5961
|
+
}
|
|
5962
|
+
const node = transcriptRef.current;
|
|
5963
|
+
if (!node || lockedTranscriptScrollTopRef.current === null) return;
|
|
5964
|
+
node.scrollTop = lockedTranscriptScrollTopRef.current;
|
|
5965
|
+
}, [receiptOpen]);
|
|
5966
|
+
function openReceipt() {
|
|
5967
|
+
const node = transcriptRef.current;
|
|
5968
|
+
lockedTranscriptScrollTopRef.current = node?.scrollTop ?? null;
|
|
5969
|
+
setReceiptOpen(true);
|
|
5970
|
+
}
|
|
5971
|
+
function scrollToLatest() {
|
|
5972
|
+
const node = transcriptRef.current;
|
|
5973
|
+
if (!node) return;
|
|
5974
|
+
pinnedToBottomRef.current = true;
|
|
5975
|
+
setShowJumpToLatest(false);
|
|
5976
|
+
const reduceMotion = window.matchMedia(
|
|
5977
|
+
"(prefers-reduced-motion: reduce)"
|
|
5978
|
+
).matches;
|
|
5979
|
+
if (reduceMotion) {
|
|
5980
|
+
node.scrollTo({ top: node.scrollHeight, behavior: "instant" });
|
|
5981
|
+
return;
|
|
5982
|
+
}
|
|
5983
|
+
smoothScrollToLatestRef.current = true;
|
|
5984
|
+
const settle = () => {
|
|
5985
|
+
smoothScrollToLatestRef.current = false;
|
|
5986
|
+
const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;
|
|
5987
|
+
const pinned = distanceFromBottom < 48;
|
|
5988
|
+
pinnedToBottomRef.current = pinned;
|
|
5989
|
+
setShowJumpToLatest(!pinned);
|
|
5990
|
+
};
|
|
5991
|
+
node.addEventListener("scrollend", settle, { once: true });
|
|
5992
|
+
window.setTimeout(settle, 900);
|
|
5993
|
+
node.scrollTo({ top: node.scrollHeight, behavior: "smooth" });
|
|
5994
|
+
}
|
|
5995
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
5150
5996
|
"aside",
|
|
5151
5997
|
{
|
|
5152
|
-
|
|
5998
|
+
ref: railRef,
|
|
5999
|
+
className: `agent-rail not-typeset${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}${receiptOpen ? " agent-rail--receipt-open" : ""}`,
|
|
5153
6000
|
"data-not-typeset": "",
|
|
5154
6001
|
"data-color-scheme": resolvedColorScheme,
|
|
5155
6002
|
spellCheck: false,
|
|
@@ -5159,196 +6006,234 @@ function AgentRail({
|
|
|
5159
6006
|
autoFocus: mobileFullscreen || expanded,
|
|
5160
6007
|
role: mobileFullscreen || expanded ? "dialog" : void 0,
|
|
5161
6008
|
tabIndex: mobileFullscreen || expanded ? -1 : void 0,
|
|
5162
|
-
children:
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
className: "agent-
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
className: "agent-rail__brand-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
className: "agent-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
6009
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
6010
|
+
AgentRailOverlayContext.Provider,
|
|
6011
|
+
{
|
|
6012
|
+
value: { railRef, overlayRef },
|
|
6013
|
+
children: [
|
|
6014
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__surface", inert: receiptOpen || void 0, children: [
|
|
6015
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("header", { className: "agent-rail__header", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__brand-row", children: [
|
|
6016
|
+
onCollapse ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6017
|
+
"button",
|
|
6018
|
+
{
|
|
6019
|
+
type: "button",
|
|
6020
|
+
className: "agent-rail__collapse",
|
|
6021
|
+
"aria-label": "Collapse assist",
|
|
6022
|
+
onClick: onCollapse,
|
|
6023
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MinimizeIcon, {})
|
|
6024
|
+
}
|
|
6025
|
+
) : onClose ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6026
|
+
"button",
|
|
6027
|
+
{
|
|
6028
|
+
type: "button",
|
|
6029
|
+
className: "agent-rail__close",
|
|
6030
|
+
"aria-label": "Close agent",
|
|
6031
|
+
onClick: onClose,
|
|
6032
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(CloseIcon2, {})
|
|
6033
|
+
}
|
|
6034
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
|
|
6035
|
+
resolvedBrandLabel || showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "agent-rail__identity", children: [
|
|
6036
|
+
showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "agent-rail__brand-mark", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6037
|
+
"img",
|
|
6038
|
+
{
|
|
6039
|
+
className: "agent-rail__brand-logo",
|
|
6040
|
+
src: resolvedBrandLogoUrl,
|
|
6041
|
+
alt: "",
|
|
6042
|
+
onError: () => {
|
|
6043
|
+
setFailedLogoUrl(resolvedBrandLogoUrl ?? null);
|
|
6044
|
+
}
|
|
6045
|
+
}
|
|
6046
|
+
) }) : null,
|
|
6047
|
+
resolvedBrandLabel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "agent-rail__brand-label", children: resolvedBrandLabel }) : null
|
|
6048
|
+
] }) : null,
|
|
6049
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "agent-rail__actions", children: [
|
|
6050
|
+
onReset ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6051
|
+
"button",
|
|
6052
|
+
{
|
|
6053
|
+
type: "button",
|
|
6054
|
+
className: "agent-rail__new-chat",
|
|
6055
|
+
"aria-label": "Start a new conversation",
|
|
6056
|
+
disabled: !hasVisitorMessages2,
|
|
6057
|
+
onClick: handleReset,
|
|
6058
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(NewChatIcon, {})
|
|
6059
|
+
}
|
|
6060
|
+
) : null,
|
|
6061
|
+
onExpandToggle ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6062
|
+
"button",
|
|
6063
|
+
{
|
|
6064
|
+
type: "button",
|
|
6065
|
+
className: "agent-rail__expand",
|
|
6066
|
+
"aria-label": expanded ? "Exit full screen" : "Open full screen",
|
|
6067
|
+
onClick: onExpandToggle,
|
|
6068
|
+
children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RestoreIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ExpandIcon, {})
|
|
6069
|
+
}
|
|
6070
|
+
) : null
|
|
6071
|
+
] })
|
|
6072
|
+
] }) }),
|
|
6073
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: transcriptRef, className: "agent-rail__transcript", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__thread", children: [
|
|
6074
|
+
!hasVisitorMessages2 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("section", { className: "agent-rail__welcome", "aria-label": "Welcome", children: [
|
|
6075
|
+
greeting?.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6076
|
+
MessageBubble,
|
|
6077
|
+
{
|
|
6078
|
+
message: greeting,
|
|
6079
|
+
bookingDisabled: isBusy,
|
|
6080
|
+
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
6081
|
+
onBook
|
|
6082
|
+
}
|
|
6083
|
+
) : null,
|
|
6084
|
+
showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6085
|
+
FollowUpChips,
|
|
6086
|
+
{
|
|
6087
|
+
suggestions: state.followUps,
|
|
6088
|
+
disabled: isBusy,
|
|
6089
|
+
label: "Start here",
|
|
6090
|
+
onSelect: (suggestion) => handleFollowUpSelect(suggestion.label)
|
|
6091
|
+
}
|
|
6092
|
+
) }) : null,
|
|
6093
|
+
showActivity ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6094
|
+
AgentActivityBubble,
|
|
6095
|
+
{
|
|
6096
|
+
brandLabel: resolvedBrandLabel,
|
|
6097
|
+
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
6098
|
+
failed: state.phase === "error",
|
|
6099
|
+
steps: state.toolSteps
|
|
6100
|
+
}
|
|
6101
|
+
) : null,
|
|
6102
|
+
visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6103
|
+
VisitorToolResultView,
|
|
6104
|
+
{
|
|
6105
|
+
result,
|
|
6106
|
+
disabled: semanticSurfaceDisabled,
|
|
6107
|
+
onToolInput
|
|
6108
|
+
},
|
|
6109
|
+
result.id
|
|
6110
|
+
)),
|
|
6111
|
+
pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6112
|
+
HumanInputCard,
|
|
6113
|
+
{
|
|
6114
|
+
request,
|
|
6115
|
+
onRespond: onInputResponse
|
|
6116
|
+
},
|
|
6117
|
+
request.requestId
|
|
6118
|
+
))
|
|
6119
|
+
] }) : null,
|
|
6120
|
+
visibleMessages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__turn-block", children: [
|
|
6121
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6122
|
+
MessageBubble,
|
|
6123
|
+
{
|
|
6124
|
+
message,
|
|
6125
|
+
bookingDisabled: isBusy,
|
|
6126
|
+
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
6127
|
+
offer: index === lastAgentIndex ? state.pendingOffer : void 0,
|
|
6128
|
+
onBook
|
|
6129
|
+
}
|
|
6130
|
+
),
|
|
6131
|
+
index === lastAgentIndex && showMessageActions && message.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6132
|
+
MessageActions,
|
|
6133
|
+
{
|
|
6134
|
+
answeredAt: message.createdAt,
|
|
6135
|
+
copyText: hideToolCardFences(message.text).trim() || message.text,
|
|
6136
|
+
readAloud,
|
|
6137
|
+
receiptSteps,
|
|
6138
|
+
onOpenReceipt: receiptSteps ? openReceipt : void 0,
|
|
6139
|
+
onRegenerate: onRegenerate ? handleRegenerate : void 0,
|
|
6140
|
+
onFeedback: onFeedback ? (rating) => onFeedback(rating, message) : void 0
|
|
6141
|
+
}
|
|
6142
|
+
) : null,
|
|
6143
|
+
index === lastVisitorIndex ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
6144
|
+
showActivity ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6145
|
+
AgentActivityBubble,
|
|
6146
|
+
{
|
|
6147
|
+
brandLabel: resolvedBrandLabel,
|
|
6148
|
+
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
6149
|
+
failed: state.phase === "error",
|
|
6150
|
+
steps: state.toolSteps
|
|
6151
|
+
}
|
|
6152
|
+
) : null,
|
|
6153
|
+
visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6154
|
+
VisitorToolResultView,
|
|
6155
|
+
{
|
|
6156
|
+
result,
|
|
6157
|
+
disabled: semanticSurfaceDisabled,
|
|
6158
|
+
onToolInput
|
|
6159
|
+
},
|
|
6160
|
+
result.id
|
|
6161
|
+
)),
|
|
6162
|
+
pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6163
|
+
HumanInputCard,
|
|
6164
|
+
{
|
|
6165
|
+
request,
|
|
6166
|
+
onRespond: onInputResponse
|
|
6167
|
+
},
|
|
6168
|
+
request.requestId
|
|
6169
|
+
))
|
|
6170
|
+
] }) : null
|
|
6171
|
+
] }, message.id)),
|
|
6172
|
+
streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6173
|
+
MessageBubble,
|
|
6174
|
+
{
|
|
6175
|
+
message: streamingMessage,
|
|
6176
|
+
bookingDisabled: isBusy,
|
|
6177
|
+
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
6178
|
+
offer: state.pendingOffer,
|
|
6179
|
+
onBook
|
|
6180
|
+
}
|
|
6181
|
+
) : null,
|
|
6182
|
+
waitingForBooking ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(BookingCardLoader, {}) : null,
|
|
6183
|
+
state.error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("section", { className: "agent-rail__error", role: "alert", children: [
|
|
6184
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
|
|
6185
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("strong", { children: "Something went wrong" }),
|
|
6186
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: state.error })
|
|
6187
|
+
] }),
|
|
6188
|
+
onRetry ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
|
|
6189
|
+
] }) : null
|
|
6190
|
+
] }) }),
|
|
6191
|
+
showDisclaimerLabel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "agent-rail__disclaimer", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: resolvedDisclaimerLabel }) }) : null,
|
|
6192
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
|
|
6193
|
+
showJumpToLatest ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6194
|
+
"button",
|
|
6195
|
+
{
|
|
6196
|
+
type: "button",
|
|
6197
|
+
className: "agent-rail__jump-to-latest",
|
|
6198
|
+
"aria-label": "Jump to the latest message",
|
|
6199
|
+
title: "Jump to the latest message",
|
|
6200
|
+
onClick: scrollToLatest,
|
|
6201
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ChevronDownIcon, {})
|
|
6202
|
+
}
|
|
6203
|
+
) : null,
|
|
6204
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6205
|
+
Composer,
|
|
6206
|
+
{
|
|
6207
|
+
variant: expanded || mobileFullscreen ? "dock" : "default",
|
|
6208
|
+
disabled: isBusy,
|
|
6209
|
+
form: composerForm,
|
|
6210
|
+
placeholder: composerPlaceholder,
|
|
6211
|
+
onSubmit: handleSubmit
|
|
6212
|
+
}
|
|
6213
|
+
),
|
|
6214
|
+
poweredByLabel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "agent-rail__footer", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: poweredByLabel }) }) }) : null
|
|
6215
|
+
] })
|
|
6216
|
+
] }),
|
|
6217
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: overlayRef, className: "agent-rail__overlay" }),
|
|
6218
|
+
receiptOpen && receiptSteps ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6219
|
+
AnswerReceiptDialog,
|
|
5243
6220
|
{
|
|
5244
6221
|
brandLabel: resolvedBrandLabel,
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
steps: state.toolSteps
|
|
6222
|
+
onClose: () => setReceiptOpen(false),
|
|
6223
|
+
steps: receiptSteps
|
|
5248
6224
|
}
|
|
5249
|
-
) : null
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
result,
|
|
5254
|
-
disabled: semanticSurfaceDisabled,
|
|
5255
|
-
onToolInput
|
|
5256
|
-
},
|
|
5257
|
-
result.id
|
|
5258
|
-
)),
|
|
5259
|
-
pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5260
|
-
HumanInputCard,
|
|
5261
|
-
{
|
|
5262
|
-
request,
|
|
5263
|
-
onRespond: onInputResponse
|
|
5264
|
-
},
|
|
5265
|
-
request.requestId
|
|
5266
|
-
))
|
|
5267
|
-
] }) : null,
|
|
5268
|
-
visibleMessages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "agent-rail__turn-block", children: [
|
|
5269
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5270
|
-
MessageBubble,
|
|
5271
|
-
{
|
|
5272
|
-
message,
|
|
5273
|
-
bookingDisabled: isBusy,
|
|
5274
|
-
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
5275
|
-
offer: index === lastAgentIndex ? state.pendingOffer : void 0,
|
|
5276
|
-
onBook
|
|
5277
|
-
}
|
|
5278
|
-
),
|
|
5279
|
-
index === lastVisitorIndex ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
5280
|
-
showActivity ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5281
|
-
AgentActivityBubble,
|
|
5282
|
-
{
|
|
5283
|
-
brandLabel: resolvedBrandLabel,
|
|
5284
|
-
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
5285
|
-
failed: state.phase === "error",
|
|
5286
|
-
steps: state.toolSteps
|
|
5287
|
-
}
|
|
5288
|
-
) : null,
|
|
5289
|
-
visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5290
|
-
VisitorToolResultView,
|
|
5291
|
-
{
|
|
5292
|
-
result,
|
|
5293
|
-
disabled: semanticSurfaceDisabled,
|
|
5294
|
-
onToolInput
|
|
5295
|
-
},
|
|
5296
|
-
result.id
|
|
5297
|
-
)),
|
|
5298
|
-
pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5299
|
-
HumanInputCard,
|
|
5300
|
-
{
|
|
5301
|
-
request,
|
|
5302
|
-
onRespond: onInputResponse
|
|
5303
|
-
},
|
|
5304
|
-
request.requestId
|
|
5305
|
-
))
|
|
5306
|
-
] }) : null
|
|
5307
|
-
] }, message.id)),
|
|
5308
|
-
streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5309
|
-
MessageBubble,
|
|
5310
|
-
{
|
|
5311
|
-
message: streamingMessage,
|
|
5312
|
-
bookingDisabled: isBusy,
|
|
5313
|
-
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
5314
|
-
offer: state.pendingOffer,
|
|
5315
|
-
onBook
|
|
5316
|
-
}
|
|
5317
|
-
) : null,
|
|
5318
|
-
waitingForBooking ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(BookingCardLoader, {}) : null,
|
|
5319
|
-
state.error ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("section", { className: "agent-rail__error", role: "alert", children: [
|
|
5320
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
|
|
5321
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("strong", { children: "Something went wrong" }),
|
|
5322
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { children: state.error })
|
|
5323
|
-
] }),
|
|
5324
|
-
onRetry ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
|
|
5325
|
-
] }) : null
|
|
5326
|
-
] }) }),
|
|
5327
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
|
|
5328
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5329
|
-
Composer,
|
|
5330
|
-
{
|
|
5331
|
-
variant: expanded || mobileFullscreen ? "dock" : "default",
|
|
5332
|
-
disabled: isBusy,
|
|
5333
|
-
form: composerForm,
|
|
5334
|
-
placeholder: composerPlaceholder,
|
|
5335
|
-
onSubmit
|
|
5336
|
-
}
|
|
5337
|
-
),
|
|
5338
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "agent-rail__footer", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("p", { children: [
|
|
5339
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "AI can make mistakes. Check important info." }),
|
|
5340
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: poweredByLabel })
|
|
5341
|
-
] }) })
|
|
5342
|
-
] })
|
|
5343
|
-
]
|
|
6225
|
+
) : null
|
|
6226
|
+
]
|
|
6227
|
+
}
|
|
6228
|
+
)
|
|
5344
6229
|
}
|
|
5345
6230
|
);
|
|
5346
6231
|
}
|
|
5347
6232
|
|
|
5348
6233
|
// src/react/components/AssistEdgeTab/AssistEdgeTab.tsx
|
|
5349
|
-
var
|
|
6234
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
5350
6235
|
function SparklesIcon() {
|
|
5351
|
-
return /* @__PURE__ */ (0,
|
|
6236
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
5352
6237
|
"svg",
|
|
5353
6238
|
{
|
|
5354
6239
|
className: "assist-edge-tab__sparkles",
|
|
@@ -5356,21 +6241,21 @@ function SparklesIcon() {
|
|
|
5356
6241
|
fill: "none",
|
|
5357
6242
|
"aria-hidden": "true",
|
|
5358
6243
|
children: [
|
|
5359
|
-
/* @__PURE__ */ (0,
|
|
6244
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5360
6245
|
"path",
|
|
5361
6246
|
{
|
|
5362
6247
|
d: "M8 1.2l.95 2.7 2.85.05-2.25 1.75.8 2.75L8 6.7 5.65 8.45l.8-2.75L4.2 3.95l2.85-.05L8 1.2z",
|
|
5363
6248
|
fill: "currentColor"
|
|
5364
6249
|
}
|
|
5365
6250
|
),
|
|
5366
|
-
/* @__PURE__ */ (0,
|
|
6251
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5367
6252
|
"path",
|
|
5368
6253
|
{
|
|
5369
6254
|
d: "M14.2 6.4l.55 1.55 1.65.03-1.3 1 .46 1.58-1.36-1-1.36 1 .46-1.58-1.3-1 1.65-.03.55-1.55z",
|
|
5370
6255
|
fill: "currentColor"
|
|
5371
6256
|
}
|
|
5372
6257
|
),
|
|
5373
|
-
/* @__PURE__ */ (0,
|
|
6258
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5374
6259
|
"path",
|
|
5375
6260
|
{
|
|
5376
6261
|
d: "M3.1 9.1l.4 1.15 1.22.02-.96.74.34 1.17-1-.74-1 .74.34-1.17-.96-.74 1.22-.02.4-1.15z",
|
|
@@ -5384,7 +6269,7 @@ function SparklesIcon() {
|
|
|
5384
6269
|
function TabMarkIcon({ customIconUrl }) {
|
|
5385
6270
|
const url = customIconUrl?.trim();
|
|
5386
6271
|
if (url) {
|
|
5387
|
-
return /* @__PURE__ */ (0,
|
|
6272
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5388
6273
|
"img",
|
|
5389
6274
|
{
|
|
5390
6275
|
alt: "",
|
|
@@ -5394,10 +6279,10 @@ function TabMarkIcon({ customIconUrl }) {
|
|
|
5394
6279
|
}
|
|
5395
6280
|
);
|
|
5396
6281
|
}
|
|
5397
|
-
return /* @__PURE__ */ (0,
|
|
6282
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SparklesIcon, {});
|
|
5398
6283
|
}
|
|
5399
6284
|
function ChevronLeftIcon() {
|
|
5400
|
-
return /* @__PURE__ */ (0,
|
|
6285
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5401
6286
|
"path",
|
|
5402
6287
|
{
|
|
5403
6288
|
d: "M10 4L6 8l4 4",
|
|
@@ -5408,8 +6293,8 @@ function ChevronLeftIcon() {
|
|
|
5408
6293
|
}
|
|
5409
6294
|
) });
|
|
5410
6295
|
}
|
|
5411
|
-
function
|
|
5412
|
-
return /* @__PURE__ */ (0,
|
|
6296
|
+
function ChevronDownIcon2() {
|
|
6297
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5413
6298
|
"path",
|
|
5414
6299
|
{
|
|
5415
6300
|
d: "M4 6l4 4 4-4",
|
|
@@ -5421,7 +6306,7 @@ function ChevronDownIcon() {
|
|
|
5421
6306
|
) });
|
|
5422
6307
|
}
|
|
5423
6308
|
function DragDots() {
|
|
5424
|
-
return /* @__PURE__ */ (0,
|
|
6309
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__dots", "aria-hidden": "true", children: Array.from({ length: 12 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("i", {}, index)) });
|
|
5425
6310
|
}
|
|
5426
6311
|
var VARIANT_COPY = {
|
|
5427
6312
|
outline: { label: "Ask anything", aria: "Ask anything" },
|
|
@@ -5467,7 +6352,7 @@ function AssistEdgeTab({
|
|
|
5467
6352
|
...resolvedTextColor ? { "--as-text": resolvedTextColor } : {},
|
|
5468
6353
|
colorScheme: resolvedColorScheme
|
|
5469
6354
|
};
|
|
5470
|
-
return /* @__PURE__ */ (0,
|
|
6355
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
5471
6356
|
"button",
|
|
5472
6357
|
{
|
|
5473
6358
|
type: "button",
|
|
@@ -5479,15 +6364,15 @@ function AssistEdgeTab({
|
|
|
5479
6364
|
tabIndex: visible ? 0 : -1,
|
|
5480
6365
|
onClick: onOpen,
|
|
5481
6366
|
children: [
|
|
5482
|
-
mobile ? /* @__PURE__ */ (0,
|
|
5483
|
-
/* @__PURE__ */ (0,
|
|
6367
|
+
mobile ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
6368
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
5484
6369
|
"span",
|
|
5485
6370
|
{
|
|
5486
6371
|
className: "assist-edge-tab__mark assist-edge-tab__mark--mobile",
|
|
5487
6372
|
"aria-hidden": "true",
|
|
5488
6373
|
children: [
|
|
5489
|
-
/* @__PURE__ */ (0,
|
|
5490
|
-
showLogo ? /* @__PURE__ */ (0,
|
|
6374
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
|
|
6375
|
+
showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5491
6376
|
"img",
|
|
5492
6377
|
{
|
|
5493
6378
|
className: "assist-edge-tab__logo",
|
|
@@ -5501,11 +6386,11 @@ function AssistEdgeTab({
|
|
|
5501
6386
|
]
|
|
5502
6387
|
}
|
|
5503
6388
|
),
|
|
5504
|
-
/* @__PURE__ */ (0,
|
|
5505
|
-
] }) : variant === "outline" ? /* @__PURE__ */ (0,
|
|
5506
|
-
/* @__PURE__ */ (0,
|
|
5507
|
-
/* @__PURE__ */ (0,
|
|
5508
|
-
showLogo ? /* @__PURE__ */ (0,
|
|
6389
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel })
|
|
6390
|
+
] }) : variant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
6391
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
|
|
6392
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
|
|
6393
|
+
showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5509
6394
|
"img",
|
|
5510
6395
|
{
|
|
5511
6396
|
className: "assist-edge-tab__logo",
|
|
@@ -5517,18 +6402,18 @@ function AssistEdgeTab({
|
|
|
5517
6402
|
}
|
|
5518
6403
|
) : null
|
|
5519
6404
|
] }),
|
|
5520
|
-
/* @__PURE__ */ (0,
|
|
5521
|
-
/* @__PURE__ */ (0,
|
|
6405
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
|
|
6406
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronDownIcon2, {})
|
|
5522
6407
|
] }) : null,
|
|
5523
|
-
variant === "ask" ? /* @__PURE__ */ (0,
|
|
5524
|
-
/* @__PURE__ */ (0,
|
|
5525
|
-
/* @__PURE__ */ (0,
|
|
5526
|
-
/* @__PURE__ */ (0,
|
|
6408
|
+
variant === "ask" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
6409
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronLeftIcon, {}),
|
|
6410
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
|
|
6411
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DragDots, {})
|
|
5527
6412
|
] }) : null,
|
|
5528
|
-
variant === "fill" ? /* @__PURE__ */ (0,
|
|
5529
|
-
/* @__PURE__ */ (0,
|
|
5530
|
-
/* @__PURE__ */ (0,
|
|
5531
|
-
showLogo ? /* @__PURE__ */ (0,
|
|
6413
|
+
variant === "fill" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
6414
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
|
|
6415
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
|
|
6416
|
+
showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5532
6417
|
"img",
|
|
5533
6418
|
{
|
|
5534
6419
|
className: "assist-edge-tab__logo",
|
|
@@ -5540,16 +6425,72 @@ function AssistEdgeTab({
|
|
|
5540
6425
|
}
|
|
5541
6426
|
) : null
|
|
5542
6427
|
] }),
|
|
5543
|
-
/* @__PURE__ */ (0,
|
|
5544
|
-
/* @__PURE__ */ (0,
|
|
6428
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
|
|
6429
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronLeftIcon, {})
|
|
5545
6430
|
] }) : null
|
|
5546
6431
|
]
|
|
5547
6432
|
}
|
|
5548
6433
|
);
|
|
5549
6434
|
}
|
|
5550
6435
|
|
|
6436
|
+
// src/react/lib/agent-feedback.ts
|
|
6437
|
+
var AGENT_ANSWER_FEEDBACK_EVENT_TYPE = "agent_answer_feedback";
|
|
6438
|
+
function findPrecedingVisitorText(messages, agentMessageId) {
|
|
6439
|
+
const agentIndex = messages.findIndex(
|
|
6440
|
+
(message) => message.id === agentMessageId && message.role === "agent"
|
|
6441
|
+
);
|
|
6442
|
+
if (agentIndex < 0) return void 0;
|
|
6443
|
+
for (let index = agentIndex - 1; index >= 0; index -= 1) {
|
|
6444
|
+
const message = messages[index];
|
|
6445
|
+
if (message?.role === "visitor") {
|
|
6446
|
+
return message.text.trim() || void 0;
|
|
6447
|
+
}
|
|
6448
|
+
}
|
|
6449
|
+
return void 0;
|
|
6450
|
+
}
|
|
6451
|
+
function normalizeAgentFeedbackAnswerText(text) {
|
|
6452
|
+
const normalized = text.replace(/\s+/g, " ").trim();
|
|
6453
|
+
if (!normalized) return void 0;
|
|
6454
|
+
return normalized.length > 4e3 ? `${normalized.slice(0, 3997)}...` : normalized;
|
|
6455
|
+
}
|
|
6456
|
+
function buildAgentAnswerFeedbackEvent(input) {
|
|
6457
|
+
const positive = input.rating === "positive";
|
|
6458
|
+
const answer = input.answer ? normalizeAgentFeedbackAnswerText(input.answer) : void 0;
|
|
6459
|
+
return {
|
|
6460
|
+
event_type: AGENT_ANSWER_FEEDBACK_EVENT_TYPE,
|
|
6461
|
+
company: input.analytics.companyIndex,
|
|
6462
|
+
session_id: input.visitorSessionId,
|
|
6463
|
+
page: input.page,
|
|
6464
|
+
timestamp: Date.now(),
|
|
6465
|
+
tracking_consent: input.analytics.trackingConsent,
|
|
6466
|
+
feedback_value: positive ? 1 : -1,
|
|
6467
|
+
// Aggregate-safe rating enum, kept even for anonymous (no-consent) events.
|
|
6468
|
+
feedback_rating: positive ? "helpful" : "not_helpful",
|
|
6469
|
+
surface: "agent_panel",
|
|
6470
|
+
index_id: input.indexId,
|
|
6471
|
+
index_version: input.version,
|
|
6472
|
+
message_id: input.messageId,
|
|
6473
|
+
...input.agentSessionId ? { agent_session_id: input.agentSessionId } : {},
|
|
6474
|
+
...input.analytics.trackingConsent && input.query ? { query: input.query } : {},
|
|
6475
|
+
...input.analytics.trackingConsent && answer ? { answer } : {}
|
|
6476
|
+
};
|
|
6477
|
+
}
|
|
6478
|
+
function sendAgentAnswerFeedback(eventUrl, event) {
|
|
6479
|
+
try {
|
|
6480
|
+
void fetch(eventUrl, {
|
|
6481
|
+
body: JSON.stringify(event),
|
|
6482
|
+
credentials: "omit",
|
|
6483
|
+
headers: { "Content-Type": "application/json" },
|
|
6484
|
+
keepalive: true,
|
|
6485
|
+
method: "POST"
|
|
6486
|
+
}).catch(() => {
|
|
6487
|
+
});
|
|
6488
|
+
} catch {
|
|
6489
|
+
}
|
|
6490
|
+
}
|
|
6491
|
+
|
|
5551
6492
|
// src/react/components/AgentWidget/AgentWidget.tsx
|
|
5552
|
-
var
|
|
6493
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
5553
6494
|
function AgentWidget({
|
|
5554
6495
|
indexId,
|
|
5555
6496
|
customerId,
|
|
@@ -5563,13 +6504,14 @@ function AgentWidget({
|
|
|
5563
6504
|
registerPanelController = false,
|
|
5564
6505
|
colorScheme = "auto",
|
|
5565
6506
|
branding,
|
|
6507
|
+
analytics,
|
|
5566
6508
|
toolResultRegistry
|
|
5567
6509
|
}) {
|
|
5568
6510
|
const isMobile = useIsMobile();
|
|
5569
6511
|
const placement = normalizeAgentPlacement(placementInput);
|
|
5570
|
-
const railSlotRef = (0,
|
|
5571
|
-
const [railCollapsed, setRailCollapsed] = (0,
|
|
5572
|
-
const [railExpanded, setRailExpanded] = (0,
|
|
6512
|
+
const railSlotRef = (0, import_react15.useRef)(null);
|
|
6513
|
+
const [railCollapsed, setRailCollapsed] = (0, import_react15.useState)(defaultCollapsed);
|
|
6514
|
+
const [railExpanded, setRailExpanded] = (0, import_react15.useState)(false);
|
|
5573
6515
|
const pageShiftActive = shouldApplyPageShift({
|
|
5574
6516
|
pageShift,
|
|
5575
6517
|
isMobile,
|
|
@@ -5580,7 +6522,17 @@ function AgentWidget({
|
|
|
5580
6522
|
active: pageShiftActive,
|
|
5581
6523
|
railSlotRef
|
|
5582
6524
|
});
|
|
5583
|
-
const {
|
|
6525
|
+
const {
|
|
6526
|
+
state,
|
|
6527
|
+
reset,
|
|
6528
|
+
retry,
|
|
6529
|
+
regenerate,
|
|
6530
|
+
respondToInput,
|
|
6531
|
+
respondToToolInput,
|
|
6532
|
+
submit,
|
|
6533
|
+
visitorSessionId,
|
|
6534
|
+
sessionId
|
|
6535
|
+
} = useAgentChat({
|
|
5584
6536
|
customerId,
|
|
5585
6537
|
getUnpublishedPreviewGrant,
|
|
5586
6538
|
indexId,
|
|
@@ -5612,7 +6564,7 @@ function AgentWidget({
|
|
|
5612
6564
|
} : {},
|
|
5613
6565
|
...branding?.colors?.border ? { border: branding.colors.border } : {}
|
|
5614
6566
|
};
|
|
5615
|
-
(0,
|
|
6567
|
+
(0, import_react15.useEffect)(() => {
|
|
5616
6568
|
if (!registerPanelController) return;
|
|
5617
6569
|
registerAgentPanelController(customerId, {
|
|
5618
6570
|
open: () => setRailCollapsed(false),
|
|
@@ -5629,7 +6581,25 @@ function AgentWidget({
|
|
|
5629
6581
|
if (isMobile) setRailCollapsed(false);
|
|
5630
6582
|
await submit(message);
|
|
5631
6583
|
}
|
|
5632
|
-
(
|
|
6584
|
+
function handleFeedback(rating, message) {
|
|
6585
|
+
if (!analytics) return;
|
|
6586
|
+
sendAgentAnswerFeedback(
|
|
6587
|
+
analytics.eventUrl,
|
|
6588
|
+
buildAgentAnswerFeedbackEvent({
|
|
6589
|
+
agentSessionId: sessionId,
|
|
6590
|
+
analytics,
|
|
6591
|
+
indexId,
|
|
6592
|
+
messageId: message.id,
|
|
6593
|
+
page: window.location.href,
|
|
6594
|
+
query: findPrecedingVisitorText(state.messages, message.id),
|
|
6595
|
+
answer: message.text,
|
|
6596
|
+
rating,
|
|
6597
|
+
version: version ?? "published",
|
|
6598
|
+
visitorSessionId
|
|
6599
|
+
})
|
|
6600
|
+
);
|
|
6601
|
+
}
|
|
6602
|
+
(0, import_react15.useEffect)(() => {
|
|
5633
6603
|
if (railCollapsed) return;
|
|
5634
6604
|
const handleKeyDown = (event) => {
|
|
5635
6605
|
if (event.key === "Tab" && (isMobile || railExpanded)) {
|
|
@@ -5663,19 +6633,19 @@ function AgentWidget({
|
|
|
5663
6633
|
window.addEventListener("keydown", handleKeyDown);
|
|
5664
6634
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
5665
6635
|
}, [isMobile, railCollapsed, railExpanded]);
|
|
5666
|
-
return /* @__PURE__ */ (0,
|
|
5667
|
-
/* @__PURE__ */ (0,
|
|
6636
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "webless-agent-root", children: [
|
|
6637
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5668
6638
|
"div",
|
|
5669
6639
|
{
|
|
5670
6640
|
className: `webless-agent-root__shell${railCollapsed ? " webless-agent-root__shell--collapsed" : ""}${railExpanded ? " webless-agent-root__shell--expanded" : ""}`,
|
|
5671
|
-
children: /* @__PURE__ */ (0,
|
|
6641
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5672
6642
|
"div",
|
|
5673
6643
|
{
|
|
5674
6644
|
ref: railSlotRef,
|
|
5675
6645
|
className: "webless-agent-root__rail-slot",
|
|
5676
6646
|
inert: railCollapsed || void 0,
|
|
5677
6647
|
"aria-hidden": railCollapsed,
|
|
5678
|
-
children: /* @__PURE__ */ (0,
|
|
6648
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5679
6649
|
AgentRail,
|
|
5680
6650
|
{
|
|
5681
6651
|
theme,
|
|
@@ -5684,6 +6654,9 @@ function AgentWidget({
|
|
|
5684
6654
|
brandLogoUrl: branding?.logoUrl,
|
|
5685
6655
|
composerPlaceholder: branding?.composerPlaceholder ?? "Ask a question\u2026",
|
|
5686
6656
|
poweredByLabel: branding?.poweredByLabel ?? "Powered by Webless",
|
|
6657
|
+
disclaimerLabel: branding?.disclaimer,
|
|
6658
|
+
answerReceipt: branding?.answerReceipt,
|
|
6659
|
+
readAloud: branding?.readAloud,
|
|
5687
6660
|
state,
|
|
5688
6661
|
mobileFullscreen: isMobile && !railCollapsed,
|
|
5689
6662
|
expanded: railExpanded,
|
|
@@ -5693,6 +6666,8 @@ function AgentWidget({
|
|
|
5693
6666
|
onSubmit: handleSubmit,
|
|
5694
6667
|
onReset: reset,
|
|
5695
6668
|
onRetry: () => void retry(),
|
|
6669
|
+
onRegenerate: () => void regenerate(),
|
|
6670
|
+
onFeedback: analytics ? handleFeedback : void 0,
|
|
5696
6671
|
onInputResponse: (response) => void respondToInput(response),
|
|
5697
6672
|
onToolInput: (surface, values) => void respondToToolInput(surface, values),
|
|
5698
6673
|
onFollowUpSelect: (label) => void handleSubmit(label),
|
|
@@ -5706,7 +6681,7 @@ function AgentWidget({
|
|
|
5706
6681
|
)
|
|
5707
6682
|
}
|
|
5708
6683
|
),
|
|
5709
|
-
railCollapsed ? /* @__PURE__ */ (0,
|
|
6684
|
+
railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5710
6685
|
AssistEdgeTab,
|
|
5711
6686
|
{
|
|
5712
6687
|
variant: placement.variant,
|
|
@@ -5745,12 +6720,12 @@ function readUnpublishedPreviewBuildId(href) {
|
|
|
5745
6720
|
}
|
|
5746
6721
|
|
|
5747
6722
|
// src/embed/AgentWidget.tsx
|
|
5748
|
-
var
|
|
6723
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
5749
6724
|
function AgentWidget2({
|
|
5750
6725
|
manifest
|
|
5751
6726
|
}) {
|
|
5752
6727
|
const defaultCollapsed = manifest.version !== "unpublished";
|
|
5753
|
-
return /* @__PURE__ */ (0,
|
|
6728
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5754
6729
|
AgentWidget,
|
|
5755
6730
|
{
|
|
5756
6731
|
indexId: manifest.indexId,
|
|
@@ -5762,6 +6737,7 @@ function AgentWidget2({
|
|
|
5762
6737
|
pageShift: manifest.pageShift,
|
|
5763
6738
|
colorScheme: manifest.colorScheme,
|
|
5764
6739
|
branding: manifest.branding,
|
|
6740
|
+
analytics: manifest.analytics,
|
|
5765
6741
|
defaultCollapsed,
|
|
5766
6742
|
registerPanelController: true
|
|
5767
6743
|
}
|
|
@@ -5792,6 +6768,7 @@ function normalizeAgentTagManifest(manifest) {
|
|
|
5792
6768
|
runtimeOrigin: manifest.runtimeOrigin?.trim() || DEFAULT_RUNTIME_ORIGIN
|
|
5793
6769
|
});
|
|
5794
6770
|
const branding = normalizeAgentBranding(manifest.branding);
|
|
6771
|
+
const analytics = normalizeAgentAnalytics(manifest.analytics);
|
|
5795
6772
|
return {
|
|
5796
6773
|
customerId,
|
|
5797
6774
|
indexId,
|
|
@@ -5804,7 +6781,27 @@ function normalizeAgentTagManifest(manifest) {
|
|
|
5804
6781
|
placement: normalizeAgentPlacement(manifest.placement),
|
|
5805
6782
|
pageShift: manifest.pageShift ?? true,
|
|
5806
6783
|
colorScheme,
|
|
5807
|
-
...branding ? { branding } : {}
|
|
6784
|
+
...branding ? { branding } : {},
|
|
6785
|
+
...analytics ? { analytics } : {}
|
|
6786
|
+
};
|
|
6787
|
+
}
|
|
6788
|
+
function normalizeAgentAnalytics(analytics) {
|
|
6789
|
+
if (!analytics) return void 0;
|
|
6790
|
+
const companyIndex = analytics.companyIndex?.trim() ?? "";
|
|
6791
|
+
const eventUrl = analytics.eventUrl?.trim() ?? "";
|
|
6792
|
+
if (!companyIndex || !eventUrl) return void 0;
|
|
6793
|
+
try {
|
|
6794
|
+
const parsed = new URL(eventUrl);
|
|
6795
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
|
|
6796
|
+
return void 0;
|
|
6797
|
+
}
|
|
6798
|
+
} catch {
|
|
6799
|
+
return void 0;
|
|
6800
|
+
}
|
|
6801
|
+
return {
|
|
6802
|
+
companyIndex,
|
|
6803
|
+
eventUrl,
|
|
6804
|
+
trackingConsent: analytics.trackingConsent === true
|
|
5808
6805
|
};
|
|
5809
6806
|
}
|
|
5810
6807
|
function normalizeOptionalValue(value) {
|
|
@@ -5827,6 +6824,9 @@ function normalizeAgentBranding(branding) {
|
|
|
5827
6824
|
greeting: normalizeOptionalValue(branding.greeting),
|
|
5828
6825
|
composerPlaceholder: normalizeOptionalValue(branding.composerPlaceholder),
|
|
5829
6826
|
poweredByLabel: normalizeOptionalValue(branding.poweredByLabel),
|
|
6827
|
+
disclaimer: branding.disclaimer === null ? null : normalizeOptionalValue(branding.disclaimer),
|
|
6828
|
+
answerReceipt: branding.answerReceipt === true ? true : void 0,
|
|
6829
|
+
readAloud: branding.readAloud === true ? true : void 0,
|
|
5830
6830
|
fontFamily: normalizeOptionalValue(branding.fontFamily),
|
|
5831
6831
|
colors: colors && Object.keys(colors).length > 0 ? colors : void 0
|
|
5832
6832
|
};
|
|
@@ -5834,7 +6834,7 @@ function normalizeAgentBranding(branding) {
|
|
|
5834
6834
|
}
|
|
5835
6835
|
|
|
5836
6836
|
// src/embed/mount.tsx
|
|
5837
|
-
var
|
|
6837
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
5838
6838
|
var mountedHandles = /* @__PURE__ */ new Map();
|
|
5839
6839
|
var latestCustomerId = null;
|
|
5840
6840
|
function resolveMountHost(manifest, script) {
|
|
@@ -5864,7 +6864,7 @@ function mountAgent(input) {
|
|
|
5864
6864
|
const host = createHost(manifest.customerId);
|
|
5865
6865
|
mountTarget.append(host);
|
|
5866
6866
|
const root = (0, import_client5.createRoot)(host);
|
|
5867
|
-
root.render(/* @__PURE__ */ (0,
|
|
6867
|
+
root.render(/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(AgentWidget2, { manifest }));
|
|
5868
6868
|
const handle = {
|
|
5869
6869
|
customerId: manifest.customerId,
|
|
5870
6870
|
manifest,
|