@flowengage/react-chatbot 6.0.44 → 7.0.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.
@@ -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
- }, ot = typeof ArrayBuffer == "function", A = (e, t) => {
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) => ot ? ct(k(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 = A(n[e], t);
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(A(a ? e : pt.decode(e), t)), r = 0;
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 = A(e, this.socket.binaryType);
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), ot = p(""), A = 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
+ } : 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: ot.current,
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: ot.current,
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: ot.current,
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: ot.current
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 = A.current, r = st.current;
3024
- if (A.current = !1, st.current = null, c = (await We({
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
- ot.current = c;
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 || ot.current,
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 = ot.current, t = wt.current, n = k.current;
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 = ot.current, t = k.current;
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 || !ot.current) return t;
3452
+ if (!t || !k.current || !A.current) return t;
3452
3453
  try {
3453
3454
  await k.current.trackVisitor({
3454
- chatId: ot.current,
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 = ot.current, t = k.current;
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), A.current = !0, st.current = null, at.current?.disconnect(), S([]), b(""), ot.current = "", He(!1), re(!1), D(null), de(null), it(!0), s((e) => e + 1);
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, A.current = !1, st.current = e, at.current?.disconnect(), S([]), b(""), ot.current = "", He(!1), re(!1), D(null), de(null), it(!0), s((e) => e + 1);
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 xk() {
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 Sk() {
29347
- 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'], article") || document.body).querySelectorAll("h1, h2, h3"));
29348
- 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);
29342
+ function xk() {
29343
+ let e = document.querySelector("main, [role='main'], article") || document.body;
29344
+ return Array.from(e.querySelectorAll("h1, h2, h3")).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).slice(0, 12);
29349
29345
  }
29350
- function Ck(e) {
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
- flowengage_navigate: async (n) => {
29353
- $("flowengage_navigate ▶ raw parameters:", n);
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 ($("flowengage_navigate · coerced:", {
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 $("flowengage_navigate ✖", e), e;
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, $("flowengage_navigate · normalized cross-origin URL to path:", a));
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 $("flowengage_navigate ✖ 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.";
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. Call flowengage_search with keywords from the topic to find the correct URL, then navigate to the URL from the search results.`;
29382
- return $("flowengage_navigate ✖ blocked", e), e;
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), $("flowengage_navigate → real navigation", a);
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
- $("flowengage_navigate → SPA nav complete. target:", e, "actual:", n);
29408
- let s = [], c = Date.now() + 12e3;
29409
- for (; Date.now() < c && (await new Promise((e) => setTimeout(e, 300)), s = Sk(), !(s.length >= 1)););
29410
- xk(), $("flowengage_navigate → page headings collected:", s);
29411
- let l = s.length ? s.join(" | ") : "none", u = s.length ? "Use ONLY these exact heading strings for flowengage_highlight — never invent or abbreviate." : "No headings collected yetcall flowengage_get_current_page immediately (no speech) to get the live headings before speaking or highlighting.";
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, then ask: "Would you like me to walk you through the sections here?"`) : (wr(), `OK_NAVIGATE_SPA. CURRENT PAGE IS: ${r} (page: "${o}") | Section headings: ${l}. ${u} Speak 2-3 sentences about this page, then ask: "Would you like me to walk you through the sections here?"`);
29403
+ $("fwh-navigate-mvp → SPA nav complete. target:", e, "actual:", n);
29404
+ let s = [], c = Date.now() + 8e3;
29405
+ for (; Date.now() < c && (await new Promise((e) => setTimeout(e, 250)), 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." : "No headings were collected from the live DOM use your knowledge base heading strings for this page to call fwh-highlight-mvp. Follow RULE 1: call each highlight BEFORE describing its section (transition → highlight → content).";
29408
+ return i ? (wr(), `OK_NAVIGATE_SPA. Visitor is now on: ${r} (page: "${o}") | Section headings: ${l}. ${u} MANDATORY: call fwh-highlight-mvp for EVERY section before describing it — never give a plain summary. Do NOT say "I have navigated you" or "I've taken you to" start the highlighted walkthrough immediately.`) : (wr(), `OK_NAVIGATE_SPA. CURRENT PAGE IS: ${r} (page: "${o}") | Section headings: ${l}. ${u} MANDATORY: call fwh-highlight-mvp for EVERY section before describing it never give a plain summary. Describe THIS page only — do not mention the page you tried to navigate to.`);
29413
29409
  } catch {}
29414
29410
  return "OK_NAVIGATE_RELOADING. Navigating to the page now; the voice session will resume automatically on the new page. When the session resumes, immediately introduce the new page and continue guiding the visitor — do not wait for the user to speak first.";
29415
29411
  } catch (e) {
29416
29412
  let t = `Navigation error: ${e?.message || String(e)}`;
29417
- return $("flowengage_navigate ✖", t), CO("Navigation failed", {
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
- flowengage_highlight: async (e) => {
29427
- $("flowengage_highlight ▶", e);
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
- xk();
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)), xk(), i = hr(null, r);
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
- $("flowengage_highlight ✖ no element for:", r || n);
29442
- let e = Sk(), t = e.length ? `Page headings: ${e.join(" | ")}. Use one of these exact strings for section_text.` : "No headings found — skip highlight and continue.";
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), $("flowengage_highlight ✓", r || n), `OK_HIGHLIGHT: "${r || n}". WALKTHROUGH: continue immediately to the next section — do NOT pause between sections.`;
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
- flowengage_read_content: async (e) => {
29448
- $("flowengage_read_content ▶", e);
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,52 +29458,20 @@ 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)"), $("flowengage_read_content ✓", `${e.length} chars`), e || "No readable content found on this page.";
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 $("flowengage_read_content ✖", e.message), `Could not read page content: ${e.message}`;
29463
+ return $("fwh-read-content-mvp ✖", e.message), `Could not read page content: ${e.message}`;
29468
29464
  }
29469
29465
  },
29470
- flowengage_search: async (e) => {
29471
- $("flowengage_search ▶", e);
29472
- let r = yk(mk(e));
29473
- if ($("flowengage_search · query:", r, "siteId:", t, "apiBase:", n || "(empty)"), !r) return $("flowengage_search ✖ missing query"), "Missing query parameter.";
29474
- if (!t) return $("flowengage_search ✖ no siteId"), "Site is not configured for search.";
29475
- if (!n) return $("flowengage_search ✖ no api base"), "API base URL is missing; cannot search.";
29476
- CO(`Searching${r ? ` for "${r}"` : ""}…`, { spinner: !0 });
29477
- try {
29478
- let e = `${n}/api/site-tools/search`;
29479
- $("flowengage_search → POST", e);
29480
- let i = await fetch(e, {
29481
- method: "POST",
29482
- headers: { "Content-Type": "application/json" },
29483
- body: JSON.stringify({
29484
- siteId: t,
29485
- query: r,
29486
- currentUrl: typeof window < "u" ? window.location.href : ""
29487
- })
29488
- }), a = await i.json();
29489
- if ($("flowengage_search · HTTP", i.status, "success:", a.success), !a.success) {
29490
- let e = a.error || "Search failed.";
29491
- return $("flowengage_search ✖", e), e;
29492
- }
29493
- 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 flowengage_navigate 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.` : "SEARCH_RESULTS: No results found. Answer from your knowledge base.";
29495
- } catch (e) {
29496
- let t = `Search error: ${e.message || "network"}`;
29497
- return $("flowengage_search ✖", t), t;
29498
- } finally {
29499
- wO(600);
29500
- }
29501
- },
29502
- flowengage_page_content: async (e) => {
29503
- $("flowengage_page_content ▶", e);
29466
+ "fwh-page-content-mvp": async (e) => {
29467
+ $("fwh-page-content-mvp ▶", e);
29504
29468
  let r = mk(e), i = r?.url || r?.page_url || "";
29505
- if ($("flowengage_page_content · url:", i, "siteId:", t, "apiBase:", n || "(empty)"), !i) return $("flowengage_page_content ✖ missing url"), "Missing url parameter.";
29506
- if (!t) return $("flowengage_page_content ✖ no siteId"), "Site is not configured.";
29507
- if (!n) return $("flowengage_page_content ✖ no api base"), "API base URL is missing; cannot fetch page content.";
29469
+ if ($("fwh-page-content-mvp · url:", i, "siteId:", t, "apiBase:", n || "(empty)"), !i) return $("fwh-page-content-mvp ✖ missing url"), "Missing url parameter.";
29470
+ if (!t) return $("fwh-page-content-mvp ✖ no siteId"), "Site is not configured.";
29471
+ if (!n) return $("fwh-page-content-mvp ✖ no api base"), "API base URL is missing; cannot fetch page content.";
29508
29472
  try {
29509
29473
  let e = `${n}/api/site-tools/page-content`;
29510
- $("flowengage_page_content → POST", e);
29474
+ $("fwh-page-content-mvp → POST", e);
29511
29475
  let r = await fetch(e, {
29512
29476
  method: "POST",
29513
29477
  headers: { "Content-Type": "application/json" },
@@ -29516,11 +29480,11 @@ function Ck(e) {
29516
29480
  url: i
29517
29481
  })
29518
29482
  }), a = await r.json();
29519
- if ($("flowengage_page_content · HTTP", r.status, "success:", a.success), !a.success) {
29483
+ if ($("fwh-page-content-mvp · HTTP", r.status, "success:", a.success), !a.success) {
29520
29484
  let e = a.error || "Failed to get page content.";
29521
- return $("flowengage_page_content ✖", e), `${e} FALLBACK REQUIRED: This page is not in the search index. Call flowengage_read_content (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.`;
29485
+ 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
29486
  }
29523
- return $("flowengage_page_content ✓", `title: ${a.title}`, `sections: ${(a.sections || []).length}`, `content: ${(a.content || "").length} chars`), JSON.stringify({
29487
+ return $("fwh-page-content-mvp ✓", `title: ${a.title}`, `sections: ${(a.sections || []).length}`, `content: ${(a.content || "").length} chars`), JSON.stringify({
29524
29488
  title: a.title,
29525
29489
  url: a.url,
29526
29490
  sections: a.sections,
@@ -29528,36 +29492,60 @@ function Ck(e) {
29528
29492
  });
29529
29493
  } catch (e) {
29530
29494
  let t = `Page content error: ${e.message || "network"}`;
29531
- return $("flowengage_page_content ✖", t), t;
29495
+ return $("fwh-page-content-mvp ✖", t), t;
29532
29496
  }
29533
29497
  },
29534
- flowengage_end_session: async () => ($("flowengage_end_session ▶"), typeof e.requestEndSession == "function" && e.requestEndSession(), "Voice session is ending."),
29535
- flowengage_get_current_page: async () => {
29536
- if ($("flowengage_get_current_page ▶"), typeof window > "u") return "Cannot determine current page (no browser context).";
29537
- let e = window.location.href, t = window.location.pathname, n = document.title || "", r = Sk();
29538
- return $("flowengage_get_current_page ", {
29498
+ "fwh-search-mvp": async (e) => {
29499
+ $("fwh-search-mvp ▶", e);
29500
+ let r = mk(e).query;
29501
+ if (!r) return $("fwh-search-mvp missing query"), "Missing query parameter.";
29502
+ if (!t) return $("fwh-search-mvp ✖ no siteId"), "Search unavailable (no siteId configured).";
29503
+ if (!n) return $("fwh-search-mvp ✖ no api base"), "Search unavailable (no API base URL).";
29504
+ try {
29505
+ let e = `${n}/api/site-tools/search`;
29506
+ $("fwh-search-mvp → POST", e);
29507
+ let i = await fetch(e, {
29508
+ method: "POST",
29509
+ headers: { "Content-Type": "application/json" },
29510
+ body: JSON.stringify({
29511
+ siteId: t,
29512
+ query: r
29513
+ })
29514
+ }), a = await i.json();
29515
+ 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.";
29516
+ let o = a.results.slice(0, 5).map((e, t) => `${t + 1}. ${e.title || e.url} (${e.url})${e.snippet ? ` — ${e.snippet}` : ""}`).join("\n");
29517
+ return $("fwh-search-mvp ✓", `${a.results.length} result(s)`), `SEARCH_RESULTS:\n${o}`;
29518
+ } catch (e) {
29519
+ return $("fwh-search-mvp ✖", e.message), "Search failed. Use fwh-read-content-mvp to read the current page instead.";
29520
+ }
29521
+ },
29522
+ "fwh-end-session-mvp": async () => ($("fwh-end-session-mvp ▶"), typeof e.requestEndSession == "function" && e.requestEndSession(), "Voice session is ending."),
29523
+ "fwh-get-current-page-mvp": async () => {
29524
+ if ($("fwh-get-current-page-mvp ▶"), typeof window > "u") return "Cannot determine current page (no browser context).";
29525
+ let e = window.location.href, t = window.location.pathname, n = document.title || "", r = xk(), i = r.length ? r.join(" | ") : "none";
29526
+ return $("fwh-get-current-page-mvp ✓", {
29539
29527
  url: e,
29540
29528
  path: t,
29541
29529
  title: n
29542
- }), $("flowengage_get_current_page → 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]." + highlight("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.`;
29530
+ }), $("fwh-get-current-page-mvp → page headings collected:", r), `CURRENT_PAGE. URL: ${e} | Path: ${t} | Title: ${n} | Section headings: ${i}. Use ONLY these exact heading strings for fwh-highlight-mvp never invent or abbreviate section names.`;
29543
29531
  },
29544
- flowengage_list_forms: async () => {
29532
+ "fwh-list-forms-mvp": async () => {
29545
29533
  let e = XO(), t = ZO();
29546
- return $("flowengage_list_forms ✓", `${e.length} field(s)`, `${t.length} button(s)`), JSON.stringify({
29534
+ return $("fwh-list-forms-mvp ✓", `${e.length} field(s)`, `${t.length} button(s)`), JSON.stringify({
29547
29535
  fields: e,
29548
29536
  buttons: t,
29549
- hint: "field_key: placeholder/label, name (e.g. url), id (e.g. url-input). If the page has two URL boxes, flowengage_fill_form sets all matching URL inputs. flowengage_click_button picks the Conduct Audit nearest the filled field when labels duplicate."
29537
+ 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
29538
  });
29551
29539
  },
29552
- flowengage_fill_form: async (e) => {
29540
+ "fwh-fill-form-mvp": async (e) => {
29553
29541
  try {
29554
- $("flowengage_fill_form ▶ raw:", e), AO();
29542
+ $("fwh-fill-form-mvp ▶ raw:", e), AO();
29555
29543
  let t = hk(e);
29556
29544
  if (!t.length && r) {
29557
29545
  let e = r(), n = gk(e);
29558
- n.length ? $("flowengage_fill_form · inferred URL from last user utterance (model omitted usable fields):", n) : (n = _k(e), n.length && $("flowengage_fill_form · inferred contact fields from last user utterance (empty tool params):", n)), n.length && (t = n);
29546
+ 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
29547
  }
29560
- if ($("flowengage_fill_form · normalized fields:", t), !t.length) return "No fields provided. Call flowengage_list_forms for field_key strings, then flowengage_fill_form 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.";
29548
+ 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
29549
  let n = [];
29562
29550
  for (let e of t) {
29563
29551
  let t = e?.field_key, r = e?.value;
@@ -29565,23 +29553,23 @@ function Ck(e) {
29565
29553
  CO(`Filling ${String(t)}...`, { spinner: !0 });
29566
29554
  let a = YO(), o = ck(a, String(t), r);
29567
29555
  if (o.length) {
29568
- for (let [e, t] of o.entries()) jO(t), await LO(t), bk(t, r, { skipScroll: e > 0 }), MO(t), await HO(120);
29556
+ for (let [e, t] of o.entries()) jO(t), await LO(t), yk(t, r, { skipScroll: e > 0 }), MO(t), await HO(120);
29569
29557
  i = o, n.push(String(t));
29570
29558
  continue;
29571
29559
  }
29572
29560
  let s = dk(a, String(t));
29573
- s ||= nk(a, String(t)), s ||= rk(a, String(t), r), s && (jO(s), await LO(s), bk(s, r), MO(s), await HO(120), i = [s], n.push(String(t)));
29561
+ 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
29562
  }
29575
- if (!n.length) return $("flowengage_fill_form ✖ no matches"), "Could not match any fields. Call flowengage_list_forms 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.";
29563
+ 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
29564
  let a = `OK_FILLED: ${n.join(", ")}`;
29577
- return $("flowengage_fill_form ✓", a), CO("Form filled", {
29565
+ return $("fwh-fill-form-mvp ✓", a), CO("Form filled", {
29578
29566
  spinner: !1,
29579
29567
  icon: "✅",
29580
29568
  duration: 1100
29581
29569
  }), a;
29582
29570
  } catch (e) {
29583
- let t = `flowengage_fill_form error: ${e?.message || String(e)}`;
29584
- return $("flowengage_fill_form ✖", t), CO("Failed to fill form", {
29571
+ let t = `fwh-fill-form-mvp error: ${e?.message || String(e)}`;
29572
+ return $("fwh-fill-form-mvp ✖", t), CO("Failed to fill form", {
29585
29573
  spinner: !1,
29586
29574
  icon: "⚠️",
29587
29575
  duration: 1800
@@ -29590,11 +29578,11 @@ function Ck(e) {
29590
29578
  RO(), AO(), wO(700);
29591
29579
  }
29592
29580
  },
29593
- flowengage_click_button: async (e) => {
29581
+ "fwh-click-button-mvp": async (e) => {
29594
29582
  let t = mk(e), n = (t.button_text ?? t.buttonText ?? t.text ?? "").trim();
29595
- if ($("flowengage_click_button ▶", n), !n) return "Missing button_text: pass the visible label, e.g. Conduct Audit.";
29583
+ if ($("fwh-click-button-mvp ▶", n), !n) return "Missing button_text: pass the visible label, e.g. Conduct Audit.";
29596
29584
  let r = pk(n, i);
29597
- if (!r) return $("flowengage_click_button ✖ no match"), `Could not find a button matching "${n}". Call flowengage_list_forms to see button texts.`;
29585
+ 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
29586
  try {
29599
29587
  CO(`Clicking ${n}...`, { spinner: !0 });
29600
29588
  try {
@@ -29607,14 +29595,14 @@ function Ck(e) {
29607
29595
  }
29608
29596
  await LO(r), r.focus?.(), await zO(r), BO(r), r.click();
29609
29597
  let e = (r.textContent || r.value || r.getAttribute("aria-label") || "").trim().slice(0, 80) || "button", t = `OK_CLICK ${e}`;
29610
- return $("flowengage_click_button ✓", t), CO(`Clicked ${e}`, {
29598
+ return $("fwh-click-button-mvp ✓", t), CO(`Clicked ${e}`, {
29611
29599
  spinner: !1,
29612
29600
  icon: "✅",
29613
29601
  duration: 1200
29614
29602
  }), t;
29615
29603
  } catch (e) {
29616
29604
  let t = `Click failed: ${e?.message || String(e)}`;
29617
- return $("flowengage_click_button ✖", t), CO("Click failed", {
29605
+ return $("fwh-click-button-mvp ✖", t), CO("Click failed", {
29618
29606
  spinner: !1,
29619
29607
  icon: "⚠️",
29620
29608
  duration: 1800
@@ -29626,18 +29614,17 @@ function Ck(e) {
29626
29614
  };
29627
29615
  return {
29628
29616
  ...a,
29629
- highlightOnPage: a.flowengage_highlight,
29630
- searchSiteContent: a.flowengage_search,
29631
- getPageContent: a.flowengage_page_content,
29632
- endVoiceSession: a.flowengage_end_session,
29633
- listPageForms: a.flowengage_list_forms,
29634
- fillFormFields: a.flowengage_fill_form,
29635
- clickPageButton: a.flowengage_click_button
29617
+ highlightOnPage: a["fwh-highlight-mvp"],
29618
+ getPageContent: a["fwh-page-content-mvp"],
29619
+ endVoiceSession: a["fwh-end-session-mvp"],
29620
+ listPageForms: a["fwh-list-forms-mvp"],
29621
+ fillFormFields: a["fwh-fill-form-mvp"],
29622
+ clickPageButton: a["fwh-click-button-mvp"]
29636
29623
  };
29637
29624
  }
29638
29625
  //#endregion
29639
29626
  //#region src/utils/wrapVoiceToolsForLogging.js
29640
- function wk(e) {
29627
+ function Ck(e) {
29641
29628
  return !e || typeof e != "object" ? e : Object.fromEntries(Object.entries(e).map(([e, t]) => [e, async (n) => {
29642
29629
  let r = Rn();
29643
29630
  r ? console.log("[FlowEngage:voice-tool] ▶", e, n) : console.info(`[FlowEngage] voice tool » ${e}`);
@@ -29654,7 +29641,7 @@ function wk(e) {
29654
29641
  }
29655
29642
  //#endregion
29656
29643
  //#region src/components/FlowEngageWidget.jsx
29657
- var Tk = {
29644
+ var wk = {
29658
29645
  blue: "#135bd8",
29659
29646
  red: "#ef334b",
29660
29647
  yellow: "#ffbd2e",
@@ -29662,7 +29649,7 @@ var Tk = {
29662
29649
  highlight: "rgba(255,255,255,0.9)",
29663
29650
  green: "#10b981"
29664
29651
  };
29665
- function Ek(e) {
29652
+ function Tk(e) {
29666
29653
  if (!Array.isArray(e) || e.length < 2) return "linear-gradient(145deg, #dce8f022 0%, #e8dff522 45%, #f5e0e022 100%), #f7f8fa";
29667
29654
  let [t, n, r] = e;
29668
29655
  return e.length >= 3 && r ? [
@@ -29676,12 +29663,12 @@ function Ek(e) {
29676
29663
  "#f7f8fa"
29677
29664
  ].join(", ");
29678
29665
  }
29679
- function Dk(e) {
29666
+ function Ek(e) {
29680
29667
  if (!e || typeof e != "string") return "#1a1a1a";
29681
29668
  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
29669
  return .2126 * o(r) + .7152 * o(i) + .0722 * o(a) > .179 ? "#1a1a1a" : "#ffffff";
29683
29670
  }
29684
- function Ok(t) {
29671
+ function Dk(t) {
29685
29672
  let [n, r] = e.useState(null), i = typeof t == "string" ? t.trim() : "";
29686
29673
  return e.useEffect(() => {
29687
29674
  if (!i) {
@@ -29699,8 +29686,8 @@ function Ok(t) {
29699
29686
  };
29700
29687
  }, [i]), n;
29701
29688
  }
29702
- function kk({ logo: t, style: n }) {
29703
- let r = Ok(typeof t == "string" ? t : null);
29689
+ function Ok({ logo: t, style: n }) {
29690
+ let r = Dk(typeof t == "string" ? t : null);
29704
29691
  if (!t) return null;
29705
29692
  if (typeof t == "string") return r ? /* @__PURE__ */ g("img", {
29706
29693
  src: r,
@@ -29725,7 +29712,7 @@ function kk({ logo: t, style: n }) {
29725
29712
  children: i
29726
29713
  }) : null;
29727
29714
  }
29728
- function Ak({ title: e }) {
29715
+ function kk({ title: e }) {
29729
29716
  return /* @__PURE__ */ g("div", {
29730
29717
  style: {
29731
29718
  width: "100%",
@@ -29743,18 +29730,18 @@ function Ak({ title: e }) {
29743
29730
  children: String(e || "FE").split(/\s+/).filter(Boolean).slice(0, 2).map((e) => e[0]?.toUpperCase() || "").join("") || "FE"
29744
29731
  });
29745
29732
  }
29746
- function jk(e, t) {
29733
+ function Ak(e, t) {
29747
29734
  let n = (t || "").trim();
29748
29735
  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
29736
  }
29750
- function Mk({ orbColors: e, ...t }) {
29737
+ function jk({ orbColors: e, ...t }) {
29751
29738
  return /* @__PURE__ */ g(lO, {
29752
29739
  colors: e,
29753
29740
  ...t
29754
29741
  });
29755
29742
  }
29756
- function Nk({ copy: e, orbColors: t, primaryColor: n, onYes: r, onLater: i, isMobile: a, isClosing: o }) {
29757
- let s = n || Tk.green, c = Dk(s), l = a ? 72 : 94, u = /* @__PURE__ */ _("div", {
29743
+ function Mk({ copy: e, orbColors: t, primaryColor: n, onYes: r, onLater: i, isMobile: a, isClosing: o }) {
29744
+ let s = n || wk.green, c = Ek(s), l = a ? 72 : 94, u = /* @__PURE__ */ _("div", {
29758
29745
  style: {
29759
29746
  display: "flex",
29760
29747
  alignItems: a ? "flex-end" : "center",
@@ -29875,7 +29862,7 @@ function Nk({ copy: e, orbColors: t, primaryColor: n, onYes: r, onLater: i, isMo
29875
29862
  delay: 0
29876
29863
  },
29877
29864
  style: { flexShrink: 0 },
29878
- children: /* @__PURE__ */ g(Mk, {
29865
+ children: /* @__PURE__ */ g(jk, {
29879
29866
  size: l,
29880
29867
  orbColors: t
29881
29868
  })
@@ -29907,8 +29894,8 @@ function Nk({ copy: e, orbColors: t, primaryColor: n, onYes: r, onLater: i, isMo
29907
29894
  children: u
29908
29895
  })] });
29909
29896
  }
29910
- function Pk({ copy: e, orbColors: t, primaryColor: n, onVoice: r, onText: i, onClose: a, isMobile: o, isClosing: s }) {
29911
- let c = n || Tk.green, l = Dk(c);
29897
+ function Nk({ copy: e, orbColors: t, primaryColor: n, onVoice: r, onText: i, onClose: a, isMobile: o, isClosing: s }) {
29898
+ let c = n || wk.green, l = Ek(c);
29912
29899
  return /* @__PURE__ */ _(Dm.div, {
29913
29900
  initial: {
29914
29901
  scale: 50 / 350,
@@ -29979,7 +29966,7 @@ function Pk({ copy: e, orbColors: t, primaryColor: n, onVoice: r, onText: i, onC
29979
29966
  children: /* @__PURE__ */ g("polyline", { points: "6 9 12 15 18 9" })
29980
29967
  })
29981
29968
  }),
29982
- /* @__PURE__ */ g(Mk, {
29969
+ /* @__PURE__ */ g(jk, {
29983
29970
  size: 72,
29984
29971
  orbColors: t
29985
29972
  }),
@@ -30048,13 +30035,17 @@ function Pk({ copy: e, orbColors: t, primaryColor: n, onVoice: r, onText: i, onC
30048
30035
  ]
30049
30036
  });
30050
30037
  }
30051
- function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i, apiBaseUrl: a, chatId: s, historyRef: l, onMessageSync: u, voiceEndCounter: d }) {
30052
- let [f, h] = m("idle"), [v, y] = m(!1), [b, x] = m(!1), S = p(null), C = p(""), w = p(async () => {}), T = p(!1), ee = p(!1), te = p(!1), ne = p(!1), re = p("minimized"), E = p(null), ie = p(null), ae = p(null), oe = p(0), D = p(!1), se = p("idle"), ce = p(!1), le = p(null), ue = p(null), de = p(!1), fe = o((e = "minimized") => {
30053
- re.current = e, ne.current = !0, queueMicrotask(() => {
30054
- T.current || (T.current = !0, w.current?.());
30055
- });
30056
- }, [l]), pe = o(async (e) => {
30057
- ne.current = !0;
30038
+ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i, apiBaseUrl: a, chatId: s, historyRef: l, onMessageSync: u, voiceEndCounter: d, websiteName: f }) {
30039
+ c(() => (console.log("[FlowEngage:VoiceDebug] 🔵 VoiceMode MOUNTED"), () => console.log("[FlowEngage:VoiceDebug] 🔴 VoiceMode UNMOUNTED")), []);
30040
+ 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") => {
30041
+ console.warn("[FlowEngage:VoiceDebug] 🛑 requestSessionShutdown called", {
30042
+ destination: e,
30043
+ stack: (/* @__PURE__ */ Error()).stack?.split("\n").slice(1, 4).join(" | ")
30044
+ }), E.current = e, re.current = !0, queueMicrotask(() => {
30045
+ ee.current || (ee.current = !0, T.current?.());
30046
+ });
30047
+ }, [l]), me = o(async (e) => {
30048
+ re.current = !0;
30058
30049
  try {
30059
30050
  SD();
30060
30051
  } catch {}
@@ -30062,9 +30053,9 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30062
30053
  He(i);
30063
30054
  } catch {}
30064
30055
  try {
30065
- await S.current?.endSession?.();
30056
+ await C.current?.endSession?.();
30066
30057
  } catch {}
30067
- let t = E.current, n = ie.current;
30058
+ let t = ie.current, n = ae.current;
30068
30059
  if (t && s && a) {
30069
30060
  let e = n ? Math.round((Date.now() - n) / 1e3) : 0;
30070
30061
  fetch(`${a}/api/voice/save-chat-recording`, {
@@ -30078,7 +30069,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30078
30069
  })
30079
30070
  }).catch((e) => console.warn("[FlowEngage] save-chat-recording failed:", e.message));
30080
30071
  }
30081
- if (E.current = null, ie.current = null, S.current = null, h("idle"), y(!1), T.current = !1, Ar(), i) try {
30072
+ if (ie.current = null, ae.current = null, C.current = null, v("idle"), b(!1), ee.current = !1, Ar(), i) try {
30082
30073
  Me(i);
30083
30074
  } catch {}
30084
30075
  typeof u == "function" && await u(l.current), e?.();
@@ -30089,26 +30080,26 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30089
30080
  s,
30090
30081
  a
30091
30082
  ]);
30092
- return w.current = () => pe(re.current === "chat" ? t : n), c(() => {
30093
- ee.current = v;
30094
- }, [v]), c(() => {
30095
- d && fe("chat");
30083
+ return T.current = () => me(E.current === "chat" ? t : n), c(() => {
30084
+ te.current = y;
30085
+ }, [y]), c(() => {
30086
+ d && pe("chat");
30096
30087
  }, [d]), c(() => {
30097
30088
  let e = !1, o = null, c = null, d = null;
30098
30089
  return (async () => {
30099
30090
  if (!r) {
30100
- h("error");
30091
+ v("error");
30101
30092
  return;
30102
30093
  }
30103
30094
  try {
30104
30095
  if ((await navigator.mediaDevices.getUserMedia({ audio: !0 })).getTracks().forEach((e) => e.stop()), e) return;
30105
- l.current = [], C.current = "", T.current = !1, te.current = !1, ne.current = !1, re.current = "minimized", kr({ onBeforeNavigate: () => {
30096
+ l.current = [], w.current = "", ee.current = !1, ne.current = !1, re.current = !1, E.current = "minimized", kr({ onBeforeNavigate: () => {
30106
30097
  if (i && l.current.length > 0) try {
30107
30098
  let e = vO(l.current);
30108
30099
  e && Ae(i, e);
30109
30100
  } catch {}
30110
30101
  if (!er()) {
30111
- let e = E.current, t = ie.current;
30102
+ let e = ie.current, t = ae.current;
30112
30103
  if (e && s && a) try {
30113
30104
  let n = t ? Math.round((Date.now() - t) / 1e3) : 0, r = JSON.stringify({
30114
30105
  chatId: s,
@@ -30121,19 +30112,19 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30121
30112
  headers: { "Content-Type": "application/json" },
30122
30113
  body: r,
30123
30114
  keepalive: !0
30124
- }).catch(() => {}), E.current = null, ie.current = null;
30115
+ }).catch(() => {}), ie.current = null, ae.current = null;
30125
30116
  } catch {}
30126
30117
  }
30127
30118
  Pe();
30128
30119
  } });
30129
- let t = wk(Ck({
30120
+ let t = Ck(Sk({
30130
30121
  siteId: i || null,
30131
30122
  apiBaseUrl: a || null,
30132
- getLastUserVoiceText: () => C.current,
30123
+ getLastUserVoiceText: () => w.current,
30133
30124
  requestEndSession: () => {
30134
- D.current = !0;
30125
+ se.current = !0;
30135
30126
  }
30136
- })), n = i ? je(i) : null, u = !!n?.transcript, f = !!(i && He(i)), p = typeof window < "u" ? window.location.pathname : "/", m = typeof document < "u" ? document.title : "", g = p === "/" || p === "", _ = null;
30127
+ })), 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
30128
  try {
30138
30129
  let e = await fetch(`${a}/api/voice/signed-url?siteId=${encodeURIComponent(i || "")}`, {
30139
30130
  method: "GET",
@@ -30148,39 +30139,55 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30148
30139
  if (e.message && e.message.includes("Too many voice sessions")) throw e;
30149
30140
  console.warn("[FlowEngage] ⚠️ Signed URL fetch error:", e.message);
30150
30141
  }
30151
- let v = {
30142
+ let y = {
30152
30143
  clientTools: t,
30153
30144
  connectionType: "websocket",
30154
30145
  minSpeechDurationMs: 50,
30155
30146
  ..._ ? { signedUrl: _ } : { agentId: r }
30156
- }, b = (p.split("/").filter(Boolean).pop() || "").replace(/[-_]/g, " ").replace(/\b\w/g, (e) => e.toUpperCase()), x = "";
30157
- m && m.includes("|") && (x = m.split("|").map((e) => e.trim()).filter(Boolean).reduce((e, t) => e.length <= t.length ? e : t));
30158
- let w = x || b || "this page";
30159
- _ ? f ? (v.overrides = { agent: { firstMessage: `I've navigated you to the ${w} page. Let me walk you through what's here.` } }, console.log(`[FlowEngage] 🔄 Agent-nav resume: firstMessage set for "${w}" (${p})`)) : u ? v.overrides = { agent: { firstMessage: "I'm still here. Go ahead!" } } : g || (v.overrides = { agent: { firstMessage: `Hi! I see you are currently on the ${w} page. Are you looking for something specific here?` } }, console.log(`[FlowEngage] 🏠 Page-context override: "${w}" for ${p}`)) : u && (v.overrides = { agent: { firstMessage: "" } });
30160
- let ae = !1, pe = f ? `NAVIGATION RESUME — Your intro has been spoken. NOW — without waiting for the visitor to say anything — call flowengage_highlight for the first content section on this page, then speak one sentence about it. Continue section by section (highlight + one sentence each) until you have covered the key content. Prior conversation context:\n${(i ? je(i) : null)?.transcript || ""}\n\n` : null, me = await vD.startSession({
30161
- ...v,
30147
+ }, x = (m.split("/").filter(Boolean).pop() || "").replace(/[-_]/g, " ").replace(/\b\w/g, (e) => e.toUpperCase()), S = "";
30148
+ h && h.includes("|") && (S = h.split("|").map((e) => e.trim()).filter(Boolean).reduce((e, t) => e.length <= t.length ? e : t));
30149
+ let T = S || x || "this page";
30150
+ if (_) if (p) y.overrides = { agent: { firstMessage: `I've navigated you to the ${T} page. Let me walk you through what's here.` } }, console.log(`[FlowEngage] 🔄 Agent-nav resume: firstMessage set for "${T}" (${m})`);
30151
+ else if (u) y.overrides = { agent: { firstMessage: "I'm still here. Go ahead!" } };
30152
+ else {
30153
+ let e = f || "";
30154
+ 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}`);
30155
+ }
30156
+ else u && (y.overrides = { agent: { firstMessage: "" } });
30157
+ let oe = !1, me = p ? `NAVIGATION RESUME — Your intro has been spoken. NOW — without waiting for the visitor to say anything — call fwh-highlight-mvp for the first content section on this page, then speak one sentence about it. Continue with the top 3 sections only (highlight + one sentence each). Prior conversation context:\n${(i ? je(i) : null)?.transcript || ""}\n\n` : null, he = !1, ge = !p && !u ? "AUTO-START — Your greeting has been spoken. NOW — without waiting for the visitor to say anything — call fwh-get-current-page-mvp, then immediately highlight the top 3 sections and give a one-sentence summary for each. Keep it brisk — no filler, no questions until the walkthrough is done." : null, _e = await vD.startSession({
30158
+ ...y,
30162
30159
  onConnect: ({ conversationId: e }) => {
30163
- E.current = e, ie.current = Date.now(), console.log("[FlowEngage] 🎙️ AI chat session connected:", e);
30160
+ ie.current = e, ae.current = Date.now(), console.log("[FlowEngage] 🎙️ AI chat session connected:", e);
30164
30161
  },
30165
30162
  onUnhandledClientToolCall: (e) => console.error("[FlowEngage] Unhandled tool:", e?.tool_name),
30166
30163
  onModeChange: ({ mode: t }) => {
30167
30164
  if (!e) {
30168
30165
  if (t === "speaking") {
30169
- ue.current &&= (clearTimeout(ue.current), null), h("speaking"), se.current = "speaking", ce.current = !0, de.current = !1, le.current &&= (clearTimeout(le.current), null);
30166
+ de.current &&= (clearTimeout(de.current), null), v("speaking"), ce.current = "speaking", le.current = !0, fe.current = !1, ue.current &&= (clearTimeout(ue.current), null);
30170
30167
  return;
30171
30168
  }
30172
- if (se.current = "listening", D.current) {
30173
- D.current = !1, fe();
30169
+ if (ce.current = "listening", se.current) {
30170
+ se.current = !1, pe();
30174
30171
  return;
30175
30172
  }
30176
- if (pe && !ae) {
30177
- ae = !0;
30173
+ if (me && !oe) {
30174
+ oe = !0;
30175
+ try {
30176
+ C.current?.sendUserMessage?.("continue with the tour");
30177
+ } catch {}
30178
+ }
30179
+ if (ge && !he) {
30180
+ he = !0;
30178
30181
  try {
30179
- S.current?.sendUserMessage?.("continue with the tour");
30182
+ C.current?.sendContextualUpdate?.(ge);
30180
30183
  } catch {}
30181
30184
  }
30182
- ue.current && clearTimeout(ue.current), ue.current = setTimeout(() => {
30183
- e || se.current !== "speaking" && (de.current || (ue.current = null, se.current = "listening", h("listening")));
30185
+ de.current && clearTimeout(de.current), de.current = setTimeout(() => {
30186
+ e || ce.current !== "speaking" && (fe.current || (de.current = null, ce.current = "listening", v("listening"), le.current && !te.current && (ue.current && clearTimeout(ue.current), ue.current = setTimeout(() => {
30187
+ if (!e && ce.current === "listening" && !te.current) try {
30188
+ C.current?.sendContextualUpdate?.("The visitor has been silent for a while. Ask one short, natural question to re-engage — for example: 'Is there anything specific you'd like to know more about?' or 'What else can I help you with today?' Keep it to one sentence.");
30189
+ } catch {}
30190
+ }, 4e3))));
30184
30191
  }, 1200);
30185
30192
  }
30186
30193
  },
@@ -30188,7 +30195,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30188
30195
  if (e) return;
30189
30196
  let n = t.role === "user" ? "user" : "bot", r = t.message || t.text || t.content || "";
30190
30197
  if (r) {
30191
- if (n === "user" && (C.current = r, de.current = !0, ue.current &&= (clearTimeout(ue.current), null), le.current &&= (clearTimeout(le.current), null)), l.current = [...l.current, {
30198
+ 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
30199
  sender: n,
30193
30200
  message: r,
30194
30201
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
@@ -30196,63 +30203,58 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30196
30203
  let e = vO(l.current);
30197
30204
  e && Ae(i, e);
30198
30205
  } catch {}
30199
- if (jk(n, r)) {
30200
- fe("minimized");
30206
+ if (Ak(n, r)) {
30207
+ pe("minimized");
30201
30208
  return;
30202
30209
  }
30203
- if (ee.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 (oe.current += 1, oe.current === 2) try {
30204
- S.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 flowengage_end_session tool to end the voice session. Do NOT ask again after that.");
30210
+ 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 {
30211
+ 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
30212
  } catch {}
30206
- else oe.current >= 5 && fe("minimized");
30213
+ else D.current >= 5 && pe("minimized");
30207
30214
  }
30208
30215
  },
30209
30216
  onError: (t) => {
30210
- if (!e && !ne.current && !te.current && !ze()) {
30211
- te.current = !0, console.error("[FlowEngageVoiceCall] session:error", {
30217
+ if (!e && !re.current && !ne.current && !ze()) {
30218
+ ne.current = !0, console.error("[FlowEngageVoiceCall] session:error", {
30212
30219
  message: t?.message,
30213
30220
  name: t?.name,
30214
30221
  raw: t
30215
30222
  });
30216
30223
  try {
30217
- S.current?.setMicMuted?.(!0);
30224
+ C.current?.setMicMuted?.(!0);
30218
30225
  } catch {}
30219
- y(!0), h("error"), fe("chat");
30226
+ b(!0), v("error"), pe("chat");
30220
30227
  }
30221
30228
  },
30222
30229
  onDisconnect: (t) => {
30223
- if (e || ne.current || te.current || ze()) return;
30230
+ if (e || re.current || ne.current || ze()) return;
30224
30231
  let n = l.current?.length || 0;
30225
30232
  console.warn("[FlowEngageVoiceCall] session:disconnected", {
30226
30233
  historyCount: n,
30227
30234
  reason: t?.reason,
30228
30235
  closeCode: t?.context?.code,
30229
30236
  closeReason: t?.context?.reason || t?.message,
30230
- lastUserText: C.current || "",
30231
- wasMuted: ee.current
30232
- }), te.current = !0;
30237
+ lastUserText: w.current || "",
30238
+ wasMuted: te.current
30239
+ }), ne.current = !0;
30233
30240
  try {
30234
- S.current?.setMicMuted?.(!0);
30241
+ C.current?.setMicMuted?.(!0);
30235
30242
  } catch {}
30236
- y(!0), fe("chat");
30243
+ b(!0), pe("chat");
30237
30244
  }
30238
30245
  });
30239
30246
  if (e) {
30240
- me.endSession().catch(() => {});
30247
+ console.warn("[FlowEngage:VoiceDebug] ❌ cancelled=true after startSession resolved — killing session immediately"), _e.endSession().catch(() => {});
30241
30248
  return;
30242
30249
  }
30243
- o = me, S.current = me, h("listening");
30250
+ o = _e, C.current = _e, v("listening");
30244
30251
  try {
30245
30252
  let e = typeof window < "u" ? window.location.href : "", r = "[]";
30246
30253
  try {
30247
- r = await t.list_page_forms();
30248
- } catch {}
30249
- let a = "none";
30250
- if (typeof window < "u" && typeof document < "u") try {
30251
- let e = "#flowengage-root, .flowengage-shell, .flowengage-widget-root", t = document.querySelector("main, [role='main'], article") || 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
- 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(" | "));
30254
+ r = await t["fwh-list-forms-mvp"]();
30253
30255
  } catch {}
30254
- let o = u && !f ? `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` : "";
30255
- me.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
+ let a = 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` : "";
30257
+ _e.sendContextualUpdate(`${a}Page: ${e}. SiteId: ${i || "unknown"}. Forms: ${r}. Voice: call end_voice_session or say you are ending the session to stop.`);
30256
30258
  } catch {}
30257
30259
  if (typeof window < "u") {
30258
30260
  let t = window.location.pathname, n = () => {
@@ -30281,7 +30283,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30281
30283
  ts: Date.now()
30282
30284
  });
30283
30285
  try {
30284
- S.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.]`);
30286
+ 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
30287
  } catch {}
30286
30288
  };
30287
30289
  c = window.history.pushState.bind(window.history), window.history.pushState = (...e) => {
@@ -30289,33 +30291,37 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30289
30291
  }, d = () => setTimeout(n, 50), window.addEventListener("popstate", d);
30290
30292
  }
30291
30293
  } 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")) : (h("error"), re.current = "chat", window.setTimeout(() => {
30294
+ 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
30295
  e || t?.();
30294
30296
  }, 0)));
30295
30297
  }
30296
30298
  })(), () => {
30297
- e = !0, ne.current = !0;
30299
+ console.warn("[FlowEngage:VoiceDebug] ⚠️ useEffect CLEANUP fired — session will be killed", {
30300
+ agentId: r,
30301
+ siteId: i,
30302
+ apiBaseUrl: a
30303
+ }), e = !0, re.current = !0;
30298
30304
  try {
30299
30305
  SD();
30300
30306
  } catch {}
30301
30307
  if (i) try {
30302
30308
  He(i);
30303
30309
  } catch {}
30304
- typeof window < "u" && (window.__fe_user_nav_during_speech = null), Ar(), le.current &&= (clearTimeout(le.current), null), ue.current &&= (clearTimeout(ue.current), null), ce.current = !1, de.current = !1, se.current = "idle", c && typeof window < "u" && (window.history.pushState = c), d && typeof window < "u" && window.removeEventListener("popstate", d);
30305
- let t = o || S.current, n = E.current, r = ie.current;
30310
+ 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);
30311
+ let t = o || C.current, n = ie.current, f = ae.current;
30306
30312
  if (t?.endSession?.().catch(() => {}), n && s && a) {
30307
- let e = r ? Math.round((Date.now() - r) / 1e3) : 0, t = JSON.stringify({
30313
+ let e = f ? Math.round((Date.now() - f) / 1e3) : 0, t = JSON.stringify({
30308
30314
  chatId: s,
30309
30315
  elevenLabsConversationId: n,
30310
30316
  duration: e,
30311
30317
  siteId: i
30312
- }), o = `${a}/api/voice/save-chat-recording`;
30313
- typeof navigator < "u" && navigator.sendBeacon && navigator.sendBeacon(o, new Blob([t], { type: "application/json" })) || fetch(o, {
30318
+ }), r = `${a}/api/voice/save-chat-recording`;
30319
+ typeof navigator < "u" && navigator.sendBeacon && navigator.sendBeacon(r, new Blob([t], { type: "application/json" })) || fetch(r, {
30314
30320
  method: "POST",
30315
30321
  headers: { "Content-Type": "application/json" },
30316
30322
  body: t,
30317
30323
  keepalive: !0
30318
- }).catch(() => {}), E.current = null, ie.current = null;
30324
+ }).catch(() => {}), ie.current = null, ae.current = null;
30319
30325
  }
30320
30326
  typeof u == "function" && l.current.length > 0 && u(l.current).catch?.(() => {});
30321
30327
  };
@@ -30323,16 +30329,16 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30323
30329
  r,
30324
30330
  i,
30325
30331
  a,
30326
- fe
30332
+ pe
30327
30333
  ]), c(() => {
30328
- if (!b) return;
30334
+ if (!x) return;
30329
30335
  let e = (e) => {
30330
30336
  let t = e.composedPath?.()?.[0] || e.target;
30331
- ae.current && !ae.current.contains(t) && x(!1);
30337
+ oe.current && !oe.current.contains(t) && S(!1);
30332
30338
  };
30333
30339
  return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
30334
- }, [b]), /* @__PURE__ */ _("div", {
30335
- ref: ae,
30340
+ }, [x]), /* @__PURE__ */ _("div", {
30341
+ ref: oe,
30336
30342
  style: {
30337
30343
  position: "relative",
30338
30344
  display: "flex",
@@ -30345,7 +30351,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30345
30351
  /* @__PURE__ */ _("div", {
30346
30352
  style: { position: "relative" },
30347
30353
  children: [
30348
- f === "listening" && !v && /* @__PURE__ */ g("span", {
30354
+ h === "listening" && !y && /* @__PURE__ */ g("span", {
30349
30355
  style: {
30350
30356
  position: "absolute",
30351
30357
  right: "100%",
@@ -30361,7 +30367,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30361
30367
  },
30362
30368
  children: "Listening..."
30363
30369
  }),
30364
- v && /* @__PURE__ */ g("span", {
30370
+ y && /* @__PURE__ */ g("span", {
30365
30371
  style: {
30366
30372
  position: "absolute",
30367
30373
  right: "100%",
@@ -30377,15 +30383,15 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30377
30383
  },
30378
30384
  children: "Muted"
30379
30385
  }),
30380
- /* @__PURE__ */ g(Mk, {
30386
+ /* @__PURE__ */ g(jk, {
30381
30387
  size: 72,
30382
- voiceState: f,
30383
- isMuted: v,
30388
+ voiceState: h,
30389
+ isMuted: y,
30384
30390
  orbColors: e
30385
30391
  })
30386
30392
  ]
30387
30393
  }),
30388
- f === "error" && /* @__PURE__ */ g("span", {
30394
+ h === "error" && /* @__PURE__ */ g("span", {
30389
30395
  style: {
30390
30396
  color: "#f87171",
30391
30397
  fontSize: "13px",
@@ -30401,38 +30407,38 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30401
30407
  },
30402
30408
  children: [/* @__PURE__ */ g("button", {
30403
30409
  onClick: async () => {
30404
- if (S.current) try {
30405
- if (v) {
30406
- oe.current = 0, await S.current.setMicMuted?.(!1), y(!1);
30410
+ if (C.current) try {
30411
+ if (y) {
30412
+ D.current = 0, await C.current.setMicMuted?.(!1), b(!1);
30407
30413
  try {
30408
- S.current.sendContextualUpdate?.("The visitor has unmuted. Resume normal interaction and wait for them to speak.");
30414
+ C.current.sendContextualUpdate?.("The visitor has unmuted. Resume normal interaction and wait for them to speak.");
30409
30415
  } catch {}
30410
30416
  } else {
30411
- oe.current = 0, await S.current.setMicMuted?.(!0), y(!0);
30417
+ D.current = 0, await C.current.setMicMuted?.(!0), b(!0);
30412
30418
  try {
30413
- S.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.");
30419
+ 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
30420
  } catch {}
30415
30421
  }
30416
30422
  } catch {}
30417
30423
  },
30418
- title: v ? "Unmute" : "Mute",
30424
+ title: y ? "Unmute" : "Mute",
30419
30425
  style: {
30420
30426
  width: "24px",
30421
30427
  height: "24px",
30422
30428
  borderRadius: "50%",
30423
- background: v ? "#7f1d1d" : "#1f2937",
30424
- border: v ? "1.5px solid #ef4444" : "1.5px solid #4b5563",
30429
+ background: y ? "#7f1d1d" : "#1f2937",
30430
+ border: y ? "1.5px solid #ef4444" : "1.5px solid #4b5563",
30425
30431
  display: "flex",
30426
30432
  alignItems: "center",
30427
30433
  justifyContent: "center",
30428
30434
  cursor: "pointer",
30429
- color: v ? "#f87171" : "white",
30435
+ color: y ? "#f87171" : "white",
30430
30436
  transition: "all 0.2s ease",
30431
30437
  boxShadow: "0 2px 8px rgba(0,0,0,0.4)",
30432
30438
  padding: 0,
30433
30439
  flexShrink: 0
30434
30440
  },
30435
- children: v ? /* @__PURE__ */ _("svg", {
30441
+ children: y ? /* @__PURE__ */ _("svg", {
30436
30442
  width: "16",
30437
30443
  height: "16",
30438
30444
  viewBox: "0 0 24 24",
@@ -30468,7 +30474,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30468
30474
  color: "currentColor"
30469
30475
  })
30470
30476
  }), /* @__PURE__ */ g("button", {
30471
- onClick: () => x((e) => !e),
30477
+ onClick: () => S((e) => !e),
30472
30478
  style: {
30473
30479
  width: "24px",
30474
30480
  height: "24px",
@@ -30491,7 +30497,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30491
30497
  })
30492
30498
  })]
30493
30499
  }),
30494
- b && /* @__PURE__ */ _("div", {
30500
+ x && /* @__PURE__ */ _("div", {
30495
30501
  style: {
30496
30502
  position: "absolute",
30497
30503
  bottom: 0,
@@ -30509,7 +30515,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30509
30515
  children: [
30510
30516
  /* @__PURE__ */ _("button", {
30511
30517
  onClick: () => {
30512
- x(!1), re.current = "chat", pe(t);
30518
+ S(!1), E.current = "chat", me(t);
30513
30519
  },
30514
30520
  style: {
30515
30521
  display: "flex",
@@ -30538,7 +30544,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30538
30544
  }),
30539
30545
  /* @__PURE__ */ _("button", {
30540
30546
  onClick: () => {
30541
- x(!1), re.current = "minimized", pe(n);
30547
+ S(!1), E.current = "minimized", me(n);
30542
30548
  },
30543
30549
  style: {
30544
30550
  display: "flex",
@@ -30566,7 +30572,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30566
30572
  children: [/* @__PURE__ */ g(ND, {}), "End Conversation"]
30567
30573
  }),
30568
30574
  /* @__PURE__ */ g("button", {
30569
- onClick: () => x(!1),
30575
+ onClick: () => S(!1),
30570
30576
  style: {
30571
30577
  position: "absolute",
30572
30578
  bottom: "8px",
@@ -30615,7 +30621,7 @@ function Fk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30615
30621
  ]
30616
30622
  });
30617
30623
  }
30618
- function Ik({ orbColors: e }) {
30624
+ function Fk({ orbColors: e }) {
30619
30625
  return /* @__PURE__ */ g("div", {
30620
30626
  style: {
30621
30627
  flexShrink: 0,
@@ -30625,13 +30631,13 @@ function Ik({ orbColors: e }) {
30625
30631
  alignItems: "center",
30626
30632
  justifyContent: "center"
30627
30633
  },
30628
- children: /* @__PURE__ */ g(Mk, {
30634
+ children: /* @__PURE__ */ g(jk, {
30629
30635
  size: 36,
30630
30636
  orbColors: e
30631
30637
  })
30632
30638
  });
30633
30639
  }
30634
- var Lk = () => /* @__PURE__ */ g("div", {
30640
+ var Ik = () => /* @__PURE__ */ g("div", {
30635
30641
  style: {
30636
30642
  display: "flex",
30637
30643
  marginBottom: "12px",
@@ -30661,7 +30667,7 @@ var Lk = () => /* @__PURE__ */ g("div", {
30661
30667
  } }, e))
30662
30668
  })
30663
30669
  });
30664
- function Rk({ 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 }) {
30670
+ 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
30671
  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
30672
  c(() => {
30667
30673
  if (!s) return;
@@ -30797,7 +30803,7 @@ function Rk({ copy: e, orbColors: t, primaryColor: n, chatBgGradient: r, logo: i
30797
30803
  justifyContent: "center",
30798
30804
  height: "40px"
30799
30805
  },
30800
- children: i ? /* @__PURE__ */ g(kk, {
30806
+ children: i ? /* @__PURE__ */ g(Ok, {
30801
30807
  logo: i,
30802
30808
  style: {
30803
30809
  height: "34px",
@@ -30810,7 +30816,7 @@ function Rk({ copy: e, orbColors: t, primaryColor: n, chatBgGradient: r, logo: i
30810
30816
  height: "40px",
30811
30817
  flexShrink: 0
30812
30818
  },
30813
- children: /* @__PURE__ */ g(Ak, { title: e.chatTitle })
30819
+ children: /* @__PURE__ */ g(kk, { title: e.chatTitle })
30814
30820
  })
30815
30821
  }), /* @__PURE__ */ g("div", {
30816
30822
  style: {
@@ -31240,11 +31246,11 @@ function Rk({ copy: e, orbColors: t, primaryColor: n, chatBgGradient: r, logo: i
31240
31246
  isLoading: T,
31241
31247
  isAgentTyping: d,
31242
31248
  setReplyContext: de,
31243
- TypingDots: Lk,
31249
+ TypingDots: Ik,
31244
31250
  primaryColor: n,
31245
31251
  agentHeadshot: y,
31246
31252
  agentDisplayName: v || b,
31247
- botAvatarNode: /* @__PURE__ */ g(Ik, { orbColors: t })
31253
+ botAvatarNode: /* @__PURE__ */ g(Fk, { orbColors: t })
31248
31254
  }) : Ae ? /* @__PURE__ */ _("div", {
31249
31255
  style: {
31250
31256
  flex: 1,
@@ -31285,7 +31291,7 @@ function Rk({ copy: e, orbColors: t, primaryColor: n, chatBgGradient: r, logo: i
31285
31291
  padding: "28px 24px"
31286
31292
  },
31287
31293
  children: [
31288
- /* @__PURE__ */ g(Mk, {
31294
+ /* @__PURE__ */ g(jk, {
31289
31295
  size: 94,
31290
31296
  orbColors: t
31291
31297
  }),
@@ -31427,14 +31433,14 @@ function Rk({ copy: e, orbColors: t, primaryColor: n, chatBgGradient: r, logo: i
31427
31433
  ]
31428
31434
  });
31429
31435
  }
31430
- function zk() {
31436
+ function Rk() {
31431
31437
  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
31438
  c(() => {
31433
31439
  try {
31434
31440
  pr();
31435
31441
  } catch {}
31436
31442
  }, []), c(() => {
31437
- Ee && A !== "text_chat" && A !== "call_screen" && (ue?.(!1), st("text_chat"));
31443
+ Ee && A !== "voice_mode" && A !== "text_chat" && A !== "call_screen" && (ue?.(!1), ot("text_chat"));
31438
31444
  }, [Ee]);
31439
31445
  let Oe = t?.widgetSettings || {}, ke = n?.widgetSettings || {}, Ae = {
31440
31446
  ...Oe.branding || {},
@@ -31449,7 +31455,7 @@ function zk() {
31449
31455
  small: 50,
31450
31456
  medium: 64,
31451
31457
  large: 80
31452
- }, Ve = Be[Ne.orbSize] || Be.small, He = Ne.position || "bottom-right", O = Ae.fallbackAgentName || "Agent", Ue = Ek(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) => ({
31458
+ }, 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
31459
  id: e.key || `qr-${t}`,
31454
31460
  label: e.label,
31455
31461
  message: e.label,
@@ -31472,11 +31478,11 @@ function zk() {
31472
31478
  ]), rt = u && String(u).trim() || t?.ownerProfileImageUrl && String(t.ownerProfileImageUrl).trim() || null, it = r.some((e) => e.sender === "user"), at = f(() => {
31473
31479
  let e = r.findIndex((e) => e.sender === "user");
31474
31480
  return e === -1 ? !1 : r.slice(e + 1).some((e) => e.sender === "bot" || e.sender === "ai" || e.sender === "agent");
31475
- }, [r]), k = !h && it && at, ot = !!(ke._dashboardLivePreview || Oe._dashboardLivePreview), [A, st] = m(() => ot ? "text_chat" : "entry_prompt"), [ct, lt] = m(""), [ut, dt] = m(null), [ft, pt] = m(h || ""), [mt, ht] = m(""), [gt, j] = m(!1), [_t, vt] = m(0), [yt, bt] = m(null), [xt, St] = m(null), [Ct, wt] = m(""), [Tt, Et] = m(!1), [Dt, Ot] = m(!1), [kt, At] = m(!1), jt = p(null), Mt = p(!1);
31481
+ }, [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
31482
  d(() => {
31477
- if (e !== "ready" || Mt.current) return;
31478
- if (Mt.current = !0, !Ie) {
31479
- st("minimized_orb");
31483
+ if (e !== "ready" || jt.current) return;
31484
+ if (jt.current = !0, !Ie) {
31485
+ ot("minimized_orb");
31480
31486
  return;
31481
31487
  }
31482
31488
  let t = !1;
@@ -31485,22 +31491,22 @@ function zk() {
31485
31491
  } catch {}
31486
31492
  let n = Fe(), r = et ? je(et) : null, i = n || !!r?.transcript;
31487
31493
  if (t) {
31488
- ce?.({ notifyChatInitiated: !0 }), ue?.(!0), st("voice_mode");
31494
+ ce?.({ notifyChatInitiated: !0 }), ue?.(!0), ot("voice_mode");
31489
31495
  return;
31490
31496
  }
31491
31497
  if (Re()) {
31492
- ce?.({ notifyChatInitiated: !1 }), st("text_chat");
31498
+ ce?.({ notifyChatInitiated: !1 }), ot("text_chat");
31493
31499
  return;
31494
31500
  }
31495
- if (et) try {
31496
- Me(et);
31497
- } catch {}
31498
31501
  if (i) {
31499
- st("minimized_orb");
31502
+ ce?.({ notifyChatInitiated: !0 }), ue?.(!0), ot("voice_mode");
31500
31503
  return;
31501
31504
  }
31505
+ if (et) try {
31506
+ Me(et);
31507
+ } catch {}
31502
31508
  if (fe(et)) {
31503
- st("minimized_orb");
31509
+ ot("minimized_orb");
31504
31510
  return;
31505
31511
  }
31506
31512
  }, [e, r]);
@@ -31509,55 +31515,55 @@ function zk() {
31509
31515
  let e = window.matchMedia("(max-width: 640px)"), t = (e) => Pt(e.matches);
31510
31516
  return e.addEventListener("change", t), () => e.removeEventListener("change", t);
31511
31517
  }, []), c(() => {
31512
- pt(h || ""), h && ht("");
31518
+ ft(h || ""), h && mt("");
31513
31519
  }, [h]);
31514
31520
  let Ft = o(() => {
31515
- St(null), wt("");
31521
+ xt(null), Ct("");
31516
31522
  }, []), It = o((e) => {
31517
31523
  let t = qD(e);
31518
31524
  if (t) {
31519
- St(null), wt(t);
31525
+ xt(null), Ct(t);
31520
31526
  return;
31521
31527
  }
31522
- St(e), wt("");
31528
+ xt(e), Ct("");
31523
31529
  }, []);
31524
31530
  c(() => {
31525
31531
  if (!te || ee !== "connected") {
31526
- vt(0);
31532
+ _t(0);
31527
31533
  return;
31528
31534
  }
31529
31535
  let e = () => {
31530
31536
  let e = new Date(te).getTime();
31531
- isNaN(e) || vt(Math.max(0, Math.floor((Date.now() - e) / 1e3)));
31537
+ isNaN(e) || _t(Math.max(0, Math.floor((Date.now() - e) / 1e3)));
31532
31538
  };
31533
31539
  e();
31534
31540
  let t = window.setInterval(e, 1e3);
31535
31541
  return () => window.clearInterval(t);
31536
31542
  }, [te, ee]);
31537
31543
  let Lt = o(() => {
31538
- st("call_screen"), Ot(!1);
31544
+ ot("call_screen"), Dt(!1);
31539
31545
  }, []), Rt = o(() => {
31540
- st("text_chat"), Ot(!0);
31546
+ ot("text_chat"), Dt(!0);
31541
31547
  }, []);
31542
31548
  c(() => {
31543
31549
  let e = w?.callId || T || null;
31544
31550
  if (!e) {
31545
- jt.current = null;
31551
+ At.current = null;
31546
31552
  return;
31547
31553
  }
31548
31554
  if (w?.callId || ee === "connecting" || ee === "connected") {
31549
- if (A === "minimized_orb" && Dt && T && !w?.callId) {
31550
- jt.current = e;
31555
+ if (A === "minimized_orb" && Et && T && !w?.callId) {
31556
+ At.current = e;
31551
31557
  return;
31552
31558
  }
31553
- !(!i || A === "minimized_orb" || A === "voice_mode") && jt.current === e || (console.log("[FlowEngageWidget] forcing call UI to front", {
31559
+ !(!i || A === "minimized_orb" || A === "voice_mode") && At.current === e || (console.log("[FlowEngageWidget] forcing call UI to front", {
31554
31560
  forcedKey: e,
31555
31561
  isOpen: i,
31556
31562
  surface: A,
31557
31563
  hasIncomingCall: !!w?.callId,
31558
31564
  activeCallId: T,
31559
31565
  callConnectionState: ee
31560
- }), jt.current = e, A === "voice_mode" && ue?.(!1), ce?.(), Lt());
31566
+ }), At.current = e, A === "voice_mode" && ue?.(!1), ce?.(), Lt());
31561
31567
  }
31562
31568
  }, [
31563
31569
  T,
@@ -31569,31 +31575,31 @@ function zk() {
31569
31575
  ue,
31570
31576
  A
31571
31577
  ]), c(() => {
31572
- !w && !T && A === "call_screen" && st("text_chat");
31578
+ !w && !T && A === "call_screen" && ot("text_chat");
31573
31579
  }, [
31574
31580
  w,
31575
31581
  T,
31576
31582
  A
31577
31583
  ]), c(() => {
31578
- !T && Dt && Ot(!1);
31579
- }, [T, Dt]), c(() => {
31584
+ !T && Et && Dt(!1);
31585
+ }, [T, Et]), c(() => {
31580
31586
  if (!s || C) {
31581
31587
  Se?.(""), xe?.();
31582
31588
  return;
31583
31589
  }
31584
- if (!ct.trim() || xt) {
31590
+ if (!st.trim() || bt) {
31585
31591
  Se?.("");
31586
31592
  let e = window.setTimeout(() => xe?.(), 100);
31587
31593
  return () => window.clearTimeout(e);
31588
31594
  }
31589
31595
  be?.();
31590
- let e = window.setTimeout(() => Se?.(ct), 120), t = window.setTimeout(() => xe?.(), 1200);
31596
+ let e = window.setTimeout(() => Se?.(st), 120), t = window.setTimeout(() => xe?.(), 1200);
31591
31597
  return () => {
31592
31598
  window.clearTimeout(e), window.clearTimeout(t);
31593
31599
  };
31594
31600
  }, [
31595
- ct,
31596
- xt,
31601
+ st,
31602
+ bt,
31597
31603
  s,
31598
31604
  C,
31599
31605
  be,
@@ -31606,39 +31612,39 @@ function zk() {
31606
31612
  replyToSender: e.sender || null
31607
31613
  } : null, Bt = async (e) => {
31608
31614
  if (e.preventDefault(), C) return;
31609
- if (k) {
31610
- let e = ft.trim().toLowerCase();
31615
+ if (Mt) {
31616
+ let e = dt.trim().toLowerCase();
31611
31617
  if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)) {
31612
- ht("Please enter a valid email so we can continue helping you.");
31618
+ mt("Please enter a valid email so we can continue helping you.");
31613
31619
  return;
31614
31620
  }
31615
- await le(e), ht(""), j(!0), setTimeout(() => j(!1), 3e3);
31621
+ await le(e), mt(""), gt(!0), setTimeout(() => gt(!1), 3e3);
31616
31622
  return;
31617
31623
  }
31618
- let t = zt(ut);
31619
- if (!ct.trim() && !xt) return;
31620
- if (xt) {
31624
+ let t = zt(lt);
31625
+ if (!st.trim() && !bt) return;
31626
+ if (bt) {
31621
31627
  try {
31622
- Et(!0), wt("");
31623
- let e = await se(xt), n = e?.data || e, r = ct.trim() || `Shared file: ${YD(xt)}`;
31624
- lt(""), dt(null), Ft(), await D(r, "", t, {
31628
+ Tt(!0), Ct("");
31629
+ let e = await se(bt), n = e?.data || e, r = st.trim() || `Shared file: ${YD(bt)}`;
31630
+ ct(""), ut(null), Ft(), await D(r, "", t, {
31625
31631
  type: "file",
31626
31632
  metadata: {
31627
31633
  fileUrl: n?.fileUrl,
31628
- fileName: n?.fileName || xt.name,
31629
- fileType: n?.fileType || xt.type,
31630
- fileSize: n?.fileSize || xt.size
31634
+ fileName: n?.fileName || bt.name,
31635
+ fileType: n?.fileType || bt.type,
31636
+ fileSize: n?.fileSize || bt.size
31631
31637
  }
31632
31638
  });
31633
31639
  } catch (e) {
31634
- wt(e?.message || "Failed to upload the selected file.");
31640
+ Ct(e?.message || "Failed to upload the selected file.");
31635
31641
  } finally {
31636
- Et(!1);
31642
+ Tt(!1);
31637
31643
  }
31638
31644
  return;
31639
31645
  }
31640
- let n = ct.trim();
31641
- lt(""), dt(null), await D(n, "", t);
31646
+ let n = st.trim();
31647
+ ct(""), ut(null), await D(n, "", t);
31642
31648
  }, Vt = o(() => {
31643
31649
  r.length !== 0 && me?.();
31644
31650
  }, [r.length, me]), Ht = (e) => {
@@ -31686,10 +31692,10 @@ function zk() {
31686
31692
  right: "1.5rem",
31687
31693
  bottom: "1.5rem"
31688
31694
  }, Gt = o(() => {
31689
- A !== "minimized_orb" && (At(!0), setTimeout(() => {
31690
- st("minimized_orb"), At(!1), T && Ot(!0);
31695
+ A !== "minimized_orb" && (kt(!0), setTimeout(() => {
31696
+ ot("minimized_orb"), kt(!1), T && Dt(!0);
31691
31697
  }, 280));
31692
- }, [T, A]), Kt = () => st("connection_modal"), qt = () => {
31698
+ }, [T, A]), Kt = () => ot("connection_modal"), qt = () => {
31693
31699
  try {
31694
31700
  let e = window.AudioContext || window.webkitAudioContext;
31695
31701
  if (e) {
@@ -31697,9 +31703,9 @@ function zk() {
31697
31703
  t.resume().catch(() => {}), setTimeout(() => t.close().catch(() => {}), 3e3);
31698
31704
  }
31699
31705
  } catch {}
31700
- ce({ notifyChatInitiated: !0 }), ue?.(!0), st("voice_mode");
31706
+ ce({ notifyChatInitiated: !0 }), ue?.(!0), ot("voice_mode");
31701
31707
  }, Jt = () => {
31702
- ce({ notifyChatInitiated: !0 }), ue?.(!1), st("text_chat");
31708
+ ce({ notifyChatInitiated: !0 }), ue?.(!1), ot("text_chat");
31703
31709
  }, Yt = () => {
31704
31710
  ue?.(!1), Gt();
31705
31711
  };
@@ -31713,7 +31719,7 @@ function zk() {
31713
31719
  onWheel: (e) => e.stopPropagation(),
31714
31720
  onTouchMove: (e) => e.stopPropagation(),
31715
31721
  children: [
31716
- A === "entry_prompt" && /* @__PURE__ */ g(Nk, {
31722
+ A === "entry_prompt" && /* @__PURE__ */ g(Mk, {
31717
31723
  copy: Qe,
31718
31724
  orbColors: Le,
31719
31725
  primaryColor: ze,
@@ -31724,7 +31730,7 @@ function zk() {
31724
31730
  pe(et), Gt();
31725
31731
  },
31726
31732
  isMobile: Nt,
31727
- isClosing: kt
31733
+ isClosing: Ot
31728
31734
  }),
31729
31735
  A === "minimized_orb" && /* @__PURE__ */ _(Dm.div, {
31730
31736
  layoutId: "fe-main-orb",
@@ -31793,16 +31799,16 @@ function zk() {
31793
31799
  marginTop: "2px",
31794
31800
  whiteSpace: "nowrap"
31795
31801
  },
31796
- children: ee === "connected" ? `${Ht(_t)} with ${nt}` : `Tap to return to ${nt}`
31802
+ children: ee === "connected" ? `${Ht(j)} with ${nt}` : `Tap to return to ${nt}`
31797
31803
  })]
31798
31804
  })]
31799
- }), /* @__PURE__ */ g(Mk, {
31805
+ }), /* @__PURE__ */ g(jk, {
31800
31806
  size: Ve,
31801
31807
  orbColors: Le,
31802
31808
  onClick: T ? Lt : Ie ? Kt : Jt
31803
31809
  })]
31804
31810
  }),
31805
- A === "connection_modal" && /* @__PURE__ */ g(Pk, {
31811
+ A === "connection_modal" && /* @__PURE__ */ g(Nk, {
31806
31812
  copy: Qe,
31807
31813
  orbColors: Le,
31808
31814
  primaryColor: ze,
@@ -31810,9 +31816,9 @@ function zk() {
31810
31816
  onText: Jt,
31811
31817
  onClose: Gt,
31812
31818
  isMobile: Nt,
31813
- isClosing: kt
31819
+ isClosing: Ot
31814
31820
  }),
31815
- A === "voice_mode" && /* @__PURE__ */ g(Fk, {
31821
+ A === "voice_mode" && /* @__PURE__ */ g(Pk, {
31816
31822
  orbColors: Le,
31817
31823
  onEnterChat: Jt,
31818
31824
  onEndChat: Yt,
@@ -31822,13 +31828,14 @@ function zk() {
31822
31828
  chatId: ie,
31823
31829
  historyRef: ae,
31824
31830
  onMessageSync: oe,
31825
- voiceEndCounter: De
31831
+ voiceEndCounter: De,
31832
+ websiteName: t?.websiteName
31826
31833
  }, "voice"),
31827
31834
  A === "call_screen" && /* @__PURE__ */ g(gO, {
31828
31835
  incomingCall: w,
31829
31836
  activeCallId: T,
31830
31837
  callConnectionState: ee,
31831
- callDurationSeconds: _t,
31838
+ callDurationSeconds: j,
31832
31839
  isCallMuted: ne,
31833
31840
  agentName: nt,
31834
31841
  agentHeadshot: rt,
@@ -31843,8 +31850,8 @@ function zk() {
31843
31850
  orbColors: Le,
31844
31851
  chatHistory: r
31845
31852
  }),
31846
- A === "text_chat" && /* @__PURE__ */ g(Rk, {
31847
- isClosing: kt,
31853
+ A === "text_chat" && /* @__PURE__ */ g(Lk, {
31854
+ isClosing: Ot,
31848
31855
  copy: Qe,
31849
31856
  orbColors: Le,
31850
31857
  primaryColor: ze,
@@ -31860,35 +31867,35 @@ function zk() {
31860
31867
  agentName: nt,
31861
31868
  agentHeadshot: rt,
31862
31869
  fallbackAgentName: O,
31863
- input: ct,
31864
- setInput: lt,
31870
+ input: st,
31871
+ setInput: ct,
31865
31872
  onSubmit: Bt,
31866
31873
  isConversationEnded: C,
31867
31874
  isLoading: b,
31868
31875
  isRateLimited: x,
31869
31876
  rateLimitMessage: S,
31870
- selectedFile: xt,
31877
+ selectedFile: bt,
31871
31878
  onFileSelect: It,
31872
31879
  onRemoveSelectedFile: Ft,
31873
- attachmentError: Ct,
31874
- isUploadingAttachment: Tt,
31875
- requiresEmail: k,
31876
- emailInput: ft,
31877
- setEmailInput: pt,
31878
- emailError: mt,
31879
- emailCaptureSuccess: gt,
31880
- replyContext: ut,
31881
- setReplyContext: dt,
31880
+ attachmentError: St,
31881
+ isUploadingAttachment: wt,
31882
+ requiresEmail: Mt,
31883
+ emailInput: dt,
31884
+ setEmailInput: ft,
31885
+ emailError: pt,
31886
+ emailCaptureSuccess: ht,
31887
+ replyContext: lt,
31888
+ setReplyContext: ut,
31882
31889
  webRTCError: re,
31883
- micError: yt,
31884
- setMicError: bt,
31890
+ micError: vt,
31891
+ setMicError: yt,
31885
31892
  dismissCallError: ye,
31886
31893
  activeCallId: T,
31887
31894
  isCallMuted: ne,
31888
31895
  toggleCallMute: ve,
31889
31896
  endWebRTCCall: _e,
31890
31897
  formatCallDuration: Ht,
31891
- callDurationSeconds: _t,
31898
+ callDurationSeconds: j,
31892
31899
  onCollapse: Gt,
31893
31900
  onStartVoice: qt,
31894
31901
  onNewChat: Vt,
@@ -31906,7 +31913,7 @@ function zk() {
31906
31913
  }
31907
31914
  //#endregion
31908
31915
  //#region src/components/ErrorBoundary.jsx
31909
- var Bk = class extends e.Component {
31916
+ var zk = class extends e.Component {
31910
31917
  constructor(e) {
31911
31918
  super(e), this.state = { hasError: !1 };
31912
31919
  }
@@ -31921,4 +31928,4 @@ var Bk = class extends e.Component {
31921
31928
  }
31922
31929
  };
31923
31930
  //#endregion
31924
- export { lO as AnimatedOrb, Bk as ErrorBoundary, Rr as FlowEngageProvider, zk as FlowEngageWidget, Ln as useFlowEngage };
31931
+ export { lO as AnimatedOrb, zk as ErrorBoundary, Rr as FlowEngageProvider, Rk as FlowEngageWidget, Ln as useFlowEngage };