@flowengage/react-chatbot 6.0.45 → 7.0.1

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