@flowengage/react-chatbot 6.0.45 → 7.0.1
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/README.md +44 -0
- package/dist/flowengage-embed.js +19 -17
- package/dist/flowengage-react-chatbot.cjs +13 -11
- package/dist/flowengage-react-chatbot.mjs +350 -310
- package/package.json +1 -1
|
@@ -506,7 +506,7 @@ var k = (e) => {
|
|
|
506
506
|
let l = new ArrayBuffer(t), u = new Uint8Array(l);
|
|
507
507
|
for (r = 0; r < n; r += 4) a = at[e.charCodeAt(r)], o = at[e.charCodeAt(r + 1)], s = at[e.charCodeAt(r + 2)], c = at[e.charCodeAt(r + 3)], u[i++] = a << 2 | o >> 4, u[i++] = (o & 15) << 4 | s >> 2, u[i++] = (s & 3) << 6 | c & 63;
|
|
508
508
|
return l;
|
|
509
|
-
},
|
|
509
|
+
}, A = typeof ArrayBuffer == "function", ot = (e, t) => {
|
|
510
510
|
if (typeof e != "string") return {
|
|
511
511
|
type: "message",
|
|
512
512
|
data: ct(e, t)
|
|
@@ -519,7 +519,7 @@ var k = (e) => {
|
|
|
519
519
|
type: Je[n],
|
|
520
520
|
data: e.substring(1)
|
|
521
521
|
} : { type: Je[n] } : Ye;
|
|
522
|
-
}, st = (e, t) =>
|
|
522
|
+
}, st = (e, t) => A ? ct(k(e), t) : {
|
|
523
523
|
base64: !0,
|
|
524
524
|
data: e
|
|
525
525
|
}, ct = (e, t) => {
|
|
@@ -537,7 +537,7 @@ var k = (e) => {
|
|
|
537
537
|
}, dt = (e, t) => {
|
|
538
538
|
let n = e.split(lt), r = [];
|
|
539
539
|
for (let e = 0; e < n.length; e++) {
|
|
540
|
-
let i =
|
|
540
|
+
let i = ot(n[e], t);
|
|
541
541
|
if (r.push(i), i.type === "error") break;
|
|
542
542
|
}
|
|
543
543
|
return r;
|
|
@@ -594,7 +594,7 @@ function gt(e, t) {
|
|
|
594
594
|
} else {
|
|
595
595
|
if (mt(n) < i) break;
|
|
596
596
|
let e = ht(n, i);
|
|
597
|
-
s.enqueue(
|
|
597
|
+
s.enqueue(ot(a ? e : pt.decode(e), t)), r = 0;
|
|
598
598
|
}
|
|
599
599
|
if (i === 0 || i > e) {
|
|
600
600
|
s.enqueue(Ye);
|
|
@@ -707,7 +707,7 @@ var jt = class extends Error {
|
|
|
707
707
|
this.readyState = "open", this.writable = !0, super.emitReserved("open");
|
|
708
708
|
}
|
|
709
709
|
onData(e) {
|
|
710
|
-
let t =
|
|
710
|
+
let t = ot(e, this.socket.binaryType);
|
|
711
711
|
this.onPacket(t);
|
|
712
712
|
}
|
|
713
713
|
onPacket(e) {
|
|
@@ -2116,6 +2116,7 @@ function er() {
|
|
|
2116
2116
|
if (window.__VUE_ROUTER__) return "vue-router";
|
|
2117
2117
|
if (window.__NUXT__ || window.$nuxt) return "nuxt";
|
|
2118
2118
|
if (window.ng?.getComponent || document.querySelector("[ng-version]")) return "angular";
|
|
2119
|
+
if (window[Symbol.for("wouter_v3")]) return "wouter";
|
|
2119
2120
|
if (window.__sveltekit_data || document.querySelector("[data-sveltekit-hydrate]")) return "sveltekit";
|
|
2120
2121
|
if (document.querySelector("[data-astro-transition]")) return "astro";
|
|
2121
2122
|
if (window.__vite_plugin_react_preamble_installed__) return "vite-react-spa";
|
|
@@ -2839,7 +2840,7 @@ function Rr({ siteId: e, config: t, children: n, language: r = "en" }) {
|
|
|
2839
2840
|
let i = f(() => e ? {
|
|
2840
2841
|
...t || {},
|
|
2841
2842
|
siteId: e
|
|
2842
|
-
} : t || null, [e, t]), [a, s] = m(0), [l, u] = m("booting"), [d, h] = m(null), [_, v] = m(null), [y, b] = m(""), [x, S] = m([]), [C, w] = m(ve().isOpen), [T, te] = m(ve().activeScreen), [ne, re] = m(ve().isHumanHandled), [E, D] = m(ve().agentName), [se, de] = m(ve().agentHeadshot), [fe, pe] = m(() => be(i?.siteId)), [me, Se] = m(!1), [Ce, we] = m(!1), [Ee, De] = m("idle"), [Oe, ke] = m(!1), [Ae, je] = m(!1), [Me, Ne] = m(""), [Fe, Ie] = m(!1), [Le, Re] = m(0), [ze, Be] = m(0), [Ve, He] = m(!1), [O, Ue] = m(null), [qe, Je] = m(null), [Ye, Xe] = m("idle"), [Ze, Qe] = m(null), [$e, et] = m(!1), [tt, nt] = m(""), [rt, it] = m(!1), at = p(null), k = p(null),
|
|
2843
|
+
} : t || null, [e, t]), [a, s] = m(0), [l, u] = m("booting"), [d, h] = m(null), [_, v] = m(null), [y, b] = m(""), [x, S] = m([]), [C, w] = m(ve().isOpen), [T, te] = m(ve().activeScreen), [ne, re] = m(ve().isHumanHandled), [E, D] = m(ve().agentName), [se, de] = m(ve().agentHeadshot), [fe, pe] = m(() => be(i?.siteId)), [me, Se] = m(!1), [Ce, we] = m(!1), [Ee, De] = m("idle"), [Oe, ke] = m(!1), [Ae, je] = m(!1), [Me, Ne] = m(""), [Fe, Ie] = m(!1), [Le, Re] = m(0), [ze, Be] = m(0), [Ve, He] = m(!1), [O, Ue] = m(null), [qe, Je] = m(null), [Ye, Xe] = m("idle"), [Ze, Qe] = m(null), [$e, et] = m(!1), [tt, nt] = m(""), [rt, it] = m(!1), at = p(null), k = p(null), A = p(""), ot = p(!1), st = p(null), ct = p(null), lt = p(null), ut = p(null), dt = p(null), ft = p(null), pt = p([]), mt = p(null), ht = p(null), gt = p(null), j = p(!1), _t = p(!1), vt = p(""), yt = p(null), bt = p(null), xt = p([]), St = p(0), Ct = p(E), wt = p([]), Tt = p(!1), Et = p(!1), Dt = p(i), Ot = p({
|
|
2843
2844
|
notifyRouteChange: () => {},
|
|
2844
2845
|
cleanup: () => {}
|
|
2845
2846
|
}), kt = o((e = {}) => {
|
|
@@ -2904,7 +2905,7 @@ function Rr({ siteId: e, config: t, children: n, language: r = "en" }) {
|
|
|
2904
2905
|
if (!(!t?.connected || !n || j.current)) {
|
|
2905
2906
|
j.current = !0, t.emit("call:connected", {
|
|
2906
2907
|
callId: n,
|
|
2907
|
-
chatId:
|
|
2908
|
+
chatId: A.current,
|
|
2908
2909
|
connectedAt: e
|
|
2909
2910
|
});
|
|
2910
2911
|
try {
|
|
@@ -2971,7 +2972,7 @@ function Rr({ siteId: e, config: t, children: n, language: r = "en" }) {
|
|
|
2971
2972
|
if (!t || !n?.connected || !r || !e.callId) {
|
|
2972
2973
|
console.log("[FlowEngageProvider] deferring remote offer until peer/socket ready", {
|
|
2973
2974
|
callId: e.callId,
|
|
2974
|
-
chatId:
|
|
2975
|
+
chatId: A.current,
|
|
2975
2976
|
hasPeerConnection: !!t,
|
|
2976
2977
|
socketConnected: !!n?.connected,
|
|
2977
2978
|
hasOffer: !!r
|
|
@@ -2984,7 +2985,7 @@ function Rr({ siteId: e, config: t, children: n, language: r = "en" }) {
|
|
|
2984
2985
|
})), pt.current.length > 0) {
|
|
2985
2986
|
console.log("[FlowEngageProvider] flushing queued agent ICE candidates after remote offer", {
|
|
2986
2987
|
callId: e.callId,
|
|
2987
|
-
chatId:
|
|
2988
|
+
chatId: A.current,
|
|
2988
2989
|
queuedCount: pt.current.length
|
|
2989
2990
|
});
|
|
2990
2991
|
for (let e of pt.current) await t.addIceCandidate(new RTCIceCandidate(e));
|
|
@@ -2994,7 +2995,7 @@ function Rr({ siteId: e, config: t, children: n, language: r = "en" }) {
|
|
|
2994
2995
|
await t.setLocalDescription(i), n.emit("call:answer", {
|
|
2995
2996
|
callId: e.callId,
|
|
2996
2997
|
sdpAnswer: i.sdp,
|
|
2997
|
-
chatId:
|
|
2998
|
+
chatId: A.current
|
|
2998
2999
|
});
|
|
2999
3000
|
};
|
|
3000
3001
|
c(() => {
|
|
@@ -3020,8 +3021,8 @@ function Rr({ siteId: e, config: t, children: n, language: r = "en" }) {
|
|
|
3020
3021
|
if (!e) return;
|
|
3021
3022
|
let a = t.siteId, o = he(a), s = Te(a), c = "";
|
|
3022
3023
|
try {
|
|
3023
|
-
let e =
|
|
3024
|
-
if (
|
|
3024
|
+
let e = ot.current, r = st.current;
|
|
3025
|
+
if (ot.current = !1, st.current = null, c = (await We({
|
|
3025
3026
|
apiBaseUrl: t.apiBaseUrl,
|
|
3026
3027
|
userId: n.userId,
|
|
3027
3028
|
siteId: a,
|
|
@@ -3034,7 +3035,7 @@ function Rr({ siteId: e, config: t, children: n, language: r = "en" }) {
|
|
|
3034
3035
|
} catch (e) {
|
|
3035
3036
|
console.warn("[FlowEngageProvider] resolve-session failed, reusing persisted or ephemeral chat id", e?.message || e), c = o || ue(), _e(a, c);
|
|
3036
3037
|
}
|
|
3037
|
-
|
|
3038
|
+
A.current = c;
|
|
3038
3039
|
let l = Ke({
|
|
3039
3040
|
apiBaseUrl: t.apiBaseUrl,
|
|
3040
3041
|
userId: n.userId,
|
|
@@ -3180,7 +3181,7 @@ function Rr({ siteId: e, config: t, children: n, language: r = "en" }) {
|
|
|
3180
3181
|
if (!lt.current || !lt.current.remoteDescription) {
|
|
3181
3182
|
console.log("[FlowEngageProvider] queueing agent ICE candidate until peer/remote description is ready", {
|
|
3182
3183
|
callId: e.callId,
|
|
3183
|
-
chatId: e.chatId ||
|
|
3184
|
+
chatId: e.chatId || A.current,
|
|
3184
3185
|
queueSize: pt.current.length + 1
|
|
3185
3186
|
}), pt.current.push(t);
|
|
3186
3187
|
return;
|
|
@@ -3255,7 +3256,7 @@ function Rr({ siteId: e, config: t, children: n, language: r = "en" }) {
|
|
|
3255
3256
|
a
|
|
3256
3257
|
]), c(() => () => {
|
|
3257
3258
|
if (Fe && !Tt.current && wt.current.length > 0) {
|
|
3258
|
-
let e =
|
|
3259
|
+
let e = A.current, t = wt.current, n = k.current;
|
|
3259
3260
|
n && e && t.length > 0 && (console.log("[FlowEngageProvider] safety-net: syncing voice transcript on unmount"), n.beaconSyncVoice(e, t) || n.syncVoice(e, t).catch(() => {}), Tt.current = !0);
|
|
3260
3261
|
}
|
|
3261
3262
|
}, [Fe, _]);
|
|
@@ -3265,7 +3266,7 @@ function Rr({ siteId: e, config: t, children: n, language: r = "en" }) {
|
|
|
3265
3266
|
!e || !y || zt.current !== C && (C && zt.current !== null ? (e.updateChatStatus(y, "open").catch(() => {}), Bt.current = !0) : zt.current === !0 && e.updateChatStatus(y, "widget_closed").catch(() => {}), zt.current = C);
|
|
3266
3267
|
}, [C, y]), c(() => {
|
|
3267
3268
|
let e = () => {
|
|
3268
|
-
let e =
|
|
3269
|
+
let e = A.current, t = k.current;
|
|
3269
3270
|
!e || !t || typeof navigator > "u" || t.beaconWidgetClosed?.(e) || t.updateChatStatus(e, "widget_closed").catch(() => {});
|
|
3270
3271
|
};
|
|
3271
3272
|
return window.addEventListener("pagehide", e), () => window.removeEventListener("pagehide", e);
|
|
@@ -3448,10 +3449,10 @@ function Rr({ siteId: e, config: t, children: n, language: r = "en" }) {
|
|
|
3448
3449
|
}
|
|
3449
3450
|
}, qt = async (e) => {
|
|
3450
3451
|
let t = Nt(e);
|
|
3451
|
-
if (!t || !k.current || !
|
|
3452
|
+
if (!t || !k.current || !A.current) return t;
|
|
3452
3453
|
try {
|
|
3453
3454
|
await k.current.trackVisitor({
|
|
3454
|
-
chatId:
|
|
3455
|
+
chatId: A.current,
|
|
3455
3456
|
currentPagePath: typeof window < "u" && window.location.pathname || "/",
|
|
3456
3457
|
email: t
|
|
3457
3458
|
});
|
|
@@ -3611,7 +3612,7 @@ function Rr({ siteId: e, config: t, children: n, language: r = "en" }) {
|
|
|
3611
3612
|
At
|
|
3612
3613
|
]), c(() => {
|
|
3613
3614
|
let e = () => {
|
|
3614
|
-
let e =
|
|
3615
|
+
let e = A.current, t = k.current;
|
|
3615
3616
|
if (!t || !e) return;
|
|
3616
3617
|
if (Et.current && wt.current.length > 0 && Pe(), !Tt.current && wt.current.length > 0 && (t.beaconSyncVoice(e, wt.current) || t.syncVoice(e, wt.current).catch(() => {}), Tt.current = !0), mt.current) {
|
|
3617
3618
|
t.beaconEndWebRTCCall(mt.current, e);
|
|
@@ -3626,9 +3627,9 @@ function Rr({ siteId: e, config: t, children: n, language: r = "en" }) {
|
|
|
3626
3627
|
}, []);
|
|
3627
3628
|
let nn = o(() => {
|
|
3628
3629
|
let e = i?.siteId;
|
|
3629
|
-
ge(e),
|
|
3630
|
+
ge(e), ot.current = !0, st.current = null, at.current?.disconnect(), S([]), b(""), A.current = "", He(!1), re(!1), D(null), de(null), it(!0), s((e) => e + 1);
|
|
3630
3631
|
}, [i?.siteId]), rn = o((e) => {
|
|
3631
|
-
i?.siteId,
|
|
3632
|
+
i?.siteId, ot.current = !1, st.current = e, at.current?.disconnect(), S([]), b(""), A.current = "", He(!1), re(!1), D(null), de(null), it(!0), s((e) => e + 1);
|
|
3632
3633
|
}, [i?.siteId]), an = f(() => ({
|
|
3633
3634
|
status: l,
|
|
3634
3635
|
error: d,
|
|
@@ -29268,12 +29269,7 @@ function vk(e) {
|
|
|
29268
29269
|
let t = e.url ?? e.target_url ?? e.page_url ?? e.pageUrl ?? e.link ?? e.href ?? e.path;
|
|
29269
29270
|
return t == null ? null : String(t).trim() || null;
|
|
29270
29271
|
}
|
|
29271
|
-
function yk(e) {
|
|
29272
|
-
if (!e || typeof e != "object") return null;
|
|
29273
|
-
let t = e.query ?? e.q ?? e.search ?? e.text ?? e.keywords;
|
|
29274
|
-
return t == null ? null : String(t).trim() || null;
|
|
29275
|
-
}
|
|
29276
|
-
function bk(e, t, n) {
|
|
29272
|
+
function yk(e, t, n) {
|
|
29277
29273
|
if (!n?.skipScroll) try {
|
|
29278
29274
|
e.scrollIntoView({
|
|
29279
29275
|
block: "center",
|
|
@@ -29328,7 +29324,7 @@ function bk(e, t, n) {
|
|
|
29328
29324
|
} catch {}
|
|
29329
29325
|
return !0;
|
|
29330
29326
|
}
|
|
29331
|
-
function
|
|
29327
|
+
function bk() {
|
|
29332
29328
|
let e = {};
|
|
29333
29329
|
document.querySelectorAll("h1, h2, h3, h4, h5, h6").forEach((t) => {
|
|
29334
29330
|
if (t.id) return;
|
|
@@ -29343,31 +29339,31 @@ function xk() {
|
|
|
29343
29339
|
e[r] = !0, t.id = r;
|
|
29344
29340
|
});
|
|
29345
29341
|
}
|
|
29346
|
-
function
|
|
29342
|
+
function xk() {
|
|
29347
29343
|
let e = (e) => Array.from(e).filter((e) => !e.closest("#flowengage-root, .flowengage-shell, .flowengage-widget-root")).map((e) => e.textContent.replace(/\s+/g, " ").trim()).filter((e) => e.length > 2 && e.length < 200), t = e((document.querySelector("main, [role='main']") || document.body).querySelectorAll("h1, h2, h3"));
|
|
29348
29344
|
return t.length || (t = e(document.body.querySelectorAll("h1, h2, h3"))), t.length || (t = e(document.body.querySelectorAll("h4, h5"))), [...new Set(t)].slice(0, 15);
|
|
29349
29345
|
}
|
|
29350
|
-
function
|
|
29346
|
+
function Sk(e) {
|
|
29351
29347
|
let t = e.siteId || null, n = (e.apiBaseUrl || "").replace(/\/$/, ""), r = typeof e.getLastUserVoiceText == "function" ? e.getLastUserVoiceText : null, i = [], a = {
|
|
29352
|
-
|
|
29353
|
-
$("
|
|
29348
|
+
"fwh-navigate-mvp": async (n) => {
|
|
29349
|
+
$("fwh-navigate-mvp ▶ raw parameters:", n);
|
|
29354
29350
|
let i = mk(n), a = vk(i), o = i.section_text ?? i.sectionText ?? i.section, s = Array.isArray(i.expected_landmarks) ? i.expected_landmarks : Array.isArray(i.expectedLandmarks) ? i.expectedLandmarks : [];
|
|
29355
|
-
if ($("
|
|
29351
|
+
if ($("fwh-navigate-mvp · coerced:", {
|
|
29356
29352
|
url: a,
|
|
29357
29353
|
sectionText: o,
|
|
29358
29354
|
expectedLandmarks: s
|
|
29359
29355
|
}), !a) {
|
|
29360
29356
|
let e = "Missing url: pass a string url, path like /pricing, or JSON with a url field.";
|
|
29361
|
-
return $("
|
|
29357
|
+
return $("fwh-navigate-mvp ✖", e), e;
|
|
29362
29358
|
}
|
|
29363
29359
|
if (typeof window < "u") try {
|
|
29364
29360
|
let e = new URL(a, window.location.href);
|
|
29365
|
-
e.origin !== window.location.origin && /^https?:$/i.test(e.protocol) && (a = e.pathname + e.search + e.hash, $("
|
|
29361
|
+
e.origin !== window.location.origin && /^https?:$/i.test(e.protocol) && (a = e.pathname + e.search + e.hash, $("fwh-navigate-mvp · normalized cross-origin URL to path:", a));
|
|
29366
29362
|
} catch {}
|
|
29367
29363
|
if (typeof window < "u") {
|
|
29368
29364
|
try {
|
|
29369
29365
|
let e = new URL(a, window.location.href);
|
|
29370
|
-
if (e.pathname === window.location.pathname && e.search === window.location.search) return $("
|
|
29366
|
+
if (e.pathname === window.location.pathname && e.search === window.location.search) return $("fwh-navigate-mvp ✖ already on page, skipping"), "OK_ALREADY_ON_PAGE. The visitor is already on this page. Do not navigate. Proceed directly with highlights, answering the question, or reading page content.";
|
|
29371
29367
|
} catch {}
|
|
29372
29368
|
let e = window.__fe_user_nav_during_speech;
|
|
29373
29369
|
if (e && Date.now() - e.ts < 3e4) try {
|
|
@@ -29378,8 +29374,8 @@ function Ck(e) {
|
|
|
29378
29374
|
siteId: t,
|
|
29379
29375
|
apiBaseUrl: e.apiBaseUrl
|
|
29380
29376
|
})) {
|
|
29381
|
-
let e = `Page "${a}" could not be verified.
|
|
29382
|
-
return $("
|
|
29377
|
+
let e = `Page "${a}" could not be verified. Try a different URL from your known site pages, or ask the visitor to clarify which page they want.`;
|
|
29378
|
+
return $("fwh-navigate-mvp ✖ blocked", e), e;
|
|
29383
29379
|
}
|
|
29384
29380
|
try {
|
|
29385
29381
|
CO(`Navigating to ${a}...`, { spinner: !0 }), OO(), SD();
|
|
@@ -29398,23 +29394,23 @@ function Ck(e) {
|
|
|
29398
29394
|
try {
|
|
29399
29395
|
e = new URL(a, typeof window < "u" ? window.location.href : "").href;
|
|
29400
29396
|
} catch {}
|
|
29401
|
-
t && typeof window < "u" && Ve(t, window.location.href, e), Cr(e), $("
|
|
29397
|
+
t && typeof window < "u" && Ve(t, window.location.href, e), Cr(e), $("fwh-navigate-mvp → real navigation", a);
|
|
29402
29398
|
let n = typeof window < "u" && !!er();
|
|
29403
29399
|
if (typeof window < "u" && window.__fe_triggerVoiceNavHooks && window.__fe_triggerVoiceNavHooks(), n && qn(3e3), Er(a, { voiceActive: !0 }).catch(() => {}), n) try {
|
|
29404
29400
|
let e = new URL(a, window.location.origin).pathname, t = Date.now() + 2e3;
|
|
29405
29401
|
for (; Date.now() < t && !(typeof window < "u" && window.location.pathname === e);) await new Promise((e) => setTimeout(e, 80));
|
|
29406
29402
|
let n = typeof window < "u" ? window.location.pathname : e, r = typeof window < "u" ? window.location.href : a, i = n === e, o = (n.split("/").filter(Boolean).pop() || "").replace(/[-_]/g, " ").replace(/\b\w/g, (e) => e.toUpperCase()) || "Home";
|
|
29407
|
-
$("
|
|
29403
|
+
$("fwh-navigate-mvp → SPA nav complete. target:", e, "actual:", n);
|
|
29408
29404
|
let s = [], c = Date.now() + 12e3;
|
|
29409
|
-
for (; Date.now() < c && (await new Promise((e) => setTimeout(e, 300)), s =
|
|
29410
|
-
|
|
29411
|
-
let l = s.length ? s.join(" | ") : "none", u = s.length ? "Use ONLY these exact heading strings for
|
|
29412
|
-
return i ? (wr(), `OK_NAVIGATE_SPA. Visitor is now on: ${r} (page: "${o}") | Section headings: ${l}. ${u} Speak 2-3 sentences about this page
|
|
29405
|
+
for (; Date.now() < c && (await new Promise((e) => setTimeout(e, 300)), s = xk(), !(s.length >= 1)););
|
|
29406
|
+
bk(), $("fwh-navigate-mvp → page headings collected:", s);
|
|
29407
|
+
let l = s.length ? s.join(" | ") : "none", u = s.length ? "Use ONLY these exact heading strings for fwh-highlight-mvp — never invent or abbreviate." : "No headings collected yet — call fwh-get-current-page-mvp immediately (no speech) to get the live headings before speaking or highlighting.";
|
|
29408
|
+
return i ? (wr(), `OK_NAVIGATE_SPA. Visitor is now on: ${r} (page: "${o}") | Section headings: ${l}. ${u} Speak 2-3 sentences about this page from your knowledge. Then ask: "Would you like to know about a specific section, or should I give you a complete overview?" Then STOP — wait for their reply. Do NOT auto-highlight any sections.`) : (wr(), `OK_NAVIGATE_SPA. CURRENT PAGE IS: ${r} (page: "${o}") | Section headings: ${l}. ${u} Speak 2-3 sentences about this page from your knowledge. Then ask: "Would you like to know about a specific section, or should I give you a complete overview?" Then STOP — wait for their reply. Do NOT auto-highlight any sections.`);
|
|
29413
29409
|
} catch {}
|
|
29414
|
-
return "OK_NAVIGATE_RELOADING. Navigating to the page now; the voice session will resume automatically on the new page. When the session resumes,
|
|
29410
|
+
return "OK_NAVIGATE_RELOADING. Navigating to the page now; the voice session will resume automatically on the new page. When the session resumes, speak 2-3 sentences about the page, then ask: \"Would you like to know about a specific section, or should I give you a complete overview?\" Wait for the visitor's reply.";
|
|
29415
29411
|
} catch (e) {
|
|
29416
29412
|
let t = `Navigation error: ${e?.message || String(e)}`;
|
|
29417
|
-
return $("
|
|
29413
|
+
return $("fwh-navigate-mvp ✖", t), CO("Navigation failed", {
|
|
29418
29414
|
spinner: !1,
|
|
29419
29415
|
icon: "⚠️",
|
|
29420
29416
|
duration: 1800
|
|
@@ -29423,29 +29419,29 @@ function Ck(e) {
|
|
|
29423
29419
|
kO(), wO(900);
|
|
29424
29420
|
}
|
|
29425
29421
|
},
|
|
29426
|
-
|
|
29427
|
-
$("
|
|
29422
|
+
"fwh-highlight-mvp": async (e) => {
|
|
29423
|
+
$("fwh-highlight-mvp ▶", e);
|
|
29428
29424
|
let t = mk(e), n = t?.section_id || t?.sectionId, r = t?.section_text || t?.sectionText;
|
|
29429
29425
|
if (typeof window < "u" && window.__fe_user_nav_during_speech) {
|
|
29430
29426
|
let e = window.__fe_user_nav_during_speech, t = window.location.pathname;
|
|
29431
29427
|
if (Date.now() - e.ts >= 3e4) window.__fe_user_nav_during_speech = null;
|
|
29432
29428
|
else return $("flowengage_highlight ✖ blocked — user navigated during speech", e), `NAV_CHANGED: The visitor navigated from "${e.fromPageName}" to "${e.toPageName}" (current path: ${t}) while you were speaking. STOP the current walkthrough immediately. DO NOT call flowengage_highlight again. Say out loud: "I see you've navigated to the ${e.toPageName} page — do you want me to continue what I was explaining, or shall I guide you through this page?" Wait for the visitor's answer before doing anything else.`;
|
|
29433
29429
|
}
|
|
29434
|
-
|
|
29430
|
+
bk();
|
|
29435
29431
|
let i = hr(n || null, r || null);
|
|
29436
29432
|
if (!i && r) {
|
|
29437
29433
|
let e = Date.now() + 600;
|
|
29438
|
-
for (; !i && Date.now() < e;) await new Promise((e) => setTimeout(e, 50)),
|
|
29434
|
+
for (; !i && Date.now() < e;) await new Promise((e) => setTimeout(e, 50)), bk(), i = hr(null, r);
|
|
29439
29435
|
}
|
|
29440
29436
|
if (!i) {
|
|
29441
|
-
$("
|
|
29442
|
-
let e =
|
|
29437
|
+
$("fwh-highlight-mvp ✖ no element for:", r || n);
|
|
29438
|
+
let e = xk(), t = e.length ? `Page headings: ${e.join(" | ")}. Use one of these exact strings for section_text.` : "No headings found — skip highlight and continue.";
|
|
29443
29439
|
return `HIGHLIGHT_NOT_FOUND: "${r || n}" on the current page. ${t}`;
|
|
29444
29440
|
}
|
|
29445
|
-
return xD(i), $("
|
|
29441
|
+
return xD(i), $("fwh-highlight-mvp ✓", r || n), `OK_HIGHLIGHT: "${r || n}". WALKTHROUGH: continue immediately to the next section — do NOT pause between sections.`;
|
|
29446
29442
|
},
|
|
29447
|
-
|
|
29448
|
-
$("
|
|
29443
|
+
"fwh-read-content-mvp": async (e) => {
|
|
29444
|
+
$("fwh-read-content-mvp ▶", e);
|
|
29449
29445
|
let t = mk(e), n = t?.section_text || t?.sectionText || "";
|
|
29450
29446
|
try {
|
|
29451
29447
|
let e = "";
|
|
@@ -29462,36 +29458,36 @@ function Ck(e) {
|
|
|
29462
29458
|
let t = (document.querySelector("main") || document.querySelector("article") || document.querySelector("[role=\"main\"]") || document.querySelector("#content") || document.querySelector(".content") || document.body).cloneNode(!0);
|
|
29463
29459
|
t.querySelectorAll("nav, footer, header, aside, script, style, noscript, .nav, .footer, .header, .sidebar").forEach((e) => e.remove()), e = t.textContent.replace(/\s+/g, " ").trim();
|
|
29464
29460
|
}
|
|
29465
|
-
return e.length > 8e3 && (e = e.substring(0, 8e3) + "... (truncated)"), $("
|
|
29461
|
+
return e.length > 8e3 && (e = e.substring(0, 8e3) + "... (truncated)"), $("fwh-read-content-mvp ✓", `${e.length} chars`), e || "No readable content found on this page.";
|
|
29466
29462
|
} catch (e) {
|
|
29467
|
-
return $("
|
|
29463
|
+
return $("fwh-read-content-mvp ✖", e.message), `Could not read page content: ${e.message}`;
|
|
29468
29464
|
}
|
|
29469
29465
|
},
|
|
29470
29466
|
flowengage_search: async (e) => {
|
|
29471
29467
|
$("flowengage_search ▶", e);
|
|
29472
|
-
let r =
|
|
29473
|
-
if ($("flowengage_search · query:",
|
|
29468
|
+
let r = mk(e), i = pickSearchQuery(r);
|
|
29469
|
+
if ($("flowengage_search · query:", i, "siteId:", t, "apiBase:", n || "(empty)"), !i) return $("flowengage_search ✖ missing query"), "Missing query parameter.";
|
|
29474
29470
|
if (!t) return $("flowengage_search ✖ no siteId"), "Site is not configured for search.";
|
|
29475
29471
|
if (!n) return $("flowengage_search ✖ no api base"), "API base URL is missing; cannot search.";
|
|
29476
|
-
CO(`Searching${
|
|
29472
|
+
CO(`Searching${i ? ` for "${i}"` : ""}…`, { spinner: !0 });
|
|
29477
29473
|
try {
|
|
29478
29474
|
let e = `${n}/api/site-tools/search`;
|
|
29479
29475
|
$("flowengage_search → POST", e);
|
|
29480
|
-
let
|
|
29476
|
+
let r = await fetch(e, {
|
|
29481
29477
|
method: "POST",
|
|
29482
29478
|
headers: { "Content-Type": "application/json" },
|
|
29483
29479
|
body: JSON.stringify({
|
|
29484
29480
|
siteId: t,
|
|
29485
|
-
query:
|
|
29481
|
+
query: i,
|
|
29486
29482
|
currentUrl: typeof window < "u" ? window.location.href : ""
|
|
29487
29483
|
})
|
|
29488
|
-
}), a = await
|
|
29489
|
-
if ($("flowengage_search · HTTP",
|
|
29484
|
+
}), a = await r.json();
|
|
29485
|
+
if ($("flowengage_search · HTTP", r.status, "success:", a.success), !a.success) {
|
|
29490
29486
|
let e = a.error || "Search failed.";
|
|
29491
29487
|
return $("flowengage_search ✖", e), e;
|
|
29492
29488
|
}
|
|
29493
29489
|
let o = a.results || [];
|
|
29494
|
-
return $("flowengage_search ✓", `${o.length} result(s)`, o.slice(0, 3).map((e) => e?.url || e)), o.length ? `SEARCH_RESULTS: ${JSON.stringify(o)}. MANDATORY: Do NOT call
|
|
29490
|
+
return $("flowengage_search ✓", `${o.length} result(s)`, o.slice(0, 3).map((e) => e?.url || e)), o.length ? `SEARCH_RESULTS: ${JSON.stringify(o)}. MANDATORY: Do NOT call fwh-navigate-mvp now. Speak the answer from these results in 2-3 sentences. Then ask the visitor if they want to go to a relevant page — e.g. "Would you like me to take you to that page?" Only navigate if they say yes. NAVIGATION RULE: When navigating to a specific article, case study, blog post, or detail page — always use the most specific URL from the results (e.g. /case-study/cgs-detail), never the generic listing page (e.g. /case-study). If multiple URLs are in the results, pick the one whose path most closely matches the topic.` : "SEARCH_RESULTS: No results found. Answer from your knowledge base.";
|
|
29495
29491
|
} catch (e) {
|
|
29496
29492
|
let t = `Search error: ${e.message || "network"}`;
|
|
29497
29493
|
return $("flowengage_search ✖", t), t;
|
|
@@ -29499,15 +29495,15 @@ function Ck(e) {
|
|
|
29499
29495
|
wO(600);
|
|
29500
29496
|
}
|
|
29501
29497
|
},
|
|
29502
|
-
|
|
29503
|
-
$("
|
|
29498
|
+
"fwh-page-content-mvp": async (e) => {
|
|
29499
|
+
$("fwh-page-content-mvp ▶", e);
|
|
29504
29500
|
let r = mk(e), i = r?.url || r?.page_url || "";
|
|
29505
|
-
if ($("
|
|
29506
|
-
if (!t) return $("
|
|
29507
|
-
if (!n) return $("
|
|
29501
|
+
if ($("fwh-page-content-mvp · url:", i, "siteId:", t, "apiBase:", n || "(empty)"), !i) return $("fwh-page-content-mvp ✖ missing url"), "Missing url parameter.";
|
|
29502
|
+
if (!t) return $("fwh-page-content-mvp ✖ no siteId"), "Site is not configured.";
|
|
29503
|
+
if (!n) return $("fwh-page-content-mvp ✖ no api base"), "API base URL is missing; cannot fetch page content.";
|
|
29508
29504
|
try {
|
|
29509
29505
|
let e = `${n}/api/site-tools/page-content`;
|
|
29510
|
-
$("
|
|
29506
|
+
$("fwh-page-content-mvp → POST", e);
|
|
29511
29507
|
let r = await fetch(e, {
|
|
29512
29508
|
method: "POST",
|
|
29513
29509
|
headers: { "Content-Type": "application/json" },
|
|
@@ -29516,11 +29512,11 @@ function Ck(e) {
|
|
|
29516
29512
|
url: i
|
|
29517
29513
|
})
|
|
29518
29514
|
}), a = await r.json();
|
|
29519
|
-
if ($("
|
|
29515
|
+
if ($("fwh-page-content-mvp · HTTP", r.status, "success:", a.success), !a.success) {
|
|
29520
29516
|
let e = a.error || "Failed to get page content.";
|
|
29521
|
-
return $("
|
|
29517
|
+
return $("fwh-page-content-mvp ✖", e), `${e} FALLBACK REQUIRED: This page is not in the search index. Call fwh-read-content-mvp (no parameters) immediately to read the live page content directly from the visitor's browser — do NOT tell the visitor you cannot access the page.`;
|
|
29522
29518
|
}
|
|
29523
|
-
return $("
|
|
29519
|
+
return $("fwh-page-content-mvp ✓", `title: ${a.title}`, `sections: ${(a.sections || []).length}`, `content: ${(a.content || "").length} chars`), JSON.stringify({
|
|
29524
29520
|
title: a.title,
|
|
29525
29521
|
url: a.url,
|
|
29526
29522
|
sections: a.sections,
|
|
@@ -29528,36 +29524,60 @@ function Ck(e) {
|
|
|
29528
29524
|
});
|
|
29529
29525
|
} catch (e) {
|
|
29530
29526
|
let t = `Page content error: ${e.message || "network"}`;
|
|
29531
|
-
return $("
|
|
29527
|
+
return $("fwh-page-content-mvp ✖", t), t;
|
|
29532
29528
|
}
|
|
29533
29529
|
},
|
|
29534
|
-
|
|
29535
|
-
|
|
29536
|
-
|
|
29537
|
-
|
|
29538
|
-
return $("
|
|
29530
|
+
"fwh-search-mvp": async (e) => {
|
|
29531
|
+
$("fwh-search-mvp ▶", e);
|
|
29532
|
+
let r = mk(e).query;
|
|
29533
|
+
if (!r) return $("fwh-search-mvp ✖ missing query"), "Missing query parameter.";
|
|
29534
|
+
if (!t) return $("fwh-search-mvp ✖ no siteId"), "Search unavailable (no siteId configured).";
|
|
29535
|
+
if (!n) return $("fwh-search-mvp ✖ no api base"), "Search unavailable (no API base URL).";
|
|
29536
|
+
try {
|
|
29537
|
+
let e = `${n}/api/site-tools/search`;
|
|
29538
|
+
$("fwh-search-mvp → POST", e);
|
|
29539
|
+
let i = await fetch(e, {
|
|
29540
|
+
method: "POST",
|
|
29541
|
+
headers: { "Content-Type": "application/json" },
|
|
29542
|
+
body: JSON.stringify({
|
|
29543
|
+
siteId: t,
|
|
29544
|
+
query: r
|
|
29545
|
+
})
|
|
29546
|
+
}), a = await i.json();
|
|
29547
|
+
if ($("fwh-search-mvp · HTTP", i.status, "success:", a.success), !a.success || !a.results?.length) return "No results found for that query. Try rephrasing, or use fwh-read-content-mvp to read the current page.";
|
|
29548
|
+
let o = a.results.slice(0, 5).map((e, t) => `${t + 1}. ${e.title || e.url} (${e.url})${e.snippet ? ` — ${e.snippet}` : ""}`).join("\n");
|
|
29549
|
+
return $("fwh-search-mvp ✓", `${a.results.length} result(s)`), `SEARCH_RESULTS:\n${o}`;
|
|
29550
|
+
} catch (e) {
|
|
29551
|
+
return $("fwh-search-mvp ✖", e.message), "Search failed. Use fwh-read-content-mvp to read the current page instead.";
|
|
29552
|
+
}
|
|
29553
|
+
},
|
|
29554
|
+
"fwh-end-session-mvp": async () => ($("fwh-end-session-mvp ▶"), typeof e.requestEndSession == "function" && e.requestEndSession(), "Voice session is ending."),
|
|
29555
|
+
"fwh-get-current-page-mvp": async () => {
|
|
29556
|
+
if ($("fwh-get-current-page-mvp ▶"), typeof window > "u") return "Cannot determine current page (no browser context).";
|
|
29557
|
+
let e = window.location.href, t = window.location.pathname, n = document.title || "", r = xk();
|
|
29558
|
+
return $("fwh-get-current-page-mvp ✓", {
|
|
29539
29559
|
url: e,
|
|
29540
29560
|
path: t,
|
|
29541
29561
|
title: n
|
|
29542
|
-
}), $("
|
|
29562
|
+
}), $("fwh-get-current-page-mvp → page headings collected:", r), r.length ? `CURRENT_PAGE. URL: ${e} | Title: ${n} | Headings in order: ${r.map((e, t) => `${t + 1}. "${e}"`).join(", ")}. *** DO NOT call this tool again — you now have everything you need. If the visitor requested a walkthrough: START IT NOW. Use the pattern: "[transition]." + fwh-highlight-mvp("exact heading") + "[description]." for EVERY section above. If no walkthrough was requested: give 1-2 sentences about the page and stop. ***` : `CURRENT_PAGE. URL: ${e} | Title: ${n} | No headings found on this page. Describe the page from your knowledge without calling this tool again.`;
|
|
29543
29563
|
},
|
|
29544
|
-
|
|
29564
|
+
"fwh-list-forms-mvp": async () => {
|
|
29545
29565
|
let e = XO(), t = ZO();
|
|
29546
|
-
return $("
|
|
29566
|
+
return $("fwh-list-forms-mvp ✓", `${e.length} field(s)`, `${t.length} button(s)`), JSON.stringify({
|
|
29547
29567
|
fields: e,
|
|
29548
29568
|
buttons: t,
|
|
29549
|
-
hint: "field_key: placeholder/label, name (e.g. url), id (e.g. url-input). If the page has two URL boxes,
|
|
29569
|
+
hint: "field_key: placeholder/label, name (e.g. url), id (e.g. url-input). If the page has two URL boxes, fwh-fill-form-mvp sets all matching URL inputs. fwh-click-button-mvp picks the Conduct Audit nearest the filled field when labels duplicate."
|
|
29550
29570
|
});
|
|
29551
29571
|
},
|
|
29552
|
-
|
|
29572
|
+
"fwh-fill-form-mvp": async (e) => {
|
|
29553
29573
|
try {
|
|
29554
|
-
$("
|
|
29574
|
+
$("fwh-fill-form-mvp ▶ raw:", e), AO();
|
|
29555
29575
|
let t = hk(e);
|
|
29556
29576
|
if (!t.length && r) {
|
|
29557
29577
|
let e = r(), n = gk(e);
|
|
29558
|
-
n.length ? $("
|
|
29578
|
+
n.length ? $("fwh-fill-form-mvp · inferred URL from last user utterance (model omitted usable fields):", n) : (n = _k(e), n.length && $("fwh-fill-form-mvp · inferred contact fields from last user utterance (empty tool params):", n)), n.length && (t = n);
|
|
29559
29579
|
}
|
|
29560
|
-
if ($("
|
|
29580
|
+
if ($("fwh-fill-form-mvp · normalized fields:", t), !t.length) return "No fields provided. Call fwh-list-forms-mvp for field_key strings, then fwh-fill-form-mvp with { \"fields\": [ { \"field_key\": \"<label or placeholder from list>\", \"value\": \"<user value>\" } ] }. Never use empty {}. Pass the value the user just said (email, message, name, URL) in fields.";
|
|
29561
29581
|
let n = [];
|
|
29562
29582
|
for (let e of t) {
|
|
29563
29583
|
let t = e?.field_key, r = e?.value;
|
|
@@ -29565,23 +29585,23 @@ function Ck(e) {
|
|
|
29565
29585
|
CO(`Filling ${String(t)}...`, { spinner: !0 });
|
|
29566
29586
|
let a = YO(), o = ck(a, String(t), r);
|
|
29567
29587
|
if (o.length) {
|
|
29568
|
-
for (let [e, t] of o.entries()) jO(t), await LO(t),
|
|
29588
|
+
for (let [e, t] of o.entries()) jO(t), await LO(t), yk(t, r, { skipScroll: e > 0 }), MO(t), await HO(120);
|
|
29569
29589
|
i = o, n.push(String(t));
|
|
29570
29590
|
continue;
|
|
29571
29591
|
}
|
|
29572
29592
|
let s = dk(a, String(t));
|
|
29573
|
-
s ||= nk(a, String(t)), s ||= rk(a, String(t), r), s && (jO(s), await LO(s),
|
|
29593
|
+
s ||= nk(a, String(t)), s ||= rk(a, String(t), r), s && (jO(s), await LO(s), yk(s, r), MO(s), await HO(120), i = [s], n.push(String(t)));
|
|
29574
29594
|
}
|
|
29575
|
-
if (!n.length) return $("
|
|
29595
|
+
if (!n.length) return $("fwh-fill-form-mvp ✖ no matches"), "Could not match any fields. Call fwh-list-forms-mvp and use field_key values that match placeholder, label, name, or id (e.g. Enter Website URL). Ensure the form is on the page, not the chat panel.";
|
|
29576
29596
|
let a = `OK_FILLED: ${n.join(", ")}`;
|
|
29577
|
-
return $("
|
|
29597
|
+
return $("fwh-fill-form-mvp ✓", a), CO("Form filled", {
|
|
29578
29598
|
spinner: !1,
|
|
29579
29599
|
icon: "✅",
|
|
29580
29600
|
duration: 1100
|
|
29581
29601
|
}), a;
|
|
29582
29602
|
} catch (e) {
|
|
29583
|
-
let t = `
|
|
29584
|
-
return $("
|
|
29603
|
+
let t = `fwh-fill-form-mvp error: ${e?.message || String(e)}`;
|
|
29604
|
+
return $("fwh-fill-form-mvp ✖", t), CO("Failed to fill form", {
|
|
29585
29605
|
spinner: !1,
|
|
29586
29606
|
icon: "⚠️",
|
|
29587
29607
|
duration: 1800
|
|
@@ -29590,11 +29610,11 @@ function Ck(e) {
|
|
|
29590
29610
|
RO(), AO(), wO(700);
|
|
29591
29611
|
}
|
|
29592
29612
|
},
|
|
29593
|
-
|
|
29613
|
+
"fwh-click-button-mvp": async (e) => {
|
|
29594
29614
|
let t = mk(e), n = (t.button_text ?? t.buttonText ?? t.text ?? "").trim();
|
|
29595
|
-
if ($("
|
|
29615
|
+
if ($("fwh-click-button-mvp ▶", n), !n) return "Missing button_text: pass the visible label, e.g. Conduct Audit.";
|
|
29596
29616
|
let r = pk(n, i);
|
|
29597
|
-
if (!r) return $("
|
|
29617
|
+
if (!r) return $("fwh-click-button-mvp ✖ no match"), `Could not find a button matching "${n}". Call fwh-list-forms-mvp to see button texts.`;
|
|
29598
29618
|
try {
|
|
29599
29619
|
CO(`Clicking ${n}...`, { spinner: !0 });
|
|
29600
29620
|
try {
|
|
@@ -29607,14 +29627,14 @@ function Ck(e) {
|
|
|
29607
29627
|
}
|
|
29608
29628
|
await LO(r), r.focus?.(), await zO(r), BO(r), r.click();
|
|
29609
29629
|
let e = (r.textContent || r.value || r.getAttribute("aria-label") || "").trim().slice(0, 80) || "button", t = `OK_CLICK ${e}`;
|
|
29610
|
-
return $("
|
|
29630
|
+
return $("fwh-click-button-mvp ✓", t), CO(`Clicked ${e}`, {
|
|
29611
29631
|
spinner: !1,
|
|
29612
29632
|
icon: "✅",
|
|
29613
29633
|
duration: 1200
|
|
29614
29634
|
}), t;
|
|
29615
29635
|
} catch (e) {
|
|
29616
29636
|
let t = `Click failed: ${e?.message || String(e)}`;
|
|
29617
|
-
return $("
|
|
29637
|
+
return $("fwh-click-button-mvp ✖", t), CO("Click failed", {
|
|
29618
29638
|
spinner: !1,
|
|
29619
29639
|
icon: "⚠️",
|
|
29620
29640
|
duration: 1800
|
|
@@ -29626,18 +29646,17 @@ function Ck(e) {
|
|
|
29626
29646
|
};
|
|
29627
29647
|
return {
|
|
29628
29648
|
...a,
|
|
29629
|
-
highlightOnPage: a
|
|
29630
|
-
|
|
29631
|
-
|
|
29632
|
-
|
|
29633
|
-
|
|
29634
|
-
|
|
29635
|
-
clickPageButton: a.flowengage_click_button
|
|
29649
|
+
highlightOnPage: a["fwh-highlight-mvp"],
|
|
29650
|
+
getPageContent: a["fwh-page-content-mvp"],
|
|
29651
|
+
endVoiceSession: a["fwh-end-session-mvp"],
|
|
29652
|
+
listPageForms: a["fwh-list-forms-mvp"],
|
|
29653
|
+
fillFormFields: a["fwh-fill-form-mvp"],
|
|
29654
|
+
clickPageButton: a["fwh-click-button-mvp"]
|
|
29636
29655
|
};
|
|
29637
29656
|
}
|
|
29638
29657
|
//#endregion
|
|
29639
29658
|
//#region src/utils/wrapVoiceToolsForLogging.js
|
|
29640
|
-
function
|
|
29659
|
+
function Ck(e) {
|
|
29641
29660
|
return !e || typeof e != "object" ? e : Object.fromEntries(Object.entries(e).map(([e, t]) => [e, async (n) => {
|
|
29642
29661
|
let r = Rn();
|
|
29643
29662
|
r ? console.log("[FlowEngage:voice-tool] ▶", e, n) : console.info(`[FlowEngage] voice tool » ${e}`);
|
|
@@ -29654,7 +29673,7 @@ function wk(e) {
|
|
|
29654
29673
|
}
|
|
29655
29674
|
//#endregion
|
|
29656
29675
|
//#region src/components/FlowEngageWidget.jsx
|
|
29657
|
-
var
|
|
29676
|
+
var wk = {
|
|
29658
29677
|
blue: "#135bd8",
|
|
29659
29678
|
red: "#ef334b",
|
|
29660
29679
|
yellow: "#ffbd2e",
|
|
@@ -29662,7 +29681,7 @@ var Tk = {
|
|
|
29662
29681
|
highlight: "rgba(255,255,255,0.9)",
|
|
29663
29682
|
green: "#10b981"
|
|
29664
29683
|
};
|
|
29665
|
-
function
|
|
29684
|
+
function Tk(e) {
|
|
29666
29685
|
if (!Array.isArray(e) || e.length < 2) return "linear-gradient(145deg, #dce8f022 0%, #e8dff522 45%, #f5e0e022 100%), #f7f8fa";
|
|
29667
29686
|
let [t, n, r] = e;
|
|
29668
29687
|
return e.length >= 3 && r ? [
|
|
@@ -29676,12 +29695,12 @@ function Ek(e) {
|
|
|
29676
29695
|
"#f7f8fa"
|
|
29677
29696
|
].join(", ");
|
|
29678
29697
|
}
|
|
29679
|
-
function
|
|
29698
|
+
function Ek(e) {
|
|
29680
29699
|
if (!e || typeof e != "string") return "#1a1a1a";
|
|
29681
29700
|
let t = e.replace("#", ""), n = t.length === 3 ? t.split("").map((e) => e + e).join("") : t, r = parseInt(n.slice(0, 2), 16) / 255, i = parseInt(n.slice(2, 4), 16) / 255, a = parseInt(n.slice(4, 6), 16) / 255, o = (e) => e <= .04045 ? e / 12.92 : ((e + .055) / 1.055) ** 2.4;
|
|
29682
29701
|
return .2126 * o(r) + .7152 * o(i) + .0722 * o(a) > .179 ? "#1a1a1a" : "#ffffff";
|
|
29683
29702
|
}
|
|
29684
|
-
function
|
|
29703
|
+
function Dk(t) {
|
|
29685
29704
|
let [n, r] = e.useState(null), i = typeof t == "string" ? t.trim() : "";
|
|
29686
29705
|
return e.useEffect(() => {
|
|
29687
29706
|
if (!i) {
|
|
@@ -29699,8 +29718,8 @@ function Ok(t) {
|
|
|
29699
29718
|
};
|
|
29700
29719
|
}, [i]), n;
|
|
29701
29720
|
}
|
|
29702
|
-
function
|
|
29703
|
-
let r =
|
|
29721
|
+
function Ok({ logo: t, style: n }) {
|
|
29722
|
+
let r = Dk(typeof t == "string" ? t : null);
|
|
29704
29723
|
if (!t) return null;
|
|
29705
29724
|
if (typeof t == "string") return r ? /* @__PURE__ */ g("img", {
|
|
29706
29725
|
src: r,
|
|
@@ -29725,7 +29744,7 @@ function kk({ logo: t, style: n }) {
|
|
|
29725
29744
|
children: i
|
|
29726
29745
|
}) : null;
|
|
29727
29746
|
}
|
|
29728
|
-
function
|
|
29747
|
+
function kk({ title: e }) {
|
|
29729
29748
|
return /* @__PURE__ */ g("div", {
|
|
29730
29749
|
style: {
|
|
29731
29750
|
width: "100%",
|
|
@@ -29743,18 +29762,18 @@ function Ak({ title: e }) {
|
|
|
29743
29762
|
children: String(e || "FE").split(/\s+/).filter(Boolean).slice(0, 2).map((e) => e[0]?.toUpperCase() || "").join("") || "FE"
|
|
29744
29763
|
});
|
|
29745
29764
|
}
|
|
29746
|
-
function
|
|
29765
|
+
function Ak(e, t) {
|
|
29747
29766
|
let n = (t || "").trim();
|
|
29748
29767
|
return n ? !!(/\b(let'?s|let us)\s+(end|stop|finish|wrap up|close)\s+(the\s+)?(voice\s+)?(session|call|chat)\b/i.test(n) || /\bend\s+(this\s+)?(the\s+)?(voice\s+)?(session|call|chat)\b/i.test(n) || /\b(hang\s+up|disconnect)\b/i.test(n) || /\b(that'?s all|we'?re done)\b/i.test(n) || e === "bot" && (/\b(I'?ll|I will|Let me|I can|I'?m going to)\s+(end|close)\s+(the\s+)?(voice\s+)?(session|call)\b/i.test(n) || /\b(ending|closing)\s+(the\s+)?(voice\s+)?session\b|\bvoice\s+session\s+(is\s+)?(now\s+)?(ended|over|closing)\b/i.test(n) || /\b(session|call)\s+(is\s+)?(now\s+)?(ended|over)\b/i.test(n) || /\bwe\s+can\s+end\s+(the\s+)?(session|call)?\s*(here|now)\b/i.test(n) || /\b(wrapping\s+up|signing\s+off)\b/i.test(n)) || /^(goodbye|bye|that'?s all|we'?re done|hang up|disconnect)\b/i.test(n)) : !1;
|
|
29749
29768
|
}
|
|
29750
|
-
function
|
|
29769
|
+
function jk({ orbColors: e, ...t }) {
|
|
29751
29770
|
return /* @__PURE__ */ g(lO, {
|
|
29752
29771
|
colors: e,
|
|
29753
29772
|
...t
|
|
29754
29773
|
});
|
|
29755
29774
|
}
|
|
29756
|
-
function
|
|
29757
|
-
let s = n ||
|
|
29775
|
+
function Mk({ copy: e, orbColors: t, primaryColor: n, onYes: r, onLater: i, isMobile: a, isClosing: o }) {
|
|
29776
|
+
let s = n || wk.green, c = Ek(s), l = a ? 72 : 94, u = /* @__PURE__ */ _("div", {
|
|
29758
29777
|
style: {
|
|
29759
29778
|
display: "flex",
|
|
29760
29779
|
alignItems: a ? "flex-end" : "center",
|
|
@@ -29875,7 +29894,7 @@ function Nk({ copy: e, orbColors: t, primaryColor: n, onYes: r, onLater: i, isMo
|
|
|
29875
29894
|
delay: 0
|
|
29876
29895
|
},
|
|
29877
29896
|
style: { flexShrink: 0 },
|
|
29878
|
-
children: /* @__PURE__ */ g(
|
|
29897
|
+
children: /* @__PURE__ */ g(jk, {
|
|
29879
29898
|
size: l,
|
|
29880
29899
|
orbColors: t
|
|
29881
29900
|
})
|
|
@@ -29907,8 +29926,8 @@ function Nk({ copy: e, orbColors: t, primaryColor: n, onYes: r, onLater: i, isMo
|
|
|
29907
29926
|
children: u
|
|
29908
29927
|
})] });
|
|
29909
29928
|
}
|
|
29910
|
-
function
|
|
29911
|
-
let c = n ||
|
|
29929
|
+
function Nk({ copy: e, orbColors: t, primaryColor: n, onVoice: r, onText: i, onClose: a, isMobile: o, isClosing: s }) {
|
|
29930
|
+
let c = n || wk.green, l = Ek(c);
|
|
29912
29931
|
return /* @__PURE__ */ _(Dm.div, {
|
|
29913
29932
|
initial: {
|
|
29914
29933
|
scale: 50 / 350,
|
|
@@ -29979,7 +29998,7 @@ function Pk({ copy: e, orbColors: t, primaryColor: n, onVoice: r, onText: i, onC
|
|
|
29979
29998
|
children: /* @__PURE__ */ g("polyline", { points: "6 9 12 15 18 9" })
|
|
29980
29999
|
})
|
|
29981
30000
|
}),
|
|
29982
|
-
/* @__PURE__ */ g(
|
|
30001
|
+
/* @__PURE__ */ g(jk, {
|
|
29983
30002
|
size: 72,
|
|
29984
30003
|
orbColors: t
|
|
29985
30004
|
}),
|
|
@@ -30048,13 +30067,17 @@ function Pk({ copy: e, orbColors: t, primaryColor: n, onVoice: r, onText: i, onC
|
|
|
30048
30067
|
]
|
|
30049
30068
|
});
|
|
30050
30069
|
}
|
|
30051
|
-
function
|
|
30052
|
-
|
|
30053
|
-
|
|
30054
|
-
|
|
30055
|
-
|
|
30056
|
-
|
|
30057
|
-
|
|
30070
|
+
function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i, apiBaseUrl: a, chatId: s, historyRef: l, onMessageSync: u, voiceEndCounter: d, websiteName: f }) {
|
|
30071
|
+
c(() => (console.log("[FlowEngage:VoiceDebug] 🔵 VoiceMode MOUNTED"), () => console.log("[FlowEngage:VoiceDebug] 🔴 VoiceMode UNMOUNTED")), []);
|
|
30072
|
+
let [h, v] = m("idle"), [y, b] = m(!1), [x, S] = m(!1), C = p(null), w = p(""), T = p(async () => {}), ee = p(!1), te = p(!1), ne = p(!1), re = p(!1), E = p("minimized"), ie = p(null), ae = p(null), oe = p(null), D = p(0), se = p(!1), ce = p("idle"), le = p(!1), ue = p(null), de = p(null), fe = p(!1), pe = o((e = "minimized") => {
|
|
30073
|
+
console.warn("[FlowEngage:VoiceDebug] 🛑 requestSessionShutdown called", {
|
|
30074
|
+
destination: e,
|
|
30075
|
+
stack: (/* @__PURE__ */ Error()).stack?.split("\n").slice(1, 4).join(" | ")
|
|
30076
|
+
}), E.current = e, re.current = !0, queueMicrotask(() => {
|
|
30077
|
+
ee.current || (ee.current = !0, T.current?.());
|
|
30078
|
+
});
|
|
30079
|
+
}, [l]), me = o(async (e) => {
|
|
30080
|
+
re.current = !0;
|
|
30058
30081
|
try {
|
|
30059
30082
|
SD();
|
|
30060
30083
|
} catch {}
|
|
@@ -30062,9 +30085,9 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30062
30085
|
He(i);
|
|
30063
30086
|
} catch {}
|
|
30064
30087
|
try {
|
|
30065
|
-
await
|
|
30088
|
+
await C.current?.endSession?.();
|
|
30066
30089
|
} catch {}
|
|
30067
|
-
let t =
|
|
30090
|
+
let t = ie.current, n = ae.current;
|
|
30068
30091
|
if (t && s && a) {
|
|
30069
30092
|
let e = n ? Math.round((Date.now() - n) / 1e3) : 0;
|
|
30070
30093
|
fetch(`${a}/api/voice/save-chat-recording`, {
|
|
@@ -30078,7 +30101,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30078
30101
|
})
|
|
30079
30102
|
}).catch((e) => console.warn("[FlowEngage] save-chat-recording failed:", e.message));
|
|
30080
30103
|
}
|
|
30081
|
-
if (
|
|
30104
|
+
if (ie.current = null, ae.current = null, C.current = null, v("idle"), b(!1), ee.current = !1, Ar(), i) try {
|
|
30082
30105
|
Me(i);
|
|
30083
30106
|
} catch {}
|
|
30084
30107
|
typeof u == "function" && await u(l.current), e?.();
|
|
@@ -30089,26 +30112,26 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30089
30112
|
s,
|
|
30090
30113
|
a
|
|
30091
30114
|
]);
|
|
30092
|
-
return
|
|
30093
|
-
|
|
30094
|
-
}, [
|
|
30095
|
-
d &&
|
|
30115
|
+
return T.current = () => me(E.current === "chat" ? t : n), c(() => {
|
|
30116
|
+
te.current = y;
|
|
30117
|
+
}, [y]), c(() => {
|
|
30118
|
+
d && pe("chat");
|
|
30096
30119
|
}, [d]), c(() => {
|
|
30097
30120
|
let e = !1, o = null, c = null, d = null;
|
|
30098
30121
|
return (async () => {
|
|
30099
30122
|
if (!r) {
|
|
30100
|
-
|
|
30123
|
+
v("error");
|
|
30101
30124
|
return;
|
|
30102
30125
|
}
|
|
30103
30126
|
try {
|
|
30104
30127
|
if ((await navigator.mediaDevices.getUserMedia({ audio: !0 })).getTracks().forEach((e) => e.stop()), e) return;
|
|
30105
|
-
l.current = [],
|
|
30128
|
+
l.current = [], w.current = "", ee.current = !1, ne.current = !1, re.current = !1, E.current = "minimized", kr({ onBeforeNavigate: () => {
|
|
30106
30129
|
if (i && l.current.length > 0) try {
|
|
30107
30130
|
let e = vO(l.current);
|
|
30108
30131
|
e && Ae(i, e);
|
|
30109
30132
|
} catch {}
|
|
30110
30133
|
if (!er()) {
|
|
30111
|
-
let e =
|
|
30134
|
+
let e = ie.current, t = ae.current;
|
|
30112
30135
|
if (e && s && a) try {
|
|
30113
30136
|
let n = t ? Math.round((Date.now() - t) / 1e3) : 0, r = JSON.stringify({
|
|
30114
30137
|
chatId: s,
|
|
@@ -30121,19 +30144,19 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30121
30144
|
headers: { "Content-Type": "application/json" },
|
|
30122
30145
|
body: r,
|
|
30123
30146
|
keepalive: !0
|
|
30124
|
-
}).catch(() => {}),
|
|
30147
|
+
}).catch(() => {}), ie.current = null, ae.current = null;
|
|
30125
30148
|
} catch {}
|
|
30126
30149
|
}
|
|
30127
30150
|
Pe();
|
|
30128
30151
|
} });
|
|
30129
|
-
let t =
|
|
30152
|
+
let t = Ck(Sk({
|
|
30130
30153
|
siteId: i || null,
|
|
30131
30154
|
apiBaseUrl: a || null,
|
|
30132
|
-
getLastUserVoiceText: () =>
|
|
30155
|
+
getLastUserVoiceText: () => w.current,
|
|
30133
30156
|
requestEndSession: () => {
|
|
30134
|
-
|
|
30157
|
+
se.current = !0;
|
|
30135
30158
|
}
|
|
30136
|
-
})), n = i ? je(i) : null, u = !!n?.transcript,
|
|
30159
|
+
})), n = i ? je(i) : null, u = !!n?.transcript, p = !!(i && He(i)), m = typeof window < "u" ? window.location.pathname : "/", h = typeof document < "u" ? document.title : "", g = m === "/" || m === "", _ = null;
|
|
30137
30160
|
try {
|
|
30138
30161
|
let e = await fetch(`${a}/api/voice/signed-url?siteId=${encodeURIComponent(i || "")}`, {
|
|
30139
30162
|
method: "GET",
|
|
@@ -30148,39 +30171,51 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30148
30171
|
if (e.message && e.message.includes("Too many voice sessions")) throw e;
|
|
30149
30172
|
console.warn("[FlowEngage] ⚠️ Signed URL fetch error:", e.message);
|
|
30150
30173
|
}
|
|
30151
|
-
let
|
|
30174
|
+
let y = {
|
|
30152
30175
|
clientTools: t,
|
|
30153
30176
|
connectionType: "websocket",
|
|
30154
30177
|
minSpeechDurationMs: 50,
|
|
30155
30178
|
..._ ? { signedUrl: _ } : { agentId: r }
|
|
30156
|
-
},
|
|
30157
|
-
|
|
30158
|
-
let
|
|
30159
|
-
_
|
|
30160
|
-
|
|
30161
|
-
|
|
30179
|
+
}, x = (m.split("/").filter(Boolean).pop() || "").replace(/[-_]/g, " ").replace(/\b\w/g, (e) => e.toUpperCase()), S = "";
|
|
30180
|
+
h && h.includes("|") && (S = h.split("|").map((e) => e.trim()).filter(Boolean).reduce((e, t) => e.length <= t.length ? e : t));
|
|
30181
|
+
let T = S || x || "this page";
|
|
30182
|
+
if (_) if (p) y.overrides = { agent: { firstMessage: `Here we are — I've taken you to the ${T} page.` } }, console.log(`[FlowEngage] 🔄 Agent-nav resume: firstMessage set for "${T}" (${m})`);
|
|
30183
|
+
else if (u) y.overrides = { agent: { firstMessage: "I'm still here. Go ahead!" } };
|
|
30184
|
+
else {
|
|
30185
|
+
let e = f || "";
|
|
30186
|
+
y.overrides = { agent: { firstMessage: g ? e ? `Hi, welcome to ${e}!` : "Hi, welcome!" : `Welcome to the ${T} page!` } }, g || console.log(`[FlowEngage] 🏠 Page-context override: "${T}" for ${m}`);
|
|
30187
|
+
}
|
|
30188
|
+
else u && (y.overrides = { agent: { firstMessage: "" } });
|
|
30189
|
+
let oe = !1, me = p ? "NAVIGATION COMPLETE — Your brief intro has been spoken. Now speak 2-3 sentences about this page from your knowledge. Then ask the visitor exactly this: \"Would you like to know about a specific section, or should I give you a complete overview?\" Then STOP — wait for their reply. Do NOT auto-highlight or auto-walkthrough." : null, he = !1, ge = !p && !u ? "Your greeting has been spoken. Wait for the visitor to ask a question or tell you what they need. Do NOT auto-start a walkthrough or highlight any sections — let the visitor lead." : null, _e = await vD.startSession({
|
|
30190
|
+
...y,
|
|
30162
30191
|
onConnect: ({ conversationId: e }) => {
|
|
30163
|
-
|
|
30192
|
+
ie.current = e, ae.current = Date.now(), console.log("[FlowEngage] 🎙️ AI chat session connected:", e);
|
|
30164
30193
|
},
|
|
30165
30194
|
onUnhandledClientToolCall: (e) => console.error("[FlowEngage] Unhandled tool:", e?.tool_name),
|
|
30166
30195
|
onModeChange: ({ mode: t }) => {
|
|
30167
30196
|
if (!e) {
|
|
30168
30197
|
if (t === "speaking") {
|
|
30169
|
-
|
|
30198
|
+
de.current &&= (clearTimeout(de.current), null), v("speaking"), ce.current = "speaking", le.current = !0, fe.current = !1, ue.current &&= (clearTimeout(ue.current), null);
|
|
30170
30199
|
return;
|
|
30171
30200
|
}
|
|
30172
|
-
if (
|
|
30173
|
-
|
|
30201
|
+
if (ce.current = "listening", se.current) {
|
|
30202
|
+
se.current = !1, pe();
|
|
30174
30203
|
return;
|
|
30175
30204
|
}
|
|
30176
|
-
if (
|
|
30177
|
-
|
|
30205
|
+
if (me && !oe) {
|
|
30206
|
+
oe = !0;
|
|
30178
30207
|
try {
|
|
30179
|
-
|
|
30208
|
+
C.current?.sendContextualUpdate?.(me);
|
|
30180
30209
|
} catch {}
|
|
30181
30210
|
}
|
|
30182
|
-
|
|
30183
|
-
|
|
30211
|
+
if (ge && !he) {
|
|
30212
|
+
he = !0;
|
|
30213
|
+
try {
|
|
30214
|
+
C.current?.sendContextualUpdate?.(ge);
|
|
30215
|
+
} catch {}
|
|
30216
|
+
}
|
|
30217
|
+
de.current && clearTimeout(de.current), de.current = setTimeout(() => {
|
|
30218
|
+
e || ce.current !== "speaking" && (fe.current || (de.current = null, ce.current = "listening", v("listening")));
|
|
30184
30219
|
}, 1200);
|
|
30185
30220
|
}
|
|
30186
30221
|
},
|
|
@@ -30188,7 +30223,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30188
30223
|
if (e) return;
|
|
30189
30224
|
let n = t.role === "user" ? "user" : "bot", r = t.message || t.text || t.content || "";
|
|
30190
30225
|
if (r) {
|
|
30191
|
-
if (n === "user" && (
|
|
30226
|
+
if (n === "user" && (w.current = r, fe.current = !0, de.current &&= (clearTimeout(de.current), null), ue.current &&= (clearTimeout(ue.current), null)), l.current = [...l.current, {
|
|
30192
30227
|
sender: n,
|
|
30193
30228
|
message: r,
|
|
30194
30229
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -30196,63 +30231,63 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30196
30231
|
let e = vO(l.current);
|
|
30197
30232
|
e && Ae(i, e);
|
|
30198
30233
|
} catch {}
|
|
30199
|
-
if (
|
|
30200
|
-
|
|
30234
|
+
if (Ak(n, r)) {
|
|
30235
|
+
se.current = !0;
|
|
30201
30236
|
return;
|
|
30202
30237
|
}
|
|
30203
|
-
if (
|
|
30204
|
-
|
|
30238
|
+
if (te.current && n === "bot" && /are you still there|still there\??|hello\?|anyone there|checking in|you there|are you available|is anyone|did you step away/i.test(r)) if (D.current += 1, D.current === 2) try {
|
|
30239
|
+
C.current?.sendContextualUpdate?.("IMPORTANT: The visitor is muted and has not responded to your last 2 checks. Make exactly ONE more check. If there is still no response, say: 'I feel like you are not active, so I'm ending this session. You can connect with me anytime.' then immediately call the fwh-end-session-mvp tool to end the voice session. Do NOT ask again after that.");
|
|
30205
30240
|
} catch {}
|
|
30206
|
-
else
|
|
30241
|
+
else D.current >= 5 && pe("minimized");
|
|
30207
30242
|
}
|
|
30208
30243
|
},
|
|
30209
30244
|
onError: (t) => {
|
|
30210
|
-
if (!e && !
|
|
30211
|
-
|
|
30245
|
+
if (!e && !re.current && !ne.current && !ze()) {
|
|
30246
|
+
ne.current = !0, console.error("[FlowEngageVoiceCall] session:error", {
|
|
30212
30247
|
message: t?.message,
|
|
30213
30248
|
name: t?.name,
|
|
30214
30249
|
raw: t
|
|
30215
30250
|
});
|
|
30216
30251
|
try {
|
|
30217
|
-
|
|
30252
|
+
C.current?.setMicMuted?.(!0);
|
|
30218
30253
|
} catch {}
|
|
30219
|
-
|
|
30254
|
+
b(!0), v("error"), pe("chat");
|
|
30220
30255
|
}
|
|
30221
30256
|
},
|
|
30222
30257
|
onDisconnect: (t) => {
|
|
30223
|
-
if (e ||
|
|
30258
|
+
if (e || re.current || ne.current || ze()) return;
|
|
30224
30259
|
let n = l.current?.length || 0;
|
|
30225
30260
|
console.warn("[FlowEngageVoiceCall] session:disconnected", {
|
|
30226
30261
|
historyCount: n,
|
|
30227
30262
|
reason: t?.reason,
|
|
30228
30263
|
closeCode: t?.context?.code,
|
|
30229
30264
|
closeReason: t?.context?.reason || t?.message,
|
|
30230
|
-
lastUserText:
|
|
30231
|
-
wasMuted:
|
|
30232
|
-
}),
|
|
30265
|
+
lastUserText: w.current || "",
|
|
30266
|
+
wasMuted: te.current
|
|
30267
|
+
}), ne.current = !0;
|
|
30233
30268
|
try {
|
|
30234
|
-
|
|
30269
|
+
C.current?.setMicMuted?.(!0);
|
|
30235
30270
|
} catch {}
|
|
30236
|
-
|
|
30271
|
+
b(!0), pe("chat");
|
|
30237
30272
|
}
|
|
30238
30273
|
});
|
|
30239
30274
|
if (e) {
|
|
30240
|
-
|
|
30275
|
+
console.warn("[FlowEngage:VoiceDebug] ❌ cancelled=true after startSession resolved — killing session immediately"), _e.endSession().catch(() => {});
|
|
30241
30276
|
return;
|
|
30242
30277
|
}
|
|
30243
|
-
o =
|
|
30278
|
+
o = _e, C.current = _e, v("listening");
|
|
30244
30279
|
try {
|
|
30245
30280
|
let e = typeof window < "u" ? window.location.href : "", r = "[]";
|
|
30246
30281
|
try {
|
|
30247
|
-
r = await t
|
|
30282
|
+
r = await t["fwh-list-forms-mvp"]();
|
|
30248
30283
|
} catch {}
|
|
30249
30284
|
let a = "none";
|
|
30250
30285
|
if (typeof window < "u" && typeof document < "u") try {
|
|
30251
30286
|
let e = "#flowengage-root, .flowengage-shell, .flowengage-widget-root", t = document.querySelector("main, [role='main']") || document.body, n = Array.from(t.querySelectorAll("h1, h2, h3")).filter((t) => !t.closest(e)).map((e) => e.textContent.replace(/\s+/g, " ").trim()).filter((e) => e.length > 2 && e.length < 200);
|
|
30252
30287
|
n.length || (n = Array.from(document.body.querySelectorAll("h1, h2, h3")).filter((t) => !t.closest(e)).map((e) => e.textContent.replace(/\s+/g, " ").trim()).filter((e) => e.length > 2 && e.length < 200)), n.length && (a = [...new Set(n)].slice(0, 15).join(" | "));
|
|
30253
30288
|
} catch {}
|
|
30254
|
-
let o = u && !
|
|
30255
|
-
|
|
30289
|
+
let o = u && !p ? `RESUMING PRIOR SESSION — DO NOT GREET. The visitor is continuing the same conversation after a page reload. Do not introduce yourself or re-state your capabilities. Wait silently until the visitor speaks; if you must speak first, briefly acknowledge where you left off in one short sentence.\nPrior transcript:\n${n?.transcript || ""}\n\n` : "";
|
|
30290
|
+
_e.sendContextualUpdate(`${o}CURRENT PAGE: ${e} | Section headings: ${a}. SiteId: ${i || "unknown"}. Forms: ${r}. The visitor is ALREADY on this page — do NOT offer to navigate there. Voice: call end_voice_session or say you are ending the session to stop.`);
|
|
30256
30291
|
} catch {}
|
|
30257
30292
|
if (typeof window < "u") {
|
|
30258
30293
|
let t = window.location.pathname, n = () => {
|
|
@@ -30281,7 +30316,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30281
30316
|
ts: Date.now()
|
|
30282
30317
|
});
|
|
30283
30318
|
try {
|
|
30284
|
-
|
|
30319
|
+
C.current?.sendUserMessage?.(`[SYSTEM: I navigated away mid-walkthrough — I am now on the "${l}" page (${i}). Page title: "${a}". Sections: ${JSON.stringify(o)}. STOP everything. Do NOT describe the new page. Say EXACTLY: "I see you've navigated to the ${l} page — would you like me to continue what I was explaining, or shall I walk you through this page?" Then wait for my answer. IF I say continue/yes/carry on: resume speaking verbally from where you left off — do NOT call flowengage_navigate, do NOT call flowengage_highlight, the visitor will navigate themselves if needed. IF I want to hear about this page: call flowengage_highlight for sections of "${l}" only.]`);
|
|
30285
30320
|
} catch {}
|
|
30286
30321
|
};
|
|
30287
30322
|
c = window.history.pushState.bind(window.history), window.history.pushState = (...e) => {
|
|
@@ -30289,33 +30324,37 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30289
30324
|
}, d = () => setTimeout(n, 50), window.addEventListener("popstate", d);
|
|
30290
30325
|
}
|
|
30291
30326
|
} catch (r) {
|
|
30292
|
-
e || (console.error("[FlowEngage] startSession failed", r), r.message && r.message.includes("Too many voice sessions") ? (alert(r.message), n && n("minimized")) : (
|
|
30327
|
+
e || (console.error("[FlowEngage] startSession failed", r), r.message && r.message.includes("Too many voice sessions") ? (alert(r.message), n && n("minimized")) : (v("error"), E.current = "chat", window.setTimeout(() => {
|
|
30293
30328
|
e || t?.();
|
|
30294
30329
|
}, 0)));
|
|
30295
30330
|
}
|
|
30296
30331
|
})(), () => {
|
|
30297
|
-
|
|
30332
|
+
console.warn("[FlowEngage:VoiceDebug] ⚠️ useEffect CLEANUP fired — session will be killed", {
|
|
30333
|
+
agentId: r,
|
|
30334
|
+
siteId: i,
|
|
30335
|
+
apiBaseUrl: a
|
|
30336
|
+
}), e = !0, re.current = !0;
|
|
30298
30337
|
try {
|
|
30299
30338
|
SD();
|
|
30300
30339
|
} catch {}
|
|
30301
30340
|
if (i) try {
|
|
30302
30341
|
He(i);
|
|
30303
30342
|
} catch {}
|
|
30304
|
-
typeof window < "u" && (window.__fe_user_nav_during_speech = null), Ar(),
|
|
30305
|
-
let t = o ||
|
|
30343
|
+
typeof window < "u" && (window.__fe_user_nav_during_speech = null), Ar(), ue.current &&= (clearTimeout(ue.current), null), de.current &&= (clearTimeout(de.current), null), le.current = !1, fe.current = !1, ce.current = "idle", c && typeof window < "u" && (window.history.pushState = c), d && typeof window < "u" && window.removeEventListener("popstate", d);
|
|
30344
|
+
let t = o || C.current, n = ie.current, f = ae.current;
|
|
30306
30345
|
if (t?.endSession?.().catch(() => {}), n && s && a) {
|
|
30307
|
-
let e =
|
|
30346
|
+
let e = f ? Math.round((Date.now() - f) / 1e3) : 0, t = JSON.stringify({
|
|
30308
30347
|
chatId: s,
|
|
30309
30348
|
elevenLabsConversationId: n,
|
|
30310
30349
|
duration: e,
|
|
30311
30350
|
siteId: i
|
|
30312
|
-
}),
|
|
30313
|
-
typeof navigator < "u" && navigator.sendBeacon && navigator.sendBeacon(
|
|
30351
|
+
}), r = `${a}/api/voice/save-chat-recording`;
|
|
30352
|
+
typeof navigator < "u" && navigator.sendBeacon && navigator.sendBeacon(r, new Blob([t], { type: "application/json" })) || fetch(r, {
|
|
30314
30353
|
method: "POST",
|
|
30315
30354
|
headers: { "Content-Type": "application/json" },
|
|
30316
30355
|
body: t,
|
|
30317
30356
|
keepalive: !0
|
|
30318
|
-
}).catch(() => {}),
|
|
30357
|
+
}).catch(() => {}), ie.current = null, ae.current = null;
|
|
30319
30358
|
}
|
|
30320
30359
|
typeof u == "function" && l.current.length > 0 && u(l.current).catch?.(() => {});
|
|
30321
30360
|
};
|
|
@@ -30323,16 +30362,16 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30323
30362
|
r,
|
|
30324
30363
|
i,
|
|
30325
30364
|
a,
|
|
30326
|
-
|
|
30365
|
+
pe
|
|
30327
30366
|
]), c(() => {
|
|
30328
|
-
if (!
|
|
30367
|
+
if (!x) return;
|
|
30329
30368
|
let e = (e) => {
|
|
30330
30369
|
let t = e.composedPath?.()?.[0] || e.target;
|
|
30331
|
-
|
|
30370
|
+
oe.current && !oe.current.contains(t) && S(!1);
|
|
30332
30371
|
};
|
|
30333
30372
|
return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
|
|
30334
|
-
}, [
|
|
30335
|
-
ref:
|
|
30373
|
+
}, [x]), /* @__PURE__ */ _("div", {
|
|
30374
|
+
ref: oe,
|
|
30336
30375
|
style: {
|
|
30337
30376
|
position: "relative",
|
|
30338
30377
|
display: "flex",
|
|
@@ -30345,7 +30384,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30345
30384
|
/* @__PURE__ */ _("div", {
|
|
30346
30385
|
style: { position: "relative" },
|
|
30347
30386
|
children: [
|
|
30348
|
-
|
|
30387
|
+
h === "listening" && !y && /* @__PURE__ */ g("span", {
|
|
30349
30388
|
style: {
|
|
30350
30389
|
position: "absolute",
|
|
30351
30390
|
right: "100%",
|
|
@@ -30361,7 +30400,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30361
30400
|
},
|
|
30362
30401
|
children: "Listening..."
|
|
30363
30402
|
}),
|
|
30364
|
-
|
|
30403
|
+
y && /* @__PURE__ */ g("span", {
|
|
30365
30404
|
style: {
|
|
30366
30405
|
position: "absolute",
|
|
30367
30406
|
right: "100%",
|
|
@@ -30377,15 +30416,15 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30377
30416
|
},
|
|
30378
30417
|
children: "Muted"
|
|
30379
30418
|
}),
|
|
30380
|
-
/* @__PURE__ */ g(
|
|
30419
|
+
/* @__PURE__ */ g(jk, {
|
|
30381
30420
|
size: 72,
|
|
30382
|
-
voiceState:
|
|
30383
|
-
isMuted:
|
|
30421
|
+
voiceState: h,
|
|
30422
|
+
isMuted: y,
|
|
30384
30423
|
orbColors: e
|
|
30385
30424
|
})
|
|
30386
30425
|
]
|
|
30387
30426
|
}),
|
|
30388
|
-
|
|
30427
|
+
h === "error" && /* @__PURE__ */ g("span", {
|
|
30389
30428
|
style: {
|
|
30390
30429
|
color: "#f87171",
|
|
30391
30430
|
fontSize: "13px",
|
|
@@ -30401,38 +30440,38 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30401
30440
|
},
|
|
30402
30441
|
children: [/* @__PURE__ */ g("button", {
|
|
30403
30442
|
onClick: async () => {
|
|
30404
|
-
if (
|
|
30405
|
-
if (
|
|
30406
|
-
|
|
30443
|
+
if (C.current) try {
|
|
30444
|
+
if (y) {
|
|
30445
|
+
D.current = 0, await C.current.setMicMuted?.(!1), b(!1);
|
|
30407
30446
|
try {
|
|
30408
|
-
|
|
30447
|
+
C.current.sendContextualUpdate?.("The visitor has unmuted. Resume normal interaction and wait for them to speak.");
|
|
30409
30448
|
} catch {}
|
|
30410
30449
|
} else {
|
|
30411
|
-
|
|
30450
|
+
D.current = 0, await C.current.setMicMuted?.(!0), b(!0);
|
|
30412
30451
|
try {
|
|
30413
|
-
|
|
30452
|
+
C.current.sendContextualUpdate?.("The visitor has muted their microphone. Do NOT speak, ask if they are there, or prompt them in any way. Stay completely silent until they unmute.");
|
|
30414
30453
|
} catch {}
|
|
30415
30454
|
}
|
|
30416
30455
|
} catch {}
|
|
30417
30456
|
},
|
|
30418
|
-
title:
|
|
30457
|
+
title: y ? "Unmute" : "Mute",
|
|
30419
30458
|
style: {
|
|
30420
30459
|
width: "24px",
|
|
30421
30460
|
height: "24px",
|
|
30422
30461
|
borderRadius: "50%",
|
|
30423
|
-
background:
|
|
30424
|
-
border:
|
|
30462
|
+
background: y ? "#7f1d1d" : "#1f2937",
|
|
30463
|
+
border: y ? "1.5px solid #ef4444" : "1.5px solid #4b5563",
|
|
30425
30464
|
display: "flex",
|
|
30426
30465
|
alignItems: "center",
|
|
30427
30466
|
justifyContent: "center",
|
|
30428
30467
|
cursor: "pointer",
|
|
30429
|
-
color:
|
|
30468
|
+
color: y ? "#f87171" : "white",
|
|
30430
30469
|
transition: "all 0.2s ease",
|
|
30431
30470
|
boxShadow: "0 2px 8px rgba(0,0,0,0.4)",
|
|
30432
30471
|
padding: 0,
|
|
30433
30472
|
flexShrink: 0
|
|
30434
30473
|
},
|
|
30435
|
-
children:
|
|
30474
|
+
children: y ? /* @__PURE__ */ _("svg", {
|
|
30436
30475
|
width: "16",
|
|
30437
30476
|
height: "16",
|
|
30438
30477
|
viewBox: "0 0 24 24",
|
|
@@ -30468,7 +30507,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30468
30507
|
color: "currentColor"
|
|
30469
30508
|
})
|
|
30470
30509
|
}), /* @__PURE__ */ g("button", {
|
|
30471
|
-
onClick: () =>
|
|
30510
|
+
onClick: () => S((e) => !e),
|
|
30472
30511
|
style: {
|
|
30473
30512
|
width: "24px",
|
|
30474
30513
|
height: "24px",
|
|
@@ -30491,7 +30530,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30491
30530
|
})
|
|
30492
30531
|
})]
|
|
30493
30532
|
}),
|
|
30494
|
-
|
|
30533
|
+
x && /* @__PURE__ */ _("div", {
|
|
30495
30534
|
style: {
|
|
30496
30535
|
position: "absolute",
|
|
30497
30536
|
bottom: 0,
|
|
@@ -30509,7 +30548,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30509
30548
|
children: [
|
|
30510
30549
|
/* @__PURE__ */ _("button", {
|
|
30511
30550
|
onClick: () => {
|
|
30512
|
-
|
|
30551
|
+
S(!1), E.current = "chat", me(t);
|
|
30513
30552
|
},
|
|
30514
30553
|
style: {
|
|
30515
30554
|
display: "flex",
|
|
@@ -30538,7 +30577,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30538
30577
|
}),
|
|
30539
30578
|
/* @__PURE__ */ _("button", {
|
|
30540
30579
|
onClick: () => {
|
|
30541
|
-
|
|
30580
|
+
S(!1), E.current = "minimized", me(n);
|
|
30542
30581
|
},
|
|
30543
30582
|
style: {
|
|
30544
30583
|
display: "flex",
|
|
@@ -30566,7 +30605,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30566
30605
|
children: [/* @__PURE__ */ g(ND, {}), "End Conversation"]
|
|
30567
30606
|
}),
|
|
30568
30607
|
/* @__PURE__ */ g("button", {
|
|
30569
|
-
onClick: () =>
|
|
30608
|
+
onClick: () => S(!1),
|
|
30570
30609
|
style: {
|
|
30571
30610
|
position: "absolute",
|
|
30572
30611
|
bottom: "8px",
|
|
@@ -30615,7 +30654,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30615
30654
|
]
|
|
30616
30655
|
});
|
|
30617
30656
|
}
|
|
30618
|
-
function
|
|
30657
|
+
function Fk({ orbColors: e }) {
|
|
30619
30658
|
return /* @__PURE__ */ g("div", {
|
|
30620
30659
|
style: {
|
|
30621
30660
|
flexShrink: 0,
|
|
@@ -30625,13 +30664,13 @@ function Ik({ orbColors: e }) {
|
|
|
30625
30664
|
alignItems: "center",
|
|
30626
30665
|
justifyContent: "center"
|
|
30627
30666
|
},
|
|
30628
|
-
children: /* @__PURE__ */ g(
|
|
30667
|
+
children: /* @__PURE__ */ g(jk, {
|
|
30629
30668
|
size: 36,
|
|
30630
30669
|
orbColors: e
|
|
30631
30670
|
})
|
|
30632
30671
|
});
|
|
30633
30672
|
}
|
|
30634
|
-
var
|
|
30673
|
+
var Ik = () => /* @__PURE__ */ g("div", {
|
|
30635
30674
|
style: {
|
|
30636
30675
|
display: "flex",
|
|
30637
30676
|
marginBottom: "12px",
|
|
@@ -30661,7 +30700,7 @@ var Lk = () => /* @__PURE__ */ g("div", {
|
|
|
30661
30700
|
} }, e))
|
|
30662
30701
|
})
|
|
30663
30702
|
});
|
|
30664
|
-
function
|
|
30703
|
+
function Lk({ copy: e, orbColors: t, primaryColor: n, chatBgGradient: r, logo: i, quickChatOptions: a, onQuickChatSelect: o, isMobile: s, chatHistory: l, isAiTyping: u, isAgentTyping: d, activeScreen: f, agentName: v, agentHeadshot: y, fallbackAgentName: b, input: x, setInput: S, onSubmit: C, isConversationEnded: w, isLoading: T, isRateLimited: ee, rateLimitMessage: te, selectedFile: ne, onFileSelect: re, onRemoveSelectedFile: E, attachmentError: ie, isUploadingAttachment: ae, requiresEmail: oe, emailInput: D, setEmailInput: se, emailError: ce, emailCaptureSuccess: le, replyContext: ue, setReplyContext: de, webRTCError: fe, micError: pe, setMicError: me, dismissCallError: he, activeCallId: ge, isCallMuted: _e, toggleCallMute: ve, endWebRTCCall: ye, formatCallDuration: be, callDurationSeconds: xe, isCallMinimized: Se, onExpand: Ce, onCollapse: we, onStartVoice: Te, onNewChat: Ee, showPoweredBy: De, getVisitorChatHistory: Oe, resumeChat: ke, isSessionRestoring: Ae, isClosing: je }) {
|
|
30665
30704
|
let Me = l.length > 0, Ne = T || ee || w, Pe = !!ge, [Fe, Ie] = m(!1), [Le, Re] = m(!1), [ze, Be] = m([]), [Ve, He] = m(!1), O = p(null), [Ue, We] = m(() => typeof window < "u" ? window.visualViewport?.height ?? window.innerHeight : 600), [Ge, Ke] = m(0);
|
|
30666
30705
|
c(() => {
|
|
30667
30706
|
if (!s) return;
|
|
@@ -30797,7 +30836,7 @@ function Rk({ copy: e, orbColors: t, primaryColor: n, chatBgGradient: r, logo: i
|
|
|
30797
30836
|
justifyContent: "center",
|
|
30798
30837
|
height: "40px"
|
|
30799
30838
|
},
|
|
30800
|
-
children: i ? /* @__PURE__ */ g(
|
|
30839
|
+
children: i ? /* @__PURE__ */ g(Ok, {
|
|
30801
30840
|
logo: i,
|
|
30802
30841
|
style: {
|
|
30803
30842
|
height: "34px",
|
|
@@ -30810,7 +30849,7 @@ function Rk({ copy: e, orbColors: t, primaryColor: n, chatBgGradient: r, logo: i
|
|
|
30810
30849
|
height: "40px",
|
|
30811
30850
|
flexShrink: 0
|
|
30812
30851
|
},
|
|
30813
|
-
children: /* @__PURE__ */ g(
|
|
30852
|
+
children: /* @__PURE__ */ g(kk, { title: e.chatTitle })
|
|
30814
30853
|
})
|
|
30815
30854
|
}), /* @__PURE__ */ g("div", {
|
|
30816
30855
|
style: {
|
|
@@ -31240,11 +31279,11 @@ function Rk({ copy: e, orbColors: t, primaryColor: n, chatBgGradient: r, logo: i
|
|
|
31240
31279
|
isLoading: T,
|
|
31241
31280
|
isAgentTyping: d,
|
|
31242
31281
|
setReplyContext: de,
|
|
31243
|
-
TypingDots:
|
|
31282
|
+
TypingDots: Ik,
|
|
31244
31283
|
primaryColor: n,
|
|
31245
31284
|
agentHeadshot: y,
|
|
31246
31285
|
agentDisplayName: v || b,
|
|
31247
|
-
botAvatarNode: /* @__PURE__ */ g(
|
|
31286
|
+
botAvatarNode: /* @__PURE__ */ g(Fk, { orbColors: t })
|
|
31248
31287
|
}) : Ae ? /* @__PURE__ */ _("div", {
|
|
31249
31288
|
style: {
|
|
31250
31289
|
flex: 1,
|
|
@@ -31285,7 +31324,7 @@ function Rk({ copy: e, orbColors: t, primaryColor: n, chatBgGradient: r, logo: i
|
|
|
31285
31324
|
padding: "28px 24px"
|
|
31286
31325
|
},
|
|
31287
31326
|
children: [
|
|
31288
|
-
/* @__PURE__ */ g(
|
|
31327
|
+
/* @__PURE__ */ g(jk, {
|
|
31289
31328
|
size: 94,
|
|
31290
31329
|
orbColors: t
|
|
31291
31330
|
}),
|
|
@@ -31427,14 +31466,14 @@ function Rk({ copy: e, orbColors: t, primaryColor: n, chatBgGradient: r, logo: i
|
|
|
31427
31466
|
]
|
|
31428
31467
|
});
|
|
31429
31468
|
}
|
|
31430
|
-
function
|
|
31469
|
+
function Rk() {
|
|
31431
31470
|
let { status: e, runtimeConfig: t, resolvedConfig: n, chatHistory: r, isOpen: i, activeScreen: a, isHumanHandled: s, agentName: l, agentHeadshot: u, visitorEmail: h, isAgentTyping: v, isAiTyping: y, isLoading: b, isRateLimited: x, rateLimitMessage: S, isConversationEnded: C, incomingCall: w, activeCallId: T, callConnectionState: ee, callConnectedAt: te, isCallMuted: ne, webRTCError: re, language: E, chatId: ie, historyRef: ae, onMessageSync: oe, sendMessage: D, uploadChatFile: se, openWidget: ce, captureVisitorEmail: le, setVoiceMode: ue, endConversation: de, startNewChat: me, acceptCall: he, rejectCall: ge, endWebRTCCall: _e, toggleCallMute: ve, dismissCallError: ye, startTyping: be, stopTyping: xe, updateTypingDraft: Se, getVisitorChatHistory: Ce, resumeChat: we, isSessionRestoring: Te, openToChatCounter: Ee, voiceEndCounter: De } = Ln();
|
|
31432
31471
|
c(() => {
|
|
31433
31472
|
try {
|
|
31434
31473
|
pr();
|
|
31435
31474
|
} catch {}
|
|
31436
31475
|
}, []), c(() => {
|
|
31437
|
-
Ee && A !== "text_chat" && A !== "call_screen" && (ue?.(!1),
|
|
31476
|
+
Ee && A !== "voice_mode" && A !== "text_chat" && A !== "call_screen" && (ue?.(!1), ot("text_chat"));
|
|
31438
31477
|
}, [Ee]);
|
|
31439
31478
|
let Oe = t?.widgetSettings || {}, ke = n?.widgetSettings || {}, Ae = {
|
|
31440
31479
|
...Oe.branding || {},
|
|
@@ -31449,7 +31488,7 @@ function zk() {
|
|
|
31449
31488
|
small: 50,
|
|
31450
31489
|
medium: 64,
|
|
31451
31490
|
large: 80
|
|
31452
|
-
}, Ve = Be[Ne.orbSize] || Be.small, He = Ne.position || "bottom-right", O = Ae.fallbackAgentName || "Agent", Ue =
|
|
31491
|
+
}, Ve = Be[Ne.orbSize] || Be.small, He = Ne.position || "bottom-right", O = Ae.fallbackAgentName || "Agent", Ue = Tk(Le ?? Ne.chatBgColors), We = Ae.logo || Ae.logoUrl || null, Ge = E || "en", Ke = Oe.recommendations?.[Ge] || [], qe = (ke.recommendations?.[Ge] ?? Ke).filter((e) => String(e?.label ?? "").trim()).map((e, t) => ({
|
|
31453
31492
|
id: e.key || `qr-${t}`,
|
|
31454
31493
|
label: e.label,
|
|
31455
31494
|
message: e.label,
|
|
@@ -31472,11 +31511,11 @@ function zk() {
|
|
|
31472
31511
|
]), rt = u && String(u).trim() || t?.ownerProfileImageUrl && String(t.ownerProfileImageUrl).trim() || null, it = r.some((e) => e.sender === "user"), at = f(() => {
|
|
31473
31512
|
let e = r.findIndex((e) => e.sender === "user");
|
|
31474
31513
|
return e === -1 ? !1 : r.slice(e + 1).some((e) => e.sender === "bot" || e.sender === "ai" || e.sender === "agent");
|
|
31475
|
-
}, [r]), k =
|
|
31514
|
+
}, [r]), k = !!(ke._dashboardLivePreview || Oe._dashboardLivePreview), [A, ot] = m(() => k ? "text_chat" : "entry_prompt"), [st, ct] = m(""), [lt, ut] = m(null), [dt, ft] = m(h || ""), [pt, mt] = m(""), [ht, gt] = m(!1), [j, _t] = m(0), [vt, yt] = m(null), [bt, xt] = m(null), [St, Ct] = m(""), [wt, Tt] = m(!1), [Et, Dt] = m(!1), [Ot, kt] = m(!1), At = p(null), jt = p(!1), Mt = !h && it && at && A !== "voice_mode";
|
|
31476
31515
|
d(() => {
|
|
31477
|
-
if (e !== "ready" ||
|
|
31478
|
-
if (
|
|
31479
|
-
|
|
31516
|
+
if (e !== "ready" || jt.current) return;
|
|
31517
|
+
if (jt.current = !0, !Ie) {
|
|
31518
|
+
ot("minimized_orb");
|
|
31480
31519
|
return;
|
|
31481
31520
|
}
|
|
31482
31521
|
let t = !1;
|
|
@@ -31485,22 +31524,22 @@ function zk() {
|
|
|
31485
31524
|
} catch {}
|
|
31486
31525
|
let n = Fe(), r = et ? je(et) : null, i = n || !!r?.transcript;
|
|
31487
31526
|
if (t) {
|
|
31488
|
-
ce?.({ notifyChatInitiated: !0 }), ue?.(!0),
|
|
31527
|
+
ce?.({ notifyChatInitiated: !0 }), ue?.(!0), ot("voice_mode");
|
|
31489
31528
|
return;
|
|
31490
31529
|
}
|
|
31491
31530
|
if (Re()) {
|
|
31492
|
-
ce?.({ notifyChatInitiated: !1 }),
|
|
31531
|
+
ce?.({ notifyChatInitiated: !1 }), ot("text_chat");
|
|
31493
31532
|
return;
|
|
31494
31533
|
}
|
|
31495
|
-
if (et) try {
|
|
31496
|
-
Me(et);
|
|
31497
|
-
} catch {}
|
|
31498
31534
|
if (i) {
|
|
31499
|
-
|
|
31535
|
+
ce?.({ notifyChatInitiated: !0 }), ue?.(!0), ot("voice_mode");
|
|
31500
31536
|
return;
|
|
31501
31537
|
}
|
|
31538
|
+
if (et) try {
|
|
31539
|
+
Me(et);
|
|
31540
|
+
} catch {}
|
|
31502
31541
|
if (fe(et)) {
|
|
31503
|
-
|
|
31542
|
+
ot("minimized_orb");
|
|
31504
31543
|
return;
|
|
31505
31544
|
}
|
|
31506
31545
|
}, [e, r]);
|
|
@@ -31509,55 +31548,55 @@ function zk() {
|
|
|
31509
31548
|
let e = window.matchMedia("(max-width: 640px)"), t = (e) => Pt(e.matches);
|
|
31510
31549
|
return e.addEventListener("change", t), () => e.removeEventListener("change", t);
|
|
31511
31550
|
}, []), c(() => {
|
|
31512
|
-
|
|
31551
|
+
ft(h || ""), h && mt("");
|
|
31513
31552
|
}, [h]);
|
|
31514
31553
|
let Ft = o(() => {
|
|
31515
|
-
|
|
31554
|
+
xt(null), Ct("");
|
|
31516
31555
|
}, []), It = o((e) => {
|
|
31517
31556
|
let t = qD(e);
|
|
31518
31557
|
if (t) {
|
|
31519
|
-
|
|
31558
|
+
xt(null), Ct(t);
|
|
31520
31559
|
return;
|
|
31521
31560
|
}
|
|
31522
|
-
|
|
31561
|
+
xt(e), Ct("");
|
|
31523
31562
|
}, []);
|
|
31524
31563
|
c(() => {
|
|
31525
31564
|
if (!te || ee !== "connected") {
|
|
31526
|
-
|
|
31565
|
+
_t(0);
|
|
31527
31566
|
return;
|
|
31528
31567
|
}
|
|
31529
31568
|
let e = () => {
|
|
31530
31569
|
let e = new Date(te).getTime();
|
|
31531
|
-
isNaN(e) ||
|
|
31570
|
+
isNaN(e) || _t(Math.max(0, Math.floor((Date.now() - e) / 1e3)));
|
|
31532
31571
|
};
|
|
31533
31572
|
e();
|
|
31534
31573
|
let t = window.setInterval(e, 1e3);
|
|
31535
31574
|
return () => window.clearInterval(t);
|
|
31536
31575
|
}, [te, ee]);
|
|
31537
31576
|
let Lt = o(() => {
|
|
31538
|
-
|
|
31577
|
+
ot("call_screen"), Dt(!1);
|
|
31539
31578
|
}, []), Rt = o(() => {
|
|
31540
|
-
|
|
31579
|
+
ot("text_chat"), Dt(!0);
|
|
31541
31580
|
}, []);
|
|
31542
31581
|
c(() => {
|
|
31543
31582
|
let e = w?.callId || T || null;
|
|
31544
31583
|
if (!e) {
|
|
31545
|
-
|
|
31584
|
+
At.current = null;
|
|
31546
31585
|
return;
|
|
31547
31586
|
}
|
|
31548
31587
|
if (w?.callId || ee === "connecting" || ee === "connected") {
|
|
31549
|
-
if (A === "minimized_orb" &&
|
|
31550
|
-
|
|
31588
|
+
if (A === "minimized_orb" && Et && T && !w?.callId) {
|
|
31589
|
+
At.current = e;
|
|
31551
31590
|
return;
|
|
31552
31591
|
}
|
|
31553
|
-
!(!i || A === "minimized_orb" || A === "voice_mode") &&
|
|
31592
|
+
!(!i || A === "minimized_orb" || A === "voice_mode") && At.current === e || (console.log("[FlowEngageWidget] forcing call UI to front", {
|
|
31554
31593
|
forcedKey: e,
|
|
31555
31594
|
isOpen: i,
|
|
31556
31595
|
surface: A,
|
|
31557
31596
|
hasIncomingCall: !!w?.callId,
|
|
31558
31597
|
activeCallId: T,
|
|
31559
31598
|
callConnectionState: ee
|
|
31560
|
-
}),
|
|
31599
|
+
}), At.current = e, A === "voice_mode" && ue?.(!1), ce?.(), Lt());
|
|
31561
31600
|
}
|
|
31562
31601
|
}, [
|
|
31563
31602
|
T,
|
|
@@ -31569,31 +31608,31 @@ function zk() {
|
|
|
31569
31608
|
ue,
|
|
31570
31609
|
A
|
|
31571
31610
|
]), c(() => {
|
|
31572
|
-
!w && !T && A === "call_screen" &&
|
|
31611
|
+
!w && !T && A === "call_screen" && ot("text_chat");
|
|
31573
31612
|
}, [
|
|
31574
31613
|
w,
|
|
31575
31614
|
T,
|
|
31576
31615
|
A
|
|
31577
31616
|
]), c(() => {
|
|
31578
|
-
!T &&
|
|
31579
|
-
}, [T,
|
|
31617
|
+
!T && Et && Dt(!1);
|
|
31618
|
+
}, [T, Et]), c(() => {
|
|
31580
31619
|
if (!s || C) {
|
|
31581
31620
|
Se?.(""), xe?.();
|
|
31582
31621
|
return;
|
|
31583
31622
|
}
|
|
31584
|
-
if (!
|
|
31623
|
+
if (!st.trim() || bt) {
|
|
31585
31624
|
Se?.("");
|
|
31586
31625
|
let e = window.setTimeout(() => xe?.(), 100);
|
|
31587
31626
|
return () => window.clearTimeout(e);
|
|
31588
31627
|
}
|
|
31589
31628
|
be?.();
|
|
31590
|
-
let e = window.setTimeout(() => Se?.(
|
|
31629
|
+
let e = window.setTimeout(() => Se?.(st), 120), t = window.setTimeout(() => xe?.(), 1200);
|
|
31591
31630
|
return () => {
|
|
31592
31631
|
window.clearTimeout(e), window.clearTimeout(t);
|
|
31593
31632
|
};
|
|
31594
31633
|
}, [
|
|
31595
|
-
|
|
31596
|
-
|
|
31634
|
+
st,
|
|
31635
|
+
bt,
|
|
31597
31636
|
s,
|
|
31598
31637
|
C,
|
|
31599
31638
|
be,
|
|
@@ -31606,39 +31645,39 @@ function zk() {
|
|
|
31606
31645
|
replyToSender: e.sender || null
|
|
31607
31646
|
} : null, Bt = async (e) => {
|
|
31608
31647
|
if (e.preventDefault(), C) return;
|
|
31609
|
-
if (
|
|
31610
|
-
let e =
|
|
31648
|
+
if (Mt) {
|
|
31649
|
+
let e = dt.trim().toLowerCase();
|
|
31611
31650
|
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)) {
|
|
31612
|
-
|
|
31651
|
+
mt("Please enter a valid email so we can continue helping you.");
|
|
31613
31652
|
return;
|
|
31614
31653
|
}
|
|
31615
|
-
await le(e),
|
|
31654
|
+
await le(e), mt(""), gt(!0), setTimeout(() => gt(!1), 3e3);
|
|
31616
31655
|
return;
|
|
31617
31656
|
}
|
|
31618
|
-
let t = zt(
|
|
31619
|
-
if (!
|
|
31620
|
-
if (
|
|
31657
|
+
let t = zt(lt);
|
|
31658
|
+
if (!st.trim() && !bt) return;
|
|
31659
|
+
if (bt) {
|
|
31621
31660
|
try {
|
|
31622
|
-
|
|
31623
|
-
let e = await se(
|
|
31624
|
-
|
|
31661
|
+
Tt(!0), Ct("");
|
|
31662
|
+
let e = await se(bt), n = e?.data || e, r = st.trim() || `Shared file: ${YD(bt)}`;
|
|
31663
|
+
ct(""), ut(null), Ft(), await D(r, "", t, {
|
|
31625
31664
|
type: "file",
|
|
31626
31665
|
metadata: {
|
|
31627
31666
|
fileUrl: n?.fileUrl,
|
|
31628
|
-
fileName: n?.fileName ||
|
|
31629
|
-
fileType: n?.fileType ||
|
|
31630
|
-
fileSize: n?.fileSize ||
|
|
31667
|
+
fileName: n?.fileName || bt.name,
|
|
31668
|
+
fileType: n?.fileType || bt.type,
|
|
31669
|
+
fileSize: n?.fileSize || bt.size
|
|
31631
31670
|
}
|
|
31632
31671
|
});
|
|
31633
31672
|
} catch (e) {
|
|
31634
|
-
|
|
31673
|
+
Ct(e?.message || "Failed to upload the selected file.");
|
|
31635
31674
|
} finally {
|
|
31636
|
-
|
|
31675
|
+
Tt(!1);
|
|
31637
31676
|
}
|
|
31638
31677
|
return;
|
|
31639
31678
|
}
|
|
31640
|
-
let n =
|
|
31641
|
-
|
|
31679
|
+
let n = st.trim();
|
|
31680
|
+
ct(""), ut(null), await D(n, "", t);
|
|
31642
31681
|
}, Vt = o(() => {
|
|
31643
31682
|
r.length !== 0 && me?.();
|
|
31644
31683
|
}, [r.length, me]), Ht = (e) => {
|
|
@@ -31686,10 +31725,10 @@ function zk() {
|
|
|
31686
31725
|
right: "1.5rem",
|
|
31687
31726
|
bottom: "1.5rem"
|
|
31688
31727
|
}, Gt = o(() => {
|
|
31689
|
-
A !== "minimized_orb" && (
|
|
31690
|
-
|
|
31728
|
+
A !== "minimized_orb" && (kt(!0), setTimeout(() => {
|
|
31729
|
+
ot("minimized_orb"), kt(!1), T && Dt(!0);
|
|
31691
31730
|
}, 280));
|
|
31692
|
-
}, [T, A]), Kt = () =>
|
|
31731
|
+
}, [T, A]), Kt = () => ot("connection_modal"), qt = () => {
|
|
31693
31732
|
try {
|
|
31694
31733
|
let e = window.AudioContext || window.webkitAudioContext;
|
|
31695
31734
|
if (e) {
|
|
@@ -31697,9 +31736,9 @@ function zk() {
|
|
|
31697
31736
|
t.resume().catch(() => {}), setTimeout(() => t.close().catch(() => {}), 3e3);
|
|
31698
31737
|
}
|
|
31699
31738
|
} catch {}
|
|
31700
|
-
ce({ notifyChatInitiated: !0 }), ue?.(!0),
|
|
31739
|
+
ce({ notifyChatInitiated: !0 }), ue?.(!0), ot("voice_mode");
|
|
31701
31740
|
}, Jt = () => {
|
|
31702
|
-
ce({ notifyChatInitiated: !0 }), ue?.(!1),
|
|
31741
|
+
ce({ notifyChatInitiated: !0 }), ue?.(!1), ot("text_chat");
|
|
31703
31742
|
}, Yt = () => {
|
|
31704
31743
|
ue?.(!1), Gt();
|
|
31705
31744
|
};
|
|
@@ -31713,7 +31752,7 @@ function zk() {
|
|
|
31713
31752
|
onWheel: (e) => e.stopPropagation(),
|
|
31714
31753
|
onTouchMove: (e) => e.stopPropagation(),
|
|
31715
31754
|
children: [
|
|
31716
|
-
A === "entry_prompt" && /* @__PURE__ */ g(
|
|
31755
|
+
A === "entry_prompt" && /* @__PURE__ */ g(Mk, {
|
|
31717
31756
|
copy: Qe,
|
|
31718
31757
|
orbColors: Le,
|
|
31719
31758
|
primaryColor: ze,
|
|
@@ -31724,7 +31763,7 @@ function zk() {
|
|
|
31724
31763
|
pe(et), Gt();
|
|
31725
31764
|
},
|
|
31726
31765
|
isMobile: Nt,
|
|
31727
|
-
isClosing:
|
|
31766
|
+
isClosing: Ot
|
|
31728
31767
|
}),
|
|
31729
31768
|
A === "minimized_orb" && /* @__PURE__ */ _(Dm.div, {
|
|
31730
31769
|
layoutId: "fe-main-orb",
|
|
@@ -31793,16 +31832,16 @@ function zk() {
|
|
|
31793
31832
|
marginTop: "2px",
|
|
31794
31833
|
whiteSpace: "nowrap"
|
|
31795
31834
|
},
|
|
31796
|
-
children: ee === "connected" ? `${Ht(
|
|
31835
|
+
children: ee === "connected" ? `${Ht(j)} with ${nt}` : `Tap to return to ${nt}`
|
|
31797
31836
|
})]
|
|
31798
31837
|
})]
|
|
31799
|
-
}), /* @__PURE__ */ g(
|
|
31838
|
+
}), /* @__PURE__ */ g(jk, {
|
|
31800
31839
|
size: Ve,
|
|
31801
31840
|
orbColors: Le,
|
|
31802
31841
|
onClick: T ? Lt : Ie ? Kt : Jt
|
|
31803
31842
|
})]
|
|
31804
31843
|
}),
|
|
31805
|
-
A === "connection_modal" && /* @__PURE__ */ g(
|
|
31844
|
+
A === "connection_modal" && /* @__PURE__ */ g(Nk, {
|
|
31806
31845
|
copy: Qe,
|
|
31807
31846
|
orbColors: Le,
|
|
31808
31847
|
primaryColor: ze,
|
|
@@ -31810,9 +31849,9 @@ function zk() {
|
|
|
31810
31849
|
onText: Jt,
|
|
31811
31850
|
onClose: Gt,
|
|
31812
31851
|
isMobile: Nt,
|
|
31813
|
-
isClosing:
|
|
31852
|
+
isClosing: Ot
|
|
31814
31853
|
}),
|
|
31815
|
-
A === "voice_mode" && /* @__PURE__ */ g(
|
|
31854
|
+
A === "voice_mode" && /* @__PURE__ */ g(Pk, {
|
|
31816
31855
|
orbColors: Le,
|
|
31817
31856
|
onEnterChat: Jt,
|
|
31818
31857
|
onEndChat: Yt,
|
|
@@ -31822,13 +31861,14 @@ function zk() {
|
|
|
31822
31861
|
chatId: ie,
|
|
31823
31862
|
historyRef: ae,
|
|
31824
31863
|
onMessageSync: oe,
|
|
31825
|
-
voiceEndCounter: De
|
|
31864
|
+
voiceEndCounter: De,
|
|
31865
|
+
websiteName: t?.websiteName
|
|
31826
31866
|
}, "voice"),
|
|
31827
31867
|
A === "call_screen" && /* @__PURE__ */ g(gO, {
|
|
31828
31868
|
incomingCall: w,
|
|
31829
31869
|
activeCallId: T,
|
|
31830
31870
|
callConnectionState: ee,
|
|
31831
|
-
callDurationSeconds:
|
|
31871
|
+
callDurationSeconds: j,
|
|
31832
31872
|
isCallMuted: ne,
|
|
31833
31873
|
agentName: nt,
|
|
31834
31874
|
agentHeadshot: rt,
|
|
@@ -31843,8 +31883,8 @@ function zk() {
|
|
|
31843
31883
|
orbColors: Le,
|
|
31844
31884
|
chatHistory: r
|
|
31845
31885
|
}),
|
|
31846
|
-
A === "text_chat" && /* @__PURE__ */ g(
|
|
31847
|
-
isClosing:
|
|
31886
|
+
A === "text_chat" && /* @__PURE__ */ g(Lk, {
|
|
31887
|
+
isClosing: Ot,
|
|
31848
31888
|
copy: Qe,
|
|
31849
31889
|
orbColors: Le,
|
|
31850
31890
|
primaryColor: ze,
|
|
@@ -31860,35 +31900,35 @@ function zk() {
|
|
|
31860
31900
|
agentName: nt,
|
|
31861
31901
|
agentHeadshot: rt,
|
|
31862
31902
|
fallbackAgentName: O,
|
|
31863
|
-
input:
|
|
31864
|
-
setInput:
|
|
31903
|
+
input: st,
|
|
31904
|
+
setInput: ct,
|
|
31865
31905
|
onSubmit: Bt,
|
|
31866
31906
|
isConversationEnded: C,
|
|
31867
31907
|
isLoading: b,
|
|
31868
31908
|
isRateLimited: x,
|
|
31869
31909
|
rateLimitMessage: S,
|
|
31870
|
-
selectedFile:
|
|
31910
|
+
selectedFile: bt,
|
|
31871
31911
|
onFileSelect: It,
|
|
31872
31912
|
onRemoveSelectedFile: Ft,
|
|
31873
|
-
attachmentError:
|
|
31874
|
-
isUploadingAttachment:
|
|
31875
|
-
requiresEmail:
|
|
31876
|
-
emailInput:
|
|
31877
|
-
setEmailInput:
|
|
31878
|
-
emailError:
|
|
31879
|
-
emailCaptureSuccess:
|
|
31880
|
-
replyContext:
|
|
31881
|
-
setReplyContext:
|
|
31913
|
+
attachmentError: St,
|
|
31914
|
+
isUploadingAttachment: wt,
|
|
31915
|
+
requiresEmail: Mt,
|
|
31916
|
+
emailInput: dt,
|
|
31917
|
+
setEmailInput: ft,
|
|
31918
|
+
emailError: pt,
|
|
31919
|
+
emailCaptureSuccess: ht,
|
|
31920
|
+
replyContext: lt,
|
|
31921
|
+
setReplyContext: ut,
|
|
31882
31922
|
webRTCError: re,
|
|
31883
|
-
micError:
|
|
31884
|
-
setMicError:
|
|
31923
|
+
micError: vt,
|
|
31924
|
+
setMicError: yt,
|
|
31885
31925
|
dismissCallError: ye,
|
|
31886
31926
|
activeCallId: T,
|
|
31887
31927
|
isCallMuted: ne,
|
|
31888
31928
|
toggleCallMute: ve,
|
|
31889
31929
|
endWebRTCCall: _e,
|
|
31890
31930
|
formatCallDuration: Ht,
|
|
31891
|
-
callDurationSeconds:
|
|
31931
|
+
callDurationSeconds: j,
|
|
31892
31932
|
onCollapse: Gt,
|
|
31893
31933
|
onStartVoice: qt,
|
|
31894
31934
|
onNewChat: Vt,
|
|
@@ -31906,7 +31946,7 @@ function zk() {
|
|
|
31906
31946
|
}
|
|
31907
31947
|
//#endregion
|
|
31908
31948
|
//#region src/components/ErrorBoundary.jsx
|
|
31909
|
-
var
|
|
31949
|
+
var zk = class extends e.Component {
|
|
31910
31950
|
constructor(e) {
|
|
31911
31951
|
super(e), this.state = { hasError: !1 };
|
|
31912
31952
|
}
|
|
@@ -31921,4 +31961,4 @@ var Bk = class extends e.Component {
|
|
|
31921
31961
|
}
|
|
31922
31962
|
};
|
|
31923
31963
|
//#endregion
|
|
31924
|
-
export { lO as AnimatedOrb,
|
|
31964
|
+
export { lO as AnimatedOrb, zk as ErrorBoundary, Rr as FlowEngageProvider, Rk as FlowEngageWidget, Ln as useFlowEngage };
|