@webless/agent 0.6.10 → 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-NEI5GKGH.js → chunk-CYI3OSWG.js} +1741 -695
- package/dist/chunk-CYI3OSWG.js.map +1 -0
- package/dist/embed.cjs +1755 -687
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.css +359 -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-RhudtqWJ.d.cts → manifest-BNJQfEow.d.cts} +15 -2
- package/dist/{manifest-RhudtqWJ.d.ts → manifest-BNJQfEow.d.ts} +15 -2
- package/dist/react.cjs +1735 -682
- package/dist/react.cjs.map +1 -1
- package/dist/react.css +359 -3
- package/dist/react.css.map +1 -1
- package/dist/react.d.cts +67 -8
- package/dist/react.d.ts +67 -8
- package/dist/react.js +11 -1
- package/package.json +1 -1
- package/dist/chunk-NEI5GKGH.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()
|
|
@@ -2302,6 +2355,30 @@ function bookingPresenter(kind) {
|
|
|
2302
2355
|
}
|
|
2303
2356
|
};
|
|
2304
2357
|
}
|
|
2358
|
+
function providerErrorPresenter() {
|
|
2359
|
+
return {
|
|
2360
|
+
kind: "provider_error",
|
|
2361
|
+
present: ({ envelope }) => {
|
|
2362
|
+
const output = asRecord3(envelope.output);
|
|
2363
|
+
const providerError = asRecord3(output?.providerError);
|
|
2364
|
+
const message = safeText(providerError?.message);
|
|
2365
|
+
const action = safeText(providerError?.action);
|
|
2366
|
+
if (!message || !action) return null;
|
|
2367
|
+
const resourceLabels = Array.isArray(providerError?.resourceLabels) ? providerError.resourceLabels.map(safeText).filter(Boolean).slice(0, MAX_DETAILS) : [];
|
|
2368
|
+
return {
|
|
2369
|
+
kind: "summary",
|
|
2370
|
+
status: "failed",
|
|
2371
|
+
title: message,
|
|
2372
|
+
description: action,
|
|
2373
|
+
...resourceLabels.length ? {
|
|
2374
|
+
details: [
|
|
2375
|
+
{ label: "Affected", value: resourceLabels.join(", ") }
|
|
2376
|
+
]
|
|
2377
|
+
} : {}
|
|
2378
|
+
};
|
|
2379
|
+
}
|
|
2380
|
+
};
|
|
2381
|
+
}
|
|
2305
2382
|
function asRecord3(value) {
|
|
2306
2383
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
2307
2384
|
}
|
|
@@ -2419,6 +2496,7 @@ function fallbackTitleFromKind(kind) {
|
|
|
2419
2496
|
return "Saved";
|
|
2420
2497
|
}
|
|
2421
2498
|
var builtInVisitorToolResultRegistry = [
|
|
2499
|
+
providerErrorPresenter(),
|
|
2422
2500
|
bookingPresenter("booking_offer"),
|
|
2423
2501
|
bookingPresenter("booking_confirmed"),
|
|
2424
2502
|
bookingPresenter("booking_canceled"),
|
|
@@ -2468,7 +2546,7 @@ function finalizeSummaryPresentation(result, proposed) {
|
|
|
2468
2546
|
return {
|
|
2469
2547
|
id: result.callId,
|
|
2470
2548
|
toolName: result.toolName,
|
|
2471
|
-
status: result.status,
|
|
2549
|
+
status: proposed.status ?? result.status,
|
|
2472
2550
|
kind: "summary",
|
|
2473
2551
|
title,
|
|
2474
2552
|
...description && description !== title ? { description } : {},
|
|
@@ -2477,7 +2555,7 @@ function finalizeSummaryPresentation(result, proposed) {
|
|
|
2477
2555
|
};
|
|
2478
2556
|
}
|
|
2479
2557
|
function presentVisitorToolResult(result, registry = []) {
|
|
2480
|
-
const envelope = parseAgentToolResultEnvelope(result.output) ?? legacyBookingEnvelope(result.output);
|
|
2558
|
+
const envelope = parseAgentToolResultEnvelope(result.output) ?? providerErrorEnvelope(result.output) ?? legacyBookingEnvelope(result.output);
|
|
2481
2559
|
const proposed = envelope ? resolvePresenterOutput(result, envelope, registry) : null;
|
|
2482
2560
|
if (proposed?.kind === "booking") {
|
|
2483
2561
|
return {
|
|
@@ -2540,6 +2618,25 @@ function presentVisitorToolResult(result, registry = []) {
|
|
|
2540
2618
|
}
|
|
2541
2619
|
return finalizeSummaryPresentation(result, proposed);
|
|
2542
2620
|
}
|
|
2621
|
+
function providerErrorEnvelope(output) {
|
|
2622
|
+
const record = asRecord3(output);
|
|
2623
|
+
const providerError = asRecord3(record?.providerError);
|
|
2624
|
+
const message = safeText(providerError?.message);
|
|
2625
|
+
const action = safeText(providerError?.action);
|
|
2626
|
+
if (!message || !action) return null;
|
|
2627
|
+
const resourceLabels = Array.isArray(providerError?.resourceLabels) ? providerError.resourceLabels.map(safeText).filter(Boolean).slice(0, MAX_DETAILS) : [];
|
|
2628
|
+
return {
|
|
2629
|
+
schemaVersion: "webless.tool-result.v1",
|
|
2630
|
+
output: {
|
|
2631
|
+
providerError: {
|
|
2632
|
+
action,
|
|
2633
|
+
message,
|
|
2634
|
+
...resourceLabels.length ? { resourceLabels } : {}
|
|
2635
|
+
}
|
|
2636
|
+
},
|
|
2637
|
+
presentationKinds: ["provider_error"]
|
|
2638
|
+
};
|
|
2639
|
+
}
|
|
2543
2640
|
function legacyBookingEnvelope(output) {
|
|
2544
2641
|
const card = bookingCardFromActionOutput(output);
|
|
2545
2642
|
return card ? {
|
|
@@ -2837,6 +2934,7 @@ function useAgentChat({
|
|
|
2837
2934
|
const {
|
|
2838
2935
|
controller,
|
|
2839
2936
|
initialText = "",
|
|
2937
|
+
regenerate: regenerate2 = false,
|
|
2840
2938
|
responses,
|
|
2841
2939
|
resume,
|
|
2842
2940
|
visitorText
|
|
@@ -2847,6 +2945,7 @@ function useAgentChat({
|
|
|
2847
2945
|
let streamStarted = Boolean(initialText);
|
|
2848
2946
|
let streamed = initialText;
|
|
2849
2947
|
const capturedOffers = [];
|
|
2948
|
+
let bookingConfirmed = false;
|
|
2850
2949
|
let capturedInputCount = 0;
|
|
2851
2950
|
const handlers = {
|
|
2852
2951
|
onWork: (item) => {
|
|
@@ -2871,6 +2970,7 @@ function useAgentChat({
|
|
|
2871
2970
|
}
|
|
2872
2971
|
if (!isActiveRun()) return;
|
|
2873
2972
|
if (card.type === "booking_confirmed") {
|
|
2973
|
+
bookingConfirmed = true;
|
|
2874
2974
|
pendingBookingRef.current = card;
|
|
2875
2975
|
savePendingWidgetBooking(
|
|
2876
2976
|
resolvedStorageKeyPrefix,
|
|
@@ -2946,7 +3046,13 @@ function useAgentChat({
|
|
|
2946
3046
|
initialText,
|
|
2947
3047
|
message: visitorText,
|
|
2948
3048
|
signal
|
|
2949
|
-
}) : await clientRef.current.
|
|
3049
|
+
}) : regenerate2 ? await clientRef.current.regenerateTurn(visitorText, {
|
|
3050
|
+
handlers,
|
|
3051
|
+
signal
|
|
3052
|
+
}) : await clientRef.current.sendTurn(visitorText, {
|
|
3053
|
+
handlers,
|
|
3054
|
+
signal
|
|
3055
|
+
});
|
|
2950
3056
|
if (resume && finalText === null) {
|
|
2951
3057
|
finalText = await clientRef.current.sendTurn(visitorText, {
|
|
2952
3058
|
handlers,
|
|
@@ -2965,6 +3071,7 @@ function useAgentChat({
|
|
|
2965
3071
|
const parsedCards = extractToolCards(displayText);
|
|
2966
3072
|
for (const card of parsedCards) {
|
|
2967
3073
|
if (card.type === "booking_confirmed") {
|
|
3074
|
+
bookingConfirmed = true;
|
|
2968
3075
|
pendingBookingRef.current = card;
|
|
2969
3076
|
savePendingWidgetBooking(resolvedStorageKeyPrefix, visitorId, card);
|
|
2970
3077
|
}
|
|
@@ -2979,7 +3086,7 @@ function useAgentChat({
|
|
|
2979
3086
|
messages: appendAgentTurnMessage(prev.messages, displayText),
|
|
2980
3087
|
toolSteps: completeActivePlanning(prev.toolSteps),
|
|
2981
3088
|
streamingText: "",
|
|
2982
|
-
pendingOffer: capturedOffers.at(-1) ?? prev.pendingOffer,
|
|
3089
|
+
pendingOffer: bookingConfirmed ? null : capturedOffers.at(-1) ?? prev.pendingOffer,
|
|
2983
3090
|
pendingInputs: (prev.pendingInputs ?? []).filter(
|
|
2984
3091
|
isChatCollectibleInputRequest
|
|
2985
3092
|
),
|
|
@@ -3005,7 +3112,6 @@ function useAgentChat({
|
|
|
3005
3112
|
} : step
|
|
3006
3113
|
),
|
|
3007
3114
|
streamingText: "",
|
|
3008
|
-
pendingOffer: null,
|
|
3009
3115
|
error: message
|
|
3010
3116
|
}));
|
|
3011
3117
|
runRef.current = null;
|
|
@@ -3113,7 +3219,7 @@ ${outgoing}` : outgoing;
|
|
|
3113
3219
|
journey: null,
|
|
3114
3220
|
followUps: [],
|
|
3115
3221
|
streamingText: "",
|
|
3116
|
-
pendingOffer: null,
|
|
3222
|
+
pendingOffer: options?.preservePendingOffer ? prev.pendingOffer : null,
|
|
3117
3223
|
pendingInputs: [],
|
|
3118
3224
|
toolResults: [],
|
|
3119
3225
|
error: null
|
|
@@ -3149,7 +3255,6 @@ ${outgoing}` : outgoing;
|
|
|
3149
3255
|
journey: null,
|
|
3150
3256
|
followUps: [],
|
|
3151
3257
|
streamingText: "",
|
|
3152
|
-
pendingOffer: null,
|
|
3153
3258
|
pendingInputs: [],
|
|
3154
3259
|
toolResults: [],
|
|
3155
3260
|
error: null
|
|
@@ -3160,6 +3265,49 @@ ${outgoing}` : outgoing;
|
|
|
3160
3265
|
visitorText: visitorTurnText(visitorMessage)
|
|
3161
3266
|
});
|
|
3162
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]);
|
|
3163
3311
|
const respondToToolInput = (0, import_react2.useCallback)(
|
|
3164
3312
|
async (surface, values) => {
|
|
3165
3313
|
await submit(`${surface.title} submitted`, {
|
|
@@ -3236,6 +3384,7 @@ ${outgoing}` : outgoing;
|
|
|
3236
3384
|
state,
|
|
3237
3385
|
reset,
|
|
3238
3386
|
retry,
|
|
3387
|
+
regenerate,
|
|
3239
3388
|
respondToInput,
|
|
3240
3389
|
respondToToolInput,
|
|
3241
3390
|
submit,
|
|
@@ -3286,7 +3435,7 @@ function normalizeAgentPlacement(placement) {
|
|
|
3286
3435
|
}
|
|
3287
3436
|
|
|
3288
3437
|
// src/react/components/AgentRail/AgentRail.tsx
|
|
3289
|
-
var
|
|
3438
|
+
var import_react14 = require("react");
|
|
3290
3439
|
|
|
3291
3440
|
// src/react/types/conversation.ts
|
|
3292
3441
|
var defaultAgentRailTheme = {
|
|
@@ -3408,6 +3557,60 @@ function stepDetail(step, steps) {
|
|
|
3408
3557
|
return "Searched this site";
|
|
3409
3558
|
return step.detail;
|
|
3410
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
|
+
}
|
|
3411
3614
|
function AgentActivityBubble({
|
|
3412
3615
|
brandLabel = "",
|
|
3413
3616
|
failed = false,
|
|
@@ -3419,14 +3622,7 @@ function AgentActivityBubble({
|
|
|
3419
3622
|
const [expandedReceiptId, setExpandedReceiptId] = (0, import_react5.useState)(
|
|
3420
3623
|
null
|
|
3421
3624
|
);
|
|
3422
|
-
const detailsOpen = active
|
|
3423
|
-
const delegationCount = steps.filter(
|
|
3424
|
-
(step) => step.kind === "specialist"
|
|
3425
|
-
).length;
|
|
3426
|
-
const delegated = delegationCount > 0 && steps.some((step) => step.kind === "planning");
|
|
3427
|
-
const visibleSteps = steps.filter(
|
|
3428
|
-
(step) => step.kind !== "planning" || Boolean(brandLabel)
|
|
3429
|
-
);
|
|
3625
|
+
const detailsOpen = !active && expandedReceiptId === receiptId;
|
|
3430
3626
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", { className: "agent-activity-bubble", children: [
|
|
3431
3627
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "agent-activity-bubble__status", "aria-live": "polite", children: [
|
|
3432
3628
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -3436,9 +3632,10 @@ function AgentActivityBubble({
|
|
|
3436
3632
|
"aria-hidden": "true"
|
|
3437
3633
|
}
|
|
3438
3634
|
),
|
|
3439
|
-
workSummary(steps, failed, brandLabel)
|
|
3635
|
+
workSummary(steps, failed, brandLabel),
|
|
3636
|
+
active ? "\u2026" : ""
|
|
3440
3637
|
] }),
|
|
3441
|
-
/* @__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: [
|
|
3442
3639
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3443
3640
|
"button",
|
|
3444
3641
|
{
|
|
@@ -3446,7 +3643,6 @@ function AgentActivityBubble({
|
|
|
3446
3643
|
className: "agent-activity-bubble__summary",
|
|
3447
3644
|
"aria-expanded": detailsOpen,
|
|
3448
3645
|
onClick: () => {
|
|
3449
|
-
if (active) return;
|
|
3450
3646
|
setExpandedReceiptId(
|
|
3451
3647
|
(current) => current === receiptId ? null : receiptId
|
|
3452
3648
|
);
|
|
@@ -3454,56 +3650,145 @@ function AgentActivityBubble({
|
|
|
3454
3650
|
children: "How this answer was made"
|
|
3455
3651
|
}
|
|
3456
3652
|
),
|
|
3457
|
-
detailsOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
children: [
|
|
3467
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3468
|
-
"span",
|
|
3469
|
-
{
|
|
3470
|
-
className: "agent-activity-bubble__step-icon",
|
|
3471
|
-
"aria-hidden": "true"
|
|
3472
|
-
}
|
|
3473
|
-
),
|
|
3474
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__step-copy", children: [
|
|
3475
|
-
/* @__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) }) }),
|
|
3476
|
-
detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-activity-bubble__step-detail", children: detail }) : null,
|
|
3477
|
-
delegated && step.kind === "planning" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__delegation", children: [
|
|
3478
|
-
"Delegated ",
|
|
3479
|
-
delegationCount,
|
|
3480
|
-
" ",
|
|
3481
|
-
delegationCount === 1 ? "task" : "tasks"
|
|
3482
|
-
] }) : null,
|
|
3483
|
-
step.state === "error" && onRetryStep ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3484
|
-
"button",
|
|
3485
|
-
{
|
|
3486
|
-
type: "button",
|
|
3487
|
-
className: "agent-activity-bubble__step-retry",
|
|
3488
|
-
onClick: () => onRetryStep(step),
|
|
3489
|
-
children: "Retry"
|
|
3490
|
-
}
|
|
3491
|
-
) : null
|
|
3492
|
-
] })
|
|
3493
|
-
]
|
|
3494
|
-
},
|
|
3495
|
-
step.id
|
|
3496
|
-
);
|
|
3497
|
-
}) }) : null
|
|
3498
|
-
] })
|
|
3653
|
+
detailsOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3654
|
+
AgentWorkSteps,
|
|
3655
|
+
{
|
|
3656
|
+
brandLabel,
|
|
3657
|
+
onRetryStep,
|
|
3658
|
+
steps
|
|
3659
|
+
}
|
|
3660
|
+
) : null
|
|
3661
|
+
] }) : null
|
|
3499
3662
|
] });
|
|
3500
3663
|
}
|
|
3501
3664
|
|
|
3502
|
-
// 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
|
|
3503
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
|
|
3504
3680
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
3505
|
-
|
|
3681
|
+
var FOCUSABLE_SELECTOR = 'button:not(:disabled), a[href], textarea:not(:disabled), input:not(:disabled), [tabindex]:not([tabindex="-1"])';
|
|
3682
|
+
function CloseIcon() {
|
|
3506
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)(
|
|
3507
3792
|
"path",
|
|
3508
3793
|
{
|
|
3509
3794
|
d: "M8 12V4M8 4l-3 3M8 4l3 3",
|
|
@@ -3526,21 +3811,21 @@ function Composer({
|
|
|
3526
3811
|
form = null,
|
|
3527
3812
|
onSubmit
|
|
3528
3813
|
}) {
|
|
3529
|
-
const [value, setValue] = (0,
|
|
3530
|
-
const [values, setValues] = (0,
|
|
3814
|
+
const [value, setValue] = (0, import_react8.useState)("");
|
|
3815
|
+
const [values, setValues] = (0, import_react8.useState)(
|
|
3531
3816
|
() => emptyValues(form)
|
|
3532
3817
|
);
|
|
3533
|
-
const [blurred, setBlurred] = (0,
|
|
3534
|
-
const inputRef = (0,
|
|
3535
|
-
const firstFieldRef = (0,
|
|
3536
|
-
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)();
|
|
3537
3822
|
const activeForm = form;
|
|
3538
3823
|
const canSendForm = activeForm ? isComposerFormComplete(activeForm, values) : Boolean(value.trim());
|
|
3539
|
-
(0,
|
|
3824
|
+
(0, import_react8.useEffect)(() => {
|
|
3540
3825
|
setValues(emptyValues(form));
|
|
3541
3826
|
setBlurred({});
|
|
3542
3827
|
}, [form?.id]);
|
|
3543
|
-
(0,
|
|
3828
|
+
(0, import_react8.useEffect)(() => {
|
|
3544
3829
|
if (activeForm) firstFieldRef.current?.focus();
|
|
3545
3830
|
}, [activeForm?.id]);
|
|
3546
3831
|
function submitChat() {
|
|
@@ -3575,7 +3860,7 @@ function Composer({
|
|
|
3575
3860
|
submitForm();
|
|
3576
3861
|
}
|
|
3577
3862
|
}
|
|
3578
|
-
return /* @__PURE__ */ (0,
|
|
3863
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3579
3864
|
"form",
|
|
3580
3865
|
{
|
|
3581
3866
|
className: [
|
|
@@ -3584,7 +3869,7 @@ function Composer({
|
|
|
3584
3869
|
activeForm ? "composer--form" : ""
|
|
3585
3870
|
].filter(Boolean).join(" "),
|
|
3586
3871
|
onSubmit: handleSubmit,
|
|
3587
|
-
children: activeForm ? /* @__PURE__ */ (0,
|
|
3872
|
+
children: activeForm ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "composer__sheet", role: "group", "aria-label": "Required details", children: [
|
|
3588
3873
|
activeForm.fields.map((field, index) => {
|
|
3589
3874
|
const fieldId = `${formId}-${field.id}`;
|
|
3590
3875
|
const invalid = Boolean(blurred[field.id]) && !isValidComposerFieldValue(field, values[field.id] ?? "");
|
|
@@ -3609,7 +3894,7 @@ function Composer({
|
|
|
3609
3894
|
},
|
|
3610
3895
|
onKeyDown: handleFormKeyDown
|
|
3611
3896
|
};
|
|
3612
|
-
return /* @__PURE__ */ (0,
|
|
3897
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
3613
3898
|
"div",
|
|
3614
3899
|
{
|
|
3615
3900
|
className: [
|
|
@@ -3617,9 +3902,9 @@ function Composer({
|
|
|
3617
3902
|
field.kind === "textarea" ? "composer__row--grow" : ""
|
|
3618
3903
|
].filter(Boolean).join(" "),
|
|
3619
3904
|
children: [
|
|
3620
|
-
/* @__PURE__ */ (0,
|
|
3621
|
-
/* @__PURE__ */ (0,
|
|
3622
|
-
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)(
|
|
3623
3908
|
"textarea",
|
|
3624
3909
|
{
|
|
3625
3910
|
...controlProps,
|
|
@@ -3629,7 +3914,7 @@ function Composer({
|
|
|
3629
3914
|
className: "composer__control composer__control--area",
|
|
3630
3915
|
rows: 3
|
|
3631
3916
|
}
|
|
3632
|
-
) : /* @__PURE__ */ (0,
|
|
3917
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3633
3918
|
"input",
|
|
3634
3919
|
{
|
|
3635
3920
|
...controlProps,
|
|
@@ -3642,24 +3927,24 @@ function Composer({
|
|
|
3642
3927
|
}
|
|
3643
3928
|
)
|
|
3644
3929
|
] }),
|
|
3645
|
-
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
|
|
3646
3931
|
]
|
|
3647
3932
|
},
|
|
3648
3933
|
field.id
|
|
3649
3934
|
);
|
|
3650
3935
|
}),
|
|
3651
|
-
/* @__PURE__ */ (0,
|
|
3936
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "composer__toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3652
3937
|
"button",
|
|
3653
3938
|
{
|
|
3654
3939
|
type: "submit",
|
|
3655
3940
|
className: "composer__send",
|
|
3656
3941
|
disabled: disabled || !canSendForm,
|
|
3657
3942
|
"aria-label": "Send details",
|
|
3658
|
-
children: /* @__PURE__ */ (0,
|
|
3943
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SendIcon, {})
|
|
3659
3944
|
}
|
|
3660
3945
|
) })
|
|
3661
|
-
] }) : /* @__PURE__ */ (0,
|
|
3662
|
-
/* @__PURE__ */ (0,
|
|
3946
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "composer__field", children: [
|
|
3947
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3663
3948
|
"textarea",
|
|
3664
3949
|
{
|
|
3665
3950
|
ref: inputRef,
|
|
@@ -3674,14 +3959,14 @@ function Composer({
|
|
|
3674
3959
|
onKeyDown: handleChatKeyDown
|
|
3675
3960
|
}
|
|
3676
3961
|
),
|
|
3677
|
-
/* @__PURE__ */ (0,
|
|
3962
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3678
3963
|
"button",
|
|
3679
3964
|
{
|
|
3680
3965
|
type: "submit",
|
|
3681
3966
|
className: "composer__send",
|
|
3682
3967
|
disabled: disabled || !value.trim(),
|
|
3683
3968
|
"aria-label": "Send message",
|
|
3684
|
-
children: /* @__PURE__ */ (0,
|
|
3969
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SendIcon, {})
|
|
3685
3970
|
}
|
|
3686
3971
|
)
|
|
3687
3972
|
] })
|
|
@@ -3690,7 +3975,7 @@ function Composer({
|
|
|
3690
3975
|
}
|
|
3691
3976
|
|
|
3692
3977
|
// src/react/components/FollowUpChips/FollowUpChips.tsx
|
|
3693
|
-
var
|
|
3978
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
3694
3979
|
function FollowUpChips({
|
|
3695
3980
|
suggestions,
|
|
3696
3981
|
disabled = false,
|
|
@@ -3700,7 +3985,7 @@ function FollowUpChips({
|
|
|
3700
3985
|
}) {
|
|
3701
3986
|
if (suggestions.length === 0) return null;
|
|
3702
3987
|
if (variant === "dock") {
|
|
3703
|
-
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)(
|
|
3704
3989
|
"button",
|
|
3705
3990
|
{
|
|
3706
3991
|
type: "button",
|
|
@@ -3712,9 +3997,9 @@ function FollowUpChips({
|
|
|
3712
3997
|
suggestion.id
|
|
3713
3998
|
)) }) });
|
|
3714
3999
|
}
|
|
3715
|
-
return /* @__PURE__ */ (0,
|
|
3716
|
-
/* @__PURE__ */ (0,
|
|
3717
|
-
/* @__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)(
|
|
3718
4003
|
"button",
|
|
3719
4004
|
{
|
|
3720
4005
|
type: "button",
|
|
@@ -3729,11 +4014,11 @@ function FollowUpChips({
|
|
|
3729
4014
|
}
|
|
3730
4015
|
|
|
3731
4016
|
// src/react/components/MessageBubble/MessageBubble.tsx
|
|
3732
|
-
var
|
|
4017
|
+
var import_react10 = require("react");
|
|
3733
4018
|
|
|
3734
4019
|
// src/react/components/BookingCard/BookingCard.tsx
|
|
3735
|
-
var
|
|
3736
|
-
var
|
|
4020
|
+
var import_react9 = require("react");
|
|
4021
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
3737
4022
|
var BOOKING_STEPS = [
|
|
3738
4023
|
{ id: "date", label: "Date" },
|
|
3739
4024
|
{ id: "time", label: "Time" },
|
|
@@ -3764,33 +4049,34 @@ function calendarCells(year, month) {
|
|
|
3764
4049
|
return cells;
|
|
3765
4050
|
}
|
|
3766
4051
|
function BookingCardLoader() {
|
|
3767
|
-
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" }) });
|
|
3768
4053
|
}
|
|
3769
4054
|
function BookingCard({
|
|
4055
|
+
disabled = false,
|
|
3770
4056
|
offer,
|
|
3771
4057
|
onBook
|
|
3772
4058
|
}) {
|
|
3773
|
-
const fieldId = (0,
|
|
4059
|
+
const fieldId = (0, import_react9.useId)();
|
|
3774
4060
|
const defaultType = offer.eventTypes[0]?.uri ?? offer.slots[0]?.eventTypeUri ?? "";
|
|
3775
|
-
const [step, setStep] = (0,
|
|
3776
|
-
const [eventTypeUri, setEventTypeUri] = (0,
|
|
3777
|
-
const [selectedDate, setSelectedDate] = (0,
|
|
3778
|
-
const [startTime, setStartTime] = (0,
|
|
3779
|
-
const [name, setName] = (0,
|
|
3780
|
-
const [email, setEmail] = (0,
|
|
3781
|
-
const activeStepRef = (0,
|
|
3782
|
-
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);
|
|
3783
4069
|
const stepIndex = BOOKING_STEPS.findIndex((item) => item.id === step);
|
|
3784
|
-
(0,
|
|
4070
|
+
(0, import_react9.useEffect)(() => {
|
|
3785
4071
|
if (previousStepRef.current === step) return;
|
|
3786
4072
|
previousStepRef.current = step;
|
|
3787
4073
|
activeStepRef.current?.scrollIntoView({ block: "nearest" });
|
|
3788
4074
|
}, [step]);
|
|
3789
|
-
const slots = (0,
|
|
4075
|
+
const slots = (0, import_react9.useMemo)(
|
|
3790
4076
|
() => bookingSlotsForEventType(offer.slots, eventTypeUri),
|
|
3791
4077
|
[eventTypeUri, offer.slots]
|
|
3792
4078
|
);
|
|
3793
|
-
const availableByDate = (0,
|
|
4079
|
+
const availableByDate = (0, import_react9.useMemo)(() => {
|
|
3794
4080
|
const next = /* @__PURE__ */ new Map();
|
|
3795
4081
|
for (const slot of slots) {
|
|
3796
4082
|
const key = slotDateKey(slot.startTime);
|
|
@@ -3798,7 +4084,7 @@ function BookingCard({
|
|
|
3798
4084
|
}
|
|
3799
4085
|
return next;
|
|
3800
4086
|
}, [slots]);
|
|
3801
|
-
const [visibleMonth, setVisibleMonth] = (0,
|
|
4087
|
+
const [visibleMonth, setVisibleMonth] = (0, import_react9.useState)(
|
|
3802
4088
|
() => firstAvailableBookingMonth(slots)
|
|
3803
4089
|
);
|
|
3804
4090
|
function selectEventType(nextType) {
|
|
@@ -3811,7 +4097,7 @@ function BookingCard({
|
|
|
3811
4097
|
)
|
|
3812
4098
|
);
|
|
3813
4099
|
}
|
|
3814
|
-
const daySlots = (0,
|
|
4100
|
+
const daySlots = (0, import_react9.useMemo)(
|
|
3815
4101
|
() => slots.filter((slot) => slotDateKey(slot.startTime) === selectedDate),
|
|
3816
4102
|
[selectedDate, slots]
|
|
3817
4103
|
);
|
|
@@ -3820,7 +4106,7 @@ function BookingCard({
|
|
|
3820
4106
|
);
|
|
3821
4107
|
const selectedSample = availableByDate.get(selectedDate) ?? startTime;
|
|
3822
4108
|
const timeZone = formatSlotTimeZone(slots[0]?.startTime ?? selectedSample);
|
|
3823
|
-
const weekdays = (0,
|
|
4109
|
+
const weekdays = (0, import_react9.useMemo)(() => weekdayLabels(), []);
|
|
3824
4110
|
const cells = calendarCells(visibleMonth.year, visibleMonth.month);
|
|
3825
4111
|
const canPrevMonth = [...availableByDate.keys()].some((key) => {
|
|
3826
4112
|
const month = monthFromKey(key);
|
|
@@ -3862,222 +4148,236 @@ function BookingCard({
|
|
|
3862
4148
|
})
|
|
3863
4149
|
});
|
|
3864
4150
|
}
|
|
3865
|
-
return /* @__PURE__ */ (0,
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
"aria-current": index === stepIndex ? "step" : void 0,
|
|
3875
|
-
children: [
|
|
3876
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { "aria-hidden": "true", children: index + 1 }),
|
|
3877
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: item.label })
|
|
3878
|
-
]
|
|
3879
|
-
},
|
|
3880
|
-
item.id
|
|
3881
|
-
)) }),
|
|
3882
|
-
step === "date" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
|
|
3883
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__title", children: selectedType?.name || "Pick a date" }),
|
|
3884
|
-
timeZone ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "booking-card__tz", children: [
|
|
3885
|
-
"Times in ",
|
|
3886
|
-
timeZone
|
|
3887
|
-
] }) : null,
|
|
3888
|
-
offer.eventTypes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
3889
|
-
"label",
|
|
3890
|
-
{
|
|
3891
|
-
className: "booking-card__field",
|
|
3892
|
-
htmlFor: `${fieldId}-type`,
|
|
3893
|
-
children: [
|
|
3894
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Meeting" }),
|
|
3895
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3896
|
-
"select",
|
|
3897
|
-
{
|
|
3898
|
-
id: `${fieldId}-type`,
|
|
3899
|
-
value: eventTypeUri,
|
|
3900
|
-
onChange: (event) => selectEventType(event.target.value),
|
|
3901
|
-
children: offer.eventTypes.map((item) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: item.uri, children: item.name }, item.uri))
|
|
3902
|
-
}
|
|
3903
|
-
)
|
|
3904
|
-
]
|
|
3905
|
-
}
|
|
3906
|
-
) : null,
|
|
3907
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__month", children: [
|
|
3908
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3909
|
-
"button",
|
|
3910
|
-
{
|
|
3911
|
-
type: "button",
|
|
3912
|
-
className: "booking-card__nav",
|
|
3913
|
-
"aria-label": "Previous month",
|
|
3914
|
-
disabled: !canPrevMonth,
|
|
3915
|
-
onClick: () => goToMonth(-1),
|
|
3916
|
-
children: "\u2039"
|
|
3917
|
-
}
|
|
3918
|
-
),
|
|
3919
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__month-title", children: formatMonthTitle(visibleMonth.year, visibleMonth.month) }),
|
|
3920
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3921
|
-
"button",
|
|
4151
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
4152
|
+
"section",
|
|
4153
|
+
{
|
|
4154
|
+
className: "booking-card",
|
|
4155
|
+
"aria-busy": disabled || void 0,
|
|
4156
|
+
"aria-label": "Book a meeting",
|
|
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)(
|
|
4159
|
+
"li",
|
|
3922
4160
|
{
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
{
|
|
3937
|
-
className: "booking-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
4161
|
+
className: [
|
|
4162
|
+
"booking-card__step-indicator",
|
|
4163
|
+
index === stepIndex ? "booking-card__step-indicator--active" : "",
|
|
4164
|
+
index < stepIndex ? "booking-card__step-indicator--complete" : ""
|
|
4165
|
+
].filter(Boolean).join(" "),
|
|
4166
|
+
"aria-current": index === stepIndex ? "step" : void 0,
|
|
4167
|
+
children: [
|
|
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 })
|
|
4170
|
+
]
|
|
4171
|
+
},
|
|
4172
|
+
item.id
|
|
4173
|
+
)) }),
|
|
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: [
|
|
4177
|
+
"Times in ",
|
|
4178
|
+
timeZone
|
|
4179
|
+
] }) : null,
|
|
4180
|
+
offer.eventTypes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
4181
|
+
"label",
|
|
4182
|
+
{
|
|
4183
|
+
className: "booking-card__field",
|
|
4184
|
+
htmlFor: `${fieldId}-type`,
|
|
4185
|
+
children: [
|
|
4186
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Meeting" }),
|
|
4187
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
4188
|
+
"select",
|
|
4189
|
+
{
|
|
4190
|
+
id: `${fieldId}-type`,
|
|
4191
|
+
value: eventTypeUri,
|
|
4192
|
+
disabled,
|
|
4193
|
+
onChange: (event) => selectEventType(event.target.value),
|
|
4194
|
+
children: offer.eventTypes.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: item.uri, children: item.name }, item.uri))
|
|
4195
|
+
}
|
|
4196
|
+
)
|
|
4197
|
+
]
|
|
3949
4198
|
}
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
4199
|
+
) : null,
|
|
4200
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__month", children: [
|
|
4201
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3953
4202
|
"button",
|
|
3954
4203
|
{
|
|
3955
4204
|
type: "button",
|
|
3956
|
-
className:
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
{
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
"
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
"button",
|
|
3994
|
-
{
|
|
3995
|
-
type: "button",
|
|
3996
|
-
className: startTime === slot.startTime ? "booking-card__time booking-card__time--selected" : "booking-card__time",
|
|
3997
|
-
onClick: () => selectTime(slot.startTime),
|
|
3998
|
-
children: formatTimeChip(slot.startTime)
|
|
3999
|
-
},
|
|
4000
|
-
slot.startTime
|
|
4001
|
-
)) })
|
|
4002
|
-
] }, "time") : null,
|
|
4003
|
-
step === "details" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
|
|
4004
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__step-bar", children: [
|
|
4005
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
4006
|
-
"button",
|
|
4007
|
-
{
|
|
4008
|
-
type: "button",
|
|
4009
|
-
className: "booking-card__nav",
|
|
4010
|
-
"aria-label": "Back to times",
|
|
4011
|
-
onClick: () => setStep("time"),
|
|
4012
|
-
children: "\u2039"
|
|
4013
|
-
}
|
|
4014
|
-
),
|
|
4015
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
|
|
4016
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__title", children: "Enter details" }),
|
|
4017
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__tz", children: formatSlotLabel(startTime) }),
|
|
4018
|
-
selectedType?.location ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__tz", children: selectedType.location }) : null
|
|
4019
|
-
] })
|
|
4020
|
-
] }),
|
|
4021
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__identity", children: [
|
|
4022
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
4023
|
-
"label",
|
|
4024
|
-
{
|
|
4025
|
-
className: "booking-card__field",
|
|
4026
|
-
htmlFor: `${fieldId}-name`,
|
|
4027
|
-
children: [
|
|
4028
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Name" }),
|
|
4029
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
4030
|
-
"input",
|
|
4031
|
-
{
|
|
4032
|
-
id: `${fieldId}-name`,
|
|
4033
|
-
autoComplete: "name",
|
|
4034
|
-
value: name,
|
|
4035
|
-
onChange: (event) => setName(event.target.value),
|
|
4036
|
-
required: true
|
|
4037
|
-
}
|
|
4038
|
-
)
|
|
4039
|
-
]
|
|
4040
|
-
}
|
|
4041
|
-
),
|
|
4042
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
4043
|
-
"label",
|
|
4044
|
-
{
|
|
4045
|
-
className: "booking-card__field",
|
|
4046
|
-
htmlFor: `${fieldId}-email`,
|
|
4047
|
-
children: [
|
|
4048
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Email" }),
|
|
4049
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
4050
|
-
"input",
|
|
4051
|
-
{
|
|
4052
|
-
id: `${fieldId}-email`,
|
|
4053
|
-
type: "email",
|
|
4054
|
-
autoComplete: "email",
|
|
4055
|
-
value: email,
|
|
4056
|
-
onChange: (event) => setEmail(event.target.value),
|
|
4057
|
-
required: true
|
|
4205
|
+
className: "booking-card__nav",
|
|
4206
|
+
"aria-label": "Previous month",
|
|
4207
|
+
disabled: disabled || !canPrevMonth,
|
|
4208
|
+
onClick: () => goToMonth(-1),
|
|
4209
|
+
children: "\u2039"
|
|
4210
|
+
}
|
|
4211
|
+
),
|
|
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)(
|
|
4214
|
+
"button",
|
|
4215
|
+
{
|
|
4216
|
+
type: "button",
|
|
4217
|
+
className: "booking-card__nav",
|
|
4218
|
+
"aria-label": "Next month",
|
|
4219
|
+
disabled: disabled || !canNextMonth,
|
|
4220
|
+
onClick: () => goToMonth(1),
|
|
4221
|
+
children: "\u203A"
|
|
4222
|
+
}
|
|
4223
|
+
)
|
|
4224
|
+
] }),
|
|
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)(
|
|
4228
|
+
"div",
|
|
4229
|
+
{
|
|
4230
|
+
className: "booking-card__calendar",
|
|
4231
|
+
role: "grid",
|
|
4232
|
+
"aria-label": "Available dates",
|
|
4233
|
+
children: cells.map((cell, index) => {
|
|
4234
|
+
if (!cell) {
|
|
4235
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
4236
|
+
"span",
|
|
4237
|
+
{
|
|
4238
|
+
className: "booking-card__day"
|
|
4239
|
+
},
|
|
4240
|
+
`empty-${index}`
|
|
4241
|
+
);
|
|
4058
4242
|
}
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4243
|
+
const available = availableByDate.has(cell.key);
|
|
4244
|
+
const selected = cell.key === selectedDate;
|
|
4245
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
4246
|
+
"button",
|
|
4247
|
+
{
|
|
4248
|
+
type: "button",
|
|
4249
|
+
className: [
|
|
4250
|
+
"booking-card__day",
|
|
4251
|
+
available ? "booking-card__day--available" : "",
|
|
4252
|
+
selected ? "booking-card__day--selected" : ""
|
|
4253
|
+
].filter(Boolean).join(" "),
|
|
4254
|
+
disabled: disabled || !available,
|
|
4255
|
+
"aria-pressed": selected,
|
|
4256
|
+
onClick: () => selectDate(cell.key),
|
|
4257
|
+
children: cell.day
|
|
4258
|
+
},
|
|
4259
|
+
cell.key
|
|
4260
|
+
);
|
|
4261
|
+
})
|
|
4262
|
+
}
|
|
4263
|
+
)
|
|
4264
|
+
] }, "date") : null,
|
|
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)(
|
|
4268
|
+
"button",
|
|
4269
|
+
{
|
|
4270
|
+
type: "button",
|
|
4271
|
+
className: "booking-card__nav",
|
|
4272
|
+
"aria-label": "Back to dates",
|
|
4273
|
+
disabled,
|
|
4274
|
+
onClick: () => setStep("date"),
|
|
4275
|
+
children: "\u2039"
|
|
4276
|
+
}
|
|
4277
|
+
),
|
|
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: [
|
|
4281
|
+
"Times in ",
|
|
4282
|
+
timeZone
|
|
4283
|
+
] }) : null
|
|
4284
|
+
] })
|
|
4285
|
+
] }),
|
|
4286
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "booking-card__times", children: daySlots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
4287
|
+
"button",
|
|
4288
|
+
{
|
|
4289
|
+
type: "button",
|
|
4290
|
+
className: startTime === slot.startTime ? "booking-card__time booking-card__time--selected" : "booking-card__time",
|
|
4291
|
+
disabled,
|
|
4292
|
+
onClick: () => selectTime(slot.startTime),
|
|
4293
|
+
children: formatTimeChip(slot.startTime)
|
|
4294
|
+
},
|
|
4295
|
+
slot.startTime
|
|
4296
|
+
)) })
|
|
4297
|
+
] }, "time") : null,
|
|
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)(
|
|
4301
|
+
"button",
|
|
4302
|
+
{
|
|
4303
|
+
type: "button",
|
|
4304
|
+
className: "booking-card__nav",
|
|
4305
|
+
"aria-label": "Back to times",
|
|
4306
|
+
disabled,
|
|
4307
|
+
onClick: () => setStep("time"),
|
|
4308
|
+
children: "\u2039"
|
|
4309
|
+
}
|
|
4310
|
+
),
|
|
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
|
|
4315
|
+
] })
|
|
4316
|
+
] }),
|
|
4317
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__identity", children: [
|
|
4318
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
4319
|
+
"label",
|
|
4320
|
+
{
|
|
4321
|
+
className: "booking-card__field",
|
|
4322
|
+
htmlFor: `${fieldId}-name`,
|
|
4323
|
+
children: [
|
|
4324
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Name" }),
|
|
4325
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
4326
|
+
"input",
|
|
4327
|
+
{
|
|
4328
|
+
id: `${fieldId}-name`,
|
|
4329
|
+
autoComplete: "name",
|
|
4330
|
+
disabled,
|
|
4331
|
+
value: name,
|
|
4332
|
+
onChange: (event) => setName(event.target.value),
|
|
4333
|
+
required: true
|
|
4334
|
+
}
|
|
4335
|
+
)
|
|
4336
|
+
]
|
|
4337
|
+
}
|
|
4338
|
+
),
|
|
4339
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
4340
|
+
"label",
|
|
4341
|
+
{
|
|
4342
|
+
className: "booking-card__field",
|
|
4343
|
+
htmlFor: `${fieldId}-email`,
|
|
4344
|
+
children: [
|
|
4345
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Email" }),
|
|
4346
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
4347
|
+
"input",
|
|
4348
|
+
{
|
|
4349
|
+
id: `${fieldId}-email`,
|
|
4350
|
+
type: "email",
|
|
4351
|
+
autoComplete: "email",
|
|
4352
|
+
disabled,
|
|
4353
|
+
value: email,
|
|
4354
|
+
onChange: (event) => setEmail(event.target.value),
|
|
4355
|
+
required: true
|
|
4356
|
+
}
|
|
4357
|
+
)
|
|
4358
|
+
]
|
|
4359
|
+
}
|
|
4360
|
+
)
|
|
4361
|
+
] }),
|
|
4362
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
4363
|
+
"button",
|
|
4364
|
+
{
|
|
4365
|
+
type: "submit",
|
|
4366
|
+
className: "booking-card__submit",
|
|
4367
|
+
disabled: disabled || !name.trim() || !email.trim(),
|
|
4368
|
+
children: disabled ? "Booking\u2026" : "Book this time"
|
|
4369
|
+
}
|
|
4370
|
+
)
|
|
4371
|
+
] }, "details") : null
|
|
4372
|
+
] })
|
|
4373
|
+
}
|
|
4374
|
+
);
|
|
4075
4375
|
}
|
|
4076
4376
|
|
|
4077
4377
|
// src/react/components/MessageBubble/MessageBubble.tsx
|
|
4078
4378
|
var import_streamdown = require("streamdown");
|
|
4079
4379
|
var import_styles = require("streamdown/styles.css");
|
|
4080
|
-
var
|
|
4380
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
4081
4381
|
function normalizeDedupeText(text) {
|
|
4082
4382
|
return text.trim().replace(/\s+/g, " ").toLowerCase();
|
|
4083
4383
|
}
|
|
@@ -4088,9 +4388,7 @@ function paragraphsAreNearDuplicates(first, second) {
|
|
|
4088
4388
|
if (left === right) return true;
|
|
4089
4389
|
const shorter = left.length <= right.length ? left : right;
|
|
4090
4390
|
const longer = left.length <= right.length ? right : left;
|
|
4091
|
-
return longer.startsWith(
|
|
4092
|
-
shorter.slice(0, Math.floor(shorter.length * 0.85))
|
|
4093
|
-
);
|
|
4391
|
+
return longer.startsWith(shorter.slice(0, Math.floor(shorter.length * 0.85)));
|
|
4094
4392
|
}
|
|
4095
4393
|
function paragraphsShareOpening(first, second) {
|
|
4096
4394
|
const opening = first.split("\n")[0]?.trim();
|
|
@@ -4118,11 +4416,12 @@ function collapseRepeatedText(text) {
|
|
|
4118
4416
|
function MessageBubble({
|
|
4119
4417
|
message,
|
|
4120
4418
|
brandLogoUrl,
|
|
4419
|
+
bookingDisabled = false,
|
|
4121
4420
|
offer,
|
|
4122
4421
|
onBook
|
|
4123
4422
|
}) {
|
|
4124
4423
|
const resolvedLogoUrl = brandLogoUrl?.trim();
|
|
4125
|
-
const [failedLogoUrl, setFailedLogoUrl] = (0,
|
|
4424
|
+
const [failedLogoUrl, setFailedLogoUrl] = (0, import_react10.useState)(null);
|
|
4126
4425
|
const showBrandLogo = Boolean(resolvedLogoUrl) && failedLogoUrl !== resolvedLogoUrl;
|
|
4127
4426
|
const cards = message.role === "agent" ? extractToolCards(message.text) : [];
|
|
4128
4427
|
const extractedOffers = cards.filter(
|
|
@@ -4135,11 +4434,11 @@ function MessageBubble({
|
|
|
4135
4434
|
offers.length > 0 ? sanitizeBookingOfferCopy(visibleText) : looksLikeBookingAvailabilityDump(visibleText) ? sanitizeBookingOfferCopy(visibleText) : visibleText || (isStreaming ? "" : message.text)
|
|
4136
4435
|
);
|
|
4137
4436
|
if (message.role === "visitor") {
|
|
4138
|
-
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 }) });
|
|
4139
4438
|
}
|
|
4140
4439
|
const citations = message.citations ?? [];
|
|
4141
|
-
const agentText = /* @__PURE__ */ (0,
|
|
4142
|
-
/* @__PURE__ */ (0,
|
|
4440
|
+
const agentText = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "message-bubble__text", children: [
|
|
4441
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4143
4442
|
import_streamdown.Streamdown,
|
|
4144
4443
|
{
|
|
4145
4444
|
animated: isStreaming,
|
|
@@ -4153,22 +4452,21 @@ function MessageBubble({
|
|
|
4153
4452
|
children: displayText
|
|
4154
4453
|
}
|
|
4155
4454
|
),
|
|
4156
|
-
citations.length > 0 ? /* @__PURE__ */ (0,
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
) }, citation.id)) }) : null
|
|
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)(
|
|
4457
|
+
"span",
|
|
4458
|
+
{
|
|
4459
|
+
className: "message-bubble__source-icon",
|
|
4460
|
+
"aria-hidden": "true",
|
|
4461
|
+
children: "\u25A6"
|
|
4462
|
+
}
|
|
4463
|
+
),
|
|
4464
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: citation.label })
|
|
4465
|
+
] }) }, citation.id)) }) : null
|
|
4168
4466
|
] });
|
|
4169
|
-
return /* @__PURE__ */ (0,
|
|
4170
|
-
displayText ? showBrandLogo ? /* @__PURE__ */ (0,
|
|
4171
|
-
/* @__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)(
|
|
4172
4470
|
"img",
|
|
4173
4471
|
{
|
|
4174
4472
|
src: resolvedLogoUrl,
|
|
@@ -4180,9 +4478,10 @@ function MessageBubble({
|
|
|
4180
4478
|
) }),
|
|
4181
4479
|
agentText
|
|
4182
4480
|
] }) : agentText : null,
|
|
4183
|
-
offers.map((nextOffer, index) => /* @__PURE__ */ (0,
|
|
4481
|
+
offers.map((nextOffer, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4184
4482
|
BookingCard,
|
|
4185
4483
|
{
|
|
4484
|
+
disabled: bookingDisabled,
|
|
4186
4485
|
offer: nextOffer,
|
|
4187
4486
|
onBook
|
|
4188
4487
|
},
|
|
@@ -4191,11 +4490,498 @@ function MessageBubble({
|
|
|
4191
4490
|
] });
|
|
4192
4491
|
}
|
|
4193
4492
|
|
|
4493
|
+
// src/react/components/MessageActions/MessageActions.tsx
|
|
4494
|
+
var import_react11 = require("react");
|
|
4495
|
+
var import_react_dom2 = require("react-dom");
|
|
4496
|
+
|
|
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";
|
|
4519
|
+
}
|
|
4520
|
+
|
|
4521
|
+
// src/react/components/MessageActions/MessageActions.tsx
|
|
4522
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
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
|
+
] });
|
|
4546
|
+
}
|
|
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"
|
|
4556
|
+
}
|
|
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
|
+
|
|
4194
4980
|
// src/react/components/HumanInputCard/HumanInputCard.tsx
|
|
4195
|
-
var
|
|
4981
|
+
var import_react13 = require("react");
|
|
4196
4982
|
|
|
4197
4983
|
// src/react/components/ConfirmationCard/ConfirmationCard.tsx
|
|
4198
|
-
var
|
|
4984
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
4199
4985
|
function ConfirmationCard({
|
|
4200
4986
|
disabled = false,
|
|
4201
4987
|
request,
|
|
@@ -4204,17 +4990,17 @@ function ConfirmationCard({
|
|
|
4204
4990
|
const options = request.options ?? [];
|
|
4205
4991
|
const heading = request.kind === "tool-approval" ? "Confirm this action" : request.prompt;
|
|
4206
4992
|
const prompt = request.kind === "tool-approval" ? request.prompt : void 0;
|
|
4207
|
-
return /* @__PURE__ */ (0,
|
|
4993
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
4208
4994
|
"section",
|
|
4209
4995
|
{
|
|
4210
4996
|
className: "confirmation-card",
|
|
4211
4997
|
"aria-labelledby": `confirmation-${request.requestId}`,
|
|
4212
4998
|
children: [
|
|
4213
|
-
/* @__PURE__ */ (0,
|
|
4214
|
-
/* @__PURE__ */ (0,
|
|
4215
|
-
prompt ? /* @__PURE__ */ (0,
|
|
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
|
|
4216
5002
|
] }),
|
|
4217
|
-
/* @__PURE__ */ (0,
|
|
5003
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "confirmation-card__actions", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4218
5004
|
"button",
|
|
4219
5005
|
{
|
|
4220
5006
|
type: "button",
|
|
@@ -4234,8 +5020,8 @@ function ConfirmationCard({
|
|
|
4234
5020
|
}
|
|
4235
5021
|
|
|
4236
5022
|
// src/react/components/ToolInputCard/ToolInputCard.tsx
|
|
4237
|
-
var
|
|
4238
|
-
var
|
|
5023
|
+
var import_react12 = require("react");
|
|
5024
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
4239
5025
|
function isRecord5(value) {
|
|
4240
5026
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4241
5027
|
}
|
|
@@ -4359,7 +5145,7 @@ function FieldDescription({
|
|
|
4359
5145
|
field,
|
|
4360
5146
|
id
|
|
4361
5147
|
}) {
|
|
4362
|
-
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;
|
|
4363
5149
|
}
|
|
4364
5150
|
function ChoiceField({
|
|
4365
5151
|
field,
|
|
@@ -4378,7 +5164,7 @@ function ChoiceField({
|
|
|
4378
5164
|
const selectedIndex = options.findIndex(
|
|
4379
5165
|
(option) => valuesMatch(option.value, value)
|
|
4380
5166
|
);
|
|
4381
|
-
return /* @__PURE__ */ (0,
|
|
5167
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4382
5168
|
"select",
|
|
4383
5169
|
{
|
|
4384
5170
|
id,
|
|
@@ -4393,13 +5179,13 @@ function ChoiceField({
|
|
|
4393
5179
|
if (option) onChange(option.value);
|
|
4394
5180
|
},
|
|
4395
5181
|
children: [
|
|
4396
|
-
/* @__PURE__ */ (0,
|
|
4397
|
-
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)))
|
|
4398
5184
|
]
|
|
4399
5185
|
}
|
|
4400
5186
|
);
|
|
4401
5187
|
}
|
|
4402
|
-
return /* @__PURE__ */ (0,
|
|
5188
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4403
5189
|
"div",
|
|
4404
5190
|
{
|
|
4405
5191
|
className: "tool-input-card__choices",
|
|
@@ -4410,8 +5196,8 @@ function ChoiceField({
|
|
|
4410
5196
|
"aria-required": field.required,
|
|
4411
5197
|
children: options.map((option, index) => {
|
|
4412
5198
|
const checked = multiple ? selected.some((item) => valuesMatch(item, option.value)) : valuesMatch(value, option.value);
|
|
4413
|
-
return /* @__PURE__ */ (0,
|
|
4414
|
-
/* @__PURE__ */ (0,
|
|
5199
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "tool-input-card__choice", children: [
|
|
5200
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4415
5201
|
"input",
|
|
4416
5202
|
{
|
|
4417
5203
|
type: multiple ? "checkbox" : "radio",
|
|
@@ -4433,7 +5219,7 @@ function ChoiceField({
|
|
|
4433
5219
|
}
|
|
4434
5220
|
}
|
|
4435
5221
|
),
|
|
4436
|
-
/* @__PURE__ */ (0,
|
|
5222
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: option.label })
|
|
4437
5223
|
] }, optionKey(option));
|
|
4438
5224
|
})
|
|
4439
5225
|
}
|
|
@@ -4453,9 +5239,9 @@ function ToolField({
|
|
|
4453
5239
|
error ? `${id}-error` : ""
|
|
4454
5240
|
].filter(Boolean).join(" ");
|
|
4455
5241
|
if (field.kind === "checkbox" || field.kind === "confirmation") {
|
|
4456
|
-
return /* @__PURE__ */ (0,
|
|
4457
|
-
/* @__PURE__ */ (0,
|
|
4458
|
-
/* @__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)(
|
|
4459
5245
|
"input",
|
|
4460
5246
|
{
|
|
4461
5247
|
id,
|
|
@@ -4468,17 +5254,17 @@ function ToolField({
|
|
|
4468
5254
|
onChange: (event) => onChange(event.target.checked)
|
|
4469
5255
|
}
|
|
4470
5256
|
),
|
|
4471
|
-
/* @__PURE__ */ (0,
|
|
4472
|
-
/* @__PURE__ */ (0,
|
|
4473
|
-
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
|
|
4474
5260
|
] })
|
|
4475
5261
|
] }),
|
|
4476
|
-
error ? /* @__PURE__ */ (0,
|
|
5262
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
|
|
4477
5263
|
] });
|
|
4478
5264
|
}
|
|
4479
|
-
const label = /* @__PURE__ */ (0,
|
|
5265
|
+
const label = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { id: `${id}-label`, htmlFor: id, children: [
|
|
4480
5266
|
field.label,
|
|
4481
|
-
field.required ? /* @__PURE__ */ (0,
|
|
5267
|
+
field.required ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
|
|
4482
5268
|
] });
|
|
4483
5269
|
const common = {
|
|
4484
5270
|
id,
|
|
@@ -4490,7 +5276,7 @@ function ToolField({
|
|
|
4490
5276
|
};
|
|
4491
5277
|
let control;
|
|
4492
5278
|
if (field.kind === "select" || field.kind === "radio" || field.kind === "multi-select") {
|
|
4493
|
-
control = /* @__PURE__ */ (0,
|
|
5279
|
+
control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4494
5280
|
ChoiceField,
|
|
4495
5281
|
{
|
|
4496
5282
|
field,
|
|
@@ -4504,7 +5290,7 @@ function ToolField({
|
|
|
4504
5290
|
}
|
|
4505
5291
|
);
|
|
4506
5292
|
} else if (field.kind === "textarea" || field.kind === "json") {
|
|
4507
|
-
control = /* @__PURE__ */ (0,
|
|
5293
|
+
control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4508
5294
|
"textarea",
|
|
4509
5295
|
{
|
|
4510
5296
|
...common,
|
|
@@ -4518,8 +5304,8 @@ function ToolField({
|
|
|
4518
5304
|
);
|
|
4519
5305
|
} else if (field.kind === "range") {
|
|
4520
5306
|
const numericValue = typeof value === "number" ? value : field.min ?? 0;
|
|
4521
|
-
control = /* @__PURE__ */ (0,
|
|
4522
|
-
/* @__PURE__ */ (0,
|
|
5307
|
+
control = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__range", children: [
|
|
5308
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4523
5309
|
"input",
|
|
4524
5310
|
{
|
|
4525
5311
|
...common,
|
|
@@ -4531,11 +5317,11 @@ function ToolField({
|
|
|
4531
5317
|
onChange: (event) => onChange(Number(event.target.value))
|
|
4532
5318
|
}
|
|
4533
5319
|
),
|
|
4534
|
-
/* @__PURE__ */ (0,
|
|
5320
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("output", { htmlFor: id, children: numericValue })
|
|
4535
5321
|
] });
|
|
4536
5322
|
} else {
|
|
4537
5323
|
const type = field.kind === "date-time" ? "datetime-local" : field.kind === "calendar" ? "date" : field.kind;
|
|
4538
|
-
control = /* @__PURE__ */ (0,
|
|
5324
|
+
control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4539
5325
|
"input",
|
|
4540
5326
|
{
|
|
4541
5327
|
...common,
|
|
@@ -4553,11 +5339,11 @@ function ToolField({
|
|
|
4553
5339
|
}
|
|
4554
5340
|
);
|
|
4555
5341
|
}
|
|
4556
|
-
return /* @__PURE__ */ (0,
|
|
5342
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__field", children: [
|
|
4557
5343
|
label,
|
|
4558
|
-
/* @__PURE__ */ (0,
|
|
5344
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FieldDescription, { field, id: `${id}-description` }),
|
|
4559
5345
|
control,
|
|
4560
|
-
error ? /* @__PURE__ */ (0,
|
|
5346
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
|
|
4561
5347
|
] });
|
|
4562
5348
|
}
|
|
4563
5349
|
function ToolInputCard({
|
|
@@ -4565,11 +5351,11 @@ function ToolInputCard({
|
|
|
4565
5351
|
surface,
|
|
4566
5352
|
onSubmit
|
|
4567
5353
|
}) {
|
|
4568
|
-
const [values, setValues] = (0,
|
|
5354
|
+
const [values, setValues] = (0, import_react12.useState)(
|
|
4569
5355
|
() => initialValues(surface)
|
|
4570
5356
|
);
|
|
4571
|
-
const [touched, setTouched] = (0,
|
|
4572
|
-
const [submitted, setSubmitted] = (0,
|
|
5357
|
+
const [touched, setTouched] = (0, import_react12.useState)(() => /* @__PURE__ */ new Set());
|
|
5358
|
+
const [submitted, setSubmitted] = (0, import_react12.useState)(false);
|
|
4573
5359
|
const errors = Object.fromEntries(
|
|
4574
5360
|
surface.fields.map((field) => [
|
|
4575
5361
|
field.path,
|
|
@@ -4594,14 +5380,14 @@ function ToolInputCard({
|
|
|
4594
5380
|
onSubmit?.(surface, result);
|
|
4595
5381
|
}
|
|
4596
5382
|
if (submitted) {
|
|
4597
|
-
return /* @__PURE__ */ (0,
|
|
5383
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4598
5384
|
"section",
|
|
4599
5385
|
{
|
|
4600
5386
|
className: "tool-input-card tool-input-card--submitted",
|
|
4601
5387
|
role: "status",
|
|
4602
5388
|
children: [
|
|
4603
|
-
/* @__PURE__ */ (0,
|
|
4604
|
-
/* @__PURE__ */ (0,
|
|
5389
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-hidden": "true", children: "\u2713" }),
|
|
5390
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("strong", { children: [
|
|
4605
5391
|
surface.title,
|
|
4606
5392
|
" submitted"
|
|
4607
5393
|
] })
|
|
@@ -4609,18 +5395,18 @@ function ToolInputCard({
|
|
|
4609
5395
|
}
|
|
4610
5396
|
);
|
|
4611
5397
|
}
|
|
4612
|
-
return /* @__PURE__ */ (0,
|
|
5398
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4613
5399
|
"section",
|
|
4614
5400
|
{
|
|
4615
5401
|
className: "tool-input-card",
|
|
4616
5402
|
"aria-labelledby": `tool-input-${surface.id}`,
|
|
4617
5403
|
children: [
|
|
4618
|
-
/* @__PURE__ */ (0,
|
|
4619
|
-
/* @__PURE__ */ (0,
|
|
4620
|
-
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
|
|
4621
5407
|
] }),
|
|
4622
|
-
/* @__PURE__ */ (0,
|
|
4623
|
-
/* @__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)(
|
|
4624
5410
|
ToolField,
|
|
4625
5411
|
{
|
|
4626
5412
|
disabled,
|
|
@@ -4633,8 +5419,8 @@ function ToolInputCard({
|
|
|
4633
5419
|
},
|
|
4634
5420
|
field.path
|
|
4635
5421
|
)) }),
|
|
4636
|
-
/* @__PURE__ */ (0,
|
|
4637
|
-
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)(
|
|
4638
5424
|
"button",
|
|
4639
5425
|
{
|
|
4640
5426
|
type: "button",
|
|
@@ -4647,7 +5433,7 @@ function ToolInputCard({
|
|
|
4647
5433
|
children: surface.actions.find((action) => action.id === "reset")?.label ?? "Clear"
|
|
4648
5434
|
}
|
|
4649
5435
|
) : null,
|
|
4650
|
-
/* @__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" })
|
|
4651
5437
|
] })
|
|
4652
5438
|
] })
|
|
4653
5439
|
]
|
|
@@ -4656,17 +5442,17 @@ function ToolInputCard({
|
|
|
4656
5442
|
}
|
|
4657
5443
|
|
|
4658
5444
|
// src/react/components/HumanInputCard/HumanInputCard.tsx
|
|
4659
|
-
var
|
|
5445
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
4660
5446
|
function HumanInputCard({
|
|
4661
5447
|
disabled = false,
|
|
4662
5448
|
request,
|
|
4663
5449
|
onRespond
|
|
4664
5450
|
}) {
|
|
4665
|
-
const [text, setText] = (0,
|
|
5451
|
+
const [text, setText] = (0, import_react13.useState)("");
|
|
4666
5452
|
const options = request.options ?? [];
|
|
4667
5453
|
const showText = request.display === "text" || request.allowFreeform && options.length === 0;
|
|
4668
5454
|
if (request.ui) {
|
|
4669
|
-
return /* @__PURE__ */ (0,
|
|
5455
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4670
5456
|
ToolInputCard,
|
|
4671
5457
|
{
|
|
4672
5458
|
disabled,
|
|
@@ -4676,7 +5462,7 @@ function HumanInputCard({
|
|
|
4676
5462
|
);
|
|
4677
5463
|
}
|
|
4678
5464
|
if (options.length > 0) {
|
|
4679
|
-
return /* @__PURE__ */ (0,
|
|
5465
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4680
5466
|
ConfirmationCard,
|
|
4681
5467
|
{
|
|
4682
5468
|
disabled,
|
|
@@ -4691,17 +5477,17 @@ function HumanInputCard({
|
|
|
4691
5477
|
if (!value || disabled) return;
|
|
4692
5478
|
onRespond?.({ requestId: request.requestId, text: value });
|
|
4693
5479
|
}
|
|
4694
|
-
return /* @__PURE__ */ (0,
|
|
5480
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
4695
5481
|
"section",
|
|
4696
5482
|
{
|
|
4697
5483
|
className: "human-input-card",
|
|
4698
5484
|
"aria-labelledby": `human-input-${request.requestId}`,
|
|
4699
5485
|
children: [
|
|
4700
|
-
/* @__PURE__ */ (0,
|
|
4701
|
-
showText ? /* @__PURE__ */ (0,
|
|
4702
|
-
/* @__PURE__ */ (0,
|
|
4703
|
-
/* @__PURE__ */ (0,
|
|
4704
|
-
/* @__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)(
|
|
4705
5491
|
"input",
|
|
4706
5492
|
{
|
|
4707
5493
|
id: `human-input-text-${request.requestId}`,
|
|
@@ -4710,39 +5496,39 @@ function HumanInputCard({
|
|
|
4710
5496
|
onChange: (event) => setText(event.target.value)
|
|
4711
5497
|
}
|
|
4712
5498
|
),
|
|
4713
|
-
/* @__PURE__ */ (0,
|
|
5499
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "submit", disabled: disabled || !text.trim(), children: "Send" })
|
|
4714
5500
|
] })
|
|
4715
5501
|
] }) : null,
|
|
4716
|
-
!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
|
|
4717
5503
|
]
|
|
4718
5504
|
}
|
|
4719
5505
|
);
|
|
4720
5506
|
}
|
|
4721
5507
|
|
|
4722
5508
|
// src/react/components/CollectionResultCard/CollectionResultCard.tsx
|
|
4723
|
-
var
|
|
5509
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
4724
5510
|
function CollectionResultCard({
|
|
4725
5511
|
result
|
|
4726
5512
|
}) {
|
|
4727
5513
|
const empty = result.items.length === 0;
|
|
4728
|
-
return /* @__PURE__ */ (0,
|
|
5514
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
4729
5515
|
"section",
|
|
4730
5516
|
{
|
|
4731
5517
|
className: `collection-result-card tool-result-card tool-result-card--${result.status}`,
|
|
4732
5518
|
"aria-label": result.title,
|
|
4733
5519
|
children: [
|
|
4734
|
-
/* @__PURE__ */ (0,
|
|
4735
|
-
/* @__PURE__ */ (0,
|
|
4736
|
-
/* @__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 })
|
|
4737
5523
|
] }),
|
|
4738
|
-
empty ? /* @__PURE__ */ (0,
|
|
4739
|
-
/* @__PURE__ */ (0,
|
|
4740
|
-
item.description ? /* @__PURE__ */ (0,
|
|
4741
|
-
item.details?.length ? /* @__PURE__ */ (0,
|
|
4742
|
-
/* @__PURE__ */ (0,
|
|
4743
|
-
/* @__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 })
|
|
4744
5530
|
] }, `${detail.label}:${detail.value}`)) }) : null,
|
|
4745
|
-
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
|
|
4746
5532
|
] }, item.title)) })
|
|
4747
5533
|
]
|
|
4748
5534
|
}
|
|
@@ -4750,26 +5536,26 @@ function CollectionResultCard({
|
|
|
4750
5536
|
}
|
|
4751
5537
|
|
|
4752
5538
|
// src/react/components/EntityResultCard/EntityResultCard.tsx
|
|
4753
|
-
var
|
|
5539
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
4754
5540
|
function EntityResultCard({
|
|
4755
5541
|
result
|
|
4756
5542
|
}) {
|
|
4757
|
-
return /* @__PURE__ */ (0,
|
|
5543
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
4758
5544
|
"section",
|
|
4759
5545
|
{
|
|
4760
5546
|
className: `entity-result-card tool-result-card tool-result-card--${result.status}`,
|
|
4761
5547
|
"aria-label": result.title,
|
|
4762
5548
|
children: [
|
|
4763
|
-
/* @__PURE__ */ (0,
|
|
4764
|
-
/* @__PURE__ */ (0,
|
|
4765
|
-
/* @__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 })
|
|
4766
5552
|
] }),
|
|
4767
|
-
result.description ? /* @__PURE__ */ (0,
|
|
4768
|
-
result.details?.length ? /* @__PURE__ */ (0,
|
|
4769
|
-
/* @__PURE__ */ (0,
|
|
4770
|
-
/* @__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 })
|
|
4771
5557
|
] }, `${detail.label}:${detail.value}`)) }) : null,
|
|
4772
|
-
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)(
|
|
4773
5559
|
"a",
|
|
4774
5560
|
{
|
|
4775
5561
|
href: link.href,
|
|
@@ -4785,24 +5571,24 @@ function EntityResultCard({
|
|
|
4785
5571
|
}
|
|
4786
5572
|
|
|
4787
5573
|
// src/react/components/SignatureResultCard/SignatureResultCard.tsx
|
|
4788
|
-
var
|
|
5574
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
4789
5575
|
function SignatureResultCard({
|
|
4790
5576
|
result
|
|
4791
5577
|
}) {
|
|
4792
5578
|
const primaryLink = result.links?.[0];
|
|
4793
|
-
return /* @__PURE__ */ (0,
|
|
5579
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
4794
5580
|
"section",
|
|
4795
5581
|
{
|
|
4796
5582
|
className: `signature-result-card tool-result-card tool-result-card--${result.status}`,
|
|
4797
5583
|
"aria-label": result.title,
|
|
4798
5584
|
children: [
|
|
4799
|
-
/* @__PURE__ */ (0,
|
|
4800
|
-
/* @__PURE__ */ (0,
|
|
4801
|
-
/* @__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 })
|
|
4802
5588
|
] }),
|
|
4803
|
-
result.statusLabel ? /* @__PURE__ */ (0,
|
|
4804
|
-
result.description ? /* @__PURE__ */ (0,
|
|
4805
|
-
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)(
|
|
4806
5592
|
"a",
|
|
4807
5593
|
{
|
|
4808
5594
|
className: "signature-result-card__cta",
|
|
@@ -4818,26 +5604,26 @@ function SignatureResultCard({
|
|
|
4818
5604
|
}
|
|
4819
5605
|
|
|
4820
5606
|
// src/react/components/ToolResultCard/ToolResultCard.tsx
|
|
4821
|
-
var
|
|
5607
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
4822
5608
|
function ToolResultCard({
|
|
4823
5609
|
result
|
|
4824
5610
|
}) {
|
|
4825
|
-
return /* @__PURE__ */ (0,
|
|
5611
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
4826
5612
|
"section",
|
|
4827
5613
|
{
|
|
4828
5614
|
className: `tool-result-card tool-result-card--${result.status}`,
|
|
4829
5615
|
"aria-label": result.title,
|
|
4830
5616
|
children: [
|
|
4831
|
-
/* @__PURE__ */ (0,
|
|
4832
|
-
/* @__PURE__ */ (0,
|
|
4833
|
-
/* @__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 })
|
|
4834
5620
|
] }),
|
|
4835
|
-
result.description ? /* @__PURE__ */ (0,
|
|
4836
|
-
result.details?.length ? /* @__PURE__ */ (0,
|
|
4837
|
-
/* @__PURE__ */ (0,
|
|
4838
|
-
/* @__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 })
|
|
4839
5625
|
] }, `${detail.label}:${detail.value}`)) }) : null,
|
|
4840
|
-
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)(
|
|
4841
5627
|
"a",
|
|
4842
5628
|
{
|
|
4843
5629
|
href: link.href,
|
|
@@ -4853,14 +5639,14 @@ function ToolResultCard({
|
|
|
4853
5639
|
}
|
|
4854
5640
|
|
|
4855
5641
|
// src/react/components/VisitorToolResultView/VisitorToolResultView.tsx
|
|
4856
|
-
var
|
|
5642
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
4857
5643
|
function VisitorToolResultView({
|
|
4858
5644
|
disabled = false,
|
|
4859
5645
|
onToolInput,
|
|
4860
5646
|
result
|
|
4861
5647
|
}) {
|
|
4862
5648
|
if (result.kind === "input") {
|
|
4863
|
-
return /* @__PURE__ */ (0,
|
|
5649
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
4864
5650
|
ToolInputCard,
|
|
4865
5651
|
{
|
|
4866
5652
|
disabled,
|
|
@@ -4870,16 +5656,16 @@ function VisitorToolResultView({
|
|
|
4870
5656
|
);
|
|
4871
5657
|
}
|
|
4872
5658
|
if (result.kind === "entity") {
|
|
4873
|
-
return /* @__PURE__ */ (0,
|
|
5659
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(EntityResultCard, { result });
|
|
4874
5660
|
}
|
|
4875
5661
|
if (result.kind === "collection") {
|
|
4876
|
-
return /* @__PURE__ */ (0,
|
|
5662
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CollectionResultCard, { result });
|
|
4877
5663
|
}
|
|
4878
5664
|
if (result.kind === "signature") {
|
|
4879
|
-
return /* @__PURE__ */ (0,
|
|
5665
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SignatureResultCard, { result });
|
|
4880
5666
|
}
|
|
4881
5667
|
if (result.kind === "summary") {
|
|
4882
|
-
return /* @__PURE__ */ (0,
|
|
5668
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolResultCard, { result });
|
|
4883
5669
|
}
|
|
4884
5670
|
return null;
|
|
4885
5671
|
}
|
|
@@ -4888,9 +5674,9 @@ function isRenderableVisitorToolResult(result) {
|
|
|
4888
5674
|
}
|
|
4889
5675
|
|
|
4890
5676
|
// src/react/components/AgentRail/AgentRail.tsx
|
|
4891
|
-
var
|
|
5677
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
4892
5678
|
function MinimizeIcon() {
|
|
4893
|
-
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)(
|
|
4894
5680
|
"path",
|
|
4895
5681
|
{
|
|
4896
5682
|
d: "M3.5 8h9",
|
|
@@ -4900,8 +5686,8 @@ function MinimizeIcon() {
|
|
|
4900
5686
|
}
|
|
4901
5687
|
) });
|
|
4902
5688
|
}
|
|
4903
|
-
function
|
|
4904
|
-
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)(
|
|
4905
5691
|
"path",
|
|
4906
5692
|
{
|
|
4907
5693
|
d: "M4 4l8 8M12 4l-8 8",
|
|
@@ -4912,7 +5698,7 @@ function CloseIcon() {
|
|
|
4912
5698
|
) });
|
|
4913
5699
|
}
|
|
4914
5700
|
function NewChatIcon() {
|
|
4915
|
-
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)(
|
|
4916
5702
|
"path",
|
|
4917
5703
|
{
|
|
4918
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",
|
|
@@ -4924,7 +5710,7 @@ function NewChatIcon() {
|
|
|
4924
5710
|
) });
|
|
4925
5711
|
}
|
|
4926
5712
|
function ExpandIcon() {
|
|
4927
|
-
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)(
|
|
4928
5714
|
"path",
|
|
4929
5715
|
{
|
|
4930
5716
|
d: "M6 3.5H3.5V6M10 3.5h2.5V6M10 12.5h2.5V10M6 12.5H3.5V10",
|
|
@@ -4936,7 +5722,7 @@ function ExpandIcon() {
|
|
|
4936
5722
|
) });
|
|
4937
5723
|
}
|
|
4938
5724
|
function RestoreIcon() {
|
|
4939
|
-
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)(
|
|
4940
5726
|
"path",
|
|
4941
5727
|
{
|
|
4942
5728
|
d: "M5.5 5.5H3.5V7.5M10.5 5.5h2V7.5M10.5 10.5h2V8.5M5.5 10.5H3.5V8.5",
|
|
@@ -4947,6 +5733,19 @@ function RestoreIcon() {
|
|
|
4947
5733
|
}
|
|
4948
5734
|
) });
|
|
4949
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.";
|
|
4950
5749
|
function AgentRail({
|
|
4951
5750
|
state,
|
|
4952
5751
|
theme,
|
|
@@ -4954,6 +5753,9 @@ function AgentRail({
|
|
|
4954
5753
|
brandLabel = "",
|
|
4955
5754
|
brandLogoUrl,
|
|
4956
5755
|
poweredByLabel = "Powered by Webless",
|
|
5756
|
+
disclaimerLabel,
|
|
5757
|
+
answerReceipt = false,
|
|
5758
|
+
readAloud = false,
|
|
4957
5759
|
composerPlaceholder = "Ask anything\u2026",
|
|
4958
5760
|
mobileFullscreen = false,
|
|
4959
5761
|
expanded = false,
|
|
@@ -4962,16 +5764,26 @@ function AgentRail({
|
|
|
4962
5764
|
onExpandToggle,
|
|
4963
5765
|
onReset,
|
|
4964
5766
|
onRetry,
|
|
5767
|
+
onRegenerate,
|
|
5768
|
+
onFeedback,
|
|
4965
5769
|
onSubmit,
|
|
4966
5770
|
onFollowUpSelect,
|
|
4967
5771
|
onBook,
|
|
4968
5772
|
onInputResponse,
|
|
4969
5773
|
onToolInput
|
|
4970
5774
|
}) {
|
|
4971
|
-
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);
|
|
4972
5783
|
const resolvedBrandLabel = brandLabel.trim();
|
|
4973
5784
|
const resolvedBrandLogoUrl = brandLogoUrl?.trim();
|
|
4974
|
-
const
|
|
5785
|
+
const resolvedDisclaimerLabel = disclaimerLabel === void 0 ? DEFAULT_DISCLAIMER_LABEL : disclaimerLabel;
|
|
5786
|
+
const [failedLogoUrl, setFailedLogoUrl] = (0, import_react14.useState)(null);
|
|
4975
5787
|
const showBrandLogo = Boolean(resolvedBrandLogoUrl) && failedLogoUrl !== resolvedBrandLogoUrl;
|
|
4976
5788
|
const resolvedColorScheme = useAgentColorScheme(colorScheme);
|
|
4977
5789
|
const brandedTheme = { ...defaultAgentRailTheme, ...theme };
|
|
@@ -5022,10 +5834,15 @@ function AgentRail({
|
|
|
5022
5834
|
);
|
|
5023
5835
|
const activeVisitorToolInput = [...visitorToolResults].reverse().find((result) => result.kind === "input");
|
|
5024
5836
|
const visibleVisitorToolResults = activeVisitorToolInput ? [activeVisitorToolInput] : visitorToolResults;
|
|
5025
|
-
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;
|
|
5026
5839
|
const hasVisitorMessages2 = state.messages.some(
|
|
5027
5840
|
(message) => message.role === "visitor"
|
|
5028
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));
|
|
5029
5846
|
const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
|
|
5030
5847
|
const greeting = state.messages.find(
|
|
5031
5848
|
(message) => message.role === "agent" && message.id === "greeting"
|
|
@@ -5047,6 +5864,7 @@ function AgentRail({
|
|
|
5047
5864
|
}
|
|
5048
5865
|
}
|
|
5049
5866
|
const lastIsAgent = lastMessage?.role === "agent";
|
|
5867
|
+
const showMessageActions = state.phase === "complete" && lastIsAgent && hasVisitorMessages2;
|
|
5050
5868
|
const streamingMessage = state.phase === "streaming" && state.streamingText && !lastIsAgent ? {
|
|
5051
5869
|
createdAt: 0,
|
|
5052
5870
|
id: "streaming-response",
|
|
@@ -5073,10 +5891,36 @@ function AgentRail({
|
|
|
5073
5891
|
hasPendingConfirmation,
|
|
5074
5892
|
enabled: lastIsAgent && !isBusy
|
|
5075
5893
|
});
|
|
5076
|
-
|
|
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)(() => {
|
|
5077
5917
|
const node = transcriptRef.current;
|
|
5078
5918
|
if (!node) return;
|
|
5079
|
-
|
|
5919
|
+
const lastMessage2 = state.messages.at(-1);
|
|
5920
|
+
const visitorJustSent = lastMessage2?.role === "visitor";
|
|
5921
|
+
if (pinnedToBottomRef.current || visitorJustSent) {
|
|
5922
|
+
node.scrollTop = node.scrollHeight;
|
|
5923
|
+
}
|
|
5080
5924
|
}, [
|
|
5081
5925
|
state.messages,
|
|
5082
5926
|
state.toolSteps,
|
|
@@ -5084,10 +5928,75 @@ function AgentRail({
|
|
|
5084
5928
|
state.followUps,
|
|
5085
5929
|
state.journey
|
|
5086
5930
|
]);
|
|
5087
|
-
|
|
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)(
|
|
5088
5996
|
"aside",
|
|
5089
5997
|
{
|
|
5090
|
-
|
|
5998
|
+
ref: railRef,
|
|
5999
|
+
className: `agent-rail not-typeset${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}${receiptOpen ? " agent-rail--receipt-open" : ""}`,
|
|
5091
6000
|
"data-not-typeset": "",
|
|
5092
6001
|
"data-color-scheme": resolvedColorScheme,
|
|
5093
6002
|
spellCheck: false,
|
|
@@ -5097,193 +6006,234 @@ function AgentRail({
|
|
|
5097
6006
|
autoFocus: mobileFullscreen || expanded,
|
|
5098
6007
|
role: mobileFullscreen || expanded ? "dialog" : void 0,
|
|
5099
6008
|
tabIndex: mobileFullscreen || expanded ? -1 : void 0,
|
|
5100
|
-
children:
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
className: "agent-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
className: "agent-rail__brand-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
className: "agent-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
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,
|
|
5180
6220
|
{
|
|
5181
6221
|
brandLabel: resolvedBrandLabel,
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
steps: state.toolSteps
|
|
6222
|
+
onClose: () => setReceiptOpen(false),
|
|
6223
|
+
steps: receiptSteps
|
|
5185
6224
|
}
|
|
5186
|
-
) : null
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
result,
|
|
5191
|
-
disabled: semanticSurfaceDisabled,
|
|
5192
|
-
onToolInput
|
|
5193
|
-
},
|
|
5194
|
-
result.id
|
|
5195
|
-
)),
|
|
5196
|
-
pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5197
|
-
HumanInputCard,
|
|
5198
|
-
{
|
|
5199
|
-
request,
|
|
5200
|
-
onRespond: onInputResponse
|
|
5201
|
-
},
|
|
5202
|
-
request.requestId
|
|
5203
|
-
))
|
|
5204
|
-
] }) : null,
|
|
5205
|
-
visibleMessages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "agent-rail__turn-block", children: [
|
|
5206
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5207
|
-
MessageBubble,
|
|
5208
|
-
{
|
|
5209
|
-
message,
|
|
5210
|
-
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
5211
|
-
offer: index === lastAgentIndex ? state.pendingOffer : void 0,
|
|
5212
|
-
onBook
|
|
5213
|
-
}
|
|
5214
|
-
),
|
|
5215
|
-
index === lastVisitorIndex ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
5216
|
-
showActivity ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5217
|
-
AgentActivityBubble,
|
|
5218
|
-
{
|
|
5219
|
-
brandLabel: resolvedBrandLabel,
|
|
5220
|
-
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
5221
|
-
failed: state.phase === "error",
|
|
5222
|
-
steps: state.toolSteps
|
|
5223
|
-
}
|
|
5224
|
-
) : null,
|
|
5225
|
-
visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5226
|
-
VisitorToolResultView,
|
|
5227
|
-
{
|
|
5228
|
-
result,
|
|
5229
|
-
disabled: semanticSurfaceDisabled,
|
|
5230
|
-
onToolInput
|
|
5231
|
-
},
|
|
5232
|
-
result.id
|
|
5233
|
-
)),
|
|
5234
|
-
pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5235
|
-
HumanInputCard,
|
|
5236
|
-
{
|
|
5237
|
-
request,
|
|
5238
|
-
onRespond: onInputResponse
|
|
5239
|
-
},
|
|
5240
|
-
request.requestId
|
|
5241
|
-
))
|
|
5242
|
-
] }) : null
|
|
5243
|
-
] }, message.id)),
|
|
5244
|
-
streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5245
|
-
MessageBubble,
|
|
5246
|
-
{
|
|
5247
|
-
message: streamingMessage,
|
|
5248
|
-
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
5249
|
-
offer: state.pendingOffer,
|
|
5250
|
-
onBook
|
|
5251
|
-
}
|
|
5252
|
-
) : null,
|
|
5253
|
-
waitingForBooking ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(BookingCardLoader, {}) : null,
|
|
5254
|
-
state.error ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("section", { className: "agent-rail__error", role: "alert", children: [
|
|
5255
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
|
|
5256
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("strong", { children: "Something went wrong" }),
|
|
5257
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { children: state.error })
|
|
5258
|
-
] }),
|
|
5259
|
-
onRetry ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
|
|
5260
|
-
] }) : null
|
|
5261
|
-
] }) }),
|
|
5262
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
|
|
5263
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5264
|
-
Composer,
|
|
5265
|
-
{
|
|
5266
|
-
variant: expanded || mobileFullscreen ? "dock" : "default",
|
|
5267
|
-
disabled: isBusy,
|
|
5268
|
-
form: composerForm,
|
|
5269
|
-
placeholder: composerPlaceholder,
|
|
5270
|
-
onSubmit
|
|
5271
|
-
}
|
|
5272
|
-
),
|
|
5273
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "agent-rail__footer", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("p", { children: [
|
|
5274
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "AI can make mistakes. Check important info." }),
|
|
5275
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: poweredByLabel })
|
|
5276
|
-
] }) })
|
|
5277
|
-
] })
|
|
5278
|
-
]
|
|
6225
|
+
) : null
|
|
6226
|
+
]
|
|
6227
|
+
}
|
|
6228
|
+
)
|
|
5279
6229
|
}
|
|
5280
6230
|
);
|
|
5281
6231
|
}
|
|
5282
6232
|
|
|
5283
6233
|
// src/react/components/AssistEdgeTab/AssistEdgeTab.tsx
|
|
5284
|
-
var
|
|
6234
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
5285
6235
|
function SparklesIcon() {
|
|
5286
|
-
return /* @__PURE__ */ (0,
|
|
6236
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
5287
6237
|
"svg",
|
|
5288
6238
|
{
|
|
5289
6239
|
className: "assist-edge-tab__sparkles",
|
|
@@ -5291,21 +6241,21 @@ function SparklesIcon() {
|
|
|
5291
6241
|
fill: "none",
|
|
5292
6242
|
"aria-hidden": "true",
|
|
5293
6243
|
children: [
|
|
5294
|
-
/* @__PURE__ */ (0,
|
|
6244
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5295
6245
|
"path",
|
|
5296
6246
|
{
|
|
5297
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",
|
|
5298
6248
|
fill: "currentColor"
|
|
5299
6249
|
}
|
|
5300
6250
|
),
|
|
5301
|
-
/* @__PURE__ */ (0,
|
|
6251
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5302
6252
|
"path",
|
|
5303
6253
|
{
|
|
5304
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",
|
|
5305
6255
|
fill: "currentColor"
|
|
5306
6256
|
}
|
|
5307
6257
|
),
|
|
5308
|
-
/* @__PURE__ */ (0,
|
|
6258
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5309
6259
|
"path",
|
|
5310
6260
|
{
|
|
5311
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",
|
|
@@ -5319,7 +6269,7 @@ function SparklesIcon() {
|
|
|
5319
6269
|
function TabMarkIcon({ customIconUrl }) {
|
|
5320
6270
|
const url = customIconUrl?.trim();
|
|
5321
6271
|
if (url) {
|
|
5322
|
-
return /* @__PURE__ */ (0,
|
|
6272
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5323
6273
|
"img",
|
|
5324
6274
|
{
|
|
5325
6275
|
alt: "",
|
|
@@ -5329,10 +6279,10 @@ function TabMarkIcon({ customIconUrl }) {
|
|
|
5329
6279
|
}
|
|
5330
6280
|
);
|
|
5331
6281
|
}
|
|
5332
|
-
return /* @__PURE__ */ (0,
|
|
6282
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SparklesIcon, {});
|
|
5333
6283
|
}
|
|
5334
6284
|
function ChevronLeftIcon() {
|
|
5335
|
-
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)(
|
|
5336
6286
|
"path",
|
|
5337
6287
|
{
|
|
5338
6288
|
d: "M10 4L6 8l4 4",
|
|
@@ -5343,8 +6293,8 @@ function ChevronLeftIcon() {
|
|
|
5343
6293
|
}
|
|
5344
6294
|
) });
|
|
5345
6295
|
}
|
|
5346
|
-
function
|
|
5347
|
-
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)(
|
|
5348
6298
|
"path",
|
|
5349
6299
|
{
|
|
5350
6300
|
d: "M4 6l4 4 4-4",
|
|
@@ -5356,7 +6306,7 @@ function ChevronDownIcon() {
|
|
|
5356
6306
|
) });
|
|
5357
6307
|
}
|
|
5358
6308
|
function DragDots() {
|
|
5359
|
-
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)) });
|
|
5360
6310
|
}
|
|
5361
6311
|
var VARIANT_COPY = {
|
|
5362
6312
|
outline: { label: "Ask anything", aria: "Ask anything" },
|
|
@@ -5402,7 +6352,7 @@ function AssistEdgeTab({
|
|
|
5402
6352
|
...resolvedTextColor ? { "--as-text": resolvedTextColor } : {},
|
|
5403
6353
|
colorScheme: resolvedColorScheme
|
|
5404
6354
|
};
|
|
5405
|
-
return /* @__PURE__ */ (0,
|
|
6355
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
5406
6356
|
"button",
|
|
5407
6357
|
{
|
|
5408
6358
|
type: "button",
|
|
@@ -5414,15 +6364,15 @@ function AssistEdgeTab({
|
|
|
5414
6364
|
tabIndex: visible ? 0 : -1,
|
|
5415
6365
|
onClick: onOpen,
|
|
5416
6366
|
children: [
|
|
5417
|
-
mobile ? /* @__PURE__ */ (0,
|
|
5418
|
-
/* @__PURE__ */ (0,
|
|
6367
|
+
mobile ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
6368
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
5419
6369
|
"span",
|
|
5420
6370
|
{
|
|
5421
6371
|
className: "assist-edge-tab__mark assist-edge-tab__mark--mobile",
|
|
5422
6372
|
"aria-hidden": "true",
|
|
5423
6373
|
children: [
|
|
5424
|
-
/* @__PURE__ */ (0,
|
|
5425
|
-
showLogo ? /* @__PURE__ */ (0,
|
|
6374
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
|
|
6375
|
+
showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5426
6376
|
"img",
|
|
5427
6377
|
{
|
|
5428
6378
|
className: "assist-edge-tab__logo",
|
|
@@ -5436,11 +6386,11 @@ function AssistEdgeTab({
|
|
|
5436
6386
|
]
|
|
5437
6387
|
}
|
|
5438
6388
|
),
|
|
5439
|
-
/* @__PURE__ */ (0,
|
|
5440
|
-
] }) : variant === "outline" ? /* @__PURE__ */ (0,
|
|
5441
|
-
/* @__PURE__ */ (0,
|
|
5442
|
-
/* @__PURE__ */ (0,
|
|
5443
|
-
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)(
|
|
5444
6394
|
"img",
|
|
5445
6395
|
{
|
|
5446
6396
|
className: "assist-edge-tab__logo",
|
|
@@ -5452,18 +6402,18 @@ function AssistEdgeTab({
|
|
|
5452
6402
|
}
|
|
5453
6403
|
) : null
|
|
5454
6404
|
] }),
|
|
5455
|
-
/* @__PURE__ */ (0,
|
|
5456
|
-
/* @__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, {})
|
|
5457
6407
|
] }) : null,
|
|
5458
|
-
variant === "ask" ? /* @__PURE__ */ (0,
|
|
5459
|
-
/* @__PURE__ */ (0,
|
|
5460
|
-
/* @__PURE__ */ (0,
|
|
5461
|
-
/* @__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, {})
|
|
5462
6412
|
] }) : null,
|
|
5463
|
-
variant === "fill" ? /* @__PURE__ */ (0,
|
|
5464
|
-
/* @__PURE__ */ (0,
|
|
5465
|
-
/* @__PURE__ */ (0,
|
|
5466
|
-
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)(
|
|
5467
6417
|
"img",
|
|
5468
6418
|
{
|
|
5469
6419
|
className: "assist-edge-tab__logo",
|
|
@@ -5475,16 +6425,72 @@ function AssistEdgeTab({
|
|
|
5475
6425
|
}
|
|
5476
6426
|
) : null
|
|
5477
6427
|
] }),
|
|
5478
|
-
/* @__PURE__ */ (0,
|
|
5479
|
-
/* @__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, {})
|
|
5480
6430
|
] }) : null
|
|
5481
6431
|
]
|
|
5482
6432
|
}
|
|
5483
6433
|
);
|
|
5484
6434
|
}
|
|
5485
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
|
+
|
|
5486
6492
|
// src/react/components/AgentWidget/AgentWidget.tsx
|
|
5487
|
-
var
|
|
6493
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
5488
6494
|
function AgentWidget({
|
|
5489
6495
|
indexId,
|
|
5490
6496
|
customerId,
|
|
@@ -5498,13 +6504,14 @@ function AgentWidget({
|
|
|
5498
6504
|
registerPanelController = false,
|
|
5499
6505
|
colorScheme = "auto",
|
|
5500
6506
|
branding,
|
|
6507
|
+
analytics,
|
|
5501
6508
|
toolResultRegistry
|
|
5502
6509
|
}) {
|
|
5503
6510
|
const isMobile = useIsMobile();
|
|
5504
6511
|
const placement = normalizeAgentPlacement(placementInput);
|
|
5505
|
-
const railSlotRef = (0,
|
|
5506
|
-
const [railCollapsed, setRailCollapsed] = (0,
|
|
5507
|
-
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);
|
|
5508
6515
|
const pageShiftActive = shouldApplyPageShift({
|
|
5509
6516
|
pageShift,
|
|
5510
6517
|
isMobile,
|
|
@@ -5515,7 +6522,17 @@ function AgentWidget({
|
|
|
5515
6522
|
active: pageShiftActive,
|
|
5516
6523
|
railSlotRef
|
|
5517
6524
|
});
|
|
5518
|
-
const {
|
|
6525
|
+
const {
|
|
6526
|
+
state,
|
|
6527
|
+
reset,
|
|
6528
|
+
retry,
|
|
6529
|
+
regenerate,
|
|
6530
|
+
respondToInput,
|
|
6531
|
+
respondToToolInput,
|
|
6532
|
+
submit,
|
|
6533
|
+
visitorSessionId,
|
|
6534
|
+
sessionId
|
|
6535
|
+
} = useAgentChat({
|
|
5519
6536
|
customerId,
|
|
5520
6537
|
getUnpublishedPreviewGrant,
|
|
5521
6538
|
indexId,
|
|
@@ -5547,7 +6564,7 @@ function AgentWidget({
|
|
|
5547
6564
|
} : {},
|
|
5548
6565
|
...branding?.colors?.border ? { border: branding.colors.border } : {}
|
|
5549
6566
|
};
|
|
5550
|
-
(0,
|
|
6567
|
+
(0, import_react15.useEffect)(() => {
|
|
5551
6568
|
if (!registerPanelController) return;
|
|
5552
6569
|
registerAgentPanelController(customerId, {
|
|
5553
6570
|
open: () => setRailCollapsed(false),
|
|
@@ -5564,7 +6581,25 @@ function AgentWidget({
|
|
|
5564
6581
|
if (isMobile) setRailCollapsed(false);
|
|
5565
6582
|
await submit(message);
|
|
5566
6583
|
}
|
|
5567
|
-
(
|
|
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)(() => {
|
|
5568
6603
|
if (railCollapsed) return;
|
|
5569
6604
|
const handleKeyDown = (event) => {
|
|
5570
6605
|
if (event.key === "Tab" && (isMobile || railExpanded)) {
|
|
@@ -5598,19 +6633,19 @@ function AgentWidget({
|
|
|
5598
6633
|
window.addEventListener("keydown", handleKeyDown);
|
|
5599
6634
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
5600
6635
|
}, [isMobile, railCollapsed, railExpanded]);
|
|
5601
|
-
return /* @__PURE__ */ (0,
|
|
5602
|
-
/* @__PURE__ */ (0,
|
|
6636
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "webless-agent-root", children: [
|
|
6637
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5603
6638
|
"div",
|
|
5604
6639
|
{
|
|
5605
6640
|
className: `webless-agent-root__shell${railCollapsed ? " webless-agent-root__shell--collapsed" : ""}${railExpanded ? " webless-agent-root__shell--expanded" : ""}`,
|
|
5606
|
-
children: /* @__PURE__ */ (0,
|
|
6641
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5607
6642
|
"div",
|
|
5608
6643
|
{
|
|
5609
6644
|
ref: railSlotRef,
|
|
5610
6645
|
className: "webless-agent-root__rail-slot",
|
|
5611
6646
|
inert: railCollapsed || void 0,
|
|
5612
6647
|
"aria-hidden": railCollapsed,
|
|
5613
|
-
children: /* @__PURE__ */ (0,
|
|
6648
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5614
6649
|
AgentRail,
|
|
5615
6650
|
{
|
|
5616
6651
|
theme,
|
|
@@ -5619,6 +6654,9 @@ function AgentWidget({
|
|
|
5619
6654
|
brandLogoUrl: branding?.logoUrl,
|
|
5620
6655
|
composerPlaceholder: branding?.composerPlaceholder ?? "Ask a question\u2026",
|
|
5621
6656
|
poweredByLabel: branding?.poweredByLabel ?? "Powered by Webless",
|
|
6657
|
+
disclaimerLabel: branding?.disclaimer,
|
|
6658
|
+
answerReceipt: branding?.answerReceipt,
|
|
6659
|
+
readAloud: branding?.readAloud,
|
|
5622
6660
|
state,
|
|
5623
6661
|
mobileFullscreen: isMobile && !railCollapsed,
|
|
5624
6662
|
expanded: railExpanded,
|
|
@@ -5628,17 +6666,22 @@ function AgentWidget({
|
|
|
5628
6666
|
onSubmit: handleSubmit,
|
|
5629
6667
|
onReset: reset,
|
|
5630
6668
|
onRetry: () => void retry(),
|
|
6669
|
+
onRegenerate: () => void regenerate(),
|
|
6670
|
+
onFeedback: analytics ? handleFeedback : void 0,
|
|
5631
6671
|
onInputResponse: (response) => void respondToInput(response),
|
|
5632
6672
|
onToolInput: (surface, values) => void respondToToolInput(surface, values),
|
|
5633
6673
|
onFollowUpSelect: (label) => void handleSubmit(label),
|
|
5634
|
-
onBook: (input) => void submit(input.displayText, {
|
|
6674
|
+
onBook: (input) => void submit(input.displayText, {
|
|
6675
|
+
preservePendingOffer: true,
|
|
6676
|
+
runtimeText: input.runtimeText
|
|
6677
|
+
})
|
|
5635
6678
|
}
|
|
5636
6679
|
)
|
|
5637
6680
|
}
|
|
5638
6681
|
)
|
|
5639
6682
|
}
|
|
5640
6683
|
),
|
|
5641
|
-
railCollapsed ? /* @__PURE__ */ (0,
|
|
6684
|
+
railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5642
6685
|
AssistEdgeTab,
|
|
5643
6686
|
{
|
|
5644
6687
|
variant: placement.variant,
|
|
@@ -5677,12 +6720,12 @@ function readUnpublishedPreviewBuildId(href) {
|
|
|
5677
6720
|
}
|
|
5678
6721
|
|
|
5679
6722
|
// src/embed/AgentWidget.tsx
|
|
5680
|
-
var
|
|
6723
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
5681
6724
|
function AgentWidget2({
|
|
5682
6725
|
manifest
|
|
5683
6726
|
}) {
|
|
5684
6727
|
const defaultCollapsed = manifest.version !== "unpublished";
|
|
5685
|
-
return /* @__PURE__ */ (0,
|
|
6728
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5686
6729
|
AgentWidget,
|
|
5687
6730
|
{
|
|
5688
6731
|
indexId: manifest.indexId,
|
|
@@ -5694,6 +6737,7 @@ function AgentWidget2({
|
|
|
5694
6737
|
pageShift: manifest.pageShift,
|
|
5695
6738
|
colorScheme: manifest.colorScheme,
|
|
5696
6739
|
branding: manifest.branding,
|
|
6740
|
+
analytics: manifest.analytics,
|
|
5697
6741
|
defaultCollapsed,
|
|
5698
6742
|
registerPanelController: true
|
|
5699
6743
|
}
|
|
@@ -5724,6 +6768,7 @@ function normalizeAgentTagManifest(manifest) {
|
|
|
5724
6768
|
runtimeOrigin: manifest.runtimeOrigin?.trim() || DEFAULT_RUNTIME_ORIGIN
|
|
5725
6769
|
});
|
|
5726
6770
|
const branding = normalizeAgentBranding(manifest.branding);
|
|
6771
|
+
const analytics = normalizeAgentAnalytics(manifest.analytics);
|
|
5727
6772
|
return {
|
|
5728
6773
|
customerId,
|
|
5729
6774
|
indexId,
|
|
@@ -5736,7 +6781,27 @@ function normalizeAgentTagManifest(manifest) {
|
|
|
5736
6781
|
placement: normalizeAgentPlacement(manifest.placement),
|
|
5737
6782
|
pageShift: manifest.pageShift ?? true,
|
|
5738
6783
|
colorScheme,
|
|
5739
|
-
...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
|
|
5740
6805
|
};
|
|
5741
6806
|
}
|
|
5742
6807
|
function normalizeOptionalValue(value) {
|
|
@@ -5759,6 +6824,9 @@ function normalizeAgentBranding(branding) {
|
|
|
5759
6824
|
greeting: normalizeOptionalValue(branding.greeting),
|
|
5760
6825
|
composerPlaceholder: normalizeOptionalValue(branding.composerPlaceholder),
|
|
5761
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,
|
|
5762
6830
|
fontFamily: normalizeOptionalValue(branding.fontFamily),
|
|
5763
6831
|
colors: colors && Object.keys(colors).length > 0 ? colors : void 0
|
|
5764
6832
|
};
|
|
@@ -5766,7 +6834,7 @@ function normalizeAgentBranding(branding) {
|
|
|
5766
6834
|
}
|
|
5767
6835
|
|
|
5768
6836
|
// src/embed/mount.tsx
|
|
5769
|
-
var
|
|
6837
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
5770
6838
|
var mountedHandles = /* @__PURE__ */ new Map();
|
|
5771
6839
|
var latestCustomerId = null;
|
|
5772
6840
|
function resolveMountHost(manifest, script) {
|
|
@@ -5796,7 +6864,7 @@ function mountAgent(input) {
|
|
|
5796
6864
|
const host = createHost(manifest.customerId);
|
|
5797
6865
|
mountTarget.append(host);
|
|
5798
6866
|
const root = (0, import_client5.createRoot)(host);
|
|
5799
|
-
root.render(/* @__PURE__ */ (0,
|
|
6867
|
+
root.render(/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(AgentWidget2, { manifest }));
|
|
5800
6868
|
const handle = {
|
|
5801
6869
|
customerId: manifest.customerId,
|
|
5802
6870
|
manifest,
|