@flowengage/react-chatbot 5.0.45 → 5.0.47

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.
@@ -29387,10 +29387,10 @@ function Ck(e) {
29387
29387
  $("flowengage_navigate → real navigation", a);
29388
29388
  let e = typeof window < "u" && !!(window.next?.router || window.__NEXT_ROUTER__ || window.__remixRouter || window.__staticRouterHydrationData || window.___gatsby || window.___navigate || window.__VUE_ROUTER__ || window.__NUXT__ || window.$nuxt || window.ng?.getComponent || typeof document < "u" && document.querySelector("[ng-version]") || window.__sveltekit_data || typeof document < "u" && document.querySelector("[data-sveltekit-hydrate]"));
29389
29389
  if (typeof window < "u" && window.__fe_triggerVoiceNavHooks && window.__fe_triggerVoiceNavHooks(), e && qn(3e3), Tr(a, { voiceActive: !0 }).catch(() => {}), e) try {
29390
- let e = new URL(a, window.location.origin).pathname;
29391
- await new Promise((e) => setTimeout(e, 400));
29392
- let t = typeof window < "u" ? window.location.pathname : e, n = typeof window < "u" ? window.location.href : a, r = t === e, i = (t.split("/").filter(Boolean).pop() || "").replace(/[-_]/g, " ").replace(/\b\w/g, (e) => e.toUpperCase()) || "Home";
29393
- return $("flowengage_navigate → SPA nav complete. target:", e, "actual:", t), r ? `OK_NAVIGATE_SPA. Navigation confirmed. Visitor is now at: ${n}. Page name: "${i}". Continue with your response about this page — do NOT say "I have navigated you to..." (the page is already changing visually). Just start talking about the content.` : `OK_NAVIGATE_SPA. IMPORTANT: Navigation was interrupted. The visitor is currently at ${n} (page: "${i}"), NOT the page you tried to navigate to. Adjust your response to describe the page the visitor is ACTUALLY on right now.`;
29390
+ let e = new URL(a, window.location.origin).pathname, t = Date.now() + 2e3;
29391
+ for (; Date.now() < t && !(typeof window < "u" && window.location.pathname === e);) await new Promise((e) => setTimeout(e, 80));
29392
+ 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";
29393
+ return $("flowengage_navigate → SPA nav complete. target:", e, "actual:", n), i ? `OK_NAVIGATE_SPA. Visitor is now on: ${r} (page: "${o}"). Do NOT say "I have navigated you" or "I've taken you to" the page is already loaded visually. Start immediately with highlights and content about THIS page.` : `OK_NAVIGATE_SPA. CURRENT PAGE IS: ${r} (page: "${o}"). The visitor manually navigated here. Describe THIS page only do not mention the page you tried to navigate to.`;
29394
29394
  } catch {}
29395
29395
  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.";
29396
29396
  } catch (e) {
@@ -29988,11 +29988,11 @@ function Nk({ copy: e, orbColors: t, primaryColor: n, onVoice: r, onText: i, onC
29988
29988
  });
29989
29989
  }
29990
29990
  function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, voiceId: i, siteId: a, apiBaseUrl: s, chatId: l, historyRef: u, onMessageSync: d, voiceEndCounter: f }) {
29991
- 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 = p([]), me = p(null), he = p(null), ge = p(null), _e = o((e = "minimized") => {
29991
+ 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") => {
29992
29992
  E.current = e, re.current = !0, queueMicrotask(() => {
29993
29993
  ee.current || (ee.current = !0, T.current?.());
29994
29994
  });
29995
- }, [u]), ve = o(async (e) => {
29995
+ }, [u]), me = o(async (e) => {
29996
29996
  re.current = !0;
29997
29997
  try {
29998
29998
  CD();
@@ -30025,44 +30025,12 @@ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, voiceId: i
30025
30025
  l,
30026
30026
  s
30027
30027
  ]);
30028
- T.current = () => ve(E.current === "chat" ? t : n);
30029
- let ye = o(() => {
30030
- let e = he.current, t = me.current;
30031
- if (e) {
30032
- he.current = null;
30033
- try {
30034
- t && ge.current && (ge.current.gain.setValueAtTime(ge.current.gain.value, t.currentTime), ge.current.gain.linearRampToValueAtTime(0, t.currentTime + .12), ge.current = null), setTimeout(() => {
30035
- try {
30036
- e.stop();
30037
- } catch {}
30038
- }, 130);
30039
- } catch {
30040
- try {
30041
- e.stop();
30042
- } catch {}
30043
- }
30044
- }
30045
- }, []), be = o(() => {
30046
- let e = pe.current, t = me.current;
30047
- if (!(!e.length || !t)) {
30048
- ye();
30049
- try {
30050
- t.state === "suspended" && t.resume().catch(() => {});
30051
- let n = e[Math.floor(Math.random() * e.length)], r = t.createBufferSource();
30052
- r.buffer = n;
30053
- let i = t.createGain();
30054
- i.gain.setValueAtTime(1, t.currentTime), r.connect(i), i.connect(t.destination), r.onended = () => {
30055
- he.current === r && (he.current = null);
30056
- }, r.start(0), he.current = r, ge.current = i;
30057
- } catch {}
30058
- }
30059
- }, [ye]);
30060
- return c(() => {
30028
+ return T.current = () => me(E.current === "chat" ? t : n), c(() => {
30061
30029
  te.current = y;
30062
30030
  }, [y]), c(() => {
30063
- f && _e("chat");
30031
+ f && pe("chat");
30064
30032
  }, [f]), c(() => {
30065
- let e = !1, o = null, c = null, f = null;
30033
+ let e = !1, i = null, o = null, c = null;
30066
30034
  return (async () => {
30067
30035
  if (!r) {
30068
30036
  v("error");
@@ -30101,13 +30069,13 @@ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, voiceId: i
30101
30069
  requestEndSession: () => {
30102
30070
  se.current = !0;
30103
30071
  }
30104
- })), n = a ? je(a) : null, d = !!n?.transcript, p = !!(a && Ve(a)), m = typeof window < "u" ? window.location.pathname : "/", h = typeof document < "u" ? document.title : "", g = m === "/" || m === "", _ = null;
30072
+ })), n = a ? je(a) : null, d = !!n?.transcript, f = !!(a && Ve(a)), p = typeof window < "u" ? window.location.pathname : "/", m = typeof document < "u" ? document.title : "", h = p === "/" || p === "", g = null;
30105
30073
  try {
30106
30074
  let e = await fetch(`${s}/api/voice/signed-url?siteId=${encodeURIComponent(a || "")}`, {
30107
30075
  method: "GET",
30108
30076
  headers: { "Content-Type": "application/json" }
30109
30077
  });
30110
- if (e.ok) _ = (await e.json()).signedUrl || null, _ && console.log("[FlowEngage] ✅ Using signed ElevenLabs URL");
30078
+ if (e.ok) g = (await e.json()).signedUrl || null, g && console.log("[FlowEngage] ✅ Using signed ElevenLabs URL");
30111
30079
  else if (e.status === 429) {
30112
30080
  let t = await e.json().catch(() => ({}));
30113
30081
  throw Error(t.message || "Too many voice sessions started. Please wait a minute before trying again.");
@@ -30116,35 +30084,16 @@ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, voiceId: i
30116
30084
  if (e.message && e.message.includes("Too many voice sessions")) throw e;
30117
30085
  console.warn("[FlowEngage] ⚠️ Signed URL fetch error:", e.message);
30118
30086
  }
30119
- (async () => {
30120
- try {
30121
- let e = new URLSearchParams({ siteId: a || "" });
30122
- i && e.set("voiceId", i);
30123
- let t = await fetch(`${s}/api/voice/fillers?${e}`);
30124
- if (!t.ok) return;
30125
- let n = await t.json();
30126
- if (!n.success || !Array.isArray(n.fillers) || !n.fillers.length) return;
30127
- let r = new (window.AudioContext || window.webkitAudioContext)(), o = (await Promise.all(n.fillers.map(async (e) => {
30128
- try {
30129
- let t = Uint8Array.from(atob(e), (e) => e.charCodeAt(0));
30130
- return await r.decodeAudioData(t.buffer);
30131
- } catch {
30132
- return null;
30133
- }
30134
- }))).filter(Boolean);
30135
- o.length && (pe.current = o, me.current = r, console.log(`[FlowEngage] 🔊 ${o.length} filler clips ready`));
30136
- } catch {}
30137
- })();
30138
- let y = {
30087
+ let _ = {
30139
30088
  clientTools: t,
30140
30089
  connectionType: "websocket",
30141
- ..._ ? { signedUrl: _ } : { agentId: r }
30142
- }, x = (m.split("/").filter(Boolean).pop() || "").replace(/[-_]/g, " ").replace(/\b\w/g, (e) => e.toUpperCase()), S = "";
30143
- h && h.includes("|") && (S = h.split("|").map((e) => e.trim()).filter(Boolean).reduce((e, t) => e.length <= t.length ? e : t));
30144
- let T = S || x || "this page";
30145
- _ ? p ? (y.overrides = { agent: { firstMessage: `I've navigated you to the ${T} page. Let me walk you through what's here.` } }, console.log(`[FlowEngage] 🔄 Agent-nav resume: firstMessage set for "${T}" (${m})`)) : d ? y.overrides = { agent: { firstMessage: "I'm still here. Go ahead!" } } : g || (y.overrides = { agent: { firstMessage: `Hi! I see you are currently on the ${T} page. Are you looking for something specific here?` } }, console.log(`[FlowEngage] 🏠 Page-context override: "${T}" for ${m}`)) : d && (y.overrides = { agent: { firstMessage: "" } });
30146
- let oe = !1, he = p ? `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${(a ? je(a) : null)?.transcript || ""}\n\n` : null, ge = await _D.startSession({
30147
- ...y,
30090
+ ...g ? { signedUrl: g } : { agentId: r }
30091
+ }, y = (p.split("/").filter(Boolean).pop() || "").replace(/[-_]/g, " ").replace(/\b\w/g, (e) => e.toUpperCase()), x = "";
30092
+ m && m.includes("|") && (x = m.split("|").map((e) => e.trim()).filter(Boolean).reduce((e, t) => e.length <= t.length ? e : t));
30093
+ let S = x || y || "this page";
30094
+ g ? f ? (_.overrides = { agent: { firstMessage: `I've navigated you to the ${S} page. Let me walk you through what's here.` } }, console.log(`[FlowEngage] 🔄 Agent-nav resume: firstMessage set for "${S}" (${p})`)) : d ? _.overrides = { agent: { firstMessage: "I'm still here. Go ahead!" } } : h || (_.overrides = { agent: { firstMessage: `Hi! I see you are currently on the ${S} page. Are you looking for something specific here?` } }, console.log(`[FlowEngage] 🏠 Page-context override: "${S}" for ${p}`)) : d && (_.overrides = { agent: { firstMessage: "" } });
30095
+ let T = !1, oe = 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${(a ? je(a) : null)?.transcript || ""}\n\n` : null, me = await _D.startSession({
30096
+ ..._,
30148
30097
  onConnect: ({ conversationId: e }) => {
30149
30098
  ie.current = e, ae.current = Date.now(), console.log("[FlowEngage] 🎙️ AI chat session connected:", e);
30150
30099
  },
@@ -30152,15 +30101,15 @@ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, voiceId: i
30152
30101
  onModeChange: ({ mode: t }) => {
30153
30102
  if (!e) {
30154
30103
  if (t === "speaking") {
30155
- ye(), de.current &&= (clearTimeout(de.current), null), v("speaking"), ce.current = "speaking", le.current = !0, fe.current = !1, ue.current &&= (clearTimeout(ue.current), null);
30104
+ de.current &&= (clearTimeout(de.current), null), v("speaking"), ce.current = "speaking", le.current = !0, fe.current = !1, ue.current &&= (clearTimeout(ue.current), null);
30156
30105
  return;
30157
30106
  }
30158
30107
  if (ce.current = "listening", se.current) {
30159
- se.current = !1, _e();
30108
+ se.current = !1, pe();
30160
30109
  return;
30161
30110
  }
30162
- if (he && !oe) {
30163
- oe = !0;
30111
+ if (oe && !T) {
30112
+ T = !0;
30164
30113
  try {
30165
30114
  C.current?.sendUserMessage?.("continue with the tour");
30166
30115
  } catch {}
@@ -30178,7 +30127,7 @@ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, voiceId: i
30178
30127
  if (e) return;
30179
30128
  let n = t.role === "user" ? "user" : "bot", r = t.message || t.text || t.content || "";
30180
30129
  if (r) {
30181
- if (n === "user" && (w.current = r, fe.current = !0, de.current &&= (clearTimeout(de.current), null), ce.current = "thinking", ue.current &&= (clearTimeout(ue.current), null), be()), u.current = [...u.current, {
30130
+ if (n === "user" && (w.current = r, fe.current = !0, de.current &&= (clearTimeout(de.current), null), ce.current = "thinking", ue.current &&= (clearTimeout(ue.current), null)), u.current = [...u.current, {
30182
30131
  sender: n,
30183
30132
  message: r,
30184
30133
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
@@ -30187,13 +30136,13 @@ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, voiceId: i
30187
30136
  e && Ae(a, e);
30188
30137
  } catch {}
30189
30138
  if (Ak(n, r)) {
30190
- _e("minimized");
30139
+ pe("minimized");
30191
30140
  return;
30192
30141
  }
30193
30142
  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 {
30194
30143
  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 flowengage_end_session tool to end the voice session. Do NOT ask again after that.");
30195
30144
  } catch {}
30196
- else D.current >= 5 && _e("minimized");
30145
+ else D.current >= 5 && pe("minimized");
30197
30146
  }
30198
30147
  },
30199
30148
  onError: (t) => {
@@ -30206,7 +30155,7 @@ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, voiceId: i
30206
30155
  try {
30207
30156
  C.current?.setMicMuted?.(!0);
30208
30157
  } catch {}
30209
- b(!0), v("error"), _e("chat");
30158
+ b(!0), v("error"), pe("chat");
30210
30159
  }
30211
30160
  },
30212
30161
  onDisconnect: (t) => {
@@ -30223,21 +30172,21 @@ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, voiceId: i
30223
30172
  try {
30224
30173
  C.current?.setMicMuted?.(!0);
30225
30174
  } catch {}
30226
- b(!0), _e("chat");
30175
+ b(!0), pe("chat");
30227
30176
  }
30228
30177
  });
30229
30178
  if (e) {
30230
- ge.endSession().catch(() => {});
30179
+ me.endSession().catch(() => {});
30231
30180
  return;
30232
30181
  }
30233
- o = ge, C.current = ge, v("listening");
30182
+ i = me, C.current = me, v("listening");
30234
30183
  try {
30235
30184
  let e = typeof window < "u" ? window.location.href : "", r = "[]";
30236
30185
  try {
30237
30186
  r = await t.list_page_forms();
30238
30187
  } catch {}
30239
- let i = d && !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` : "";
30240
- ge.sendContextualUpdate(`${i}Page: ${e}. SiteId: ${a || "unknown"}. Forms: ${r}. Voice: call end_voice_session or say you are ending the session to stop.`);
30188
+ let i = d && !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` : "";
30189
+ me.sendContextualUpdate(`${i}Page: ${e}. SiteId: ${a || "unknown"}. Forms: ${r}. Voice: call end_voice_session or say you are ending the session to stop.`);
30241
30190
  } catch {}
30242
30191
  if (typeof window < "u") {
30243
30192
  let t = window.location.pathname, n = () => {
@@ -30257,9 +30206,9 @@ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, voiceId: i
30257
30206
  C.current?.sendContextualUpdate?.(`PAGE CHANGED — visitor navigated manually. Current URL is now: ${r}. Page title: "${i}". Sections on this page: ${JSON.stringify(a)}. When the visitor asks about "this page", "current page", or "what page am I on", refer to this new URL — not any previously mentioned page.`);
30258
30207
  } catch {}
30259
30208
  };
30260
- c = window.history.pushState.bind(window.history), window.history.pushState = (...e) => {
30261
- c(...e), setTimeout(n, 50);
30262
- }, f = () => setTimeout(n, 50), window.addEventListener("popstate", f);
30209
+ o = window.history.pushState.bind(window.history), window.history.pushState = (...e) => {
30210
+ o(...e), setTimeout(n, 50);
30211
+ }, c = () => setTimeout(n, 50), window.addEventListener("popstate", c);
30263
30212
  }
30264
30213
  } catch (r) {
30265
30214
  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(() => {
@@ -30267,14 +30216,8 @@ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, voiceId: i
30267
30216
  }, 0)));
30268
30217
  }
30269
30218
  })(), () => {
30270
- if (e = !0, re.current = !0, kr(), ue.current &&= (clearTimeout(ue.current), null), de.current &&= (clearTimeout(de.current), null), le.current = !1, fe.current = !1, ce.current = "idle", he.current) {
30271
- try {
30272
- he.current.stop();
30273
- } catch {}
30274
- he.current = null;
30275
- }
30276
- me.current && (me.current.close().catch(() => {}), me.current = null, pe.current = [], ge.current = null), c && typeof window < "u" && (window.history.pushState = c), f && typeof window < "u" && window.removeEventListener("popstate", f);
30277
- let t = o || C.current, n = ie.current, r = ae.current;
30219
+ e = !0, re.current = !0, kr(), ue.current &&= (clearTimeout(ue.current), null), de.current &&= (clearTimeout(de.current), null), le.current = !1, fe.current = !1, ce.current = "idle", o && typeof window < "u" && (window.history.pushState = o), c && typeof window < "u" && window.removeEventListener("popstate", c);
30220
+ let t = i || C.current, n = ie.current, r = ae.current;
30278
30221
  if (t?.endSession?.().catch(() => {}), n && l && s) {
30279
30222
  let e = r ? Math.round((Date.now() - r) / 1e3) : 0, t = JSON.stringify({
30280
30223
  chatId: l,
@@ -30295,7 +30238,7 @@ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, voiceId: i
30295
30238
  r,
30296
30239
  a,
30297
30240
  s,
30298
- _e
30241
+ pe
30299
30242
  ]), c(() => {
30300
30243
  if (!x) return;
30301
30244
  let e = (e) => {
@@ -30481,7 +30424,7 @@ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, voiceId: i
30481
30424
  children: [
30482
30425
  /* @__PURE__ */ _("button", {
30483
30426
  onClick: () => {
30484
- S(!1), E.current = "chat", ve(t);
30427
+ S(!1), E.current = "chat", me(t);
30485
30428
  },
30486
30429
  style: {
30487
30430
  display: "flex",
@@ -30510,7 +30453,7 @@ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, voiceId: i
30510
30453
  }),
30511
30454
  /* @__PURE__ */ _("button", {
30512
30455
  onClick: () => {
30513
- S(!1), E.current = "minimized", ve(n);
30456
+ S(!1), E.current = "minimized", me(n);
30514
30457
  },
30515
30458
  style: {
30516
30459
  display: "flex",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowengage/react-chatbot",
3
- "version": "5.0.45",
3
+ "version": "5.0.47",
4
4
  "description": "Embeddable AI chat widget for React — powered by FlowEngage. Drop it in with a single siteId.",
5
5
  "keywords": [
6
6
  "chatbot",