@flowengage/react-chatbot 7.0.0 → 7.0.2
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.
|
@@ -29340,8 +29340,8 @@ function bk() {
|
|
|
29340
29340
|
});
|
|
29341
29341
|
}
|
|
29342
29342
|
function xk() {
|
|
29343
|
-
let e = document.querySelector("main, [role='main']
|
|
29344
|
-
return
|
|
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"));
|
|
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);
|
|
29345
29345
|
}
|
|
29346
29346
|
function Sk(e) {
|
|
29347
29347
|
let t = e.siteId || null, n = (e.apiBaseUrl || "").replace(/\/$/, ""), r = typeof e.getLastUserVoiceText == "function" ? e.getLastUserVoiceText : null, i = [], a = {
|
|
@@ -29401,13 +29401,13 @@ function Sk(e) {
|
|
|
29401
29401
|
for (; Date.now() < t && !(typeof window < "u" && window.location.pathname === e);) await new Promise((e) => setTimeout(e, 80));
|
|
29402
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";
|
|
29403
29403
|
$("fwh-navigate-mvp → SPA nav complete. target:", e, "actual:", n);
|
|
29404
|
-
let s = [], c = Date.now() +
|
|
29405
|
-
for (; Date.now() < c && (await new Promise((e) => setTimeout(e,
|
|
29404
|
+
let s = [], c = Date.now() + 12e3;
|
|
29405
|
+
for (; Date.now() < c && (await new Promise((e) => setTimeout(e, 300)), s = xk(), !(s.length >= 1)););
|
|
29406
29406
|
bk(), $("fwh-navigate-mvp → page headings collected:", s);
|
|
29407
|
-
let l = s.length ? s.join(" | ") : "none", u = s.length ? "Use ONLY these exact heading strings for fwh-highlight-mvp." : "No headings
|
|
29408
|
-
return i ? (wr(), `OK_NAVIGATE_SPA. Visitor is now on: ${r} (page: "${o}") | Section headings: ${l}. ${u}
|
|
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.`);
|
|
29409
29409
|
} catch {}
|
|
29410
|
-
return "OK_NAVIGATE_RELOADING. Navigating to the page now; the voice session will resume automatically on the new page. When the session resumes,
|
|
29410
|
+
return "OK_NAVIGATE_RELOADING. Navigating to the page now; the voice session will resume automatically on the new page. When the session resumes, speak 2-3 sentences about the page, then ask: \"Would you like to know about a specific section, or should I give you a complete overview?\" Wait for the visitor's reply.";
|
|
29411
29411
|
} catch (e) {
|
|
29412
29412
|
let t = `Navigation error: ${e?.message || String(e)}`;
|
|
29413
29413
|
return $("fwh-navigate-mvp ✖", t), CO("Navigation failed", {
|
|
@@ -29463,6 +29463,38 @@ function Sk(e) {
|
|
|
29463
29463
|
return $("fwh-read-content-mvp ✖", e.message), `Could not read page content: ${e.message}`;
|
|
29464
29464
|
}
|
|
29465
29465
|
},
|
|
29466
|
+
flowengage_search: async (e) => {
|
|
29467
|
+
$("flowengage_search ▶", e);
|
|
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.";
|
|
29470
|
+
if (!t) return $("flowengage_search ✖ no siteId"), "Site is not configured for search.";
|
|
29471
|
+
if (!n) return $("flowengage_search ✖ no api base"), "API base URL is missing; cannot search.";
|
|
29472
|
+
CO(`Searching${i ? ` for "${i}"` : ""}…`, { spinner: !0 });
|
|
29473
|
+
try {
|
|
29474
|
+
let e = `${n}/api/site-tools/search`;
|
|
29475
|
+
$("flowengage_search → POST", e);
|
|
29476
|
+
let r = await fetch(e, {
|
|
29477
|
+
method: "POST",
|
|
29478
|
+
headers: { "Content-Type": "application/json" },
|
|
29479
|
+
body: JSON.stringify({
|
|
29480
|
+
siteId: t,
|
|
29481
|
+
query: i,
|
|
29482
|
+
currentUrl: typeof window < "u" ? window.location.href : ""
|
|
29483
|
+
})
|
|
29484
|
+
}), a = await r.json();
|
|
29485
|
+
if ($("flowengage_search · HTTP", r.status, "success:", a.success), !a.success) {
|
|
29486
|
+
let e = a.error || "Search failed.";
|
|
29487
|
+
return $("flowengage_search ✖", e), e;
|
|
29488
|
+
}
|
|
29489
|
+
let o = a.results || [];
|
|
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.";
|
|
29491
|
+
} catch (e) {
|
|
29492
|
+
let t = `Search error: ${e.message || "network"}`;
|
|
29493
|
+
return $("flowengage_search ✖", t), t;
|
|
29494
|
+
} finally {
|
|
29495
|
+
wO(600);
|
|
29496
|
+
}
|
|
29497
|
+
},
|
|
29466
29498
|
"fwh-page-content-mvp": async (e) => {
|
|
29467
29499
|
$("fwh-page-content-mvp ▶", e);
|
|
29468
29500
|
let r = mk(e), i = r?.url || r?.page_url || "";
|
|
@@ -29522,12 +29554,12 @@ function Sk(e) {
|
|
|
29522
29554
|
"fwh-end-session-mvp": async () => ($("fwh-end-session-mvp ▶"), typeof e.requestEndSession == "function" && e.requestEndSession(), "Voice session is ending."),
|
|
29523
29555
|
"fwh-get-current-page-mvp": async () => {
|
|
29524
29556
|
if ($("fwh-get-current-page-mvp ▶"), typeof window > "u") return "Cannot determine current page (no browser context).";
|
|
29525
|
-
let e = window.location.href, t = window.location.pathname, n = document.title || "", r = xk()
|
|
29557
|
+
let e = window.location.href, t = window.location.pathname, n = document.title || "", r = xk();
|
|
29526
29558
|
return $("fwh-get-current-page-mvp ✓", {
|
|
29527
29559
|
url: e,
|
|
29528
29560
|
path: t,
|
|
29529
29561
|
title: n
|
|
29530
|
-
}), $("fwh-get-current-page-mvp → page headings collected:", r), `CURRENT_PAGE. URL: ${e} |
|
|
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.`;
|
|
29531
29563
|
},
|
|
29532
29564
|
"fwh-list-forms-mvp": async () => {
|
|
29533
29565
|
let e = XO(), t = ZO();
|
|
@@ -29732,7 +29764,7 @@ function kk({ title: e }) {
|
|
|
29732
29764
|
}
|
|
29733
29765
|
function Ak(e, t) {
|
|
29734
29766
|
let n = (t || "").trim();
|
|
29735
|
-
return n ? !!(/\b(let'?s|let us)\s+(end|stop|finish|wrap up|close)\s+(the\s+)?(voice\s+)?(session|call|chat)\b/i.test(n) || /\bend\s+(this\s+)?(the\s+)?(voice\s+)?(session|call|chat)\b/i.test(n) || /\b(hang\s+up|disconnect)\b/i.test(n) || /\b(that'?s all|we'?re done)\b/i.test(n) ||
|
|
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) || e === "bot" && (/\b(that'?s all|we'?re done)\b/i.test(n) || /\b(goodbye|bye)\b/i.test(n) || /\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))) : !1;
|
|
29736
29768
|
}
|
|
29737
29769
|
function jk({ orbColors: e, ...t }) {
|
|
29738
29770
|
return /* @__PURE__ */ g(lO, {
|
|
@@ -30147,14 +30179,14 @@ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30147
30179
|
}, x = (m.split("/").filter(Boolean).pop() || "").replace(/[-_]/g, " ").replace(/\b\w/g, (e) => e.toUpperCase()), S = "";
|
|
30148
30180
|
h && h.includes("|") && (S = h.split("|").map((e) => e.trim()).filter(Boolean).reduce((e, t) => e.length <= t.length ? e : t));
|
|
30149
30181
|
let T = S || x || "this page";
|
|
30150
|
-
if (_) if (p) y.overrides = { agent: { firstMessage: `I've
|
|
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})`);
|
|
30151
30183
|
else if (u) y.overrides = { agent: { firstMessage: "I'm still here. Go ahead!" } };
|
|
30152
30184
|
else {
|
|
30153
30185
|
let e = f || "";
|
|
30154
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}`);
|
|
30155
30187
|
}
|
|
30156
30188
|
else u && (y.overrides = { agent: { firstMessage: "" } });
|
|
30157
|
-
let oe = !1, me = p ?
|
|
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({
|
|
30158
30190
|
...y,
|
|
30159
30191
|
onConnect: ({ conversationId: e }) => {
|
|
30160
30192
|
ie.current = e, ae.current = Date.now(), console.log("[FlowEngage] 🎙️ AI chat session connected:", e);
|
|
@@ -30173,7 +30205,7 @@ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30173
30205
|
if (me && !oe) {
|
|
30174
30206
|
oe = !0;
|
|
30175
30207
|
try {
|
|
30176
|
-
C.current?.
|
|
30208
|
+
C.current?.sendContextualUpdate?.(me);
|
|
30177
30209
|
} catch {}
|
|
30178
30210
|
}
|
|
30179
30211
|
if (ge && !he) {
|
|
@@ -30183,11 +30215,7 @@ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30183
30215
|
} catch {}
|
|
30184
30216
|
}
|
|
30185
30217
|
de.current && clearTimeout(de.current), de.current = setTimeout(() => {
|
|
30186
|
-
e || ce.current !== "speaking" && (fe.current || (de.current = null, ce.current = "listening", v("listening")
|
|
30187
|
-
if (!e && ce.current === "listening" && !te.current) try {
|
|
30188
|
-
C.current?.sendContextualUpdate?.("The visitor has been silent for a while. Ask one short, natural question to re-engage — for example: 'Is there anything specific you'd like to know more about?' or 'What else can I help you with today?' Keep it to one sentence.");
|
|
30189
|
-
} catch {}
|
|
30190
|
-
}, 4e3))));
|
|
30218
|
+
e || ce.current !== "speaking" && (fe.current || (de.current = null, ce.current = "listening", v("listening")));
|
|
30191
30219
|
}, 1200);
|
|
30192
30220
|
}
|
|
30193
30221
|
},
|
|
@@ -30204,7 +30232,7 @@ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30204
30232
|
e && Ae(i, e);
|
|
30205
30233
|
} catch {}
|
|
30206
30234
|
if (Ak(n, r)) {
|
|
30207
|
-
|
|
30235
|
+
se.current = !0;
|
|
30208
30236
|
return;
|
|
30209
30237
|
}
|
|
30210
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 {
|
|
@@ -30253,8 +30281,13 @@ function Pk({ orbColors: e, onEnterChat: t, onEndChat: n, agentId: r, siteId: i,
|
|
|
30253
30281
|
try {
|
|
30254
30282
|
r = await t["fwh-list-forms-mvp"]();
|
|
30255
30283
|
} catch {}
|
|
30256
|
-
let a =
|
|
30257
|
-
|
|
30284
|
+
let a = "none";
|
|
30285
|
+
if (typeof window < "u" && typeof document < "u") try {
|
|
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);
|
|
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(" | "));
|
|
30288
|
+
} catch {}
|
|
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.`);
|
|
30258
30291
|
} catch {}
|
|
30259
30292
|
if (typeof window < "u") {
|
|
30260
30293
|
let t = window.location.pathname, n = () => {
|
|
@@ -31499,6 +31532,10 @@ function Rk() {
|
|
|
31499
31532
|
return;
|
|
31500
31533
|
}
|
|
31501
31534
|
if (i) {
|
|
31535
|
+
if ((typeof performance < "u" ? performance.getEntriesByType?.("navigation")?.[0]?.type ?? "navigate" : "navigate") === "reload") {
|
|
31536
|
+
ot("minimized_orb");
|
|
31537
|
+
return;
|
|
31538
|
+
}
|
|
31502
31539
|
ce?.({ notifyChatInitiated: !0 }), ue?.(!0), ot("voice_mode");
|
|
31503
31540
|
return;
|
|
31504
31541
|
}
|