@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
|
@@ -780,6 +780,30 @@ function bookingPresenter(kind) {
|
|
|
780
780
|
}
|
|
781
781
|
};
|
|
782
782
|
}
|
|
783
|
+
function providerErrorPresenter() {
|
|
784
|
+
return {
|
|
785
|
+
kind: "provider_error",
|
|
786
|
+
present: ({ envelope }) => {
|
|
787
|
+
const output = asRecord3(envelope.output);
|
|
788
|
+
const providerError = asRecord3(output?.providerError);
|
|
789
|
+
const message = safeText(providerError?.message);
|
|
790
|
+
const action = safeText(providerError?.action);
|
|
791
|
+
if (!message || !action) return null;
|
|
792
|
+
const resourceLabels = Array.isArray(providerError?.resourceLabels) ? providerError.resourceLabels.map(safeText).filter(Boolean).slice(0, MAX_DETAILS) : [];
|
|
793
|
+
return {
|
|
794
|
+
kind: "summary",
|
|
795
|
+
status: "failed",
|
|
796
|
+
title: message,
|
|
797
|
+
description: action,
|
|
798
|
+
...resourceLabels.length ? {
|
|
799
|
+
details: [
|
|
800
|
+
{ label: "Affected", value: resourceLabels.join(", ") }
|
|
801
|
+
]
|
|
802
|
+
} : {}
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
};
|
|
806
|
+
}
|
|
783
807
|
function asRecord3(value) {
|
|
784
808
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
785
809
|
}
|
|
@@ -897,6 +921,7 @@ function fallbackTitleFromKind(kind) {
|
|
|
897
921
|
return "Saved";
|
|
898
922
|
}
|
|
899
923
|
var builtInVisitorToolResultRegistry = [
|
|
924
|
+
providerErrorPresenter(),
|
|
900
925
|
bookingPresenter("booking_offer"),
|
|
901
926
|
bookingPresenter("booking_confirmed"),
|
|
902
927
|
bookingPresenter("booking_canceled"),
|
|
@@ -946,7 +971,7 @@ function finalizeSummaryPresentation(result, proposed) {
|
|
|
946
971
|
return {
|
|
947
972
|
id: result.callId,
|
|
948
973
|
toolName: result.toolName,
|
|
949
|
-
status: result.status,
|
|
974
|
+
status: proposed.status ?? result.status,
|
|
950
975
|
kind: "summary",
|
|
951
976
|
title,
|
|
952
977
|
...description && description !== title ? { description } : {},
|
|
@@ -955,7 +980,7 @@ function finalizeSummaryPresentation(result, proposed) {
|
|
|
955
980
|
};
|
|
956
981
|
}
|
|
957
982
|
function presentVisitorToolResult(result, registry = []) {
|
|
958
|
-
const envelope = parseAgentToolResultEnvelope(result.output) ?? legacyBookingEnvelope(result.output);
|
|
983
|
+
const envelope = parseAgentToolResultEnvelope(result.output) ?? providerErrorEnvelope(result.output) ?? legacyBookingEnvelope(result.output);
|
|
959
984
|
const proposed = envelope ? resolvePresenterOutput(result, envelope, registry) : null;
|
|
960
985
|
if (proposed?.kind === "booking") {
|
|
961
986
|
return {
|
|
@@ -1018,6 +1043,25 @@ function presentVisitorToolResult(result, registry = []) {
|
|
|
1018
1043
|
}
|
|
1019
1044
|
return finalizeSummaryPresentation(result, proposed);
|
|
1020
1045
|
}
|
|
1046
|
+
function providerErrorEnvelope(output) {
|
|
1047
|
+
const record = asRecord3(output);
|
|
1048
|
+
const providerError = asRecord3(record?.providerError);
|
|
1049
|
+
const message = safeText(providerError?.message);
|
|
1050
|
+
const action = safeText(providerError?.action);
|
|
1051
|
+
if (!message || !action) return null;
|
|
1052
|
+
const resourceLabels = Array.isArray(providerError?.resourceLabels) ? providerError.resourceLabels.map(safeText).filter(Boolean).slice(0, MAX_DETAILS) : [];
|
|
1053
|
+
return {
|
|
1054
|
+
schemaVersion: "webless.tool-result.v1",
|
|
1055
|
+
output: {
|
|
1056
|
+
providerError: {
|
|
1057
|
+
action,
|
|
1058
|
+
message,
|
|
1059
|
+
...resourceLabels.length ? { resourceLabels } : {}
|
|
1060
|
+
}
|
|
1061
|
+
},
|
|
1062
|
+
presentationKinds: ["provider_error"]
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1021
1065
|
function legacyBookingEnvelope(output) {
|
|
1022
1066
|
const card = bookingCardFromActionOutput(output);
|
|
1023
1067
|
return card ? {
|
|
@@ -1573,6 +1617,20 @@ function latestTurnEvents(events) {
|
|
|
1573
1617
|
}
|
|
1574
1618
|
return startIndex >= 0 ? events.slice(startIndex) : [];
|
|
1575
1619
|
}
|
|
1620
|
+
function streamIndexBeforeLastTurn(input) {
|
|
1621
|
+
let turnStart = -1;
|
|
1622
|
+
for (let index = input.events.length - 1; index >= 0; index -= 1) {
|
|
1623
|
+
if (input.events[index]?.type === "message.received") {
|
|
1624
|
+
turnStart = index;
|
|
1625
|
+
break;
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
if (turnStart < 0) return null;
|
|
1629
|
+
return Math.max(
|
|
1630
|
+
0,
|
|
1631
|
+
input.currentStreamIndex - (input.events.length - turnStart)
|
|
1632
|
+
);
|
|
1633
|
+
}
|
|
1576
1634
|
function renderTurn(events) {
|
|
1577
1635
|
let rendered = "";
|
|
1578
1636
|
for (const event of events) {
|
|
@@ -1757,6 +1815,40 @@ var AgentSession = class {
|
|
|
1757
1815
|
this.storeOptions
|
|
1758
1816
|
);
|
|
1759
1817
|
}
|
|
1818
|
+
async rewindBeforeLastTurn(signal) {
|
|
1819
|
+
const persisted = loadPersistedAgentSession(
|
|
1820
|
+
this.visitorSessionId,
|
|
1821
|
+
this.storeOptions
|
|
1822
|
+
);
|
|
1823
|
+
if (!persisted?.sessionId) return false;
|
|
1824
|
+
const client = this.ensureClient();
|
|
1825
|
+
const attached = client.sessions.attach(persisted.sessionId, {
|
|
1826
|
+
streamIndex: persisted.streamIndex
|
|
1827
|
+
});
|
|
1828
|
+
const snapshot = await withCapabilityRefresh(
|
|
1829
|
+
this.capability,
|
|
1830
|
+
() => attached.snapshot({ signal })
|
|
1831
|
+
);
|
|
1832
|
+
const rewindStreamIndex = streamIndexBeforeLastTurn({
|
|
1833
|
+
currentStreamIndex: snapshot.session.streamIndex,
|
|
1834
|
+
events: snapshot.events
|
|
1835
|
+
});
|
|
1836
|
+
if (rewindStreamIndex === null) return false;
|
|
1837
|
+
this.session = client.sessions.attach(persisted.sessionId, {
|
|
1838
|
+
streamIndex: rewindStreamIndex
|
|
1839
|
+
});
|
|
1840
|
+
savePersistedAgentSession(
|
|
1841
|
+
this.visitorSessionId,
|
|
1842
|
+
persisted.sessionId,
|
|
1843
|
+
rewindStreamIndex,
|
|
1844
|
+
this.storeOptions
|
|
1845
|
+
);
|
|
1846
|
+
return true;
|
|
1847
|
+
}
|
|
1848
|
+
async regenerateTurn(message, signal, handlers) {
|
|
1849
|
+
await this.rewindBeforeLastTurn(signal);
|
|
1850
|
+
return this.sendTurn(message, signal, handlers);
|
|
1851
|
+
}
|
|
1760
1852
|
ensureClient() {
|
|
1761
1853
|
const config = resolveAgentRuntimeConfig({
|
|
1762
1854
|
indexId: this.indexId,
|
|
@@ -2092,6 +2184,11 @@ function createAgentClient(options) {
|
|
|
2092
2184
|
respondOptions.signal ?? new AbortController().signal,
|
|
2093
2185
|
respondOptions.handlers
|
|
2094
2186
|
),
|
|
2187
|
+
regenerateTurn: (message, regenerateOptions) => session.regenerateTurn(
|
|
2188
|
+
message,
|
|
2189
|
+
regenerateOptions.signal ?? new AbortController().signal,
|
|
2190
|
+
regenerateOptions.handlers
|
|
2191
|
+
),
|
|
2095
2192
|
reset: () => session.reset(),
|
|
2096
2193
|
cancelActive: () => session.cancelActive(),
|
|
2097
2194
|
getActiveSessionId: () => session.getActiveSessionId()
|
|
@@ -2692,6 +2789,7 @@ function useAgentChat({
|
|
|
2692
2789
|
const {
|
|
2693
2790
|
controller,
|
|
2694
2791
|
initialText = "",
|
|
2792
|
+
regenerate: regenerate2 = false,
|
|
2695
2793
|
responses,
|
|
2696
2794
|
resume,
|
|
2697
2795
|
visitorText
|
|
@@ -2702,6 +2800,7 @@ function useAgentChat({
|
|
|
2702
2800
|
let streamStarted = Boolean(initialText);
|
|
2703
2801
|
let streamed = initialText;
|
|
2704
2802
|
const capturedOffers = [];
|
|
2803
|
+
let bookingConfirmed = false;
|
|
2705
2804
|
let capturedInputCount = 0;
|
|
2706
2805
|
const handlers = {
|
|
2707
2806
|
onWork: (item) => {
|
|
@@ -2726,6 +2825,7 @@ function useAgentChat({
|
|
|
2726
2825
|
}
|
|
2727
2826
|
if (!isActiveRun()) return;
|
|
2728
2827
|
if (card.type === "booking_confirmed") {
|
|
2828
|
+
bookingConfirmed = true;
|
|
2729
2829
|
pendingBookingRef.current = card;
|
|
2730
2830
|
savePendingWidgetBooking(
|
|
2731
2831
|
resolvedStorageKeyPrefix,
|
|
@@ -2801,7 +2901,13 @@ function useAgentChat({
|
|
|
2801
2901
|
initialText,
|
|
2802
2902
|
message: visitorText,
|
|
2803
2903
|
signal
|
|
2804
|
-
}) : await clientRef.current.
|
|
2904
|
+
}) : regenerate2 ? await clientRef.current.regenerateTurn(visitorText, {
|
|
2905
|
+
handlers,
|
|
2906
|
+
signal
|
|
2907
|
+
}) : await clientRef.current.sendTurn(visitorText, {
|
|
2908
|
+
handlers,
|
|
2909
|
+
signal
|
|
2910
|
+
});
|
|
2805
2911
|
if (resume && finalText === null) {
|
|
2806
2912
|
finalText = await clientRef.current.sendTurn(visitorText, {
|
|
2807
2913
|
handlers,
|
|
@@ -2820,6 +2926,7 @@ function useAgentChat({
|
|
|
2820
2926
|
const parsedCards = extractToolCards(displayText);
|
|
2821
2927
|
for (const card of parsedCards) {
|
|
2822
2928
|
if (card.type === "booking_confirmed") {
|
|
2929
|
+
bookingConfirmed = true;
|
|
2823
2930
|
pendingBookingRef.current = card;
|
|
2824
2931
|
savePendingWidgetBooking(resolvedStorageKeyPrefix, visitorId, card);
|
|
2825
2932
|
}
|
|
@@ -2834,7 +2941,7 @@ function useAgentChat({
|
|
|
2834
2941
|
messages: appendAgentTurnMessage(prev.messages, displayText),
|
|
2835
2942
|
toolSteps: completeActivePlanning(prev.toolSteps),
|
|
2836
2943
|
streamingText: "",
|
|
2837
|
-
pendingOffer: capturedOffers.at(-1) ?? prev.pendingOffer,
|
|
2944
|
+
pendingOffer: bookingConfirmed ? null : capturedOffers.at(-1) ?? prev.pendingOffer,
|
|
2838
2945
|
pendingInputs: (prev.pendingInputs ?? []).filter(
|
|
2839
2946
|
isChatCollectibleInputRequest
|
|
2840
2947
|
),
|
|
@@ -2860,7 +2967,6 @@ function useAgentChat({
|
|
|
2860
2967
|
} : step
|
|
2861
2968
|
),
|
|
2862
2969
|
streamingText: "",
|
|
2863
|
-
pendingOffer: null,
|
|
2864
2970
|
error: message
|
|
2865
2971
|
}));
|
|
2866
2972
|
runRef.current = null;
|
|
@@ -2968,7 +3074,7 @@ ${outgoing}` : outgoing;
|
|
|
2968
3074
|
journey: null,
|
|
2969
3075
|
followUps: [],
|
|
2970
3076
|
streamingText: "",
|
|
2971
|
-
pendingOffer: null,
|
|
3077
|
+
pendingOffer: options?.preservePendingOffer ? prev.pendingOffer : null,
|
|
2972
3078
|
pendingInputs: [],
|
|
2973
3079
|
toolResults: [],
|
|
2974
3080
|
error: null
|
|
@@ -3004,7 +3110,6 @@ ${outgoing}` : outgoing;
|
|
|
3004
3110
|
journey: null,
|
|
3005
3111
|
followUps: [],
|
|
3006
3112
|
streamingText: "",
|
|
3007
|
-
pendingOffer: null,
|
|
3008
3113
|
pendingInputs: [],
|
|
3009
3114
|
toolResults: [],
|
|
3010
3115
|
error: null
|
|
@@ -3015,6 +3120,49 @@ ${outgoing}` : outgoing;
|
|
|
3015
3120
|
visitorText: visitorTurnText(visitorMessage)
|
|
3016
3121
|
});
|
|
3017
3122
|
}, [runTurn, state.messages]);
|
|
3123
|
+
const regenerate = useCallback(async () => {
|
|
3124
|
+
let lastVisitorIndex = -1;
|
|
3125
|
+
for (let index = state.messages.length - 1; index >= 0; index -= 1) {
|
|
3126
|
+
if (state.messages[index]?.role === "visitor") {
|
|
3127
|
+
lastVisitorIndex = index;
|
|
3128
|
+
break;
|
|
3129
|
+
}
|
|
3130
|
+
}
|
|
3131
|
+
const visitorMessage = lastVisitorIndex >= 0 ? state.messages[lastVisitorIndex] : void 0;
|
|
3132
|
+
if (!visitorMessage) return null;
|
|
3133
|
+
if (runRef.current) {
|
|
3134
|
+
runRef.current.abort();
|
|
3135
|
+
clientRef.current.cancelActive();
|
|
3136
|
+
}
|
|
3137
|
+
const controller = new AbortController();
|
|
3138
|
+
runRef.current = controller;
|
|
3139
|
+
setState((prev) => ({
|
|
3140
|
+
...prev,
|
|
3141
|
+
phase: "thinking",
|
|
3142
|
+
messages: prev.messages.slice(0, lastVisitorIndex + 1),
|
|
3143
|
+
toolSteps: [
|
|
3144
|
+
{
|
|
3145
|
+
id: "planning",
|
|
3146
|
+
kind: "planning",
|
|
3147
|
+
label: "Understanding your question",
|
|
3148
|
+
state: "active"
|
|
3149
|
+
}
|
|
3150
|
+
],
|
|
3151
|
+
journey: null,
|
|
3152
|
+
followUps: [],
|
|
3153
|
+
streamingText: "",
|
|
3154
|
+
pendingOffer: null,
|
|
3155
|
+
pendingInputs: [],
|
|
3156
|
+
toolResults: [],
|
|
3157
|
+
error: null
|
|
3158
|
+
}));
|
|
3159
|
+
return await runTurn({
|
|
3160
|
+
controller,
|
|
3161
|
+
regenerate: true,
|
|
3162
|
+
resume: false,
|
|
3163
|
+
visitorText: visitorTurnText(visitorMessage)
|
|
3164
|
+
});
|
|
3165
|
+
}, [runTurn, state.messages]);
|
|
3018
3166
|
const respondToToolInput = useCallback(
|
|
3019
3167
|
async (surface, values) => {
|
|
3020
3168
|
await submit(`${surface.title} submitted`, {
|
|
@@ -3091,6 +3239,7 @@ ${outgoing}` : outgoing;
|
|
|
3091
3239
|
state,
|
|
3092
3240
|
reset,
|
|
3093
3241
|
retry,
|
|
3242
|
+
regenerate,
|
|
3094
3243
|
respondToInput,
|
|
3095
3244
|
respondToToolInput,
|
|
3096
3245
|
submit,
|
|
@@ -3196,8 +3345,505 @@ var defaultDarkAgentRailTheme = {
|
|
|
3196
3345
|
danger: "#ff8da1"
|
|
3197
3346
|
};
|
|
3198
3347
|
|
|
3348
|
+
// src/react/components/MessageActions/MessageActions.tsx
|
|
3349
|
+
import { useEffect as useEffect2, useLayoutEffect, useRef as useRef2, useState as useState2 } from "react";
|
|
3350
|
+
import { createPortal } from "react-dom";
|
|
3351
|
+
|
|
3352
|
+
// src/react/lib/speech.ts
|
|
3353
|
+
function toSpeechText(text) {
|
|
3354
|
+
let out = hideToolCardFences(text);
|
|
3355
|
+
out = out.replace(/```[\s\S]*?```/g, " ");
|
|
3356
|
+
out = out.replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1");
|
|
3357
|
+
out = out.replace(/\[([^\]]+)\]\([^)]*\)/g, "$1");
|
|
3358
|
+
out = out.replace(/^\s{0,3}#{1,6}\s+/gm, "");
|
|
3359
|
+
out = out.replace(/(\*\*|__)(.*?)\1/g, "$2");
|
|
3360
|
+
out = out.replace(/(\*|_)(.*?)\1/g, "$2");
|
|
3361
|
+
out = out.replace(/~~(.*?)~~/g, "$1");
|
|
3362
|
+
out = out.replace(/`([^`]*)`/g, "$1");
|
|
3363
|
+
out = out.replace(/^\s*>\s?/gm, "");
|
|
3364
|
+
out = out.replace(/^\s*[-*+]\s+/gm, "");
|
|
3365
|
+
out = out.replace(/^\s*\d+\.\s+/gm, "");
|
|
3366
|
+
out = out.replace(/\|/g, " ");
|
|
3367
|
+
out = out.replace(/^\s*[-:]{3,}\s*$/gm, " ");
|
|
3368
|
+
out = out.replace(/\s*\n\s*/g, ". ");
|
|
3369
|
+
out = out.replace(/(?:\.\s*){2,}/g, ". ");
|
|
3370
|
+
return out.replace(/\s{2,}/g, " ").trim();
|
|
3371
|
+
}
|
|
3372
|
+
function isSpeechSupported() {
|
|
3373
|
+
return typeof window !== "undefined" && "speechSynthesis" in window && typeof window.SpeechSynthesisUtterance === "function";
|
|
3374
|
+
}
|
|
3375
|
+
|
|
3376
|
+
// src/react/components/AgentRail/AgentRailOverlayContext.tsx
|
|
3377
|
+
import { createContext, useContext } from "react";
|
|
3378
|
+
var AgentRailOverlayContext = createContext(null);
|
|
3379
|
+
function useAgentRailPortalRoots() {
|
|
3380
|
+
return useContext(AgentRailOverlayContext);
|
|
3381
|
+
}
|
|
3382
|
+
function useAgentRailMenuPortalRoot() {
|
|
3383
|
+
return useContext(AgentRailOverlayContext)?.railRef ?? null;
|
|
3384
|
+
}
|
|
3385
|
+
|
|
3386
|
+
// src/react/components/MessageActions/MessageActions.tsx
|
|
3387
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3388
|
+
function CopyIcon() {
|
|
3389
|
+
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
|
|
3390
|
+
/* @__PURE__ */ jsx(
|
|
3391
|
+
"rect",
|
|
3392
|
+
{
|
|
3393
|
+
x: "5.75",
|
|
3394
|
+
y: "5.75",
|
|
3395
|
+
width: "7.5",
|
|
3396
|
+
height: "7.5",
|
|
3397
|
+
rx: "1.5",
|
|
3398
|
+
stroke: "currentColor",
|
|
3399
|
+
strokeWidth: "1.5"
|
|
3400
|
+
}
|
|
3401
|
+
),
|
|
3402
|
+
/* @__PURE__ */ jsx(
|
|
3403
|
+
"path",
|
|
3404
|
+
{
|
|
3405
|
+
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",
|
|
3406
|
+
stroke: "currentColor",
|
|
3407
|
+
strokeWidth: "1.5"
|
|
3408
|
+
}
|
|
3409
|
+
)
|
|
3410
|
+
] });
|
|
3411
|
+
}
|
|
3412
|
+
function CheckIcon() {
|
|
3413
|
+
return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
|
|
3414
|
+
"path",
|
|
3415
|
+
{
|
|
3416
|
+
d: "M3.5 8.5l3 3 6-7",
|
|
3417
|
+
stroke: "currentColor",
|
|
3418
|
+
strokeWidth: "1.6",
|
|
3419
|
+
strokeLinecap: "round",
|
|
3420
|
+
strokeLinejoin: "round"
|
|
3421
|
+
}
|
|
3422
|
+
) });
|
|
3423
|
+
}
|
|
3424
|
+
function ThumbUpIcon() {
|
|
3425
|
+
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
|
|
3426
|
+
/* @__PURE__ */ jsx(
|
|
3427
|
+
"path",
|
|
3428
|
+
{
|
|
3429
|
+
d: "M4.67 6.67v8",
|
|
3430
|
+
stroke: "currentColor",
|
|
3431
|
+
strokeWidth: "1.5",
|
|
3432
|
+
strokeLinecap: "round"
|
|
3433
|
+
}
|
|
3434
|
+
),
|
|
3435
|
+
/* @__PURE__ */ jsx(
|
|
3436
|
+
"path",
|
|
3437
|
+
{
|
|
3438
|
+
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",
|
|
3439
|
+
stroke: "currentColor",
|
|
3440
|
+
strokeWidth: "1.5",
|
|
3441
|
+
strokeLinecap: "round",
|
|
3442
|
+
strokeLinejoin: "round"
|
|
3443
|
+
}
|
|
3444
|
+
)
|
|
3445
|
+
] });
|
|
3446
|
+
}
|
|
3447
|
+
function ThumbDownIcon() {
|
|
3448
|
+
return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxs("g", { transform: "rotate(180 8 8)", children: [
|
|
3449
|
+
/* @__PURE__ */ jsx(
|
|
3450
|
+
"path",
|
|
3451
|
+
{
|
|
3452
|
+
d: "M4.67 6.67v8",
|
|
3453
|
+
stroke: "currentColor",
|
|
3454
|
+
strokeWidth: "1.5",
|
|
3455
|
+
strokeLinecap: "round"
|
|
3456
|
+
}
|
|
3457
|
+
),
|
|
3458
|
+
/* @__PURE__ */ jsx(
|
|
3459
|
+
"path",
|
|
3460
|
+
{
|
|
3461
|
+
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",
|
|
3462
|
+
stroke: "currentColor",
|
|
3463
|
+
strokeWidth: "1.5",
|
|
3464
|
+
strokeLinecap: "round",
|
|
3465
|
+
strokeLinejoin: "round"
|
|
3466
|
+
}
|
|
3467
|
+
)
|
|
3468
|
+
] }) });
|
|
3469
|
+
}
|
|
3470
|
+
function RegenerateIcon() {
|
|
3471
|
+
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
|
|
3472
|
+
/* @__PURE__ */ jsx(
|
|
3473
|
+
"path",
|
|
3474
|
+
{
|
|
3475
|
+
d: "M2 8a6 6 0 0 1 6-6 6.5 6.5 0 0 1 4.5 1.83L14 5.33",
|
|
3476
|
+
stroke: "currentColor",
|
|
3477
|
+
strokeWidth: "1.5",
|
|
3478
|
+
strokeLinecap: "round"
|
|
3479
|
+
}
|
|
3480
|
+
),
|
|
3481
|
+
/* @__PURE__ */ jsx(
|
|
3482
|
+
"path",
|
|
3483
|
+
{
|
|
3484
|
+
d: "M14 2v3.33h-3.33",
|
|
3485
|
+
stroke: "currentColor",
|
|
3486
|
+
strokeWidth: "1.5",
|
|
3487
|
+
strokeLinecap: "round",
|
|
3488
|
+
strokeLinejoin: "round"
|
|
3489
|
+
}
|
|
3490
|
+
),
|
|
3491
|
+
/* @__PURE__ */ jsx(
|
|
3492
|
+
"path",
|
|
3493
|
+
{
|
|
3494
|
+
d: "M14 8a6 6 0 0 1-6 6 6.5 6.5 0 0 1-4.5-1.83L2 10.67",
|
|
3495
|
+
stroke: "currentColor",
|
|
3496
|
+
strokeWidth: "1.5",
|
|
3497
|
+
strokeLinecap: "round"
|
|
3498
|
+
}
|
|
3499
|
+
),
|
|
3500
|
+
/* @__PURE__ */ jsx(
|
|
3501
|
+
"path",
|
|
3502
|
+
{
|
|
3503
|
+
d: "M5.33 10.67H2V14",
|
|
3504
|
+
stroke: "currentColor",
|
|
3505
|
+
strokeWidth: "1.5",
|
|
3506
|
+
strokeLinecap: "round",
|
|
3507
|
+
strokeLinejoin: "round"
|
|
3508
|
+
}
|
|
3509
|
+
)
|
|
3510
|
+
] });
|
|
3511
|
+
}
|
|
3512
|
+
function MoreIcon() {
|
|
3513
|
+
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
|
|
3514
|
+
/* @__PURE__ */ jsx("circle", { cx: "3.5", cy: "8", r: "1.15", fill: "currentColor" }),
|
|
3515
|
+
/* @__PURE__ */ jsx("circle", { cx: "8", cy: "8", r: "1.15", fill: "currentColor" }),
|
|
3516
|
+
/* @__PURE__ */ jsx("circle", { cx: "12.5", cy: "8", r: "1.15", fill: "currentColor" })
|
|
3517
|
+
] });
|
|
3518
|
+
}
|
|
3519
|
+
function SourcesIcon() {
|
|
3520
|
+
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
|
|
3521
|
+
/* @__PURE__ */ jsx(
|
|
3522
|
+
"path",
|
|
3523
|
+
{
|
|
3524
|
+
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",
|
|
3525
|
+
stroke: "currentColor",
|
|
3526
|
+
strokeWidth: "1.4",
|
|
3527
|
+
strokeLinecap: "round",
|
|
3528
|
+
strokeLinejoin: "round"
|
|
3529
|
+
}
|
|
3530
|
+
),
|
|
3531
|
+
/* @__PURE__ */ jsx(
|
|
3532
|
+
"path",
|
|
3533
|
+
{
|
|
3534
|
+
d: "M8 4.5v9",
|
|
3535
|
+
stroke: "currentColor",
|
|
3536
|
+
strokeWidth: "1.4",
|
|
3537
|
+
strokeLinecap: "round"
|
|
3538
|
+
}
|
|
3539
|
+
)
|
|
3540
|
+
] });
|
|
3541
|
+
}
|
|
3542
|
+
function ReadAloudIcon() {
|
|
3543
|
+
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
|
|
3544
|
+
/* @__PURE__ */ jsx(
|
|
3545
|
+
"path",
|
|
3546
|
+
{
|
|
3547
|
+
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",
|
|
3548
|
+
stroke: "currentColor",
|
|
3549
|
+
strokeWidth: "1.4",
|
|
3550
|
+
strokeLinecap: "round",
|
|
3551
|
+
strokeLinejoin: "round"
|
|
3552
|
+
}
|
|
3553
|
+
),
|
|
3554
|
+
/* @__PURE__ */ jsx(
|
|
3555
|
+
"path",
|
|
3556
|
+
{
|
|
3557
|
+
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",
|
|
3558
|
+
stroke: "currentColor",
|
|
3559
|
+
strokeWidth: "1.4",
|
|
3560
|
+
strokeLinecap: "round"
|
|
3561
|
+
}
|
|
3562
|
+
)
|
|
3563
|
+
] });
|
|
3564
|
+
}
|
|
3565
|
+
function StopIcon() {
|
|
3566
|
+
return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
|
|
3567
|
+
"rect",
|
|
3568
|
+
{
|
|
3569
|
+
x: "4",
|
|
3570
|
+
y: "4",
|
|
3571
|
+
width: "8",
|
|
3572
|
+
height: "8",
|
|
3573
|
+
rx: "1.5",
|
|
3574
|
+
stroke: "currentColor",
|
|
3575
|
+
strokeWidth: "1.5"
|
|
3576
|
+
}
|
|
3577
|
+
) });
|
|
3578
|
+
}
|
|
3579
|
+
async function writeToClipboard(text) {
|
|
3580
|
+
try {
|
|
3581
|
+
await navigator.clipboard.writeText(text);
|
|
3582
|
+
} catch {
|
|
3583
|
+
const textarea = document.createElement("textarea");
|
|
3584
|
+
textarea.value = text;
|
|
3585
|
+
textarea.style.position = "fixed";
|
|
3586
|
+
textarea.style.opacity = "0";
|
|
3587
|
+
document.body.appendChild(textarea);
|
|
3588
|
+
textarea.select();
|
|
3589
|
+
document.execCommand("copy");
|
|
3590
|
+
textarea.remove();
|
|
3591
|
+
}
|
|
3592
|
+
}
|
|
3593
|
+
function formatAnsweredAt(answeredAt) {
|
|
3594
|
+
if (!answeredAt) return null;
|
|
3595
|
+
const date = new Date(answeredAt);
|
|
3596
|
+
if (Number.isNaN(date.getTime())) return null;
|
|
3597
|
+
return new Intl.DateTimeFormat(void 0, {
|
|
3598
|
+
dateStyle: "medium",
|
|
3599
|
+
timeStyle: "short"
|
|
3600
|
+
}).format(date);
|
|
3601
|
+
}
|
|
3602
|
+
function resolveMenuPosition(input) {
|
|
3603
|
+
const padding = 8;
|
|
3604
|
+
const { button, menuHeight, menuWidth, rail } = input;
|
|
3605
|
+
if (!rail) {
|
|
3606
|
+
return {
|
|
3607
|
+
left: button.left,
|
|
3608
|
+
top: button.top - menuHeight - 6
|
|
3609
|
+
};
|
|
3610
|
+
}
|
|
3611
|
+
let left = button.left - rail.left;
|
|
3612
|
+
let top = button.top - rail.top - menuHeight - 6;
|
|
3613
|
+
left = Math.min(
|
|
3614
|
+
Math.max(left, padding),
|
|
3615
|
+
rail.width - menuWidth - padding
|
|
3616
|
+
);
|
|
3617
|
+
if (top < padding) {
|
|
3618
|
+
top = button.bottom - rail.top + 6;
|
|
3619
|
+
}
|
|
3620
|
+
top = Math.min(top, rail.height - menuHeight - padding);
|
|
3621
|
+
return { left, top };
|
|
3622
|
+
}
|
|
3623
|
+
function MessageActions({
|
|
3624
|
+
answeredAt,
|
|
3625
|
+
copyText,
|
|
3626
|
+
disabled = false,
|
|
3627
|
+
onOpenReceipt,
|
|
3628
|
+
onRegenerate,
|
|
3629
|
+
onFeedback,
|
|
3630
|
+
readAloud = false,
|
|
3631
|
+
receiptSteps,
|
|
3632
|
+
speechText
|
|
3633
|
+
}) {
|
|
3634
|
+
const menuPortalRoot = useAgentRailMenuPortalRoot();
|
|
3635
|
+
const [copied, setCopied] = useState2(false);
|
|
3636
|
+
const [rating, setRating] = useState2(null);
|
|
3637
|
+
const [menuOpen, setMenuOpen] = useState2(false);
|
|
3638
|
+
const [menuPosition, setMenuPosition] = useState2(null);
|
|
3639
|
+
const [speaking, setSpeaking] = useState2(false);
|
|
3640
|
+
const copyTimerRef = useRef2(null);
|
|
3641
|
+
const menuRef = useRef2(null);
|
|
3642
|
+
const portaledMenuRef = useRef2(null);
|
|
3643
|
+
const moreButtonRef = useRef2(null);
|
|
3644
|
+
const answeredLabel = formatAnsweredAt(answeredAt ?? 0);
|
|
3645
|
+
const resolvedSpeechText = speechText ?? toSpeechText(copyText);
|
|
3646
|
+
const canReadAloud = readAloud && isSpeechSupported() && resolvedSpeechText;
|
|
3647
|
+
const showMenu = Boolean(answeredLabel) || Boolean(receiptSteps) || canReadAloud;
|
|
3648
|
+
const canOpenReceipt = Boolean(receiptSteps) && Boolean(onOpenReceipt);
|
|
3649
|
+
useLayoutEffect(() => {
|
|
3650
|
+
if (!menuOpen || !moreButtonRef.current || !portaledMenuRef.current) {
|
|
3651
|
+
setMenuPosition(null);
|
|
3652
|
+
return;
|
|
3653
|
+
}
|
|
3654
|
+
const button = moreButtonRef.current.getBoundingClientRect();
|
|
3655
|
+
const menu2 = portaledMenuRef.current;
|
|
3656
|
+
const rail = menuPortalRoot?.current?.getBoundingClientRect() ?? null;
|
|
3657
|
+
setMenuPosition(
|
|
3658
|
+
resolveMenuPosition({
|
|
3659
|
+
button,
|
|
3660
|
+
menuHeight: menu2.offsetHeight,
|
|
3661
|
+
menuWidth: menu2.offsetWidth || 190,
|
|
3662
|
+
rail
|
|
3663
|
+
})
|
|
3664
|
+
);
|
|
3665
|
+
}, [menuOpen, menuPortalRoot]);
|
|
3666
|
+
useEffect2(
|
|
3667
|
+
() => () => {
|
|
3668
|
+
if (copyTimerRef.current !== null) {
|
|
3669
|
+
window.clearTimeout(copyTimerRef.current);
|
|
3670
|
+
}
|
|
3671
|
+
if (speaking) window.speechSynthesis.cancel();
|
|
3672
|
+
},
|
|
3673
|
+
// Cancel speech only when this answer's actions unmount.
|
|
3674
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3675
|
+
[]
|
|
3676
|
+
);
|
|
3677
|
+
useEffect2(() => {
|
|
3678
|
+
if (!menuOpen) return;
|
|
3679
|
+
const handlePointerDown = (event) => {
|
|
3680
|
+
const target = event.target;
|
|
3681
|
+
if (!menuRef.current?.contains(target) && !portaledMenuRef.current?.contains(target)) {
|
|
3682
|
+
setMenuOpen(false);
|
|
3683
|
+
}
|
|
3684
|
+
};
|
|
3685
|
+
const handleKeyDown = (event) => {
|
|
3686
|
+
if (event.key !== "Escape") return;
|
|
3687
|
+
event.preventDefault();
|
|
3688
|
+
event.stopPropagation();
|
|
3689
|
+
setMenuOpen(false);
|
|
3690
|
+
};
|
|
3691
|
+
document.addEventListener("pointerdown", handlePointerDown);
|
|
3692
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
3693
|
+
return () => {
|
|
3694
|
+
document.removeEventListener("pointerdown", handlePointerDown);
|
|
3695
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
3696
|
+
};
|
|
3697
|
+
}, [menuOpen]);
|
|
3698
|
+
function handleCopy() {
|
|
3699
|
+
void writeToClipboard(copyText);
|
|
3700
|
+
setCopied(true);
|
|
3701
|
+
if (copyTimerRef.current !== null) {
|
|
3702
|
+
window.clearTimeout(copyTimerRef.current);
|
|
3703
|
+
}
|
|
3704
|
+
copyTimerRef.current = window.setTimeout(() => setCopied(false), 1600);
|
|
3705
|
+
}
|
|
3706
|
+
function handleFeedback(next) {
|
|
3707
|
+
const resolved = rating === next ? null : next;
|
|
3708
|
+
setRating(resolved);
|
|
3709
|
+
if (resolved) onFeedback?.(resolved);
|
|
3710
|
+
}
|
|
3711
|
+
function handleReadAloud() {
|
|
3712
|
+
if (!canReadAloud) return;
|
|
3713
|
+
setMenuOpen(false);
|
|
3714
|
+
if (speaking) {
|
|
3715
|
+
window.speechSynthesis.cancel();
|
|
3716
|
+
setSpeaking(false);
|
|
3717
|
+
return;
|
|
3718
|
+
}
|
|
3719
|
+
const utterance = new SpeechSynthesisUtterance(resolvedSpeechText);
|
|
3720
|
+
utterance.onend = () => setSpeaking(false);
|
|
3721
|
+
utterance.onerror = () => setSpeaking(false);
|
|
3722
|
+
window.speechSynthesis.cancel();
|
|
3723
|
+
window.speechSynthesis.speak(utterance);
|
|
3724
|
+
setSpeaking(true);
|
|
3725
|
+
}
|
|
3726
|
+
const menu = menuOpen ? /* @__PURE__ */ jsxs(
|
|
3727
|
+
"div",
|
|
3728
|
+
{
|
|
3729
|
+
className: "agent-message-actions__menu agent-message-actions__menu--portal",
|
|
3730
|
+
ref: portaledMenuRef,
|
|
3731
|
+
role: "menu",
|
|
3732
|
+
style: menuPosition ? {
|
|
3733
|
+
left: `${menuPosition.left}px`,
|
|
3734
|
+
top: `${menuPosition.top}px`
|
|
3735
|
+
} : { visibility: "hidden" },
|
|
3736
|
+
children: [
|
|
3737
|
+
answeredLabel ? /* @__PURE__ */ jsxs("p", { className: "agent-message-actions__menu-meta", children: [
|
|
3738
|
+
"Answered ",
|
|
3739
|
+
answeredLabel
|
|
3740
|
+
] }) : null,
|
|
3741
|
+
canOpenReceipt ? /* @__PURE__ */ jsxs(
|
|
3742
|
+
"button",
|
|
3743
|
+
{
|
|
3744
|
+
type: "button",
|
|
3745
|
+
className: "agent-message-actions__menu-item",
|
|
3746
|
+
role: "menuitem",
|
|
3747
|
+
onClick: () => {
|
|
3748
|
+
setMenuOpen(false);
|
|
3749
|
+
onOpenReceipt?.();
|
|
3750
|
+
},
|
|
3751
|
+
children: [
|
|
3752
|
+
/* @__PURE__ */ jsx(SourcesIcon, {}),
|
|
3753
|
+
"View sources"
|
|
3754
|
+
]
|
|
3755
|
+
}
|
|
3756
|
+
) : null,
|
|
3757
|
+
canReadAloud ? /* @__PURE__ */ jsxs(
|
|
3758
|
+
"button",
|
|
3759
|
+
{
|
|
3760
|
+
type: "button",
|
|
3761
|
+
className: "agent-message-actions__menu-item",
|
|
3762
|
+
role: "menuitem",
|
|
3763
|
+
onClick: handleReadAloud,
|
|
3764
|
+
children: [
|
|
3765
|
+
speaking ? /* @__PURE__ */ jsx(StopIcon, {}) : /* @__PURE__ */ jsx(ReadAloudIcon, {}),
|
|
3766
|
+
speaking ? "Stop reading" : "Read aloud"
|
|
3767
|
+
]
|
|
3768
|
+
}
|
|
3769
|
+
) : null
|
|
3770
|
+
]
|
|
3771
|
+
}
|
|
3772
|
+
) : null;
|
|
3773
|
+
return /* @__PURE__ */ jsxs("div", { className: "agent-message-actions", "aria-label": "Answer actions", children: [
|
|
3774
|
+
/* @__PURE__ */ jsx(
|
|
3775
|
+
"button",
|
|
3776
|
+
{
|
|
3777
|
+
type: "button",
|
|
3778
|
+
className: `agent-message-actions__button${copied ? " is-copied" : ""}`,
|
|
3779
|
+
"aria-label": copied ? "Copied" : "Copy answer",
|
|
3780
|
+
title: copied ? "Copied" : "Copy answer",
|
|
3781
|
+
disabled,
|
|
3782
|
+
onClick: handleCopy,
|
|
3783
|
+
children: copied ? /* @__PURE__ */ jsx(CheckIcon, {}) : /* @__PURE__ */ jsx(CopyIcon, {})
|
|
3784
|
+
}
|
|
3785
|
+
),
|
|
3786
|
+
/* @__PURE__ */ jsx(
|
|
3787
|
+
"button",
|
|
3788
|
+
{
|
|
3789
|
+
type: "button",
|
|
3790
|
+
className: `agent-message-actions__button${rating === "positive" ? " is-active" : ""}`,
|
|
3791
|
+
"aria-label": "Good answer",
|
|
3792
|
+
"aria-pressed": rating === "positive",
|
|
3793
|
+
title: "Good answer",
|
|
3794
|
+
disabled,
|
|
3795
|
+
onClick: () => handleFeedback("positive"),
|
|
3796
|
+
children: /* @__PURE__ */ jsx(ThumbUpIcon, {})
|
|
3797
|
+
}
|
|
3798
|
+
),
|
|
3799
|
+
/* @__PURE__ */ jsx(
|
|
3800
|
+
"button",
|
|
3801
|
+
{
|
|
3802
|
+
type: "button",
|
|
3803
|
+
className: `agent-message-actions__button${rating === "negative" ? " is-active" : ""}`,
|
|
3804
|
+
"aria-label": "Bad answer",
|
|
3805
|
+
"aria-pressed": rating === "negative",
|
|
3806
|
+
title: "Bad answer",
|
|
3807
|
+
disabled,
|
|
3808
|
+
onClick: () => handleFeedback("negative"),
|
|
3809
|
+
children: /* @__PURE__ */ jsx(ThumbDownIcon, {})
|
|
3810
|
+
}
|
|
3811
|
+
),
|
|
3812
|
+
onRegenerate ? /* @__PURE__ */ jsx(
|
|
3813
|
+
"button",
|
|
3814
|
+
{
|
|
3815
|
+
type: "button",
|
|
3816
|
+
className: "agent-message-actions__button",
|
|
3817
|
+
"aria-label": "Regenerate answer",
|
|
3818
|
+
title: "Regenerate answer",
|
|
3819
|
+
disabled,
|
|
3820
|
+
onClick: onRegenerate,
|
|
3821
|
+
children: /* @__PURE__ */ jsx(RegenerateIcon, {})
|
|
3822
|
+
}
|
|
3823
|
+
) : null,
|
|
3824
|
+
showMenu ? /* @__PURE__ */ jsxs("div", { className: "agent-message-actions__more", ref: menuRef, children: [
|
|
3825
|
+
/* @__PURE__ */ jsx(
|
|
3826
|
+
"button",
|
|
3827
|
+
{
|
|
3828
|
+
ref: moreButtonRef,
|
|
3829
|
+
type: "button",
|
|
3830
|
+
className: `agent-message-actions__button${menuOpen ? " is-menu-open" : ""}`,
|
|
3831
|
+
"aria-label": "More actions",
|
|
3832
|
+
"aria-haspopup": "menu",
|
|
3833
|
+
"aria-expanded": menuOpen,
|
|
3834
|
+
title: "More actions",
|
|
3835
|
+
disabled,
|
|
3836
|
+
onClick: () => setMenuOpen((open) => !open),
|
|
3837
|
+
children: /* @__PURE__ */ jsx(MoreIcon, {})
|
|
3838
|
+
}
|
|
3839
|
+
),
|
|
3840
|
+
menuPortalRoot?.current && menu ? createPortal(menu, menuPortalRoot.current) : menu
|
|
3841
|
+
] }) : null
|
|
3842
|
+
] });
|
|
3843
|
+
}
|
|
3844
|
+
|
|
3199
3845
|
// src/react/components/AgentRail/AgentRail.tsx
|
|
3200
|
-
import { useEffect as
|
|
3846
|
+
import { useEffect as useEffect6, useRef as useRef6, useState as useState9 } from "react";
|
|
3201
3847
|
|
|
3202
3848
|
// src/react/hooks/useAgentColorScheme.ts
|
|
3203
3849
|
import { useSyncExternalStore } from "react";
|
|
@@ -3230,8 +3876,8 @@ function resolveAgentColorScheme(colorScheme = "auto", prefersDarkMode) {
|
|
|
3230
3876
|
}
|
|
3231
3877
|
|
|
3232
3878
|
// src/react/components/AgentActivityBubble/AgentActivityBubble.tsx
|
|
3233
|
-
import { useState as
|
|
3234
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3879
|
+
import { useState as useState3 } from "react";
|
|
3880
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
3235
3881
|
function joinLabels(labels) {
|
|
3236
3882
|
if (labels.length <= 1) return labels[0] ?? "";
|
|
3237
3883
|
if (labels.length === 2) return `${labels[0]} and ${labels[1]}`;
|
|
@@ -3281,18 +3927,11 @@ function stepDetail(step, steps) {
|
|
|
3281
3927
|
return "Searched this site";
|
|
3282
3928
|
return step.detail;
|
|
3283
3929
|
}
|
|
3284
|
-
function
|
|
3930
|
+
function AgentWorkSteps({
|
|
3285
3931
|
brandLabel = "",
|
|
3286
|
-
|
|
3287
|
-
steps
|
|
3288
|
-
onRetryStep
|
|
3932
|
+
onRetryStep,
|
|
3933
|
+
steps
|
|
3289
3934
|
}) {
|
|
3290
|
-
const active = steps.some((step) => step.state === "active");
|
|
3291
|
-
const receiptId = steps.map((step) => step.id).join(":");
|
|
3292
|
-
const [expandedReceiptId, setExpandedReceiptId] = useState2(
|
|
3293
|
-
null
|
|
3294
|
-
);
|
|
3295
|
-
const detailsOpen = active || expandedReceiptId === receiptId;
|
|
3296
3935
|
const delegationCount = steps.filter(
|
|
3297
3936
|
(step) => step.kind === "specialist"
|
|
3298
3937
|
).length;
|
|
@@ -3300,26 +3939,80 @@ function AgentActivityBubble({
|
|
|
3300
3939
|
const visibleSteps = steps.filter(
|
|
3301
3940
|
(step) => step.kind !== "planning" || Boolean(brandLabel)
|
|
3302
3941
|
);
|
|
3303
|
-
return /* @__PURE__ */
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3942
|
+
return /* @__PURE__ */ jsx2("ol", { className: "agent-activity-bubble__steps", children: visibleSteps.map((step) => {
|
|
3943
|
+
const detail = stepDetail(step, steps);
|
|
3944
|
+
const child = delegated && step.kind === "specialist";
|
|
3945
|
+
return /* @__PURE__ */ jsxs2(
|
|
3946
|
+
"li",
|
|
3947
|
+
{
|
|
3948
|
+
className: `agent-activity-bubble__step${child ? " agent-activity-bubble__step--child" : ""}`,
|
|
3949
|
+
"data-kind": step.kind,
|
|
3950
|
+
"data-state": step.state,
|
|
3951
|
+
children: [
|
|
3952
|
+
/* @__PURE__ */ jsx2(
|
|
3953
|
+
"span",
|
|
3954
|
+
{
|
|
3955
|
+
className: "agent-activity-bubble__step-icon",
|
|
3956
|
+
"aria-hidden": "true"
|
|
3957
|
+
}
|
|
3958
|
+
),
|
|
3959
|
+
/* @__PURE__ */ jsxs2("span", { className: "agent-activity-bubble__step-copy", children: [
|
|
3960
|
+
/* @__PURE__ */ jsx2("span", { className: "agent-activity-bubble__step-heading", children: /* @__PURE__ */ jsx2("strong", { children: stepLabel(step, brandLabel) }) }),
|
|
3961
|
+
detail ? /* @__PURE__ */ jsx2("span", { className: "agent-activity-bubble__step-detail", children: detail }) : null,
|
|
3962
|
+
delegated && step.kind === "planning" ? /* @__PURE__ */ jsxs2("span", { className: "agent-activity-bubble__delegation", children: [
|
|
3963
|
+
"Delegated ",
|
|
3964
|
+
delegationCount,
|
|
3965
|
+
" ",
|
|
3966
|
+
delegationCount === 1 ? "task" : "tasks"
|
|
3967
|
+
] }) : null,
|
|
3968
|
+
step.state === "error" && onRetryStep ? /* @__PURE__ */ jsx2(
|
|
3969
|
+
"button",
|
|
3970
|
+
{
|
|
3971
|
+
type: "button",
|
|
3972
|
+
className: "agent-activity-bubble__step-retry",
|
|
3973
|
+
onClick: () => onRetryStep(step),
|
|
3974
|
+
children: "Retry"
|
|
3975
|
+
}
|
|
3976
|
+
) : null
|
|
3977
|
+
] })
|
|
3978
|
+
]
|
|
3979
|
+
},
|
|
3980
|
+
step.id
|
|
3981
|
+
);
|
|
3982
|
+
}) });
|
|
3983
|
+
}
|
|
3984
|
+
function AgentActivityBubble({
|
|
3985
|
+
brandLabel = "",
|
|
3986
|
+
failed = false,
|
|
3987
|
+
steps,
|
|
3988
|
+
onRetryStep
|
|
3989
|
+
}) {
|
|
3990
|
+
const active = steps.some((step) => step.state === "active");
|
|
3991
|
+
const receiptId = steps.map((step) => step.id).join(":");
|
|
3992
|
+
const [expandedReceiptId, setExpandedReceiptId] = useState3(
|
|
3993
|
+
null
|
|
3994
|
+
);
|
|
3995
|
+
const detailsOpen = !active && expandedReceiptId === receiptId;
|
|
3996
|
+
return /* @__PURE__ */ jsxs2("article", { className: "agent-activity-bubble", children: [
|
|
3997
|
+
/* @__PURE__ */ jsxs2("p", { className: "agent-activity-bubble__status", "aria-live": "polite", children: [
|
|
3998
|
+
/* @__PURE__ */ jsx2(
|
|
3999
|
+
"span",
|
|
3307
4000
|
{
|
|
3308
4001
|
className: `agent-activity-bubble__pulse${active ? " is-active" : failed ? " is-error" : ""}`,
|
|
3309
4002
|
"aria-hidden": "true"
|
|
3310
4003
|
}
|
|
3311
4004
|
),
|
|
3312
|
-
workSummary(steps, failed, brandLabel)
|
|
4005
|
+
workSummary(steps, failed, brandLabel),
|
|
4006
|
+
active ? "\u2026" : ""
|
|
3313
4007
|
] }),
|
|
3314
|
-
/* @__PURE__ */
|
|
3315
|
-
/* @__PURE__ */
|
|
4008
|
+
!active ? /* @__PURE__ */ jsxs2("div", { className: "agent-activity-bubble__details", children: [
|
|
4009
|
+
/* @__PURE__ */ jsx2(
|
|
3316
4010
|
"button",
|
|
3317
4011
|
{
|
|
3318
4012
|
type: "button",
|
|
3319
4013
|
className: "agent-activity-bubble__summary",
|
|
3320
4014
|
"aria-expanded": detailsOpen,
|
|
3321
4015
|
onClick: () => {
|
|
3322
|
-
if (active) return;
|
|
3323
4016
|
setExpandedReceiptId(
|
|
3324
4017
|
(current) => current === receiptId ? null : receiptId
|
|
3325
4018
|
);
|
|
@@ -3327,61 +4020,138 @@ function AgentActivityBubble({
|
|
|
3327
4020
|
children: "How this answer was made"
|
|
3328
4021
|
}
|
|
3329
4022
|
),
|
|
3330
|
-
detailsOpen ? /* @__PURE__ */
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
4023
|
+
detailsOpen ? /* @__PURE__ */ jsx2(
|
|
4024
|
+
AgentWorkSteps,
|
|
4025
|
+
{
|
|
4026
|
+
brandLabel,
|
|
4027
|
+
onRetryStep,
|
|
4028
|
+
steps
|
|
4029
|
+
}
|
|
4030
|
+
) : null
|
|
4031
|
+
] }) : null
|
|
4032
|
+
] });
|
|
4033
|
+
}
|
|
4034
|
+
|
|
4035
|
+
// src/react/components/AnswerReceiptDialog/AnswerReceiptDialog.tsx
|
|
4036
|
+
import { useEffect as useEffect3, useRef as useRef3 } from "react";
|
|
4037
|
+
import { createPortal as createPortal2 } from "react-dom";
|
|
4038
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
4039
|
+
var FOCUSABLE_SELECTOR = 'button:not(:disabled), a[href], textarea:not(:disabled), input:not(:disabled), [tabindex]:not([tabindex="-1"])';
|
|
4040
|
+
function CloseIcon() {
|
|
4041
|
+
return /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(
|
|
4042
|
+
"path",
|
|
4043
|
+
{
|
|
4044
|
+
d: "M4 4l8 8M12 4l-8 8",
|
|
4045
|
+
stroke: "currentColor",
|
|
4046
|
+
strokeWidth: "1.5",
|
|
4047
|
+
strokeLinecap: "round"
|
|
4048
|
+
}
|
|
4049
|
+
) });
|
|
4050
|
+
}
|
|
4051
|
+
function AnswerReceiptDialog({
|
|
4052
|
+
brandLabel = "",
|
|
4053
|
+
onClose,
|
|
4054
|
+
steps
|
|
4055
|
+
}) {
|
|
4056
|
+
const portalRoots = useAgentRailPortalRoots();
|
|
4057
|
+
const overlayRoot = portalRoots?.overlayRef ?? null;
|
|
4058
|
+
const cardRef = useRef3(null);
|
|
4059
|
+
const closeButtonRef = useRef3(null);
|
|
4060
|
+
const previouslyFocusedRef = useRef3(null);
|
|
4061
|
+
useEffect3(() => {
|
|
4062
|
+
previouslyFocusedRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
4063
|
+
closeButtonRef.current?.focus({ preventScroll: true });
|
|
4064
|
+
const handleKeyDown = (event) => {
|
|
4065
|
+
if (event.key === "Escape") {
|
|
4066
|
+
event.preventDefault();
|
|
4067
|
+
event.stopPropagation();
|
|
4068
|
+
onClose();
|
|
4069
|
+
return;
|
|
4070
|
+
}
|
|
4071
|
+
if (event.key !== "Tab" || !cardRef.current) return;
|
|
4072
|
+
const focusable = cardRef.current.querySelectorAll(
|
|
4073
|
+
FOCUSABLE_SELECTOR
|
|
4074
|
+
);
|
|
4075
|
+
if (focusable.length === 0) return;
|
|
4076
|
+
const first = focusable.item(0);
|
|
4077
|
+
const last = focusable.item(focusable.length - 1);
|
|
4078
|
+
if (event.shiftKey && document.activeElement === first) {
|
|
4079
|
+
event.preventDefault();
|
|
4080
|
+
last.focus({ preventScroll: true });
|
|
4081
|
+
} else if (!event.shiftKey && document.activeElement === last) {
|
|
4082
|
+
event.preventDefault();
|
|
4083
|
+
first.focus({ preventScroll: true });
|
|
4084
|
+
}
|
|
4085
|
+
};
|
|
4086
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
4087
|
+
return () => {
|
|
4088
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
4089
|
+
previouslyFocusedRef.current?.focus({ preventScroll: true });
|
|
4090
|
+
};
|
|
4091
|
+
}, [onClose]);
|
|
4092
|
+
const content = /* @__PURE__ */ jsxs3("div", { className: "agent-receipt-dialog", children: [
|
|
4093
|
+
/* @__PURE__ */ jsx3(
|
|
4094
|
+
"button",
|
|
4095
|
+
{
|
|
4096
|
+
type: "button",
|
|
4097
|
+
className: "agent-receipt-dialog__backdrop",
|
|
4098
|
+
"aria-label": "Close",
|
|
4099
|
+
tabIndex: -1,
|
|
4100
|
+
onClick: onClose
|
|
4101
|
+
}
|
|
4102
|
+
),
|
|
4103
|
+
/* @__PURE__ */ jsxs3(
|
|
4104
|
+
"div",
|
|
4105
|
+
{
|
|
4106
|
+
ref: cardRef,
|
|
4107
|
+
className: "agent-receipt-dialog__card",
|
|
4108
|
+
role: "dialog",
|
|
4109
|
+
"aria-modal": "true",
|
|
4110
|
+
"aria-labelledby": "agent-receipt-dialog-title",
|
|
4111
|
+
children: [
|
|
4112
|
+
/* @__PURE__ */ jsxs3("div", { className: "agent-receipt-dialog__header", children: [
|
|
4113
|
+
/* @__PURE__ */ jsx3(
|
|
4114
|
+
"p",
|
|
4115
|
+
{
|
|
4116
|
+
className: "agent-receipt-dialog__title",
|
|
4117
|
+
id: "agent-receipt-dialog-title",
|
|
4118
|
+
children: "How this answer was made"
|
|
4119
|
+
}
|
|
4120
|
+
),
|
|
4121
|
+
/* @__PURE__ */ jsx3(
|
|
4122
|
+
"button",
|
|
4123
|
+
{
|
|
4124
|
+
ref: closeButtonRef,
|
|
4125
|
+
type: "button",
|
|
4126
|
+
className: "agent-receipt-dialog__close",
|
|
4127
|
+
"aria-label": "Close",
|
|
4128
|
+
onClick: onClose,
|
|
4129
|
+
children: /* @__PURE__ */ jsx3(CloseIcon, {})
|
|
4130
|
+
}
|
|
4131
|
+
)
|
|
4132
|
+
] }),
|
|
4133
|
+
/* @__PURE__ */ jsx3("p", { className: "agent-receipt-dialog__summary", children: workSummary(steps, false, brandLabel) }),
|
|
4134
|
+
/* @__PURE__ */ jsx3("div", { className: "agent-receipt-dialog__body", children: /* @__PURE__ */ jsx3(AgentWorkSteps, { brandLabel, steps }) })
|
|
4135
|
+
]
|
|
4136
|
+
}
|
|
4137
|
+
)
|
|
3372
4138
|
] });
|
|
4139
|
+
if (overlayRoot?.current) {
|
|
4140
|
+
return createPortal2(content, overlayRoot.current);
|
|
4141
|
+
}
|
|
4142
|
+
return content;
|
|
3373
4143
|
}
|
|
3374
4144
|
|
|
3375
4145
|
// src/react/components/Composer/Composer.tsx
|
|
3376
4146
|
import {
|
|
3377
|
-
useEffect as
|
|
4147
|
+
useEffect as useEffect4,
|
|
3378
4148
|
useId,
|
|
3379
|
-
useRef as
|
|
3380
|
-
useState as
|
|
4149
|
+
useRef as useRef4,
|
|
4150
|
+
useState as useState4
|
|
3381
4151
|
} from "react";
|
|
3382
|
-
import { jsx as
|
|
4152
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
3383
4153
|
function SendIcon() {
|
|
3384
|
-
return /* @__PURE__ */
|
|
4154
|
+
return /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx4(
|
|
3385
4155
|
"path",
|
|
3386
4156
|
{
|
|
3387
4157
|
d: "M8 12V4M8 4l-3 3M8 4l3 3",
|
|
@@ -3404,21 +4174,21 @@ function Composer({
|
|
|
3404
4174
|
form = null,
|
|
3405
4175
|
onSubmit
|
|
3406
4176
|
}) {
|
|
3407
|
-
const [value, setValue] =
|
|
3408
|
-
const [values, setValues] =
|
|
4177
|
+
const [value, setValue] = useState4("");
|
|
4178
|
+
const [values, setValues] = useState4(
|
|
3409
4179
|
() => emptyValues(form)
|
|
3410
4180
|
);
|
|
3411
|
-
const [blurred, setBlurred] =
|
|
3412
|
-
const inputRef =
|
|
3413
|
-
const firstFieldRef =
|
|
4181
|
+
const [blurred, setBlurred] = useState4({});
|
|
4182
|
+
const inputRef = useRef4(null);
|
|
4183
|
+
const firstFieldRef = useRef4(null);
|
|
3414
4184
|
const formId = useId();
|
|
3415
4185
|
const activeForm = form;
|
|
3416
4186
|
const canSendForm = activeForm ? isComposerFormComplete(activeForm, values) : Boolean(value.trim());
|
|
3417
|
-
|
|
4187
|
+
useEffect4(() => {
|
|
3418
4188
|
setValues(emptyValues(form));
|
|
3419
4189
|
setBlurred({});
|
|
3420
4190
|
}, [form?.id]);
|
|
3421
|
-
|
|
4191
|
+
useEffect4(() => {
|
|
3422
4192
|
if (activeForm) firstFieldRef.current?.focus();
|
|
3423
4193
|
}, [activeForm?.id]);
|
|
3424
4194
|
function submitChat() {
|
|
@@ -3453,7 +4223,7 @@ function Composer({
|
|
|
3453
4223
|
submitForm();
|
|
3454
4224
|
}
|
|
3455
4225
|
}
|
|
3456
|
-
return /* @__PURE__ */
|
|
4226
|
+
return /* @__PURE__ */ jsx4(
|
|
3457
4227
|
"form",
|
|
3458
4228
|
{
|
|
3459
4229
|
className: [
|
|
@@ -3462,7 +4232,7 @@ function Composer({
|
|
|
3462
4232
|
activeForm ? "composer--form" : ""
|
|
3463
4233
|
].filter(Boolean).join(" "),
|
|
3464
4234
|
onSubmit: handleSubmit,
|
|
3465
|
-
children: activeForm ? /* @__PURE__ */
|
|
4235
|
+
children: activeForm ? /* @__PURE__ */ jsxs4("div", { className: "composer__sheet", role: "group", "aria-label": "Required details", children: [
|
|
3466
4236
|
activeForm.fields.map((field, index) => {
|
|
3467
4237
|
const fieldId = `${formId}-${field.id}`;
|
|
3468
4238
|
const invalid = Boolean(blurred[field.id]) && !isValidComposerFieldValue(field, values[field.id] ?? "");
|
|
@@ -3487,7 +4257,7 @@ function Composer({
|
|
|
3487
4257
|
},
|
|
3488
4258
|
onKeyDown: handleFormKeyDown
|
|
3489
4259
|
};
|
|
3490
|
-
return /* @__PURE__ */
|
|
4260
|
+
return /* @__PURE__ */ jsxs4(
|
|
3491
4261
|
"div",
|
|
3492
4262
|
{
|
|
3493
4263
|
className: [
|
|
@@ -3495,9 +4265,9 @@ function Composer({
|
|
|
3495
4265
|
field.kind === "textarea" ? "composer__row--grow" : ""
|
|
3496
4266
|
].filter(Boolean).join(" "),
|
|
3497
4267
|
children: [
|
|
3498
|
-
/* @__PURE__ */
|
|
3499
|
-
/* @__PURE__ */
|
|
3500
|
-
field.kind === "textarea" ? /* @__PURE__ */
|
|
4268
|
+
/* @__PURE__ */ jsxs4("label", { className: "composer__label", htmlFor: fieldId, children: [
|
|
4269
|
+
/* @__PURE__ */ jsx4("span", { className: "composer__sr-only", children: field.label }),
|
|
4270
|
+
field.kind === "textarea" ? /* @__PURE__ */ jsx4(
|
|
3501
4271
|
"textarea",
|
|
3502
4272
|
{
|
|
3503
4273
|
...controlProps,
|
|
@@ -3507,7 +4277,7 @@ function Composer({
|
|
|
3507
4277
|
className: "composer__control composer__control--area",
|
|
3508
4278
|
rows: 3
|
|
3509
4279
|
}
|
|
3510
|
-
) : /* @__PURE__ */
|
|
4280
|
+
) : /* @__PURE__ */ jsx4(
|
|
3511
4281
|
"input",
|
|
3512
4282
|
{
|
|
3513
4283
|
...controlProps,
|
|
@@ -3520,24 +4290,24 @@ function Composer({
|
|
|
3520
4290
|
}
|
|
3521
4291
|
)
|
|
3522
4292
|
] }),
|
|
3523
|
-
invalid ? /* @__PURE__ */
|
|
4293
|
+
invalid ? /* @__PURE__ */ jsx4("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
|
|
3524
4294
|
]
|
|
3525
4295
|
},
|
|
3526
4296
|
field.id
|
|
3527
4297
|
);
|
|
3528
4298
|
}),
|
|
3529
|
-
/* @__PURE__ */
|
|
4299
|
+
/* @__PURE__ */ jsx4("div", { className: "composer__toolbar", children: /* @__PURE__ */ jsx4(
|
|
3530
4300
|
"button",
|
|
3531
4301
|
{
|
|
3532
4302
|
type: "submit",
|
|
3533
4303
|
className: "composer__send",
|
|
3534
4304
|
disabled: disabled || !canSendForm,
|
|
3535
4305
|
"aria-label": "Send details",
|
|
3536
|
-
children: /* @__PURE__ */
|
|
4306
|
+
children: /* @__PURE__ */ jsx4(SendIcon, {})
|
|
3537
4307
|
}
|
|
3538
4308
|
) })
|
|
3539
|
-
] }) : /* @__PURE__ */
|
|
3540
|
-
/* @__PURE__ */
|
|
4309
|
+
] }) : /* @__PURE__ */ jsxs4("div", { className: "composer__field", children: [
|
|
4310
|
+
/* @__PURE__ */ jsx4(
|
|
3541
4311
|
"textarea",
|
|
3542
4312
|
{
|
|
3543
4313
|
ref: inputRef,
|
|
@@ -3552,14 +4322,14 @@ function Composer({
|
|
|
3552
4322
|
onKeyDown: handleChatKeyDown
|
|
3553
4323
|
}
|
|
3554
4324
|
),
|
|
3555
|
-
/* @__PURE__ */
|
|
4325
|
+
/* @__PURE__ */ jsx4(
|
|
3556
4326
|
"button",
|
|
3557
4327
|
{
|
|
3558
4328
|
type: "submit",
|
|
3559
4329
|
className: "composer__send",
|
|
3560
4330
|
disabled: disabled || !value.trim(),
|
|
3561
4331
|
"aria-label": "Send message",
|
|
3562
|
-
children: /* @__PURE__ */
|
|
4332
|
+
children: /* @__PURE__ */ jsx4(SendIcon, {})
|
|
3563
4333
|
}
|
|
3564
4334
|
)
|
|
3565
4335
|
] })
|
|
@@ -3568,7 +4338,7 @@ function Composer({
|
|
|
3568
4338
|
}
|
|
3569
4339
|
|
|
3570
4340
|
// src/react/components/FollowUpChips/FollowUpChips.tsx
|
|
3571
|
-
import { jsx as
|
|
4341
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
3572
4342
|
function FollowUpChips({
|
|
3573
4343
|
suggestions,
|
|
3574
4344
|
disabled = false,
|
|
@@ -3578,7 +4348,7 @@ function FollowUpChips({
|
|
|
3578
4348
|
}) {
|
|
3579
4349
|
if (suggestions.length === 0) return null;
|
|
3580
4350
|
if (variant === "dock") {
|
|
3581
|
-
return /* @__PURE__ */
|
|
4351
|
+
return /* @__PURE__ */ jsx5("div", { className: "followups followups--dock", children: /* @__PURE__ */ jsx5("div", { className: "followups__scroll", children: suggestions.map((suggestion) => /* @__PURE__ */ jsx5(
|
|
3582
4352
|
"button",
|
|
3583
4353
|
{
|
|
3584
4354
|
type: "button",
|
|
@@ -3590,9 +4360,9 @@ function FollowUpChips({
|
|
|
3590
4360
|
suggestion.id
|
|
3591
4361
|
)) }) });
|
|
3592
4362
|
}
|
|
3593
|
-
return /* @__PURE__ */
|
|
3594
|
-
/* @__PURE__ */
|
|
3595
|
-
/* @__PURE__ */
|
|
4363
|
+
return /* @__PURE__ */ jsxs5("div", { className: "followups", children: [
|
|
4364
|
+
/* @__PURE__ */ jsx5("span", { className: "followups__label", children: label }),
|
|
4365
|
+
/* @__PURE__ */ jsx5("div", { className: "followups__list", children: suggestions.map((suggestion) => /* @__PURE__ */ jsx5(
|
|
3596
4366
|
"button",
|
|
3597
4367
|
{
|
|
3598
4368
|
type: "button",
|
|
@@ -3607,17 +4377,17 @@ function FollowUpChips({
|
|
|
3607
4377
|
}
|
|
3608
4378
|
|
|
3609
4379
|
// src/react/components/MessageBubble/MessageBubble.tsx
|
|
3610
|
-
import { useState as
|
|
4380
|
+
import { useState as useState6 } from "react";
|
|
3611
4381
|
|
|
3612
4382
|
// src/react/components/BookingCard/BookingCard.tsx
|
|
3613
4383
|
import {
|
|
3614
|
-
useEffect as
|
|
4384
|
+
useEffect as useEffect5,
|
|
3615
4385
|
useId as useId2,
|
|
3616
4386
|
useMemo as useMemo2,
|
|
3617
|
-
useRef as
|
|
3618
|
-
useState as
|
|
4387
|
+
useRef as useRef5,
|
|
4388
|
+
useState as useState5
|
|
3619
4389
|
} from "react";
|
|
3620
|
-
import { jsx as
|
|
4390
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
3621
4391
|
var BOOKING_STEPS = [
|
|
3622
4392
|
{ id: "date", label: "Date" },
|
|
3623
4393
|
{ id: "time", label: "Time" },
|
|
@@ -3648,24 +4418,25 @@ function calendarCells(year, month) {
|
|
|
3648
4418
|
return cells;
|
|
3649
4419
|
}
|
|
3650
4420
|
function BookingCardLoader() {
|
|
3651
|
-
return /* @__PURE__ */
|
|
4421
|
+
return /* @__PURE__ */ jsx6("section", { className: "booking-card", "aria-label": "Book a meeting", children: /* @__PURE__ */ jsx6("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) });
|
|
3652
4422
|
}
|
|
3653
4423
|
function BookingCard({
|
|
4424
|
+
disabled = false,
|
|
3654
4425
|
offer,
|
|
3655
4426
|
onBook
|
|
3656
4427
|
}) {
|
|
3657
4428
|
const fieldId = useId2();
|
|
3658
4429
|
const defaultType = offer.eventTypes[0]?.uri ?? offer.slots[0]?.eventTypeUri ?? "";
|
|
3659
|
-
const [step, setStep] =
|
|
3660
|
-
const [eventTypeUri, setEventTypeUri] =
|
|
3661
|
-
const [selectedDate, setSelectedDate] =
|
|
3662
|
-
const [startTime, setStartTime] =
|
|
3663
|
-
const [name, setName] =
|
|
3664
|
-
const [email, setEmail] =
|
|
3665
|
-
const activeStepRef =
|
|
3666
|
-
const previousStepRef =
|
|
4430
|
+
const [step, setStep] = useState5("date");
|
|
4431
|
+
const [eventTypeUri, setEventTypeUri] = useState5(defaultType);
|
|
4432
|
+
const [selectedDate, setSelectedDate] = useState5("");
|
|
4433
|
+
const [startTime, setStartTime] = useState5("");
|
|
4434
|
+
const [name, setName] = useState5("");
|
|
4435
|
+
const [email, setEmail] = useState5("");
|
|
4436
|
+
const activeStepRef = useRef5(null);
|
|
4437
|
+
const previousStepRef = useRef5(step);
|
|
3667
4438
|
const stepIndex = BOOKING_STEPS.findIndex((item) => item.id === step);
|
|
3668
|
-
|
|
4439
|
+
useEffect5(() => {
|
|
3669
4440
|
if (previousStepRef.current === step) return;
|
|
3670
4441
|
previousStepRef.current = step;
|
|
3671
4442
|
activeStepRef.current?.scrollIntoView({ block: "nearest" });
|
|
@@ -3682,7 +4453,7 @@ function BookingCard({
|
|
|
3682
4453
|
}
|
|
3683
4454
|
return next;
|
|
3684
4455
|
}, [slots]);
|
|
3685
|
-
const [visibleMonth, setVisibleMonth] =
|
|
4456
|
+
const [visibleMonth, setVisibleMonth] = useState5(
|
|
3686
4457
|
() => firstAvailableBookingMonth(slots)
|
|
3687
4458
|
);
|
|
3688
4459
|
function selectEventType(nextType) {
|
|
@@ -3746,222 +4517,236 @@ function BookingCard({
|
|
|
3746
4517
|
})
|
|
3747
4518
|
});
|
|
3748
4519
|
}
|
|
3749
|
-
return /* @__PURE__ */
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
4520
|
+
return /* @__PURE__ */ jsx6(
|
|
4521
|
+
"section",
|
|
4522
|
+
{
|
|
4523
|
+
className: "booking-card",
|
|
4524
|
+
"aria-busy": disabled || void 0,
|
|
4525
|
+
"aria-label": "Book a meeting",
|
|
4526
|
+
children: /* @__PURE__ */ jsxs6("form", { className: "booking-card__form", onSubmit: handleSubmit, children: [
|
|
4527
|
+
/* @__PURE__ */ jsx6("ol", { className: "booking-card__steps", "aria-label": "Booking steps", children: BOOKING_STEPS.map((item, index) => /* @__PURE__ */ jsxs6(
|
|
4528
|
+
"li",
|
|
4529
|
+
{
|
|
4530
|
+
className: [
|
|
4531
|
+
"booking-card__step-indicator",
|
|
4532
|
+
index === stepIndex ? "booking-card__step-indicator--active" : "",
|
|
4533
|
+
index < stepIndex ? "booking-card__step-indicator--complete" : ""
|
|
4534
|
+
].filter(Boolean).join(" "),
|
|
4535
|
+
"aria-current": index === stepIndex ? "step" : void 0,
|
|
4536
|
+
children: [
|
|
4537
|
+
/* @__PURE__ */ jsx6("span", { "aria-hidden": "true", children: index + 1 }),
|
|
4538
|
+
/* @__PURE__ */ jsx6("span", { children: item.label })
|
|
4539
|
+
]
|
|
4540
|
+
},
|
|
4541
|
+
item.id
|
|
4542
|
+
)) }),
|
|
4543
|
+
step === "date" ? /* @__PURE__ */ jsxs6("div", { className: "booking-card__step", ref: activeStepRef, children: [
|
|
4544
|
+
/* @__PURE__ */ jsx6("p", { className: "booking-card__title", children: selectedType?.name || "Pick a date" }),
|
|
4545
|
+
timeZone ? /* @__PURE__ */ jsxs6("p", { className: "booking-card__tz", children: [
|
|
4546
|
+
"Times in ",
|
|
4547
|
+
timeZone
|
|
4548
|
+
] }) : null,
|
|
4549
|
+
offer.eventTypes.length > 1 ? /* @__PURE__ */ jsxs6(
|
|
4550
|
+
"label",
|
|
4551
|
+
{
|
|
4552
|
+
className: "booking-card__field",
|
|
4553
|
+
htmlFor: `${fieldId}-type`,
|
|
4554
|
+
children: [
|
|
4555
|
+
/* @__PURE__ */ jsx6("span", { children: "Meeting" }),
|
|
4556
|
+
/* @__PURE__ */ jsx6(
|
|
4557
|
+
"select",
|
|
4558
|
+
{
|
|
4559
|
+
id: `${fieldId}-type`,
|
|
4560
|
+
value: eventTypeUri,
|
|
4561
|
+
disabled,
|
|
4562
|
+
onChange: (event) => selectEventType(event.target.value),
|
|
4563
|
+
children: offer.eventTypes.map((item) => /* @__PURE__ */ jsx6("option", { value: item.uri, children: item.name }, item.uri))
|
|
4564
|
+
}
|
|
4565
|
+
)
|
|
4566
|
+
]
|
|
4567
|
+
}
|
|
4568
|
+
) : null,
|
|
4569
|
+
/* @__PURE__ */ jsxs6("div", { className: "booking-card__month", children: [
|
|
4570
|
+
/* @__PURE__ */ jsx6(
|
|
4571
|
+
"button",
|
|
3781
4572
|
{
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
4573
|
+
type: "button",
|
|
4574
|
+
className: "booking-card__nav",
|
|
4575
|
+
"aria-label": "Previous month",
|
|
4576
|
+
disabled: disabled || !canPrevMonth,
|
|
4577
|
+
onClick: () => goToMonth(-1),
|
|
4578
|
+
children: "\u2039"
|
|
4579
|
+
}
|
|
4580
|
+
),
|
|
4581
|
+
/* @__PURE__ */ jsx6("p", { className: "booking-card__month-title", children: formatMonthTitle(visibleMonth.year, visibleMonth.month) }),
|
|
4582
|
+
/* @__PURE__ */ jsx6(
|
|
4583
|
+
"button",
|
|
4584
|
+
{
|
|
4585
|
+
type: "button",
|
|
4586
|
+
className: "booking-card__nav",
|
|
4587
|
+
"aria-label": "Next month",
|
|
4588
|
+
disabled: disabled || !canNextMonth,
|
|
4589
|
+
onClick: () => goToMonth(1),
|
|
4590
|
+
children: "\u203A"
|
|
3786
4591
|
}
|
|
3787
4592
|
)
|
|
3788
|
-
]
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
return /* @__PURE__ */ jsx4(
|
|
3827
|
-
"span",
|
|
3828
|
-
{
|
|
3829
|
-
className: "booking-card__day"
|
|
3830
|
-
},
|
|
3831
|
-
`empty-${index}`
|
|
3832
|
-
);
|
|
4593
|
+
] }),
|
|
4594
|
+
/* @__PURE__ */ jsx6("div", { className: "booking-card__weekdays", children: weekdays.map((label) => /* @__PURE__ */ jsx6("span", { children: label }, label)) }),
|
|
4595
|
+
offer.slots.length === 0 ? /* @__PURE__ */ jsx6("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) : null,
|
|
4596
|
+
/* @__PURE__ */ jsx6(
|
|
4597
|
+
"div",
|
|
4598
|
+
{
|
|
4599
|
+
className: "booking-card__calendar",
|
|
4600
|
+
role: "grid",
|
|
4601
|
+
"aria-label": "Available dates",
|
|
4602
|
+
children: cells.map((cell, index) => {
|
|
4603
|
+
if (!cell) {
|
|
4604
|
+
return /* @__PURE__ */ jsx6(
|
|
4605
|
+
"span",
|
|
4606
|
+
{
|
|
4607
|
+
className: "booking-card__day"
|
|
4608
|
+
},
|
|
4609
|
+
`empty-${index}`
|
|
4610
|
+
);
|
|
4611
|
+
}
|
|
4612
|
+
const available = availableByDate.has(cell.key);
|
|
4613
|
+
const selected = cell.key === selectedDate;
|
|
4614
|
+
return /* @__PURE__ */ jsx6(
|
|
4615
|
+
"button",
|
|
4616
|
+
{
|
|
4617
|
+
type: "button",
|
|
4618
|
+
className: [
|
|
4619
|
+
"booking-card__day",
|
|
4620
|
+
available ? "booking-card__day--available" : "",
|
|
4621
|
+
selected ? "booking-card__day--selected" : ""
|
|
4622
|
+
].filter(Boolean).join(" "),
|
|
4623
|
+
disabled: disabled || !available,
|
|
4624
|
+
"aria-pressed": selected,
|
|
4625
|
+
onClick: () => selectDate(cell.key),
|
|
4626
|
+
children: cell.day
|
|
4627
|
+
},
|
|
4628
|
+
cell.key
|
|
4629
|
+
);
|
|
4630
|
+
})
|
|
3833
4631
|
}
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
4632
|
+
)
|
|
4633
|
+
] }, "date") : null,
|
|
4634
|
+
step === "time" ? /* @__PURE__ */ jsxs6("div", { className: "booking-card__step", ref: activeStepRef, children: [
|
|
4635
|
+
/* @__PURE__ */ jsxs6("div", { className: "booking-card__step-bar", children: [
|
|
4636
|
+
/* @__PURE__ */ jsx6(
|
|
3837
4637
|
"button",
|
|
3838
4638
|
{
|
|
3839
4639
|
type: "button",
|
|
3840
|
-
className:
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
]
|
|
3945
|
-
}
|
|
3946
|
-
)
|
|
3947
|
-
] }),
|
|
3948
|
-
/* @__PURE__ */ jsx4(
|
|
3949
|
-
"button",
|
|
3950
|
-
{
|
|
3951
|
-
type: "submit",
|
|
3952
|
-
className: "booking-card__submit",
|
|
3953
|
-
disabled: !name.trim() || !email.trim(),
|
|
3954
|
-
children: "Book this time"
|
|
3955
|
-
}
|
|
3956
|
-
)
|
|
3957
|
-
] }, "details") : null
|
|
3958
|
-
] }) });
|
|
4640
|
+
className: "booking-card__nav",
|
|
4641
|
+
"aria-label": "Back to dates",
|
|
4642
|
+
disabled,
|
|
4643
|
+
onClick: () => setStep("date"),
|
|
4644
|
+
children: "\u2039"
|
|
4645
|
+
}
|
|
4646
|
+
),
|
|
4647
|
+
/* @__PURE__ */ jsxs6("div", { children: [
|
|
4648
|
+
/* @__PURE__ */ jsx6("p", { className: "booking-card__title", children: selectedSample ? formatLongDate(selectedSample) : "Pick a time" }),
|
|
4649
|
+
timeZone ? /* @__PURE__ */ jsxs6("p", { className: "booking-card__tz", children: [
|
|
4650
|
+
"Times in ",
|
|
4651
|
+
timeZone
|
|
4652
|
+
] }) : null
|
|
4653
|
+
] })
|
|
4654
|
+
] }),
|
|
4655
|
+
/* @__PURE__ */ jsx6("div", { className: "booking-card__times", children: daySlots.map((slot) => /* @__PURE__ */ jsx6(
|
|
4656
|
+
"button",
|
|
4657
|
+
{
|
|
4658
|
+
type: "button",
|
|
4659
|
+
className: startTime === slot.startTime ? "booking-card__time booking-card__time--selected" : "booking-card__time",
|
|
4660
|
+
disabled,
|
|
4661
|
+
onClick: () => selectTime(slot.startTime),
|
|
4662
|
+
children: formatTimeChip(slot.startTime)
|
|
4663
|
+
},
|
|
4664
|
+
slot.startTime
|
|
4665
|
+
)) })
|
|
4666
|
+
] }, "time") : null,
|
|
4667
|
+
step === "details" ? /* @__PURE__ */ jsxs6("div", { className: "booking-card__step", ref: activeStepRef, children: [
|
|
4668
|
+
/* @__PURE__ */ jsxs6("div", { className: "booking-card__step-bar", children: [
|
|
4669
|
+
/* @__PURE__ */ jsx6(
|
|
4670
|
+
"button",
|
|
4671
|
+
{
|
|
4672
|
+
type: "button",
|
|
4673
|
+
className: "booking-card__nav",
|
|
4674
|
+
"aria-label": "Back to times",
|
|
4675
|
+
disabled,
|
|
4676
|
+
onClick: () => setStep("time"),
|
|
4677
|
+
children: "\u2039"
|
|
4678
|
+
}
|
|
4679
|
+
),
|
|
4680
|
+
/* @__PURE__ */ jsxs6("div", { children: [
|
|
4681
|
+
/* @__PURE__ */ jsx6("p", { className: "booking-card__title", children: "Enter details" }),
|
|
4682
|
+
/* @__PURE__ */ jsx6("p", { className: "booking-card__tz", children: formatSlotLabel(startTime) }),
|
|
4683
|
+
selectedType?.location ? /* @__PURE__ */ jsx6("p", { className: "booking-card__tz", children: selectedType.location }) : null
|
|
4684
|
+
] })
|
|
4685
|
+
] }),
|
|
4686
|
+
/* @__PURE__ */ jsxs6("div", { className: "booking-card__identity", children: [
|
|
4687
|
+
/* @__PURE__ */ jsxs6(
|
|
4688
|
+
"label",
|
|
4689
|
+
{
|
|
4690
|
+
className: "booking-card__field",
|
|
4691
|
+
htmlFor: `${fieldId}-name`,
|
|
4692
|
+
children: [
|
|
4693
|
+
/* @__PURE__ */ jsx6("span", { children: "Name" }),
|
|
4694
|
+
/* @__PURE__ */ jsx6(
|
|
4695
|
+
"input",
|
|
4696
|
+
{
|
|
4697
|
+
id: `${fieldId}-name`,
|
|
4698
|
+
autoComplete: "name",
|
|
4699
|
+
disabled,
|
|
4700
|
+
value: name,
|
|
4701
|
+
onChange: (event) => setName(event.target.value),
|
|
4702
|
+
required: true
|
|
4703
|
+
}
|
|
4704
|
+
)
|
|
4705
|
+
]
|
|
4706
|
+
}
|
|
4707
|
+
),
|
|
4708
|
+
/* @__PURE__ */ jsxs6(
|
|
4709
|
+
"label",
|
|
4710
|
+
{
|
|
4711
|
+
className: "booking-card__field",
|
|
4712
|
+
htmlFor: `${fieldId}-email`,
|
|
4713
|
+
children: [
|
|
4714
|
+
/* @__PURE__ */ jsx6("span", { children: "Email" }),
|
|
4715
|
+
/* @__PURE__ */ jsx6(
|
|
4716
|
+
"input",
|
|
4717
|
+
{
|
|
4718
|
+
id: `${fieldId}-email`,
|
|
4719
|
+
type: "email",
|
|
4720
|
+
autoComplete: "email",
|
|
4721
|
+
disabled,
|
|
4722
|
+
value: email,
|
|
4723
|
+
onChange: (event) => setEmail(event.target.value),
|
|
4724
|
+
required: true
|
|
4725
|
+
}
|
|
4726
|
+
)
|
|
4727
|
+
]
|
|
4728
|
+
}
|
|
4729
|
+
)
|
|
4730
|
+
] }),
|
|
4731
|
+
/* @__PURE__ */ jsx6(
|
|
4732
|
+
"button",
|
|
4733
|
+
{
|
|
4734
|
+
type: "submit",
|
|
4735
|
+
className: "booking-card__submit",
|
|
4736
|
+
disabled: disabled || !name.trim() || !email.trim(),
|
|
4737
|
+
children: disabled ? "Booking\u2026" : "Book this time"
|
|
4738
|
+
}
|
|
4739
|
+
)
|
|
4740
|
+
] }, "details") : null
|
|
4741
|
+
] })
|
|
4742
|
+
}
|
|
4743
|
+
);
|
|
3959
4744
|
}
|
|
3960
4745
|
|
|
3961
4746
|
// src/react/components/MessageBubble/MessageBubble.tsx
|
|
3962
4747
|
import { Streamdown } from "streamdown";
|
|
3963
4748
|
import "streamdown/styles.css";
|
|
3964
|
-
import { jsx as
|
|
4749
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
3965
4750
|
function normalizeDedupeText(text) {
|
|
3966
4751
|
return text.trim().replace(/\s+/g, " ").toLowerCase();
|
|
3967
4752
|
}
|
|
@@ -3972,9 +4757,7 @@ function paragraphsAreNearDuplicates(first, second) {
|
|
|
3972
4757
|
if (left === right) return true;
|
|
3973
4758
|
const shorter = left.length <= right.length ? left : right;
|
|
3974
4759
|
const longer = left.length <= right.length ? right : left;
|
|
3975
|
-
return longer.startsWith(
|
|
3976
|
-
shorter.slice(0, Math.floor(shorter.length * 0.85))
|
|
3977
|
-
);
|
|
4760
|
+
return longer.startsWith(shorter.slice(0, Math.floor(shorter.length * 0.85)));
|
|
3978
4761
|
}
|
|
3979
4762
|
function paragraphsShareOpening(first, second) {
|
|
3980
4763
|
const opening = first.split("\n")[0]?.trim();
|
|
@@ -4002,11 +4785,12 @@ function collapseRepeatedText(text) {
|
|
|
4002
4785
|
function MessageBubble({
|
|
4003
4786
|
message,
|
|
4004
4787
|
brandLogoUrl,
|
|
4788
|
+
bookingDisabled = false,
|
|
4005
4789
|
offer,
|
|
4006
4790
|
onBook
|
|
4007
4791
|
}) {
|
|
4008
4792
|
const resolvedLogoUrl = brandLogoUrl?.trim();
|
|
4009
|
-
const [failedLogoUrl, setFailedLogoUrl] =
|
|
4793
|
+
const [failedLogoUrl, setFailedLogoUrl] = useState6(null);
|
|
4010
4794
|
const showBrandLogo = Boolean(resolvedLogoUrl) && failedLogoUrl !== resolvedLogoUrl;
|
|
4011
4795
|
const cards = message.role === "agent" ? extractToolCards(message.text) : [];
|
|
4012
4796
|
const extractedOffers = cards.filter(
|
|
@@ -4019,11 +4803,11 @@ function MessageBubble({
|
|
|
4019
4803
|
offers.length > 0 ? sanitizeBookingOfferCopy(visibleText) : looksLikeBookingAvailabilityDump(visibleText) ? sanitizeBookingOfferCopy(visibleText) : visibleText || (isStreaming ? "" : message.text)
|
|
4020
4804
|
);
|
|
4021
4805
|
if (message.role === "visitor") {
|
|
4022
|
-
return /* @__PURE__ */
|
|
4806
|
+
return /* @__PURE__ */ jsx7("article", { className: "message-bubble message-bubble--visitor", children: /* @__PURE__ */ jsx7("p", { className: "message-bubble__text", children: message.text }) });
|
|
4023
4807
|
}
|
|
4024
4808
|
const citations = message.citations ?? [];
|
|
4025
|
-
const agentText = /* @__PURE__ */
|
|
4026
|
-
/* @__PURE__ */
|
|
4809
|
+
const agentText = /* @__PURE__ */ jsxs7("div", { className: "message-bubble__text", children: [
|
|
4810
|
+
/* @__PURE__ */ jsx7(
|
|
4027
4811
|
Streamdown,
|
|
4028
4812
|
{
|
|
4029
4813
|
animated: isStreaming,
|
|
@@ -4037,22 +4821,21 @@ function MessageBubble({
|
|
|
4037
4821
|
children: displayText
|
|
4038
4822
|
}
|
|
4039
4823
|
),
|
|
4040
|
-
citations.length > 0 ? /* @__PURE__ */
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
) }, citation.id)) }) : null
|
|
4824
|
+
citations.length > 0 ? /* @__PURE__ */ jsx7("ul", { className: "message-bubble__sources", "aria-label": "Sources", children: citations.map((citation) => /* @__PURE__ */ jsx7("li", { children: /* @__PURE__ */ jsxs7("a", { href: citation.url, target: "_blank", rel: "noreferrer", children: [
|
|
4825
|
+
/* @__PURE__ */ jsx7(
|
|
4826
|
+
"span",
|
|
4827
|
+
{
|
|
4828
|
+
className: "message-bubble__source-icon",
|
|
4829
|
+
"aria-hidden": "true",
|
|
4830
|
+
children: "\u25A6"
|
|
4831
|
+
}
|
|
4832
|
+
),
|
|
4833
|
+
/* @__PURE__ */ jsx7("span", { children: citation.label })
|
|
4834
|
+
] }) }, citation.id)) }) : null
|
|
4052
4835
|
] });
|
|
4053
|
-
return /* @__PURE__ */
|
|
4054
|
-
displayText ? showBrandLogo ? /* @__PURE__ */
|
|
4055
|
-
/* @__PURE__ */
|
|
4836
|
+
return /* @__PURE__ */ jsxs7("article", { className: "message-bubble message-bubble--agent", children: [
|
|
4837
|
+
displayText ? showBrandLogo ? /* @__PURE__ */ jsxs7("div", { className: "message-bubble__agent-row", children: [
|
|
4838
|
+
/* @__PURE__ */ jsx7("span", { className: "message-bubble__agent-avatar", "aria-hidden": "true", children: /* @__PURE__ */ jsx7(
|
|
4056
4839
|
"img",
|
|
4057
4840
|
{
|
|
4058
4841
|
src: resolvedLogoUrl,
|
|
@@ -4064,9 +4847,10 @@ function MessageBubble({
|
|
|
4064
4847
|
) }),
|
|
4065
4848
|
agentText
|
|
4066
4849
|
] }) : agentText : null,
|
|
4067
|
-
offers.map((nextOffer, index) => /* @__PURE__ */
|
|
4850
|
+
offers.map((nextOffer, index) => /* @__PURE__ */ jsx7(
|
|
4068
4851
|
BookingCard,
|
|
4069
4852
|
{
|
|
4853
|
+
disabled: bookingDisabled,
|
|
4070
4854
|
offer: nextOffer,
|
|
4071
4855
|
onBook
|
|
4072
4856
|
},
|
|
@@ -4076,10 +4860,10 @@ function MessageBubble({
|
|
|
4076
4860
|
}
|
|
4077
4861
|
|
|
4078
4862
|
// src/react/components/HumanInputCard/HumanInputCard.tsx
|
|
4079
|
-
import { useState as
|
|
4863
|
+
import { useState as useState8 } from "react";
|
|
4080
4864
|
|
|
4081
4865
|
// src/react/components/ConfirmationCard/ConfirmationCard.tsx
|
|
4082
|
-
import { jsx as
|
|
4866
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
4083
4867
|
function ConfirmationCard({
|
|
4084
4868
|
disabled = false,
|
|
4085
4869
|
request,
|
|
@@ -4088,17 +4872,17 @@ function ConfirmationCard({
|
|
|
4088
4872
|
const options = request.options ?? [];
|
|
4089
4873
|
const heading = request.kind === "tool-approval" ? "Confirm this action" : request.prompt;
|
|
4090
4874
|
const prompt = request.kind === "tool-approval" ? request.prompt : void 0;
|
|
4091
|
-
return /* @__PURE__ */
|
|
4875
|
+
return /* @__PURE__ */ jsxs8(
|
|
4092
4876
|
"section",
|
|
4093
4877
|
{
|
|
4094
4878
|
className: "confirmation-card",
|
|
4095
4879
|
"aria-labelledby": `confirmation-${request.requestId}`,
|
|
4096
4880
|
children: [
|
|
4097
|
-
/* @__PURE__ */
|
|
4098
|
-
/* @__PURE__ */
|
|
4099
|
-
prompt ? /* @__PURE__ */
|
|
4881
|
+
/* @__PURE__ */ jsxs8("div", { className: "confirmation-card__heading", children: [
|
|
4882
|
+
/* @__PURE__ */ jsx8("strong", { id: `confirmation-${request.requestId}`, children: heading }),
|
|
4883
|
+
prompt ? /* @__PURE__ */ jsx8("p", { children: prompt }) : null
|
|
4100
4884
|
] }),
|
|
4101
|
-
/* @__PURE__ */
|
|
4885
|
+
/* @__PURE__ */ jsx8("div", { className: "confirmation-card__actions", children: options.map((option) => /* @__PURE__ */ jsx8(
|
|
4102
4886
|
"button",
|
|
4103
4887
|
{
|
|
4104
4888
|
type: "button",
|
|
@@ -4118,8 +4902,8 @@ function ConfirmationCard({
|
|
|
4118
4902
|
}
|
|
4119
4903
|
|
|
4120
4904
|
// src/react/components/ToolInputCard/ToolInputCard.tsx
|
|
4121
|
-
import { useState as
|
|
4122
|
-
import { jsx as
|
|
4905
|
+
import { useState as useState7 } from "react";
|
|
4906
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
4123
4907
|
function isRecord5(value) {
|
|
4124
4908
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4125
4909
|
}
|
|
@@ -4243,7 +5027,7 @@ function FieldDescription({
|
|
|
4243
5027
|
field,
|
|
4244
5028
|
id
|
|
4245
5029
|
}) {
|
|
4246
|
-
return field.description ? /* @__PURE__ */
|
|
5030
|
+
return field.description ? /* @__PURE__ */ jsx9("span", { id, className: "tool-input-card__description", children: field.description }) : null;
|
|
4247
5031
|
}
|
|
4248
5032
|
function ChoiceField({
|
|
4249
5033
|
field,
|
|
@@ -4262,7 +5046,7 @@ function ChoiceField({
|
|
|
4262
5046
|
const selectedIndex = options.findIndex(
|
|
4263
5047
|
(option) => valuesMatch(option.value, value)
|
|
4264
5048
|
);
|
|
4265
|
-
return /* @__PURE__ */
|
|
5049
|
+
return /* @__PURE__ */ jsxs9(
|
|
4266
5050
|
"select",
|
|
4267
5051
|
{
|
|
4268
5052
|
id,
|
|
@@ -4277,13 +5061,13 @@ function ChoiceField({
|
|
|
4277
5061
|
if (option) onChange(option.value);
|
|
4278
5062
|
},
|
|
4279
5063
|
children: [
|
|
4280
|
-
/* @__PURE__ */
|
|
4281
|
-
options.map((option, index) => /* @__PURE__ */
|
|
5064
|
+
/* @__PURE__ */ jsx9("option", { value: "", disabled: field.required, children: "Choose an option" }),
|
|
5065
|
+
options.map((option, index) => /* @__PURE__ */ jsx9("option", { value: index, children: option.label }, optionKey(option)))
|
|
4282
5066
|
]
|
|
4283
5067
|
}
|
|
4284
5068
|
);
|
|
4285
5069
|
}
|
|
4286
|
-
return /* @__PURE__ */
|
|
5070
|
+
return /* @__PURE__ */ jsx9(
|
|
4287
5071
|
"div",
|
|
4288
5072
|
{
|
|
4289
5073
|
className: "tool-input-card__choices",
|
|
@@ -4294,8 +5078,8 @@ function ChoiceField({
|
|
|
4294
5078
|
"aria-required": field.required,
|
|
4295
5079
|
children: options.map((option, index) => {
|
|
4296
5080
|
const checked = multiple ? selected.some((item) => valuesMatch(item, option.value)) : valuesMatch(value, option.value);
|
|
4297
|
-
return /* @__PURE__ */
|
|
4298
|
-
/* @__PURE__ */
|
|
5081
|
+
return /* @__PURE__ */ jsxs9("label", { className: "tool-input-card__choice", children: [
|
|
5082
|
+
/* @__PURE__ */ jsx9(
|
|
4299
5083
|
"input",
|
|
4300
5084
|
{
|
|
4301
5085
|
type: multiple ? "checkbox" : "radio",
|
|
@@ -4317,7 +5101,7 @@ function ChoiceField({
|
|
|
4317
5101
|
}
|
|
4318
5102
|
}
|
|
4319
5103
|
),
|
|
4320
|
-
/* @__PURE__ */
|
|
5104
|
+
/* @__PURE__ */ jsx9("span", { children: option.label })
|
|
4321
5105
|
] }, optionKey(option));
|
|
4322
5106
|
})
|
|
4323
5107
|
}
|
|
@@ -4337,9 +5121,9 @@ function ToolField({
|
|
|
4337
5121
|
error ? `${id}-error` : ""
|
|
4338
5122
|
].filter(Boolean).join(" ");
|
|
4339
5123
|
if (field.kind === "checkbox" || field.kind === "confirmation") {
|
|
4340
|
-
return /* @__PURE__ */
|
|
4341
|
-
/* @__PURE__ */
|
|
4342
|
-
/* @__PURE__ */
|
|
5124
|
+
return /* @__PURE__ */ jsxs9("div", { className: "tool-input-card__field", children: [
|
|
5125
|
+
/* @__PURE__ */ jsxs9("label", { className: "tool-input-card__check", htmlFor: id, children: [
|
|
5126
|
+
/* @__PURE__ */ jsx9(
|
|
4343
5127
|
"input",
|
|
4344
5128
|
{
|
|
4345
5129
|
id,
|
|
@@ -4352,17 +5136,17 @@ function ToolField({
|
|
|
4352
5136
|
onChange: (event) => onChange(event.target.checked)
|
|
4353
5137
|
}
|
|
4354
5138
|
),
|
|
4355
|
-
/* @__PURE__ */
|
|
4356
|
-
/* @__PURE__ */
|
|
4357
|
-
field.description ? /* @__PURE__ */
|
|
5139
|
+
/* @__PURE__ */ jsxs9("span", { children: [
|
|
5140
|
+
/* @__PURE__ */ jsx9("strong", { children: field.label }),
|
|
5141
|
+
field.description ? /* @__PURE__ */ jsx9("span", { id: `${id}-description`, children: field.description }) : null
|
|
4358
5142
|
] })
|
|
4359
5143
|
] }),
|
|
4360
|
-
error ? /* @__PURE__ */
|
|
5144
|
+
error ? /* @__PURE__ */ jsx9("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
|
|
4361
5145
|
] });
|
|
4362
5146
|
}
|
|
4363
|
-
const label = /* @__PURE__ */
|
|
5147
|
+
const label = /* @__PURE__ */ jsxs9("label", { id: `${id}-label`, htmlFor: id, children: [
|
|
4364
5148
|
field.label,
|
|
4365
|
-
field.required ? /* @__PURE__ */
|
|
5149
|
+
field.required ? /* @__PURE__ */ jsx9("span", { "aria-hidden": "true", children: " *" }) : null
|
|
4366
5150
|
] });
|
|
4367
5151
|
const common = {
|
|
4368
5152
|
id,
|
|
@@ -4374,7 +5158,7 @@ function ToolField({
|
|
|
4374
5158
|
};
|
|
4375
5159
|
let control;
|
|
4376
5160
|
if (field.kind === "select" || field.kind === "radio" || field.kind === "multi-select") {
|
|
4377
|
-
control = /* @__PURE__ */
|
|
5161
|
+
control = /* @__PURE__ */ jsx9(
|
|
4378
5162
|
ChoiceField,
|
|
4379
5163
|
{
|
|
4380
5164
|
field,
|
|
@@ -4388,7 +5172,7 @@ function ToolField({
|
|
|
4388
5172
|
}
|
|
4389
5173
|
);
|
|
4390
5174
|
} else if (field.kind === "textarea" || field.kind === "json") {
|
|
4391
|
-
control = /* @__PURE__ */
|
|
5175
|
+
control = /* @__PURE__ */ jsx9(
|
|
4392
5176
|
"textarea",
|
|
4393
5177
|
{
|
|
4394
5178
|
...common,
|
|
@@ -4402,8 +5186,8 @@ function ToolField({
|
|
|
4402
5186
|
);
|
|
4403
5187
|
} else if (field.kind === "range") {
|
|
4404
5188
|
const numericValue = typeof value === "number" ? value : field.min ?? 0;
|
|
4405
|
-
control = /* @__PURE__ */
|
|
4406
|
-
/* @__PURE__ */
|
|
5189
|
+
control = /* @__PURE__ */ jsxs9("div", { className: "tool-input-card__range", children: [
|
|
5190
|
+
/* @__PURE__ */ jsx9(
|
|
4407
5191
|
"input",
|
|
4408
5192
|
{
|
|
4409
5193
|
...common,
|
|
@@ -4415,11 +5199,11 @@ function ToolField({
|
|
|
4415
5199
|
onChange: (event) => onChange(Number(event.target.value))
|
|
4416
5200
|
}
|
|
4417
5201
|
),
|
|
4418
|
-
/* @__PURE__ */
|
|
5202
|
+
/* @__PURE__ */ jsx9("output", { htmlFor: id, children: numericValue })
|
|
4419
5203
|
] });
|
|
4420
5204
|
} else {
|
|
4421
5205
|
const type = field.kind === "date-time" ? "datetime-local" : field.kind === "calendar" ? "date" : field.kind;
|
|
4422
|
-
control = /* @__PURE__ */
|
|
5206
|
+
control = /* @__PURE__ */ jsx9(
|
|
4423
5207
|
"input",
|
|
4424
5208
|
{
|
|
4425
5209
|
...common,
|
|
@@ -4437,11 +5221,11 @@ function ToolField({
|
|
|
4437
5221
|
}
|
|
4438
5222
|
);
|
|
4439
5223
|
}
|
|
4440
|
-
return /* @__PURE__ */
|
|
5224
|
+
return /* @__PURE__ */ jsxs9("div", { className: "tool-input-card__field", children: [
|
|
4441
5225
|
label,
|
|
4442
|
-
/* @__PURE__ */
|
|
5226
|
+
/* @__PURE__ */ jsx9(FieldDescription, { field, id: `${id}-description` }),
|
|
4443
5227
|
control,
|
|
4444
|
-
error ? /* @__PURE__ */
|
|
5228
|
+
error ? /* @__PURE__ */ jsx9("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
|
|
4445
5229
|
] });
|
|
4446
5230
|
}
|
|
4447
5231
|
function ToolInputCard({
|
|
@@ -4449,11 +5233,11 @@ function ToolInputCard({
|
|
|
4449
5233
|
surface,
|
|
4450
5234
|
onSubmit
|
|
4451
5235
|
}) {
|
|
4452
|
-
const [values, setValues] =
|
|
5236
|
+
const [values, setValues] = useState7(
|
|
4453
5237
|
() => initialValues(surface)
|
|
4454
5238
|
);
|
|
4455
|
-
const [touched, setTouched] =
|
|
4456
|
-
const [submitted, setSubmitted] =
|
|
5239
|
+
const [touched, setTouched] = useState7(() => /* @__PURE__ */ new Set());
|
|
5240
|
+
const [submitted, setSubmitted] = useState7(false);
|
|
4457
5241
|
const errors = Object.fromEntries(
|
|
4458
5242
|
surface.fields.map((field) => [
|
|
4459
5243
|
field.path,
|
|
@@ -4478,14 +5262,14 @@ function ToolInputCard({
|
|
|
4478
5262
|
onSubmit?.(surface, result);
|
|
4479
5263
|
}
|
|
4480
5264
|
if (submitted) {
|
|
4481
|
-
return /* @__PURE__ */
|
|
5265
|
+
return /* @__PURE__ */ jsxs9(
|
|
4482
5266
|
"section",
|
|
4483
5267
|
{
|
|
4484
5268
|
className: "tool-input-card tool-input-card--submitted",
|
|
4485
5269
|
role: "status",
|
|
4486
5270
|
children: [
|
|
4487
|
-
/* @__PURE__ */
|
|
4488
|
-
/* @__PURE__ */
|
|
5271
|
+
/* @__PURE__ */ jsx9("span", { "aria-hidden": "true", children: "\u2713" }),
|
|
5272
|
+
/* @__PURE__ */ jsxs9("strong", { children: [
|
|
4489
5273
|
surface.title,
|
|
4490
5274
|
" submitted"
|
|
4491
5275
|
] })
|
|
@@ -4493,18 +5277,18 @@ function ToolInputCard({
|
|
|
4493
5277
|
}
|
|
4494
5278
|
);
|
|
4495
5279
|
}
|
|
4496
|
-
return /* @__PURE__ */
|
|
5280
|
+
return /* @__PURE__ */ jsxs9(
|
|
4497
5281
|
"section",
|
|
4498
5282
|
{
|
|
4499
5283
|
className: "tool-input-card",
|
|
4500
5284
|
"aria-labelledby": `tool-input-${surface.id}`,
|
|
4501
5285
|
children: [
|
|
4502
|
-
/* @__PURE__ */
|
|
4503
|
-
/* @__PURE__ */
|
|
4504
|
-
surface.description ? /* @__PURE__ */
|
|
5286
|
+
/* @__PURE__ */ jsxs9("div", { className: "tool-input-card__heading", children: [
|
|
5287
|
+
/* @__PURE__ */ jsx9("strong", { id: `tool-input-${surface.id}`, children: surface.title }),
|
|
5288
|
+
surface.description ? /* @__PURE__ */ jsx9("p", { children: surface.description }) : null
|
|
4505
5289
|
] }),
|
|
4506
|
-
/* @__PURE__ */
|
|
4507
|
-
/* @__PURE__ */
|
|
5290
|
+
/* @__PURE__ */ jsxs9("form", { noValidate: true, onSubmit: submit, children: [
|
|
5291
|
+
/* @__PURE__ */ jsx9("div", { className: "tool-input-card__fields", children: surface.fields.map((field, index) => /* @__PURE__ */ jsx9(
|
|
4508
5292
|
ToolField,
|
|
4509
5293
|
{
|
|
4510
5294
|
disabled,
|
|
@@ -4517,8 +5301,8 @@ function ToolInputCard({
|
|
|
4517
5301
|
},
|
|
4518
5302
|
field.path
|
|
4519
5303
|
)) }),
|
|
4520
|
-
/* @__PURE__ */
|
|
4521
|
-
surface.actions?.some((action) => action.id === "reset") ? /* @__PURE__ */
|
|
5304
|
+
/* @__PURE__ */ jsxs9("div", { className: "tool-input-card__actions", children: [
|
|
5305
|
+
surface.actions?.some((action) => action.id === "reset") ? /* @__PURE__ */ jsx9(
|
|
4522
5306
|
"button",
|
|
4523
5307
|
{
|
|
4524
5308
|
type: "button",
|
|
@@ -4531,7 +5315,7 @@ function ToolInputCard({
|
|
|
4531
5315
|
children: surface.actions.find((action) => action.id === "reset")?.label ?? "Clear"
|
|
4532
5316
|
}
|
|
4533
5317
|
) : null,
|
|
4534
|
-
/* @__PURE__ */
|
|
5318
|
+
/* @__PURE__ */ jsx9("button", { type: "submit", disabled, children: surface.submitLabel ?? surface.actions?.find((action) => action.id === "submit")?.label ?? "Continue" })
|
|
4535
5319
|
] })
|
|
4536
5320
|
] })
|
|
4537
5321
|
]
|
|
@@ -4540,17 +5324,17 @@ function ToolInputCard({
|
|
|
4540
5324
|
}
|
|
4541
5325
|
|
|
4542
5326
|
// src/react/components/HumanInputCard/HumanInputCard.tsx
|
|
4543
|
-
import { jsx as
|
|
5327
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
4544
5328
|
function HumanInputCard({
|
|
4545
5329
|
disabled = false,
|
|
4546
5330
|
request,
|
|
4547
5331
|
onRespond
|
|
4548
5332
|
}) {
|
|
4549
|
-
const [text, setText] =
|
|
5333
|
+
const [text, setText] = useState8("");
|
|
4550
5334
|
const options = request.options ?? [];
|
|
4551
5335
|
const showText = request.display === "text" || request.allowFreeform && options.length === 0;
|
|
4552
5336
|
if (request.ui) {
|
|
4553
|
-
return /* @__PURE__ */
|
|
5337
|
+
return /* @__PURE__ */ jsx10(
|
|
4554
5338
|
ToolInputCard,
|
|
4555
5339
|
{
|
|
4556
5340
|
disabled,
|
|
@@ -4560,7 +5344,7 @@ function HumanInputCard({
|
|
|
4560
5344
|
);
|
|
4561
5345
|
}
|
|
4562
5346
|
if (options.length > 0) {
|
|
4563
|
-
return /* @__PURE__ */
|
|
5347
|
+
return /* @__PURE__ */ jsx10(
|
|
4564
5348
|
ConfirmationCard,
|
|
4565
5349
|
{
|
|
4566
5350
|
disabled,
|
|
@@ -4575,17 +5359,17 @@ function HumanInputCard({
|
|
|
4575
5359
|
if (!value || disabled) return;
|
|
4576
5360
|
onRespond?.({ requestId: request.requestId, text: value });
|
|
4577
5361
|
}
|
|
4578
|
-
return /* @__PURE__ */
|
|
5362
|
+
return /* @__PURE__ */ jsxs10(
|
|
4579
5363
|
"section",
|
|
4580
5364
|
{
|
|
4581
5365
|
className: "human-input-card",
|
|
4582
5366
|
"aria-labelledby": `human-input-${request.requestId}`,
|
|
4583
5367
|
children: [
|
|
4584
|
-
/* @__PURE__ */
|
|
4585
|
-
showText ? /* @__PURE__ */
|
|
4586
|
-
/* @__PURE__ */
|
|
4587
|
-
/* @__PURE__ */
|
|
4588
|
-
/* @__PURE__ */
|
|
5368
|
+
/* @__PURE__ */ jsx10("div", { className: "human-input-card__heading", children: /* @__PURE__ */ jsx10("strong", { id: `human-input-${request.requestId}`, children: request.prompt }) }),
|
|
5369
|
+
showText ? /* @__PURE__ */ jsxs10("form", { onSubmit: submitText, children: [
|
|
5370
|
+
/* @__PURE__ */ jsx10("label", { htmlFor: `human-input-text-${request.requestId}`, children: "Response" }),
|
|
5371
|
+
/* @__PURE__ */ jsxs10("div", { children: [
|
|
5372
|
+
/* @__PURE__ */ jsx10(
|
|
4589
5373
|
"input",
|
|
4590
5374
|
{
|
|
4591
5375
|
id: `human-input-text-${request.requestId}`,
|
|
@@ -4594,39 +5378,39 @@ function HumanInputCard({
|
|
|
4594
5378
|
onChange: (event) => setText(event.target.value)
|
|
4595
5379
|
}
|
|
4596
5380
|
),
|
|
4597
|
-
/* @__PURE__ */
|
|
5381
|
+
/* @__PURE__ */ jsx10("button", { type: "submit", disabled: disabled || !text.trim(), children: "Send" })
|
|
4598
5382
|
] })
|
|
4599
5383
|
] }) : null,
|
|
4600
|
-
!showText && options.length === 0 ? /* @__PURE__ */
|
|
5384
|
+
!showText && options.length === 0 ? /* @__PURE__ */ jsx10("p", { className: "human-input-card__unavailable", role: "status", children: "This request can\u2019t be answered here." }) : null
|
|
4601
5385
|
]
|
|
4602
5386
|
}
|
|
4603
5387
|
);
|
|
4604
5388
|
}
|
|
4605
5389
|
|
|
4606
5390
|
// src/react/components/CollectionResultCard/CollectionResultCard.tsx
|
|
4607
|
-
import { jsx as
|
|
5391
|
+
import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
4608
5392
|
function CollectionResultCard({
|
|
4609
5393
|
result
|
|
4610
5394
|
}) {
|
|
4611
5395
|
const empty = result.items.length === 0;
|
|
4612
|
-
return /* @__PURE__ */
|
|
5396
|
+
return /* @__PURE__ */ jsxs11(
|
|
4613
5397
|
"section",
|
|
4614
5398
|
{
|
|
4615
5399
|
className: `collection-result-card tool-result-card tool-result-card--${result.status}`,
|
|
4616
5400
|
"aria-label": result.title,
|
|
4617
5401
|
children: [
|
|
4618
|
-
/* @__PURE__ */
|
|
4619
|
-
/* @__PURE__ */
|
|
4620
|
-
/* @__PURE__ */
|
|
5402
|
+
/* @__PURE__ */ jsxs11("div", { className: "tool-result-card__heading", children: [
|
|
5403
|
+
/* @__PURE__ */ jsx11("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
|
|
5404
|
+
/* @__PURE__ */ jsx11("strong", { children: result.title })
|
|
4621
5405
|
] }),
|
|
4622
|
-
empty ? /* @__PURE__ */
|
|
4623
|
-
/* @__PURE__ */
|
|
4624
|
-
item.description ? /* @__PURE__ */
|
|
4625
|
-
item.details?.length ? /* @__PURE__ */
|
|
4626
|
-
/* @__PURE__ */
|
|
4627
|
-
/* @__PURE__ */
|
|
5406
|
+
empty ? /* @__PURE__ */ jsx11("p", { className: "collection-result-card__empty", children: "No matching record for the email you shared." }) : /* @__PURE__ */ jsx11("ul", { className: "collection-result-card__list", children: result.items.map((item) => /* @__PURE__ */ jsxs11("li", { children: [
|
|
5407
|
+
/* @__PURE__ */ jsx11("div", { className: "collection-result-card__item-title", children: item.title }),
|
|
5408
|
+
item.description ? /* @__PURE__ */ jsx11("p", { children: item.description }) : null,
|
|
5409
|
+
item.details?.length ? /* @__PURE__ */ jsx11("dl", { children: item.details.map((detail) => /* @__PURE__ */ jsxs11("div", { children: [
|
|
5410
|
+
/* @__PURE__ */ jsx11("dt", { children: detail.label }),
|
|
5411
|
+
/* @__PURE__ */ jsx11("dd", { children: detail.value })
|
|
4628
5412
|
] }, `${detail.label}:${detail.value}`)) }) : null,
|
|
4629
|
-
item.href ? /* @__PURE__ */
|
|
5413
|
+
item.href ? /* @__PURE__ */ jsx11("a", { href: item.href, target: "_blank", rel: "noreferrer", children: "Open record" }) : null
|
|
4630
5414
|
] }, item.title)) })
|
|
4631
5415
|
]
|
|
4632
5416
|
}
|
|
@@ -4634,26 +5418,26 @@ function CollectionResultCard({
|
|
|
4634
5418
|
}
|
|
4635
5419
|
|
|
4636
5420
|
// src/react/components/EntityResultCard/EntityResultCard.tsx
|
|
4637
|
-
import { jsx as
|
|
5421
|
+
import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
4638
5422
|
function EntityResultCard({
|
|
4639
5423
|
result
|
|
4640
5424
|
}) {
|
|
4641
|
-
return /* @__PURE__ */
|
|
5425
|
+
return /* @__PURE__ */ jsxs12(
|
|
4642
5426
|
"section",
|
|
4643
5427
|
{
|
|
4644
5428
|
className: `entity-result-card tool-result-card tool-result-card--${result.status}`,
|
|
4645
5429
|
"aria-label": result.title,
|
|
4646
5430
|
children: [
|
|
4647
|
-
/* @__PURE__ */
|
|
4648
|
-
/* @__PURE__ */
|
|
4649
|
-
/* @__PURE__ */
|
|
5431
|
+
/* @__PURE__ */ jsxs12("div", { className: "tool-result-card__heading", children: [
|
|
5432
|
+
/* @__PURE__ */ jsx12("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
|
|
5433
|
+
/* @__PURE__ */ jsx12("strong", { children: result.title })
|
|
4650
5434
|
] }),
|
|
4651
|
-
result.description ? /* @__PURE__ */
|
|
4652
|
-
result.details?.length ? /* @__PURE__ */
|
|
4653
|
-
/* @__PURE__ */
|
|
4654
|
-
/* @__PURE__ */
|
|
5435
|
+
result.description ? /* @__PURE__ */ jsx12("p", { children: result.description }) : null,
|
|
5436
|
+
result.details?.length ? /* @__PURE__ */ jsx12("dl", { children: result.details.map((detail) => /* @__PURE__ */ jsxs12("div", { children: [
|
|
5437
|
+
/* @__PURE__ */ jsx12("dt", { children: detail.label }),
|
|
5438
|
+
/* @__PURE__ */ jsx12("dd", { children: detail.value })
|
|
4655
5439
|
] }, `${detail.label}:${detail.value}`)) }) : null,
|
|
4656
|
-
result.links?.length ? /* @__PURE__ */
|
|
5440
|
+
result.links?.length ? /* @__PURE__ */ jsx12("div", { className: "tool-result-card__links", children: result.links.map((link) => /* @__PURE__ */ jsx12(
|
|
4657
5441
|
"a",
|
|
4658
5442
|
{
|
|
4659
5443
|
href: link.href,
|
|
@@ -4669,24 +5453,24 @@ function EntityResultCard({
|
|
|
4669
5453
|
}
|
|
4670
5454
|
|
|
4671
5455
|
// src/react/components/SignatureResultCard/SignatureResultCard.tsx
|
|
4672
|
-
import { jsx as
|
|
5456
|
+
import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
4673
5457
|
function SignatureResultCard({
|
|
4674
5458
|
result
|
|
4675
5459
|
}) {
|
|
4676
5460
|
const primaryLink = result.links?.[0];
|
|
4677
|
-
return /* @__PURE__ */
|
|
5461
|
+
return /* @__PURE__ */ jsxs13(
|
|
4678
5462
|
"section",
|
|
4679
5463
|
{
|
|
4680
5464
|
className: `signature-result-card tool-result-card tool-result-card--${result.status}`,
|
|
4681
5465
|
"aria-label": result.title,
|
|
4682
5466
|
children: [
|
|
4683
|
-
/* @__PURE__ */
|
|
4684
|
-
/* @__PURE__ */
|
|
4685
|
-
/* @__PURE__ */
|
|
5467
|
+
/* @__PURE__ */ jsxs13("div", { className: "tool-result-card__heading", children: [
|
|
5468
|
+
/* @__PURE__ */ jsx13("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
|
|
5469
|
+
/* @__PURE__ */ jsx13("strong", { children: result.title })
|
|
4686
5470
|
] }),
|
|
4687
|
-
result.statusLabel ? /* @__PURE__ */
|
|
4688
|
-
result.description ? /* @__PURE__ */
|
|
4689
|
-
primaryLink ? /* @__PURE__ */
|
|
5471
|
+
result.statusLabel ? /* @__PURE__ */ jsx13("span", { className: "signature-result-card__badge", children: result.statusLabel }) : null,
|
|
5472
|
+
result.description ? /* @__PURE__ */ jsx13("p", { children: result.description }) : null,
|
|
5473
|
+
primaryLink ? /* @__PURE__ */ jsx13(
|
|
4690
5474
|
"a",
|
|
4691
5475
|
{
|
|
4692
5476
|
className: "signature-result-card__cta",
|
|
@@ -4702,26 +5486,26 @@ function SignatureResultCard({
|
|
|
4702
5486
|
}
|
|
4703
5487
|
|
|
4704
5488
|
// src/react/components/ToolResultCard/ToolResultCard.tsx
|
|
4705
|
-
import { jsx as
|
|
5489
|
+
import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
4706
5490
|
function ToolResultCard({
|
|
4707
5491
|
result
|
|
4708
5492
|
}) {
|
|
4709
|
-
return /* @__PURE__ */
|
|
5493
|
+
return /* @__PURE__ */ jsxs14(
|
|
4710
5494
|
"section",
|
|
4711
5495
|
{
|
|
4712
5496
|
className: `tool-result-card tool-result-card--${result.status}`,
|
|
4713
5497
|
"aria-label": result.title,
|
|
4714
5498
|
children: [
|
|
4715
|
-
/* @__PURE__ */
|
|
4716
|
-
/* @__PURE__ */
|
|
4717
|
-
/* @__PURE__ */
|
|
5499
|
+
/* @__PURE__ */ jsxs14("div", { className: "tool-result-card__heading", children: [
|
|
5500
|
+
/* @__PURE__ */ jsx14("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
|
|
5501
|
+
/* @__PURE__ */ jsx14("strong", { children: result.title })
|
|
4718
5502
|
] }),
|
|
4719
|
-
result.description ? /* @__PURE__ */
|
|
4720
|
-
result.details?.length ? /* @__PURE__ */
|
|
4721
|
-
/* @__PURE__ */
|
|
4722
|
-
/* @__PURE__ */
|
|
5503
|
+
result.description ? /* @__PURE__ */ jsx14("p", { children: result.description }) : null,
|
|
5504
|
+
result.details?.length ? /* @__PURE__ */ jsx14("dl", { children: result.details.map((detail) => /* @__PURE__ */ jsxs14("div", { children: [
|
|
5505
|
+
/* @__PURE__ */ jsx14("dt", { children: detail.label }),
|
|
5506
|
+
/* @__PURE__ */ jsx14("dd", { children: detail.value })
|
|
4723
5507
|
] }, `${detail.label}:${detail.value}`)) }) : null,
|
|
4724
|
-
result.links?.length ? /* @__PURE__ */
|
|
5508
|
+
result.links?.length ? /* @__PURE__ */ jsx14("div", { className: "tool-result-card__links", children: result.links.map((link) => /* @__PURE__ */ jsx14(
|
|
4725
5509
|
"a",
|
|
4726
5510
|
{
|
|
4727
5511
|
href: link.href,
|
|
@@ -4737,14 +5521,14 @@ function ToolResultCard({
|
|
|
4737
5521
|
}
|
|
4738
5522
|
|
|
4739
5523
|
// src/react/components/VisitorToolResultView/VisitorToolResultView.tsx
|
|
4740
|
-
import { jsx as
|
|
5524
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
4741
5525
|
function VisitorToolResultView({
|
|
4742
5526
|
disabled = false,
|
|
4743
5527
|
onToolInput,
|
|
4744
5528
|
result
|
|
4745
5529
|
}) {
|
|
4746
5530
|
if (result.kind === "input") {
|
|
4747
|
-
return /* @__PURE__ */
|
|
5531
|
+
return /* @__PURE__ */ jsx15(
|
|
4748
5532
|
ToolInputCard,
|
|
4749
5533
|
{
|
|
4750
5534
|
disabled,
|
|
@@ -4754,16 +5538,16 @@ function VisitorToolResultView({
|
|
|
4754
5538
|
);
|
|
4755
5539
|
}
|
|
4756
5540
|
if (result.kind === "entity") {
|
|
4757
|
-
return /* @__PURE__ */
|
|
5541
|
+
return /* @__PURE__ */ jsx15(EntityResultCard, { result });
|
|
4758
5542
|
}
|
|
4759
5543
|
if (result.kind === "collection") {
|
|
4760
|
-
return /* @__PURE__ */
|
|
5544
|
+
return /* @__PURE__ */ jsx15(CollectionResultCard, { result });
|
|
4761
5545
|
}
|
|
4762
5546
|
if (result.kind === "signature") {
|
|
4763
|
-
return /* @__PURE__ */
|
|
5547
|
+
return /* @__PURE__ */ jsx15(SignatureResultCard, { result });
|
|
4764
5548
|
}
|
|
4765
5549
|
if (result.kind === "summary") {
|
|
4766
|
-
return /* @__PURE__ */
|
|
5550
|
+
return /* @__PURE__ */ jsx15(ToolResultCard, { result });
|
|
4767
5551
|
}
|
|
4768
5552
|
return null;
|
|
4769
5553
|
}
|
|
@@ -4772,9 +5556,9 @@ function isRenderableVisitorToolResult(result) {
|
|
|
4772
5556
|
}
|
|
4773
5557
|
|
|
4774
5558
|
// src/react/components/AgentRail/AgentRail.tsx
|
|
4775
|
-
import { Fragment, jsx as
|
|
5559
|
+
import { Fragment, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4776
5560
|
function MinimizeIcon() {
|
|
4777
|
-
return /* @__PURE__ */
|
|
5561
|
+
return /* @__PURE__ */ jsx16("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx16(
|
|
4778
5562
|
"path",
|
|
4779
5563
|
{
|
|
4780
5564
|
d: "M3.5 8h9",
|
|
@@ -4784,8 +5568,8 @@ function MinimizeIcon() {
|
|
|
4784
5568
|
}
|
|
4785
5569
|
) });
|
|
4786
5570
|
}
|
|
4787
|
-
function
|
|
4788
|
-
return /* @__PURE__ */
|
|
5571
|
+
function CloseIcon2() {
|
|
5572
|
+
return /* @__PURE__ */ jsx16("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx16(
|
|
4789
5573
|
"path",
|
|
4790
5574
|
{
|
|
4791
5575
|
d: "M4 4l8 8M12 4l-8 8",
|
|
@@ -4796,7 +5580,7 @@ function CloseIcon() {
|
|
|
4796
5580
|
) });
|
|
4797
5581
|
}
|
|
4798
5582
|
function NewChatIcon() {
|
|
4799
|
-
return /* @__PURE__ */
|
|
5583
|
+
return /* @__PURE__ */ jsx16("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx16(
|
|
4800
5584
|
"path",
|
|
4801
5585
|
{
|
|
4802
5586
|
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",
|
|
@@ -4808,7 +5592,7 @@ function NewChatIcon() {
|
|
|
4808
5592
|
) });
|
|
4809
5593
|
}
|
|
4810
5594
|
function ExpandIcon() {
|
|
4811
|
-
return /* @__PURE__ */
|
|
5595
|
+
return /* @__PURE__ */ jsx16("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx16(
|
|
4812
5596
|
"path",
|
|
4813
5597
|
{
|
|
4814
5598
|
d: "M6 3.5H3.5V6M10 3.5h2.5V6M10 12.5h2.5V10M6 12.5H3.5V10",
|
|
@@ -4820,7 +5604,7 @@ function ExpandIcon() {
|
|
|
4820
5604
|
) });
|
|
4821
5605
|
}
|
|
4822
5606
|
function RestoreIcon() {
|
|
4823
|
-
return /* @__PURE__ */
|
|
5607
|
+
return /* @__PURE__ */ jsx16("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx16(
|
|
4824
5608
|
"path",
|
|
4825
5609
|
{
|
|
4826
5610
|
d: "M5.5 5.5H3.5V7.5M10.5 5.5h2V7.5M10.5 10.5h2V8.5M5.5 10.5H3.5V8.5",
|
|
@@ -4831,6 +5615,19 @@ function RestoreIcon() {
|
|
|
4831
5615
|
}
|
|
4832
5616
|
) });
|
|
4833
5617
|
}
|
|
5618
|
+
function ChevronDownIcon() {
|
|
5619
|
+
return /* @__PURE__ */ jsx16("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx16(
|
|
5620
|
+
"path",
|
|
5621
|
+
{
|
|
5622
|
+
d: "M4 6.5l4 4 4-4",
|
|
5623
|
+
stroke: "currentColor",
|
|
5624
|
+
strokeWidth: "1.6",
|
|
5625
|
+
strokeLinecap: "round",
|
|
5626
|
+
strokeLinejoin: "round"
|
|
5627
|
+
}
|
|
5628
|
+
) });
|
|
5629
|
+
}
|
|
5630
|
+
var DEFAULT_DISCLAIMER_LABEL = "Agent can make mistakes. Check important info.";
|
|
4834
5631
|
function AgentRail({
|
|
4835
5632
|
state,
|
|
4836
5633
|
theme,
|
|
@@ -4838,6 +5635,9 @@ function AgentRail({
|
|
|
4838
5635
|
brandLabel = "",
|
|
4839
5636
|
brandLogoUrl,
|
|
4840
5637
|
poweredByLabel = "Powered by Webless",
|
|
5638
|
+
disclaimerLabel,
|
|
5639
|
+
answerReceipt = false,
|
|
5640
|
+
readAloud = false,
|
|
4841
5641
|
composerPlaceholder = "Ask anything\u2026",
|
|
4842
5642
|
mobileFullscreen = false,
|
|
4843
5643
|
expanded = false,
|
|
@@ -4846,16 +5646,26 @@ function AgentRail({
|
|
|
4846
5646
|
onExpandToggle,
|
|
4847
5647
|
onReset,
|
|
4848
5648
|
onRetry,
|
|
5649
|
+
onRegenerate,
|
|
5650
|
+
onFeedback,
|
|
4849
5651
|
onSubmit,
|
|
4850
5652
|
onFollowUpSelect,
|
|
4851
5653
|
onBook,
|
|
4852
5654
|
onInputResponse,
|
|
4853
5655
|
onToolInput
|
|
4854
5656
|
}) {
|
|
4855
|
-
const
|
|
5657
|
+
const railRef = useRef6(null);
|
|
5658
|
+
const overlayRef = useRef6(null);
|
|
5659
|
+
const transcriptRef = useRef6(null);
|
|
5660
|
+
const pinnedToBottomRef = useRef6(true);
|
|
5661
|
+
const smoothScrollToLatestRef = useRef6(false);
|
|
5662
|
+
const lockedTranscriptScrollTopRef = useRef6(null);
|
|
5663
|
+
const [showJumpToLatest, setShowJumpToLatest] = useState9(false);
|
|
5664
|
+
const [receiptOpen, setReceiptOpen] = useState9(false);
|
|
4856
5665
|
const resolvedBrandLabel = brandLabel.trim();
|
|
4857
5666
|
const resolvedBrandLogoUrl = brandLogoUrl?.trim();
|
|
4858
|
-
const
|
|
5667
|
+
const resolvedDisclaimerLabel = disclaimerLabel === void 0 ? DEFAULT_DISCLAIMER_LABEL : disclaimerLabel;
|
|
5668
|
+
const [failedLogoUrl, setFailedLogoUrl] = useState9(null);
|
|
4859
5669
|
const showBrandLogo = Boolean(resolvedBrandLogoUrl) && failedLogoUrl !== resolvedBrandLogoUrl;
|
|
4860
5670
|
const resolvedColorScheme = useAgentColorScheme(colorScheme);
|
|
4861
5671
|
const brandedTheme = { ...defaultAgentRailTheme, ...theme };
|
|
@@ -4906,10 +5716,15 @@ function AgentRail({
|
|
|
4906
5716
|
);
|
|
4907
5717
|
const activeVisitorToolInput = [...visitorToolResults].reverse().find((result) => result.kind === "input");
|
|
4908
5718
|
const visibleVisitorToolResults = activeVisitorToolInput ? [activeVisitorToolInput] : visitorToolResults;
|
|
4909
|
-
const
|
|
5719
|
+
const activityActive = state.toolSteps.some((step) => step.state === "active");
|
|
5720
|
+
const showActivity = state.toolSteps.length > 0 && visibleVisitorToolResults.length === 0 && pendingInputRequests.length === 0 && !state.pendingOffer && activityActive;
|
|
4910
5721
|
const hasVisitorMessages2 = state.messages.some(
|
|
4911
5722
|
(message) => message.role === "visitor"
|
|
4912
5723
|
);
|
|
5724
|
+
const hasAgentResponseAfterVisitor = state.messages.some(
|
|
5725
|
+
(message) => message.role === "agent" && message.id !== "greeting"
|
|
5726
|
+
);
|
|
5727
|
+
const showDisclaimerLabel = Boolean(resolvedDisclaimerLabel) && hasVisitorMessages2 && (hasAgentResponseAfterVisitor || state.phase === "streaming" && Boolean(state.streamingText));
|
|
4913
5728
|
const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
|
|
4914
5729
|
const greeting = state.messages.find(
|
|
4915
5730
|
(message) => message.role === "agent" && message.id === "greeting"
|
|
@@ -4931,6 +5746,7 @@ function AgentRail({
|
|
|
4931
5746
|
}
|
|
4932
5747
|
}
|
|
4933
5748
|
const lastIsAgent = lastMessage?.role === "agent";
|
|
5749
|
+
const showMessageActions = state.phase === "complete" && lastIsAgent && hasVisitorMessages2;
|
|
4934
5750
|
const streamingMessage = state.phase === "streaming" && state.streamingText && !lastIsAgent ? {
|
|
4935
5751
|
createdAt: 0,
|
|
4936
5752
|
id: "streaming-response",
|
|
@@ -4957,10 +5773,36 @@ function AgentRail({
|
|
|
4957
5773
|
hasPendingConfirmation,
|
|
4958
5774
|
enabled: lastIsAgent && !isBusy
|
|
4959
5775
|
});
|
|
4960
|
-
|
|
5776
|
+
const receiptSteps = answerReceipt && state.toolSteps.length > 0 ? state.toolSteps : void 0;
|
|
5777
|
+
useEffect6(() => {
|
|
5778
|
+
if (state.phase !== "complete") {
|
|
5779
|
+
setReceiptOpen(false);
|
|
5780
|
+
}
|
|
5781
|
+
}, [state.phase]);
|
|
5782
|
+
function handleSubmit(message) {
|
|
5783
|
+
setReceiptOpen(false);
|
|
5784
|
+
onSubmit?.(message);
|
|
5785
|
+
}
|
|
5786
|
+
function handleRegenerate() {
|
|
5787
|
+
setReceiptOpen(false);
|
|
5788
|
+
onRegenerate?.();
|
|
5789
|
+
}
|
|
5790
|
+
function handleReset() {
|
|
5791
|
+
setReceiptOpen(false);
|
|
5792
|
+
onReset?.();
|
|
5793
|
+
}
|
|
5794
|
+
function handleFollowUpSelect(label) {
|
|
5795
|
+
setReceiptOpen(false);
|
|
5796
|
+
onFollowUpSelect?.(label);
|
|
5797
|
+
}
|
|
5798
|
+
useEffect6(() => {
|
|
4961
5799
|
const node = transcriptRef.current;
|
|
4962
5800
|
if (!node) return;
|
|
4963
|
-
|
|
5801
|
+
const lastMessage2 = state.messages.at(-1);
|
|
5802
|
+
const visitorJustSent = lastMessage2?.role === "visitor";
|
|
5803
|
+
if (pinnedToBottomRef.current || visitorJustSent) {
|
|
5804
|
+
node.scrollTop = node.scrollHeight;
|
|
5805
|
+
}
|
|
4964
5806
|
}, [
|
|
4965
5807
|
state.messages,
|
|
4966
5808
|
state.toolSteps,
|
|
@@ -4968,10 +5810,75 @@ function AgentRail({
|
|
|
4968
5810
|
state.followUps,
|
|
4969
5811
|
state.journey
|
|
4970
5812
|
]);
|
|
4971
|
-
|
|
5813
|
+
useEffect6(() => {
|
|
5814
|
+
const node = transcriptRef.current;
|
|
5815
|
+
if (!node) return;
|
|
5816
|
+
const handleScroll = () => {
|
|
5817
|
+
if (node.clientHeight === 0) return;
|
|
5818
|
+
const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;
|
|
5819
|
+
const pinned = distanceFromBottom < 48 || smoothScrollToLatestRef.current;
|
|
5820
|
+
pinnedToBottomRef.current = pinned;
|
|
5821
|
+
setShowJumpToLatest(!pinned);
|
|
5822
|
+
};
|
|
5823
|
+
node.addEventListener("scroll", handleScroll, { passive: true });
|
|
5824
|
+
handleScroll();
|
|
5825
|
+
return () => node.removeEventListener("scroll", handleScroll);
|
|
5826
|
+
}, []);
|
|
5827
|
+
useEffect6(() => {
|
|
5828
|
+
const node = transcriptRef.current;
|
|
5829
|
+
if (!node) return;
|
|
5830
|
+
const observer = new ResizeObserver(() => {
|
|
5831
|
+
if (node.clientHeight === 0) return;
|
|
5832
|
+
if (pinnedToBottomRef.current) {
|
|
5833
|
+
node.scrollTo({ top: node.scrollHeight, behavior: "instant" });
|
|
5834
|
+
}
|
|
5835
|
+
});
|
|
5836
|
+
observer.observe(node);
|
|
5837
|
+
return () => observer.disconnect();
|
|
5838
|
+
}, []);
|
|
5839
|
+
useEffect6(() => {
|
|
5840
|
+
if (!receiptOpen) {
|
|
5841
|
+
lockedTranscriptScrollTopRef.current = null;
|
|
5842
|
+
return;
|
|
5843
|
+
}
|
|
5844
|
+
const node = transcriptRef.current;
|
|
5845
|
+
if (!node || lockedTranscriptScrollTopRef.current === null) return;
|
|
5846
|
+
node.scrollTop = lockedTranscriptScrollTopRef.current;
|
|
5847
|
+
}, [receiptOpen]);
|
|
5848
|
+
function openReceipt() {
|
|
5849
|
+
const node = transcriptRef.current;
|
|
5850
|
+
lockedTranscriptScrollTopRef.current = node?.scrollTop ?? null;
|
|
5851
|
+
setReceiptOpen(true);
|
|
5852
|
+
}
|
|
5853
|
+
function scrollToLatest() {
|
|
5854
|
+
const node = transcriptRef.current;
|
|
5855
|
+
if (!node) return;
|
|
5856
|
+
pinnedToBottomRef.current = true;
|
|
5857
|
+
setShowJumpToLatest(false);
|
|
5858
|
+
const reduceMotion = window.matchMedia(
|
|
5859
|
+
"(prefers-reduced-motion: reduce)"
|
|
5860
|
+
).matches;
|
|
5861
|
+
if (reduceMotion) {
|
|
5862
|
+
node.scrollTo({ top: node.scrollHeight, behavior: "instant" });
|
|
5863
|
+
return;
|
|
5864
|
+
}
|
|
5865
|
+
smoothScrollToLatestRef.current = true;
|
|
5866
|
+
const settle = () => {
|
|
5867
|
+
smoothScrollToLatestRef.current = false;
|
|
5868
|
+
const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;
|
|
5869
|
+
const pinned = distanceFromBottom < 48;
|
|
5870
|
+
pinnedToBottomRef.current = pinned;
|
|
5871
|
+
setShowJumpToLatest(!pinned);
|
|
5872
|
+
};
|
|
5873
|
+
node.addEventListener("scrollend", settle, { once: true });
|
|
5874
|
+
window.setTimeout(settle, 900);
|
|
5875
|
+
node.scrollTo({ top: node.scrollHeight, behavior: "smooth" });
|
|
5876
|
+
}
|
|
5877
|
+
return /* @__PURE__ */ jsx16(
|
|
4972
5878
|
"aside",
|
|
4973
5879
|
{
|
|
4974
|
-
|
|
5880
|
+
ref: railRef,
|
|
5881
|
+
className: `agent-rail not-typeset${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}${receiptOpen ? " agent-rail--receipt-open" : ""}`,
|
|
4975
5882
|
"data-not-typeset": "",
|
|
4976
5883
|
"data-color-scheme": resolvedColorScheme,
|
|
4977
5884
|
spellCheck: false,
|
|
@@ -4981,193 +5888,234 @@ function AgentRail({
|
|
|
4981
5888
|
autoFocus: mobileFullscreen || expanded,
|
|
4982
5889
|
role: mobileFullscreen || expanded ? "dialog" : void 0,
|
|
4983
5890
|
tabIndex: mobileFullscreen || expanded ? -1 : void 0,
|
|
4984
|
-
children:
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
className: "agent-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
className: "agent-rail__brand-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
className: "agent-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5891
|
+
children: /* @__PURE__ */ jsxs15(
|
|
5892
|
+
AgentRailOverlayContext.Provider,
|
|
5893
|
+
{
|
|
5894
|
+
value: { railRef, overlayRef },
|
|
5895
|
+
children: [
|
|
5896
|
+
/* @__PURE__ */ jsxs15("div", { className: "agent-rail__surface", inert: receiptOpen || void 0, children: [
|
|
5897
|
+
/* @__PURE__ */ jsx16("header", { className: "agent-rail__header", children: /* @__PURE__ */ jsxs15("div", { className: "agent-rail__brand-row", children: [
|
|
5898
|
+
onCollapse ? /* @__PURE__ */ jsx16(
|
|
5899
|
+
"button",
|
|
5900
|
+
{
|
|
5901
|
+
type: "button",
|
|
5902
|
+
className: "agent-rail__collapse",
|
|
5903
|
+
"aria-label": "Collapse assist",
|
|
5904
|
+
onClick: onCollapse,
|
|
5905
|
+
children: /* @__PURE__ */ jsx16(MinimizeIcon, {})
|
|
5906
|
+
}
|
|
5907
|
+
) : onClose ? /* @__PURE__ */ jsx16(
|
|
5908
|
+
"button",
|
|
5909
|
+
{
|
|
5910
|
+
type: "button",
|
|
5911
|
+
className: "agent-rail__close",
|
|
5912
|
+
"aria-label": "Close agent",
|
|
5913
|
+
onClick: onClose,
|
|
5914
|
+
children: /* @__PURE__ */ jsx16(CloseIcon2, {})
|
|
5915
|
+
}
|
|
5916
|
+
) : /* @__PURE__ */ jsx16("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
|
|
5917
|
+
resolvedBrandLabel || showBrandLogo ? /* @__PURE__ */ jsxs15("span", { className: "agent-rail__identity", children: [
|
|
5918
|
+
showBrandLogo ? /* @__PURE__ */ jsx16("span", { className: "agent-rail__brand-mark", "aria-hidden": "true", children: /* @__PURE__ */ jsx16(
|
|
5919
|
+
"img",
|
|
5920
|
+
{
|
|
5921
|
+
className: "agent-rail__brand-logo",
|
|
5922
|
+
src: resolvedBrandLogoUrl,
|
|
5923
|
+
alt: "",
|
|
5924
|
+
onError: () => {
|
|
5925
|
+
setFailedLogoUrl(resolvedBrandLogoUrl ?? null);
|
|
5926
|
+
}
|
|
5927
|
+
}
|
|
5928
|
+
) }) : null,
|
|
5929
|
+
resolvedBrandLabel ? /* @__PURE__ */ jsx16("span", { className: "agent-rail__brand-label", children: resolvedBrandLabel }) : null
|
|
5930
|
+
] }) : null,
|
|
5931
|
+
/* @__PURE__ */ jsxs15("span", { className: "agent-rail__actions", children: [
|
|
5932
|
+
onReset ? /* @__PURE__ */ jsx16(
|
|
5933
|
+
"button",
|
|
5934
|
+
{
|
|
5935
|
+
type: "button",
|
|
5936
|
+
className: "agent-rail__new-chat",
|
|
5937
|
+
"aria-label": "Start a new conversation",
|
|
5938
|
+
disabled: !hasVisitorMessages2,
|
|
5939
|
+
onClick: handleReset,
|
|
5940
|
+
children: /* @__PURE__ */ jsx16(NewChatIcon, {})
|
|
5941
|
+
}
|
|
5942
|
+
) : null,
|
|
5943
|
+
onExpandToggle ? /* @__PURE__ */ jsx16(
|
|
5944
|
+
"button",
|
|
5945
|
+
{
|
|
5946
|
+
type: "button",
|
|
5947
|
+
className: "agent-rail__expand",
|
|
5948
|
+
"aria-label": expanded ? "Exit full screen" : "Open full screen",
|
|
5949
|
+
onClick: onExpandToggle,
|
|
5950
|
+
children: expanded ? /* @__PURE__ */ jsx16(RestoreIcon, {}) : /* @__PURE__ */ jsx16(ExpandIcon, {})
|
|
5951
|
+
}
|
|
5952
|
+
) : null
|
|
5953
|
+
] })
|
|
5954
|
+
] }) }),
|
|
5955
|
+
/* @__PURE__ */ jsx16("div", { ref: transcriptRef, className: "agent-rail__transcript", children: /* @__PURE__ */ jsxs15("div", { className: "agent-rail__thread", children: [
|
|
5956
|
+
!hasVisitorMessages2 ? /* @__PURE__ */ jsxs15("section", { className: "agent-rail__welcome", "aria-label": "Welcome", children: [
|
|
5957
|
+
greeting?.role === "agent" ? /* @__PURE__ */ jsx16(
|
|
5958
|
+
MessageBubble,
|
|
5959
|
+
{
|
|
5960
|
+
message: greeting,
|
|
5961
|
+
bookingDisabled: isBusy,
|
|
5962
|
+
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
5963
|
+
onBook
|
|
5964
|
+
}
|
|
5965
|
+
) : null,
|
|
5966
|
+
showIdleFollowUps ? /* @__PURE__ */ jsx16("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ jsx16(
|
|
5967
|
+
FollowUpChips,
|
|
5968
|
+
{
|
|
5969
|
+
suggestions: state.followUps,
|
|
5970
|
+
disabled: isBusy,
|
|
5971
|
+
label: "Start here",
|
|
5972
|
+
onSelect: (suggestion) => handleFollowUpSelect(suggestion.label)
|
|
5973
|
+
}
|
|
5974
|
+
) }) : null,
|
|
5975
|
+
showActivity ? /* @__PURE__ */ jsx16(
|
|
5976
|
+
AgentActivityBubble,
|
|
5977
|
+
{
|
|
5978
|
+
brandLabel: resolvedBrandLabel,
|
|
5979
|
+
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
5980
|
+
failed: state.phase === "error",
|
|
5981
|
+
steps: state.toolSteps
|
|
5982
|
+
}
|
|
5983
|
+
) : null,
|
|
5984
|
+
visibleVisitorToolResults.map((result) => /* @__PURE__ */ jsx16(
|
|
5985
|
+
VisitorToolResultView,
|
|
5986
|
+
{
|
|
5987
|
+
result,
|
|
5988
|
+
disabled: semanticSurfaceDisabled,
|
|
5989
|
+
onToolInput
|
|
5990
|
+
},
|
|
5991
|
+
result.id
|
|
5992
|
+
)),
|
|
5993
|
+
pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ jsx16(
|
|
5994
|
+
HumanInputCard,
|
|
5995
|
+
{
|
|
5996
|
+
request,
|
|
5997
|
+
onRespond: onInputResponse
|
|
5998
|
+
},
|
|
5999
|
+
request.requestId
|
|
6000
|
+
))
|
|
6001
|
+
] }) : null,
|
|
6002
|
+
visibleMessages.map((message, index) => /* @__PURE__ */ jsxs15("div", { className: "agent-rail__turn-block", children: [
|
|
6003
|
+
/* @__PURE__ */ jsx16(
|
|
6004
|
+
MessageBubble,
|
|
6005
|
+
{
|
|
6006
|
+
message,
|
|
6007
|
+
bookingDisabled: isBusy,
|
|
6008
|
+
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
6009
|
+
offer: index === lastAgentIndex ? state.pendingOffer : void 0,
|
|
6010
|
+
onBook
|
|
6011
|
+
}
|
|
6012
|
+
),
|
|
6013
|
+
index === lastAgentIndex && showMessageActions && message.role === "agent" ? /* @__PURE__ */ jsx16(
|
|
6014
|
+
MessageActions,
|
|
6015
|
+
{
|
|
6016
|
+
answeredAt: message.createdAt,
|
|
6017
|
+
copyText: hideToolCardFences(message.text).trim() || message.text,
|
|
6018
|
+
readAloud,
|
|
6019
|
+
receiptSteps,
|
|
6020
|
+
onOpenReceipt: receiptSteps ? openReceipt : void 0,
|
|
6021
|
+
onRegenerate: onRegenerate ? handleRegenerate : void 0,
|
|
6022
|
+
onFeedback: onFeedback ? (rating) => onFeedback(rating, message) : void 0
|
|
6023
|
+
}
|
|
6024
|
+
) : null,
|
|
6025
|
+
index === lastVisitorIndex ? /* @__PURE__ */ jsxs15(Fragment, { children: [
|
|
6026
|
+
showActivity ? /* @__PURE__ */ jsx16(
|
|
6027
|
+
AgentActivityBubble,
|
|
6028
|
+
{
|
|
6029
|
+
brandLabel: resolvedBrandLabel,
|
|
6030
|
+
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
6031
|
+
failed: state.phase === "error",
|
|
6032
|
+
steps: state.toolSteps
|
|
6033
|
+
}
|
|
6034
|
+
) : null,
|
|
6035
|
+
visibleVisitorToolResults.map((result) => /* @__PURE__ */ jsx16(
|
|
6036
|
+
VisitorToolResultView,
|
|
6037
|
+
{
|
|
6038
|
+
result,
|
|
6039
|
+
disabled: semanticSurfaceDisabled,
|
|
6040
|
+
onToolInput
|
|
6041
|
+
},
|
|
6042
|
+
result.id
|
|
6043
|
+
)),
|
|
6044
|
+
pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ jsx16(
|
|
6045
|
+
HumanInputCard,
|
|
6046
|
+
{
|
|
6047
|
+
request,
|
|
6048
|
+
onRespond: onInputResponse
|
|
6049
|
+
},
|
|
6050
|
+
request.requestId
|
|
6051
|
+
))
|
|
6052
|
+
] }) : null
|
|
6053
|
+
] }, message.id)),
|
|
6054
|
+
streamingMessage ? /* @__PURE__ */ jsx16(
|
|
6055
|
+
MessageBubble,
|
|
6056
|
+
{
|
|
6057
|
+
message: streamingMessage,
|
|
6058
|
+
bookingDisabled: isBusy,
|
|
6059
|
+
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
6060
|
+
offer: state.pendingOffer,
|
|
6061
|
+
onBook
|
|
6062
|
+
}
|
|
6063
|
+
) : null,
|
|
6064
|
+
waitingForBooking ? /* @__PURE__ */ jsx16(BookingCardLoader, {}) : null,
|
|
6065
|
+
state.error ? /* @__PURE__ */ jsxs15("section", { className: "agent-rail__error", role: "alert", children: [
|
|
6066
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
6067
|
+
/* @__PURE__ */ jsx16("strong", { children: "Something went wrong" }),
|
|
6068
|
+
/* @__PURE__ */ jsx16("p", { children: state.error })
|
|
6069
|
+
] }),
|
|
6070
|
+
onRetry ? /* @__PURE__ */ jsx16("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
|
|
6071
|
+
] }) : null
|
|
6072
|
+
] }) }),
|
|
6073
|
+
showDisclaimerLabel ? /* @__PURE__ */ jsx16("div", { className: "agent-rail__disclaimer", children: /* @__PURE__ */ jsx16("p", { children: resolvedDisclaimerLabel }) }) : null,
|
|
6074
|
+
/* @__PURE__ */ jsxs15("div", { className: "agent-rail__composer-wrap", children: [
|
|
6075
|
+
showJumpToLatest ? /* @__PURE__ */ jsx16(
|
|
6076
|
+
"button",
|
|
6077
|
+
{
|
|
6078
|
+
type: "button",
|
|
6079
|
+
className: "agent-rail__jump-to-latest",
|
|
6080
|
+
"aria-label": "Jump to the latest message",
|
|
6081
|
+
title: "Jump to the latest message",
|
|
6082
|
+
onClick: scrollToLatest,
|
|
6083
|
+
children: /* @__PURE__ */ jsx16(ChevronDownIcon, {})
|
|
6084
|
+
}
|
|
6085
|
+
) : null,
|
|
6086
|
+
/* @__PURE__ */ jsx16(
|
|
6087
|
+
Composer,
|
|
6088
|
+
{
|
|
6089
|
+
variant: expanded || mobileFullscreen ? "dock" : "default",
|
|
6090
|
+
disabled: isBusy,
|
|
6091
|
+
form: composerForm,
|
|
6092
|
+
placeholder: composerPlaceholder,
|
|
6093
|
+
onSubmit: handleSubmit
|
|
6094
|
+
}
|
|
6095
|
+
),
|
|
6096
|
+
poweredByLabel ? /* @__PURE__ */ jsx16("div", { className: "agent-rail__footer", children: /* @__PURE__ */ jsx16("p", { children: /* @__PURE__ */ jsx16("span", { children: poweredByLabel }) }) }) : null
|
|
6097
|
+
] })
|
|
6098
|
+
] }),
|
|
6099
|
+
/* @__PURE__ */ jsx16("div", { ref: overlayRef, className: "agent-rail__overlay" }),
|
|
6100
|
+
receiptOpen && receiptSteps ? /* @__PURE__ */ jsx16(
|
|
6101
|
+
AnswerReceiptDialog,
|
|
5064
6102
|
{
|
|
5065
6103
|
brandLabel: resolvedBrandLabel,
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
steps: state.toolSteps
|
|
6104
|
+
onClose: () => setReceiptOpen(false),
|
|
6105
|
+
steps: receiptSteps
|
|
5069
6106
|
}
|
|
5070
|
-
) : null
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
result,
|
|
5075
|
-
disabled: semanticSurfaceDisabled,
|
|
5076
|
-
onToolInput
|
|
5077
|
-
},
|
|
5078
|
-
result.id
|
|
5079
|
-
)),
|
|
5080
|
-
pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ jsx14(
|
|
5081
|
-
HumanInputCard,
|
|
5082
|
-
{
|
|
5083
|
-
request,
|
|
5084
|
-
onRespond: onInputResponse
|
|
5085
|
-
},
|
|
5086
|
-
request.requestId
|
|
5087
|
-
))
|
|
5088
|
-
] }) : null,
|
|
5089
|
-
visibleMessages.map((message, index) => /* @__PURE__ */ jsxs13("div", { className: "agent-rail__turn-block", children: [
|
|
5090
|
-
/* @__PURE__ */ jsx14(
|
|
5091
|
-
MessageBubble,
|
|
5092
|
-
{
|
|
5093
|
-
message,
|
|
5094
|
-
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
5095
|
-
offer: index === lastAgentIndex ? state.pendingOffer : void 0,
|
|
5096
|
-
onBook
|
|
5097
|
-
}
|
|
5098
|
-
),
|
|
5099
|
-
index === lastVisitorIndex ? /* @__PURE__ */ jsxs13(Fragment, { children: [
|
|
5100
|
-
showActivity ? /* @__PURE__ */ jsx14(
|
|
5101
|
-
AgentActivityBubble,
|
|
5102
|
-
{
|
|
5103
|
-
brandLabel: resolvedBrandLabel,
|
|
5104
|
-
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
5105
|
-
failed: state.phase === "error",
|
|
5106
|
-
steps: state.toolSteps
|
|
5107
|
-
}
|
|
5108
|
-
) : null,
|
|
5109
|
-
visibleVisitorToolResults.map((result) => /* @__PURE__ */ jsx14(
|
|
5110
|
-
VisitorToolResultView,
|
|
5111
|
-
{
|
|
5112
|
-
result,
|
|
5113
|
-
disabled: semanticSurfaceDisabled,
|
|
5114
|
-
onToolInput
|
|
5115
|
-
},
|
|
5116
|
-
result.id
|
|
5117
|
-
)),
|
|
5118
|
-
pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ jsx14(
|
|
5119
|
-
HumanInputCard,
|
|
5120
|
-
{
|
|
5121
|
-
request,
|
|
5122
|
-
onRespond: onInputResponse
|
|
5123
|
-
},
|
|
5124
|
-
request.requestId
|
|
5125
|
-
))
|
|
5126
|
-
] }) : null
|
|
5127
|
-
] }, message.id)),
|
|
5128
|
-
streamingMessage ? /* @__PURE__ */ jsx14(
|
|
5129
|
-
MessageBubble,
|
|
5130
|
-
{
|
|
5131
|
-
message: streamingMessage,
|
|
5132
|
-
brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
|
|
5133
|
-
offer: state.pendingOffer,
|
|
5134
|
-
onBook
|
|
5135
|
-
}
|
|
5136
|
-
) : null,
|
|
5137
|
-
waitingForBooking ? /* @__PURE__ */ jsx14(BookingCardLoader, {}) : null,
|
|
5138
|
-
state.error ? /* @__PURE__ */ jsxs13("section", { className: "agent-rail__error", role: "alert", children: [
|
|
5139
|
-
/* @__PURE__ */ jsxs13("div", { children: [
|
|
5140
|
-
/* @__PURE__ */ jsx14("strong", { children: "Something went wrong" }),
|
|
5141
|
-
/* @__PURE__ */ jsx14("p", { children: state.error })
|
|
5142
|
-
] }),
|
|
5143
|
-
onRetry ? /* @__PURE__ */ jsx14("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
|
|
5144
|
-
] }) : null
|
|
5145
|
-
] }) }),
|
|
5146
|
-
/* @__PURE__ */ jsxs13("div", { className: "agent-rail__composer-wrap", children: [
|
|
5147
|
-
/* @__PURE__ */ jsx14(
|
|
5148
|
-
Composer,
|
|
5149
|
-
{
|
|
5150
|
-
variant: expanded || mobileFullscreen ? "dock" : "default",
|
|
5151
|
-
disabled: isBusy,
|
|
5152
|
-
form: composerForm,
|
|
5153
|
-
placeholder: composerPlaceholder,
|
|
5154
|
-
onSubmit
|
|
5155
|
-
}
|
|
5156
|
-
),
|
|
5157
|
-
/* @__PURE__ */ jsx14("div", { className: "agent-rail__footer", children: /* @__PURE__ */ jsxs13("p", { children: [
|
|
5158
|
-
/* @__PURE__ */ jsx14("span", { children: "AI can make mistakes. Check important info." }),
|
|
5159
|
-
/* @__PURE__ */ jsx14("span", { children: poweredByLabel })
|
|
5160
|
-
] }) })
|
|
5161
|
-
] })
|
|
5162
|
-
]
|
|
6107
|
+
) : null
|
|
6108
|
+
]
|
|
6109
|
+
}
|
|
6110
|
+
)
|
|
5163
6111
|
}
|
|
5164
6112
|
);
|
|
5165
6113
|
}
|
|
5166
6114
|
|
|
5167
6115
|
// src/react/components/AssistEdgeTab/AssistEdgeTab.tsx
|
|
5168
|
-
import { Fragment as Fragment2, jsx as
|
|
6116
|
+
import { Fragment as Fragment2, jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
5169
6117
|
function SparklesIcon() {
|
|
5170
|
-
return /* @__PURE__ */
|
|
6118
|
+
return /* @__PURE__ */ jsxs16(
|
|
5171
6119
|
"svg",
|
|
5172
6120
|
{
|
|
5173
6121
|
className: "assist-edge-tab__sparkles",
|
|
@@ -5175,21 +6123,21 @@ function SparklesIcon() {
|
|
|
5175
6123
|
fill: "none",
|
|
5176
6124
|
"aria-hidden": "true",
|
|
5177
6125
|
children: [
|
|
5178
|
-
/* @__PURE__ */
|
|
6126
|
+
/* @__PURE__ */ jsx17(
|
|
5179
6127
|
"path",
|
|
5180
6128
|
{
|
|
5181
6129
|
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",
|
|
5182
6130
|
fill: "currentColor"
|
|
5183
6131
|
}
|
|
5184
6132
|
),
|
|
5185
|
-
/* @__PURE__ */
|
|
6133
|
+
/* @__PURE__ */ jsx17(
|
|
5186
6134
|
"path",
|
|
5187
6135
|
{
|
|
5188
6136
|
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",
|
|
5189
6137
|
fill: "currentColor"
|
|
5190
6138
|
}
|
|
5191
6139
|
),
|
|
5192
|
-
/* @__PURE__ */
|
|
6140
|
+
/* @__PURE__ */ jsx17(
|
|
5193
6141
|
"path",
|
|
5194
6142
|
{
|
|
5195
6143
|
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",
|
|
@@ -5203,7 +6151,7 @@ function SparklesIcon() {
|
|
|
5203
6151
|
function TabMarkIcon({ customIconUrl }) {
|
|
5204
6152
|
const url = customIconUrl?.trim();
|
|
5205
6153
|
if (url) {
|
|
5206
|
-
return /* @__PURE__ */
|
|
6154
|
+
return /* @__PURE__ */ jsx17(
|
|
5207
6155
|
"img",
|
|
5208
6156
|
{
|
|
5209
6157
|
alt: "",
|
|
@@ -5213,10 +6161,10 @@ function TabMarkIcon({ customIconUrl }) {
|
|
|
5213
6161
|
}
|
|
5214
6162
|
);
|
|
5215
6163
|
}
|
|
5216
|
-
return /* @__PURE__ */
|
|
6164
|
+
return /* @__PURE__ */ jsx17(SparklesIcon, {});
|
|
5217
6165
|
}
|
|
5218
6166
|
function ChevronLeftIcon() {
|
|
5219
|
-
return /* @__PURE__ */
|
|
6167
|
+
return /* @__PURE__ */ jsx17("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx17(
|
|
5220
6168
|
"path",
|
|
5221
6169
|
{
|
|
5222
6170
|
d: "M10 4L6 8l4 4",
|
|
@@ -5227,8 +6175,8 @@ function ChevronLeftIcon() {
|
|
|
5227
6175
|
}
|
|
5228
6176
|
) });
|
|
5229
6177
|
}
|
|
5230
|
-
function
|
|
5231
|
-
return /* @__PURE__ */
|
|
6178
|
+
function ChevronDownIcon2() {
|
|
6179
|
+
return /* @__PURE__ */ jsx17("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx17(
|
|
5232
6180
|
"path",
|
|
5233
6181
|
{
|
|
5234
6182
|
d: "M4 6l4 4 4-4",
|
|
@@ -5240,7 +6188,7 @@ function ChevronDownIcon() {
|
|
|
5240
6188
|
) });
|
|
5241
6189
|
}
|
|
5242
6190
|
function DragDots() {
|
|
5243
|
-
return /* @__PURE__ */
|
|
6191
|
+
return /* @__PURE__ */ jsx17("span", { className: "assist-edge-tab__dots", "aria-hidden": "true", children: Array.from({ length: 12 }, (_, index) => /* @__PURE__ */ jsx17("i", {}, index)) });
|
|
5244
6192
|
}
|
|
5245
6193
|
var VARIANT_COPY = {
|
|
5246
6194
|
outline: { label: "Ask anything", aria: "Ask anything" },
|
|
@@ -5286,7 +6234,7 @@ function AssistEdgeTab({
|
|
|
5286
6234
|
...resolvedTextColor ? { "--as-text": resolvedTextColor } : {},
|
|
5287
6235
|
colorScheme: resolvedColorScheme
|
|
5288
6236
|
};
|
|
5289
|
-
return /* @__PURE__ */
|
|
6237
|
+
return /* @__PURE__ */ jsxs16(
|
|
5290
6238
|
"button",
|
|
5291
6239
|
{
|
|
5292
6240
|
type: "button",
|
|
@@ -5298,15 +6246,15 @@ function AssistEdgeTab({
|
|
|
5298
6246
|
tabIndex: visible ? 0 : -1,
|
|
5299
6247
|
onClick: onOpen,
|
|
5300
6248
|
children: [
|
|
5301
|
-
mobile ? /* @__PURE__ */
|
|
5302
|
-
/* @__PURE__ */
|
|
6249
|
+
mobile ? /* @__PURE__ */ jsxs16(Fragment2, { children: [
|
|
6250
|
+
/* @__PURE__ */ jsxs16(
|
|
5303
6251
|
"span",
|
|
5304
6252
|
{
|
|
5305
6253
|
className: "assist-edge-tab__mark assist-edge-tab__mark--mobile",
|
|
5306
6254
|
"aria-hidden": "true",
|
|
5307
6255
|
children: [
|
|
5308
|
-
/* @__PURE__ */
|
|
5309
|
-
showLogo ? /* @__PURE__ */
|
|
6256
|
+
/* @__PURE__ */ jsx17(TabMarkIcon, { customIconUrl }),
|
|
6257
|
+
showLogo ? /* @__PURE__ */ jsx17(
|
|
5310
6258
|
"img",
|
|
5311
6259
|
{
|
|
5312
6260
|
className: "assist-edge-tab__logo",
|
|
@@ -5320,11 +6268,11 @@ function AssistEdgeTab({
|
|
|
5320
6268
|
]
|
|
5321
6269
|
}
|
|
5322
6270
|
),
|
|
5323
|
-
/* @__PURE__ */
|
|
5324
|
-
] }) : variant === "outline" ? /* @__PURE__ */
|
|
5325
|
-
/* @__PURE__ */
|
|
5326
|
-
/* @__PURE__ */
|
|
5327
|
-
showLogo ? /* @__PURE__ */
|
|
6271
|
+
/* @__PURE__ */ jsx17("span", { className: "assist-edge-tab__label", children: visibleLabel })
|
|
6272
|
+
] }) : variant === "outline" ? /* @__PURE__ */ jsxs16(Fragment2, { children: [
|
|
6273
|
+
/* @__PURE__ */ jsxs16("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
|
|
6274
|
+
/* @__PURE__ */ jsx17(TabMarkIcon, { customIconUrl }),
|
|
6275
|
+
showLogo ? /* @__PURE__ */ jsx17(
|
|
5328
6276
|
"img",
|
|
5329
6277
|
{
|
|
5330
6278
|
className: "assist-edge-tab__logo",
|
|
@@ -5336,18 +6284,18 @@ function AssistEdgeTab({
|
|
|
5336
6284
|
}
|
|
5337
6285
|
) : null
|
|
5338
6286
|
] }),
|
|
5339
|
-
/* @__PURE__ */
|
|
5340
|
-
/* @__PURE__ */
|
|
6287
|
+
/* @__PURE__ */ jsx17("span", { className: "assist-edge-tab__label", children: visibleLabel }),
|
|
6288
|
+
/* @__PURE__ */ jsx17(ChevronDownIcon2, {})
|
|
5341
6289
|
] }) : null,
|
|
5342
|
-
variant === "ask" ? /* @__PURE__ */
|
|
5343
|
-
/* @__PURE__ */
|
|
5344
|
-
/* @__PURE__ */
|
|
5345
|
-
/* @__PURE__ */
|
|
6290
|
+
variant === "ask" ? /* @__PURE__ */ jsxs16(Fragment2, { children: [
|
|
6291
|
+
/* @__PURE__ */ jsx17(ChevronLeftIcon, {}),
|
|
6292
|
+
/* @__PURE__ */ jsx17("span", { className: "assist-edge-tab__label", children: visibleLabel }),
|
|
6293
|
+
/* @__PURE__ */ jsx17(DragDots, {})
|
|
5346
6294
|
] }) : null,
|
|
5347
|
-
variant === "fill" ? /* @__PURE__ */
|
|
5348
|
-
/* @__PURE__ */
|
|
5349
|
-
/* @__PURE__ */
|
|
5350
|
-
showLogo ? /* @__PURE__ */
|
|
6295
|
+
variant === "fill" ? /* @__PURE__ */ jsxs16(Fragment2, { children: [
|
|
6296
|
+
/* @__PURE__ */ jsxs16("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
|
|
6297
|
+
/* @__PURE__ */ jsx17(TabMarkIcon, { customIconUrl }),
|
|
6298
|
+
showLogo ? /* @__PURE__ */ jsx17(
|
|
5351
6299
|
"img",
|
|
5352
6300
|
{
|
|
5353
6301
|
className: "assist-edge-tab__logo",
|
|
@@ -5359,19 +6307,75 @@ function AssistEdgeTab({
|
|
|
5359
6307
|
}
|
|
5360
6308
|
) : null
|
|
5361
6309
|
] }),
|
|
5362
|
-
/* @__PURE__ */
|
|
5363
|
-
/* @__PURE__ */
|
|
6310
|
+
/* @__PURE__ */ jsx17("span", { className: "assist-edge-tab__label", children: visibleLabel }),
|
|
6311
|
+
/* @__PURE__ */ jsx17(ChevronLeftIcon, {})
|
|
5364
6312
|
] }) : null
|
|
5365
6313
|
]
|
|
5366
6314
|
}
|
|
5367
6315
|
);
|
|
5368
6316
|
}
|
|
5369
6317
|
|
|
6318
|
+
// src/react/lib/agent-feedback.ts
|
|
6319
|
+
var AGENT_ANSWER_FEEDBACK_EVENT_TYPE = "agent_answer_feedback";
|
|
6320
|
+
function findPrecedingVisitorText(messages, agentMessageId) {
|
|
6321
|
+
const agentIndex = messages.findIndex(
|
|
6322
|
+
(message) => message.id === agentMessageId && message.role === "agent"
|
|
6323
|
+
);
|
|
6324
|
+
if (agentIndex < 0) return void 0;
|
|
6325
|
+
for (let index = agentIndex - 1; index >= 0; index -= 1) {
|
|
6326
|
+
const message = messages[index];
|
|
6327
|
+
if (message?.role === "visitor") {
|
|
6328
|
+
return message.text.trim() || void 0;
|
|
6329
|
+
}
|
|
6330
|
+
}
|
|
6331
|
+
return void 0;
|
|
6332
|
+
}
|
|
6333
|
+
function normalizeAgentFeedbackAnswerText(text) {
|
|
6334
|
+
const normalized = text.replace(/\s+/g, " ").trim();
|
|
6335
|
+
if (!normalized) return void 0;
|
|
6336
|
+
return normalized.length > 4e3 ? `${normalized.slice(0, 3997)}...` : normalized;
|
|
6337
|
+
}
|
|
6338
|
+
function buildAgentAnswerFeedbackEvent(input) {
|
|
6339
|
+
const positive = input.rating === "positive";
|
|
6340
|
+
const answer = input.answer ? normalizeAgentFeedbackAnswerText(input.answer) : void 0;
|
|
6341
|
+
return {
|
|
6342
|
+
event_type: AGENT_ANSWER_FEEDBACK_EVENT_TYPE,
|
|
6343
|
+
company: input.analytics.companyIndex,
|
|
6344
|
+
session_id: input.visitorSessionId,
|
|
6345
|
+
page: input.page,
|
|
6346
|
+
timestamp: Date.now(),
|
|
6347
|
+
tracking_consent: input.analytics.trackingConsent,
|
|
6348
|
+
feedback_value: positive ? 1 : -1,
|
|
6349
|
+
// Aggregate-safe rating enum, kept even for anonymous (no-consent) events.
|
|
6350
|
+
feedback_rating: positive ? "helpful" : "not_helpful",
|
|
6351
|
+
surface: "agent_panel",
|
|
6352
|
+
index_id: input.indexId,
|
|
6353
|
+
index_version: input.version,
|
|
6354
|
+
message_id: input.messageId,
|
|
6355
|
+
...input.agentSessionId ? { agent_session_id: input.agentSessionId } : {},
|
|
6356
|
+
...input.analytics.trackingConsent && input.query ? { query: input.query } : {},
|
|
6357
|
+
...input.analytics.trackingConsent && answer ? { answer } : {}
|
|
6358
|
+
};
|
|
6359
|
+
}
|
|
6360
|
+
function sendAgentAnswerFeedback(eventUrl, event) {
|
|
6361
|
+
try {
|
|
6362
|
+
void fetch(eventUrl, {
|
|
6363
|
+
body: JSON.stringify(event),
|
|
6364
|
+
credentials: "omit",
|
|
6365
|
+
headers: { "Content-Type": "application/json" },
|
|
6366
|
+
keepalive: true,
|
|
6367
|
+
method: "POST"
|
|
6368
|
+
}).catch(() => {
|
|
6369
|
+
});
|
|
6370
|
+
} catch {
|
|
6371
|
+
}
|
|
6372
|
+
}
|
|
6373
|
+
|
|
5370
6374
|
// src/react/components/AgentWidget/AgentWidget.tsx
|
|
5371
|
-
import { useEffect as
|
|
6375
|
+
import { useEffect as useEffect9, useRef as useRef7, useState as useState11 } from "react";
|
|
5372
6376
|
|
|
5373
6377
|
// src/react/page-shift.ts
|
|
5374
|
-
import { useEffect as
|
|
6378
|
+
import { useEffect as useEffect7 } from "react";
|
|
5375
6379
|
var PAGE_SHIFT_CLASS = "webless-agent-page-shift";
|
|
5376
6380
|
var DEFAULT_RAIL_WIDTH_PX = 450;
|
|
5377
6381
|
function shouldApplyPageShift(input) {
|
|
@@ -5423,7 +6427,7 @@ function clearPageMargin() {
|
|
|
5423
6427
|
}
|
|
5424
6428
|
function usePageShift(input) {
|
|
5425
6429
|
const { active, railSlotRef } = input;
|
|
5426
|
-
|
|
6430
|
+
useEffect7(() => {
|
|
5427
6431
|
if (typeof document === "undefined") {
|
|
5428
6432
|
return;
|
|
5429
6433
|
}
|
|
@@ -5451,12 +6455,12 @@ function usePageShift(input) {
|
|
|
5451
6455
|
}
|
|
5452
6456
|
|
|
5453
6457
|
// src/react/hooks/useIsMobile.ts
|
|
5454
|
-
import { useEffect as
|
|
6458
|
+
import { useEffect as useEffect8, useState as useState10 } from "react";
|
|
5455
6459
|
function useIsMobile(breakpoint = 767) {
|
|
5456
|
-
const [isMobile, setIsMobile] =
|
|
6460
|
+
const [isMobile, setIsMobile] = useState10(
|
|
5457
6461
|
() => typeof window !== "undefined" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
|
|
5458
6462
|
);
|
|
5459
|
-
|
|
6463
|
+
useEffect8(() => {
|
|
5460
6464
|
const media = window.matchMedia(`(max-width: ${breakpoint}px)`);
|
|
5461
6465
|
const onChange = () => setIsMobile(media.matches);
|
|
5462
6466
|
onChange();
|
|
@@ -5467,7 +6471,7 @@ function useIsMobile(breakpoint = 767) {
|
|
|
5467
6471
|
}
|
|
5468
6472
|
|
|
5469
6473
|
// src/react/components/AgentWidget/AgentWidget.tsx
|
|
5470
|
-
import { jsx as
|
|
6474
|
+
import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
5471
6475
|
function AgentWidget({
|
|
5472
6476
|
indexId,
|
|
5473
6477
|
customerId,
|
|
@@ -5481,13 +6485,14 @@ function AgentWidget({
|
|
|
5481
6485
|
registerPanelController = false,
|
|
5482
6486
|
colorScheme = "auto",
|
|
5483
6487
|
branding,
|
|
6488
|
+
analytics,
|
|
5484
6489
|
toolResultRegistry
|
|
5485
6490
|
}) {
|
|
5486
6491
|
const isMobile = useIsMobile();
|
|
5487
6492
|
const placement = normalizeAgentPlacement(placementInput);
|
|
5488
|
-
const railSlotRef =
|
|
5489
|
-
const [railCollapsed, setRailCollapsed] =
|
|
5490
|
-
const [railExpanded, setRailExpanded] =
|
|
6493
|
+
const railSlotRef = useRef7(null);
|
|
6494
|
+
const [railCollapsed, setRailCollapsed] = useState11(defaultCollapsed);
|
|
6495
|
+
const [railExpanded, setRailExpanded] = useState11(false);
|
|
5491
6496
|
const pageShiftActive = shouldApplyPageShift({
|
|
5492
6497
|
pageShift,
|
|
5493
6498
|
isMobile,
|
|
@@ -5498,7 +6503,17 @@ function AgentWidget({
|
|
|
5498
6503
|
active: pageShiftActive,
|
|
5499
6504
|
railSlotRef
|
|
5500
6505
|
});
|
|
5501
|
-
const {
|
|
6506
|
+
const {
|
|
6507
|
+
state,
|
|
6508
|
+
reset,
|
|
6509
|
+
retry,
|
|
6510
|
+
regenerate,
|
|
6511
|
+
respondToInput,
|
|
6512
|
+
respondToToolInput,
|
|
6513
|
+
submit,
|
|
6514
|
+
visitorSessionId,
|
|
6515
|
+
sessionId
|
|
6516
|
+
} = useAgentChat({
|
|
5502
6517
|
customerId,
|
|
5503
6518
|
getUnpublishedPreviewGrant,
|
|
5504
6519
|
indexId,
|
|
@@ -5530,7 +6545,7 @@ function AgentWidget({
|
|
|
5530
6545
|
} : {},
|
|
5531
6546
|
...branding?.colors?.border ? { border: branding.colors.border } : {}
|
|
5532
6547
|
};
|
|
5533
|
-
|
|
6548
|
+
useEffect9(() => {
|
|
5534
6549
|
if (!registerPanelController) return;
|
|
5535
6550
|
registerAgentPanelController(customerId, {
|
|
5536
6551
|
open: () => setRailCollapsed(false),
|
|
@@ -5547,7 +6562,25 @@ function AgentWidget({
|
|
|
5547
6562
|
if (isMobile) setRailCollapsed(false);
|
|
5548
6563
|
await submit(message);
|
|
5549
6564
|
}
|
|
5550
|
-
|
|
6565
|
+
function handleFeedback(rating, message) {
|
|
6566
|
+
if (!analytics) return;
|
|
6567
|
+
sendAgentAnswerFeedback(
|
|
6568
|
+
analytics.eventUrl,
|
|
6569
|
+
buildAgentAnswerFeedbackEvent({
|
|
6570
|
+
agentSessionId: sessionId,
|
|
6571
|
+
analytics,
|
|
6572
|
+
indexId,
|
|
6573
|
+
messageId: message.id,
|
|
6574
|
+
page: window.location.href,
|
|
6575
|
+
query: findPrecedingVisitorText(state.messages, message.id),
|
|
6576
|
+
answer: message.text,
|
|
6577
|
+
rating,
|
|
6578
|
+
version: version ?? "published",
|
|
6579
|
+
visitorSessionId
|
|
6580
|
+
})
|
|
6581
|
+
);
|
|
6582
|
+
}
|
|
6583
|
+
useEffect9(() => {
|
|
5551
6584
|
if (railCollapsed) return;
|
|
5552
6585
|
const handleKeyDown = (event) => {
|
|
5553
6586
|
if (event.key === "Tab" && (isMobile || railExpanded)) {
|
|
@@ -5581,19 +6614,19 @@ function AgentWidget({
|
|
|
5581
6614
|
window.addEventListener("keydown", handleKeyDown);
|
|
5582
6615
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
5583
6616
|
}, [isMobile, railCollapsed, railExpanded]);
|
|
5584
|
-
return /* @__PURE__ */
|
|
5585
|
-
/* @__PURE__ */
|
|
6617
|
+
return /* @__PURE__ */ jsxs17("div", { className: "webless-agent-root", children: [
|
|
6618
|
+
/* @__PURE__ */ jsx18(
|
|
5586
6619
|
"div",
|
|
5587
6620
|
{
|
|
5588
6621
|
className: `webless-agent-root__shell${railCollapsed ? " webless-agent-root__shell--collapsed" : ""}${railExpanded ? " webless-agent-root__shell--expanded" : ""}`,
|
|
5589
|
-
children: /* @__PURE__ */
|
|
6622
|
+
children: /* @__PURE__ */ jsx18(
|
|
5590
6623
|
"div",
|
|
5591
6624
|
{
|
|
5592
6625
|
ref: railSlotRef,
|
|
5593
6626
|
className: "webless-agent-root__rail-slot",
|
|
5594
6627
|
inert: railCollapsed || void 0,
|
|
5595
6628
|
"aria-hidden": railCollapsed,
|
|
5596
|
-
children: /* @__PURE__ */
|
|
6629
|
+
children: /* @__PURE__ */ jsx18(
|
|
5597
6630
|
AgentRail,
|
|
5598
6631
|
{
|
|
5599
6632
|
theme,
|
|
@@ -5602,6 +6635,9 @@ function AgentWidget({
|
|
|
5602
6635
|
brandLogoUrl: branding?.logoUrl,
|
|
5603
6636
|
composerPlaceholder: branding?.composerPlaceholder ?? "Ask a question\u2026",
|
|
5604
6637
|
poweredByLabel: branding?.poweredByLabel ?? "Powered by Webless",
|
|
6638
|
+
disclaimerLabel: branding?.disclaimer,
|
|
6639
|
+
answerReceipt: branding?.answerReceipt,
|
|
6640
|
+
readAloud: branding?.readAloud,
|
|
5605
6641
|
state,
|
|
5606
6642
|
mobileFullscreen: isMobile && !railCollapsed,
|
|
5607
6643
|
expanded: railExpanded,
|
|
@@ -5611,17 +6647,22 @@ function AgentWidget({
|
|
|
5611
6647
|
onSubmit: handleSubmit,
|
|
5612
6648
|
onReset: reset,
|
|
5613
6649
|
onRetry: () => void retry(),
|
|
6650
|
+
onRegenerate: () => void regenerate(),
|
|
6651
|
+
onFeedback: analytics ? handleFeedback : void 0,
|
|
5614
6652
|
onInputResponse: (response) => void respondToInput(response),
|
|
5615
6653
|
onToolInput: (surface, values) => void respondToToolInput(surface, values),
|
|
5616
6654
|
onFollowUpSelect: (label) => void handleSubmit(label),
|
|
5617
|
-
onBook: (input) => void submit(input.displayText, {
|
|
6655
|
+
onBook: (input) => void submit(input.displayText, {
|
|
6656
|
+
preservePendingOffer: true,
|
|
6657
|
+
runtimeText: input.runtimeText
|
|
6658
|
+
})
|
|
5618
6659
|
}
|
|
5619
6660
|
)
|
|
5620
6661
|
}
|
|
5621
6662
|
)
|
|
5622
6663
|
}
|
|
5623
6664
|
),
|
|
5624
|
-
railCollapsed ? /* @__PURE__ */
|
|
6665
|
+
railCollapsed ? /* @__PURE__ */ jsx18(
|
|
5625
6666
|
AssistEdgeTab,
|
|
5626
6667
|
{
|
|
5627
6668
|
variant: placement.variant,
|
|
@@ -5666,8 +6707,13 @@ export {
|
|
|
5666
6707
|
submitAgentPanel,
|
|
5667
6708
|
defaultAgentRailTheme,
|
|
5668
6709
|
defaultDarkAgentRailTheme,
|
|
6710
|
+
MessageActions,
|
|
5669
6711
|
AgentRail,
|
|
5670
6712
|
AssistEdgeTab,
|
|
6713
|
+
AGENT_ANSWER_FEEDBACK_EVENT_TYPE,
|
|
6714
|
+
findPrecedingVisitorText,
|
|
6715
|
+
buildAgentAnswerFeedbackEvent,
|
|
6716
|
+
sendAgentAnswerFeedback,
|
|
5671
6717
|
AgentWidget
|
|
5672
6718
|
};
|
|
5673
|
-
//# sourceMappingURL=chunk-
|
|
6719
|
+
//# sourceMappingURL=chunk-CYI3OSWG.js.map
|