@flowengage/react-chatbot 8.0.9 → 8.0.10

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.
@@ -198,12 +198,13 @@ var v = Object.defineProperty, y = Object.getOwnPropertyDescriptor, b = Object.g
198
198
  } catch {
199
199
  return !1;
200
200
  }
201
- }, ze = (e) => e ? `flowengage.voice.navState.${e}.${De()}` : null, Be = (e, t, n) => {
201
+ }, ze = (e) => e ? `flowengage.voice.navState.${e}.${De()}` : null, Be = (e, t, n, r) => {
202
202
  if (!(!D || !e || !t)) try {
203
- let r = ze(e);
204
- r && window.sessionStorage.setItem(r, JSON.stringify({
203
+ let i = ze(e);
204
+ i && window.sessionStorage.setItem(i, JSON.stringify({
205
205
  previousPage: String(t),
206
206
  targetPath: n ? new URL(String(n), window.location.href).pathname : null,
207
+ pageName: r || null,
207
208
  ts: Date.now()
208
209
  }));
209
210
  } catch {}
@@ -216,7 +217,10 @@ var v = Object.defineProperty, y = Object.getOwnPropertyDescriptor, b = Object.g
216
217
  if (!n) return null;
217
218
  window.sessionStorage.removeItem(t);
218
219
  let r = JSON.parse(n);
219
- return !r || typeof r.previousPage != "string" || Number.isFinite(r.ts) && Date.now() - r.ts > 6e4 || r.targetPath && (window.location.pathname.replace(/\/$/, "") || "/") !== (r.targetPath.replace(/\/$/, "") || "/") ? null : { previousPage: r.previousPage };
220
+ return !r || typeof r.previousPage != "string" || Number.isFinite(r.ts) && Date.now() - r.ts > 6e4 || r.targetPath && (window.location.pathname.replace(/\/$/, "") || "/") !== (r.targetPath.replace(/\/$/, "") || "/") ? null : {
221
+ previousPage: r.previousPage,
222
+ pageName: r.pageName || null
223
+ };
220
224
  } catch {
221
225
  return null;
222
226
  }
@@ -29552,9 +29556,14 @@ function Dk(e) {
29552
29556
  try {
29553
29557
  e = new URL(a, typeof window < "u" ? window.location.href : "").href;
29554
29558
  } catch {}
29555
- t && typeof window < "u" && Be(t, window.location.href, e), wr(e), $("fwh-navigate-mvp → real navigation", a);
29556
- let n = typeof window < "u" && !!er();
29557
- if (typeof window < "u" && window.__fe_triggerVoiceNavHooks && window.__fe_triggerVoiceNavHooks(), n && Gn(12e3), Dr(a, { voiceActive: !0 }).catch(() => {}), n) try {
29559
+ let n = "this";
29560
+ try {
29561
+ let e = new URL(a, window.location.href).pathname.split("/").filter(Boolean).pop() || "";
29562
+ n = e ? e.replace(/[-_]/g, " ").replace(/\b\w/g, (e) => e.toUpperCase()) : "Home";
29563
+ } catch {}
29564
+ t && typeof window < "u" && Be(t, window.location.href, e, n), wr(e), $("fwh-navigate-mvp → real navigation", a);
29565
+ let i = typeof window < "u" && !!er();
29566
+ if (typeof window < "u" && window.__fe_triggerVoiceNavHooks && window.__fe_triggerVoiceNavHooks(), i && Gn(12e3), Dr(a, { voiceActive: !0 }).catch(() => {}), i) try {
29558
29567
  let e = new URL(a, window.location.origin).pathname, t = Date.now() + 2e3;
29559
29568
  for (; Date.now() < t && !(typeof window < "u" && window.location.pathname === e);) await new Promise((e) => setTimeout(e, 80));
29560
29569
  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";
@@ -29581,12 +29590,12 @@ function Dk(e) {
29581
29590
  } catch {}
29582
29591
  return i ? (Tr(), `OK_NAVIGATE_SPA. Visitor is now on: ${r} (page: "${o}") | Section headings: ${l}. ${u}${d} Speak EXACTLY: "I have navigated you on ${o} page. Do you want to know about any specific section or want a complete overview?" Then STOP — wait for their reply.`) : (Tr(), `OK_NAVIGATE_SPA. CURRENT PAGE IS: ${r} (page: "${o}") | Section headings: ${l}. ${u}${d} Speak EXACTLY: "I have navigated you on ${o} page. Do you want to know about any specific section or want a complete overview?" Then STOP — wait for their reply.`);
29583
29592
  } catch {}
29584
- let i = "this";
29593
+ let o = "this";
29585
29594
  try {
29586
29595
  let e = new URL(a, window.location.href).pathname.split("/").filter(Boolean).pop() || "";
29587
- i = e ? e.replace(/[-_]/g, " ").replace(/\b\w/g, (e) => e.toUpperCase()) : "Home";
29596
+ o = e ? e.replace(/[-_]/g, " ").replace(/\b\w/g, (e) => e.toUpperCase()) : "Home";
29588
29597
  } catch {}
29589
- return `OK_NAVIGATE_RELOADING. Navigating to the page now; the voice session will resume automatically on the new page. When the session resumes, say EXACTLY: "I have navigated you on ${i} page. Do you want to know about any specific section or want a complete overview?" Then STOP — wait for the visitor's reply.`;
29598
+ return `OK_NAVIGATE_RELOADING. Navigating to the page now; the voice session will resume automatically on the new page. When the session resumes, say EXACTLY: "I have navigated you on ${o} page. Do you want to know about any specific section or want a complete overview?" Then STOP — wait for the visitor's reply.`;
29590
29599
  } catch (e) {
29591
29600
  let t = `Navigation error: ${e?.message || String(e)}`;
29592
29601
  return $("fwh-navigate-mvp ✖", t), EO("Navigation failed", {
@@ -29787,7 +29796,7 @@ function Dk(e) {
29787
29796
  title: n
29788
29797
  }), $("fwh-get-current-page-mvp → page headings collected:", r), !r.length) return `CURRENT_PAGE. URL: ${e} | Title: ${n} | No headings found on this page. Describe the page from your knowledge without calling this tool again.`;
29789
29798
  let i = r.map((e) => `"${e}"`).join(" | ");
29790
- return `CURRENT_PAGE. URL: ${e} | Title: ${n} | Page sections (${r.length} total): ${i}. *** IMPORTANT: For fwh-highlight-mvp, pass the heading text EXACTLY as shown above — no numbers, no extra punctuation, no paraphrasing. DO NOT call this tool again. If the visitor requested a walkthrough: START IT NOW. For every section: speak a short transition sentence, INVOKE the fwh-highlight-mvp tool with the exact heading text (do not speak the tool name call it silently as a tool), then speak 3-4 sentences about that section. Cover ALL ${r.length} sections without pausing between them. ***`;
29799
+ return `CURRENT_PAGE. URL: ${e} | Title: ${n} | Page sections (${r.length} total): ${i}. *** WALKTHROUGH RULES: (1) For fwh-highlight-mvp, pass the heading text EXACTLY as shown — no numbers, no extra punctuation, no paraphrasing. (2) TIMING IS CRITICAL: the tool fires AFTER the speech that comes before it. This means: put the SHORT TRANSITION (1-5 words) BEFORE the tool call, put the FULL DESCRIPTION AFTER the tool call. Pattern: "Transition phrase." + fwh-highlight-mvp("Heading") + "Full description (3-4 sentences)". NEVER describe a section before calling its highlight tool. (3) DO NOT call this tool again. If the visitor requested a walkthrough: START IT NOW — "Let me walk you through this." + fwh-highlight-mvp("${r[0] || "first heading"}") + "Description..." etc. Cover ALL ${r.length} sections without pausing. ***`;
29791
29800
  },
29792
29801
  "fwh-list-forms-mvp": async () => {
29793
29802
  let e = $O(), t = ek();
@@ -30409,13 +30418,13 @@ function zk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30409
30418
  requestEndSession: () => {
30410
30419
  se.current = !0;
30411
30420
  }
30412
- })), n = i ? Ae(i) : null, u = !!n?.transcript, p = !!(i && Ve(i)), m = typeof window < "u" ? window.location.pathname : "/", h = typeof document < "u" ? document.title : "", g = m.replace(/^\/[a-z]{2}(?:-[a-z]{2})?(?=\/|$)/i, "") || "/", _ = g === "/" || g === "", y = null;
30421
+ })), n = i ? Ae(i) : null, u = !!n?.transcript, p = i ? Ve(i) : null, m = !!p, h = typeof window < "u" ? window.location.pathname : "/", g = typeof document < "u" ? document.title : "", _ = h.replace(/^\/[a-z]{2}(?:-[a-z]{2})?(?=\/|$)/i, "") || "/", y = _ === "/" || _ === "", x = null;
30413
30422
  try {
30414
30423
  let e = await fetch(`${a}/api/voice/signed-url?siteId=${encodeURIComponent(i || "")}`, {
30415
30424
  method: "GET",
30416
30425
  headers: { "Content-Type": "application/json" }
30417
30426
  });
30418
- if (e.ok) y = (await e.json()).signedUrl || null, y && console.log("[FlowEngage] ✅ Using signed ElevenLabs URL");
30427
+ if (e.ok) x = (await e.json()).signedUrl || null, x && console.log("[FlowEngage] ✅ Using signed ElevenLabs URL");
30419
30428
  else if (e.status === 429) {
30420
30429
  let t = await e.json().catch(() => ({}));
30421
30430
  throw Error(t.message || "Too many voice sessions started. Please wait a minute before trying again.");
@@ -30424,23 +30433,25 @@ function zk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30424
30433
  if (e.message && e.message.includes("Too many voice sessions")) throw e;
30425
30434
  console.warn("[FlowEngage] ⚠️ Signed URL fetch error:", e.message);
30426
30435
  }
30427
- let x = {
30436
+ let S = {
30428
30437
  clientTools: t,
30429
30438
  connectionType: "websocket",
30430
30439
  minSpeechDurationMs: 50,
30431
- ...y ? { signedUrl: y } : { agentId: r }
30432
- }, S = (m.split("/").filter(Boolean).pop() || "").replace(/[-_]/g, " ").replace(/\b\w/g, (e) => e.toUpperCase()), T = "";
30433
- h && h.includes("|") && (T = h.split("|").map((e) => e.trim()).filter(Boolean).reduce((e, t) => e.length <= t.length ? e : t));
30434
- let oe = T || S || "this page";
30435
- if (y) if (p) x.overrides = { agent: { firstMessage: `Here we are — I've taken you to the ${oe} page.` } }, console.log(`[FlowEngage] 🔄 Agent-nav resume: firstMessage set for "${oe}" (${m})`);
30436
- else if (u) x.overrides = { agent: { firstMessage: "I'm still here. Go ahead!" } };
30440
+ ...x ? { signedUrl: x } : { agentId: r }
30441
+ }, T = (h.split("/").filter(Boolean).pop() || "").replace(/[-_]/g, " ").replace(/\b\w/g, (e) => e.toUpperCase()), oe = "";
30442
+ g && g.includes("|") && (oe = g.split("|").map((e) => e.trim()).filter(Boolean).reduce((e, t) => e.length <= t.length ? e : t));
30443
+ let he = oe || T || "this page";
30444
+ if (x) if (m) {
30445
+ let e = p?.pageName || he;
30446
+ S.overrides = { agent: { firstMessage: `I have navigated you on ${e} page. Do you want to know about any specific section or want a complete overview?` } }, console.log(`[FlowEngage] 🔄 Agent-nav resume: firstMessage set for "${e}" (${h})`);
30447
+ } else if (u) S.overrides = { agent: { firstMessage: "I'm still here. Go ahead!" } };
30437
30448
  else {
30438
30449
  let e = f || "";
30439
- x.overrides = { agent: { firstMessage: _ ? e ? `Hi, welcome to ${e}!` : "Hi, welcome!" : `Welcome to the ${oe} page!` } }, _ || console.log(`[FlowEngage] 🏠 Page-context override: "${oe}" for ${m}`);
30450
+ S.overrides = { agent: { firstMessage: y ? e ? `Hi, welcome to ${e}!` : "Hi, welcome!" : `Welcome to the ${he} page!` } }, y || console.log(`[FlowEngage] 🏠 Page-context override: "${he}" for ${h}`);
30440
30451
  }
30441
- else u && (x.overrides = { agent: { firstMessage: "" } });
30442
- let he = !1, ge = p ? `NAVIGATION COMPLETE — Your brief intro has been spoken. PRIOR CONVERSATION CONTEXT (continue from here do NOT re-introduce yourself):\n${n?.transcript ? `Prior transcript:\n${n.transcript}\n` : "(no prior transcript)"}\nSTEP 1call fwh-get-current-page-mvp NOW with zero speech before it, to load the page sections.\nSTEP 2 — after the tool responds, speak 2-3 sentences about this page, drawing from your knowledge and the visitor's prior context above.\nSTEP 3 — then ask the visitor exactly this: "Would you like to know about a specific section, or should I give you a complete overview?"\nThen STOP — wait for their reply. Do NOT auto-highlight or auto-walkthrough.` : null, _e = !1, ve = !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, ye = await xD.startSession({
30443
- ...x,
30452
+ else u && (S.overrides = { agent: { firstMessage: "" } });
30453
+ let ge = !1, _e = m ? `NAVIGATION COMPLETE — The exact phrase "I have navigated you on [page] page. Do you want to know about any specific section or want a complete overview?" has already been spoken as your firstMessage. DO NOT repeat it. PRIOR CONVERSATION CONTEXT:\n${n?.transcript ? `Prior transcript:\n${n.transcript}\n` : "(no prior transcript)"}\nNow STOPwait silently for the visitor's reply. Do NOT speak, do NOT call any tool until the visitor responds. When they reply: if they name a specific section call fwh-get-current-page-mvp then answer immediately; if they say "overview" or anything non-specific call fwh-get-current-page-mvp (zero speech) then do a full highlighted walkthrough.` : null, ve = !1, ye = !m && !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, be = await xD.startSession({
30454
+ ...S,
30444
30455
  onConnect: ({ conversationId: e }) => {
30445
30456
  ie.current = e, ae.current = Date.now(), console.log("[FlowEngage] 🎙️ AI chat session connected:", e);
30446
30457
  },
@@ -30455,16 +30466,16 @@ function zk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30455
30466
  se.current = !1, me();
30456
30467
  return;
30457
30468
  }
30458
- if (ge && !he) {
30459
- he = !0;
30469
+ if (_e && !ge) {
30470
+ ge = !0;
30460
30471
  try {
30461
- C.current?.sendContextualUpdate?.(ge);
30472
+ C.current?.sendContextualUpdate?.(_e);
30462
30473
  } catch {}
30463
30474
  }
30464
- if (ve && !_e) {
30465
- _e = !0;
30475
+ if (ye && !ve) {
30476
+ ve = !0;
30466
30477
  try {
30467
- C.current?.sendContextualUpdate?.(ve);
30478
+ C.current?.sendContextualUpdate?.(ye);
30468
30479
  } catch {}
30469
30480
  }
30470
30481
  fe.current && clearTimeout(fe.current), fe.current = setTimeout(() => {
@@ -30535,10 +30546,10 @@ function zk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30535
30546
  }
30536
30547
  });
30537
30548
  if (e) {
30538
- console.warn("[FlowEngage:VoiceDebug] ❌ cancelled=true after startSession resolved — killing session immediately"), ye.endSession().catch(() => {});
30549
+ console.warn("[FlowEngage:VoiceDebug] ❌ cancelled=true after startSession resolved — killing session immediately"), be.endSession().catch(() => {});
30539
30550
  return;
30540
30551
  }
30541
- o = ye, C.current = ye, v("listening");
30552
+ o = be, C.current = be, v("listening");
30542
30553
  try {
30543
30554
  let e = typeof window < "u" ? window.location.href : "", r = "[]";
30544
30555
  try {
@@ -30549,8 +30560,8 @@ function zk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
30549
30560
  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);
30550
30561
  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(" | "));
30551
30562
  } catch {}
30552
- 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` : "";
30553
- ye.sendContextualUpdate(`${o}SESSION_CONTEXT (NOT a tool result — do NOT treat as CURRENT_PAGE): Visitor is on: ${e} | Approx headings for awareness only: ${a}. SiteId: ${i || "unknown"}. Forms: ${r}. The visitor is ALREADY on this page — do NOT offer to navigate there. WALKTHROUGH RULE: If the visitor requests a walkthrough, you MUST call fwh-get-current-page-mvp first (zero speech) to get the exact highlightable headings — do NOT use these approximate headings for highlighting. Voice: call end_voice_session or say you are ending the session to stop.`);
30563
+ let o = u && !m ? `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` : "";
30564
+ be.sendContextualUpdate(`${o}SESSION_CONTEXT (NOT a tool result — do NOT treat as CURRENT_PAGE): Visitor is on: ${e} | Approx headings for awareness only: ${a}. SiteId: ${i || "unknown"}. Forms: ${r}. The visitor is ALREADY on this page — do NOT offer to navigate there. WALKTHROUGH RULE: When the visitor asks for a walkthrough or overview of this page, you MUST IMMEDIATELY call fwh-get-current-page-mvp (zero speech — call it silently with NO words before it) to get the exact highlightable headings. The approximate headings above are for routing awareness ONLY they are NOT precise enough for fwh-highlight-mvp. Do NOT skip fwh-get-current-page-mvp. Voice: call end_voice_session or say you are ending the session to stop.`);
30554
30565
  } catch {}
30555
30566
  if (typeof window < "u") {
30556
30567
  let t = window.location.pathname, n = () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowengage/react-chatbot",
3
- "version": "8.0.9",
3
+ "version": "8.0.10",
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",