@flowengage/react-chatbot 1.0.3 → 1.0.4

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.
@@ -2689,7 +2689,11 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2689
2689
  }
2690
2690
  try {
2691
2691
  let t = await w.current.syncVoice(v, e);
2692
- t?.chat_history && b(ln(t.chat_history));
2692
+ if (t?.chat_history?.length) b(ln(t.chat_history));
2693
+ else if (t?.success) try {
2694
+ let e = await w.current.loadHistory(v, r);
2695
+ e?.chat_history?.length && b(ln(e.chat_history));
2696
+ } catch {}
2693
2697
  } catch {} finally {
2694
2698
  Fe(!1);
2695
2699
  }
@@ -22346,6 +22350,7 @@ function rg(e) {
22346
22350
  return $("search_site_content ✖", t), t;
22347
22351
  }
22348
22352
  },
22353
+ end_voice_session: async () => ($("end_voice_session ▶"), typeof e.requestEndSession == "function" && e.requestEndSession(), "Voice session is ending."),
22349
22354
  list_page_forms: async () => {
22350
22355
  let e = Mh(), t = Nh();
22351
22356
  return $("list_page_forms ✓", `${e.length} field(s)`, `${t.length} button(s)`), JSON.stringify({
@@ -22413,6 +22418,7 @@ function rg(e) {
22413
22418
  navigateToPage: a.navigate_to_page,
22414
22419
  highlightOnPage: a.highlight_on_page,
22415
22420
  searchSiteContent: a.search_site_content,
22421
+ endVoiceSession: a.end_voice_session,
22416
22422
  listPageForms: a.list_page_forms,
22417
22423
  fillFormFields: a.fill_form_fields,
22418
22424
  clickPageButton: a.click_page_button
@@ -22441,18 +22447,36 @@ var ag = {
22441
22447
  speaking: "#f59e0b",
22442
22448
  error: "#ef4444"
22443
22449
  };
22444
- function sg({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, historyRef: d, hasSyncedRef: f, onMessageSync: p, onStartSync: m }) {
22445
- let [h, g] = s("idle"), [ee, te] = s(null), [_, ne] = s(!1), re = o(null), ie = o(null), ae = o("");
22446
- i(() => {
22450
+ function sg(e, t) {
22451
+ let n = (t || "").trim();
22452
+ 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;
22453
+ }
22454
+ function cg({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, historyRef: d, hasSyncedRef: f, onMessageSync: p, onStartSync: m }) {
22455
+ let [h, g] = s("idle"), [ee, te] = s(null), [_, ne] = s(!1), re = o(null), ie = o(null), ae = o(""), oe = o(async () => {}), se = o(!1), v = n(async () => {
22456
+ try {
22457
+ await re.current?.endSession?.();
22458
+ } catch {}
22459
+ re.current = null, ne(!1), g("idle"), se.current = !1, typeof p == "function" && await p(d.current), typeof c == "function" && c();
22460
+ }, [
22461
+ d,
22462
+ p,
22463
+ c
22464
+ ]);
22465
+ oe.current = v, i(() => {
22447
22466
  let t = !1, n = null;
22448
22467
  return (async () => {
22449
22468
  try {
22450
22469
  if (await navigator.mediaDevices.getUserMedia({ audio: !0 }), t) return;
22451
- d.current = [], ae.current = "";
22470
+ d.current = [], ae.current = "", se.current = !1;
22452
22471
  let i = ig(rg({
22453
22472
  siteId: r || null,
22454
22473
  apiBaseUrl: a || null,
22455
- getLastUserVoiceText: () => ae.current
22474
+ getLastUserVoiceText: () => ae.current,
22475
+ requestEndSession: () => {
22476
+ queueMicrotask(() => {
22477
+ se.current || (se.current = !0, oe.current?.());
22478
+ });
22479
+ }
22456
22480
  })), o = await wh.startSession({
22457
22481
  agentId: e,
22458
22482
  clientTools: i,
@@ -22471,7 +22495,9 @@ function sg({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
22471
22495
  message: r,
22472
22496
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
22473
22497
  };
22474
- n === "user" && (ae.current = r), d.current = [...d.current, i];
22498
+ n === "user" && (ae.current = r), d.current = [...d.current, i], sg(n, r) && queueMicrotask(() => {
22499
+ se.current || (se.current = !0, oe.current?.());
22500
+ });
22475
22501
  },
22476
22502
  onError: (e) => {
22477
22503
  t || (console.error("[VoiceInterface] ElevenLabs error", e), g("error"), te("Voice session encountered an error."));
@@ -22492,7 +22518,7 @@ function sg({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
22492
22518
  } catch {
22493
22519
  t = "[]";
22494
22520
  }
22495
- o.sendContextualUpdate(`Current page URL: ${e}. Site ID: ${r || "unknown"}. Page fields/buttons JSON: ${t}. Navigation: search_site_content then navigate_to_page with section_text when relevant — no permission ask. Forms: use fill_form_fields then click_page_button (e.g. Conduct Audit) when the user wants to submit.`);
22521
+ o.sendContextualUpdate(`Current page URL: ${e}. Site ID: ${r || "unknown"}. Page fields/buttons JSON: ${t}. Navigation: search_site_content then navigate_to_page with section_text when relevant — no permission ask. Forms: use fill_form_fields then click_page_button (e.g. Conduct Audit) when the user wants to submit. Voice: if the user wants to end the voice session, call end_voice_session or confirm and end; you may also say you are ending the voice session.`);
22496
22522
  } catch {}
22497
22523
  typeof m == "function" && m();
22498
22524
  } catch (e) {
@@ -22508,16 +22534,7 @@ function sg({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
22508
22534
  d,
22509
22535
  m
22510
22536
  ]);
22511
- let oe = n(async () => {
22512
- try {
22513
- await re.current?.endSession?.();
22514
- } catch {}
22515
- re.current = null, ne(!1), g("idle"), typeof p == "function" && await p(d.current), typeof c == "function" && c();
22516
- }, [
22517
- d,
22518
- p,
22519
- c
22520
- ]), se = h === "listening" || h === "speaking", v = og[h] || og.idle, ce = ag[h] || ag.idle;
22537
+ let ce = h === "listening" || h === "speaking", le = og[h] || og.idle, ue = ag[h] || ag.idle;
22521
22538
  return /* @__PURE__ */ u("div", {
22522
22539
  ref: ie,
22523
22540
  style: {
@@ -22541,19 +22558,19 @@ function sg({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
22541
22558
  justifyContent: "center"
22542
22559
  },
22543
22560
  children: [
22544
- se && /* @__PURE__ */ l("div", { style: {
22561
+ ce && /* @__PURE__ */ l("div", { style: {
22545
22562
  position: "absolute",
22546
22563
  inset: "-16px",
22547
22564
  borderRadius: "50%",
22548
- border: `2px solid ${v}`,
22565
+ border: `2px solid ${le}`,
22549
22566
  animation: "fe-orb-pulse 1.4s ease-in-out infinite",
22550
22567
  opacity: .6
22551
22568
  } }),
22552
- se && /* @__PURE__ */ l("div", { style: {
22569
+ ce && /* @__PURE__ */ l("div", { style: {
22553
22570
  position: "absolute",
22554
22571
  inset: "-8px",
22555
22572
  borderRadius: "50%",
22556
- border: `2px solid ${v}`,
22573
+ border: `2px solid ${le}`,
22557
22574
  animation: "fe-orb-pulse 1.4s ease-in-out 0.35s infinite",
22558
22575
  opacity: .4
22559
22576
  } }),
@@ -22562,18 +22579,18 @@ function sg({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
22562
22579
  width: "140px",
22563
22580
  height: "140px",
22564
22581
  borderRadius: "50%",
22565
- background: ce,
22566
- border: `3px solid ${v}`,
22582
+ background: ue,
22583
+ border: `3px solid ${le}`,
22567
22584
  display: "flex",
22568
22585
  alignItems: "center",
22569
22586
  justifyContent: "center",
22570
22587
  transition: "all 0.35s ease",
22571
22588
  transform: h === "speaking" ? "scale(1.08)" : "scale(1)",
22572
- boxShadow: `0 0 40px ${ce}, 0 8px 32px rgba(0,0,0,0.08)`
22589
+ boxShadow: `0 0 40px ${ue}, 0 8px 32px rgba(0,0,0,0.08)`
22573
22590
  },
22574
22591
  children: /* @__PURE__ */ l(_n, {
22575
22592
  size: 44,
22576
- color: v
22593
+ color: le
22577
22594
  })
22578
22595
  })
22579
22596
  ]
@@ -22594,7 +22611,7 @@ function sg({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
22594
22611
  ]
22595
22612
  }),
22596
22613
  /* @__PURE__ */ u("button", {
22597
- onClick: oe,
22614
+ onClick: v,
22598
22615
  style: {
22599
22616
  display: "flex",
22600
22617
  alignItems: "center",
@@ -22623,7 +22640,7 @@ function sg({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
22623
22640
  }
22624
22641
  //#endregion
22625
22642
  //#region src/components/FlowEngageWidget.jsx
22626
- var cg = [
22643
+ var lg = [
22627
22644
  {
22628
22645
  key: "become_client",
22629
22646
  label: "Become a Client"
@@ -22644,7 +22661,7 @@ var cg = [
22644
22661
  key: "looking_for_job",
22645
22662
  label: "Looking for a Job"
22646
22663
  }
22647
- ], lg = () => /* @__PURE__ */ l("div", {
22664
+ ], ug = () => /* @__PURE__ */ l("div", {
22648
22665
  style: {
22649
22666
  display: "flex",
22650
22667
  marginBottom: "12px",
@@ -22675,13 +22692,13 @@ var cg = [
22675
22692
  } }, e)), /* @__PURE__ */ l("style", { children: "\n @keyframes fe-dot-bounce {\n 0%, 80%, 100% { transform: translateY(0); opacity: 0.5; }\n 40% { transform: translateY(-5px); opacity: 1; }\n }\n " })]
22676
22693
  })
22677
22694
  });
22678
- function ug() {
22695
+ function dg() {
22679
22696
  let { status: e, runtimeConfig: t, resolvedConfig: n, chatId: r, chatHistory: o, isOpen: c, activeScreen: d, isHumanHandled: f, agentName: p, agentHeadshot: m, visitorEmail: h, isAgentTyping: g, isAiTyping: ee, isLoading: te, isVoiceMode: _, isRateLimited: ne, rateLimitMessage: re, isConversationEnded: ie, incomingCall: ae, activeCallId: oe, callConnectionState: se, callConnectedAt: v, isCallMuted: ce, webRTCError: le, language: ue, historyRef: y, onMessageSync: b, endConversation: de, acceptCall: fe, rejectCall: pe, endWebRTCCall: me, toggleCallMute: he, dismissCallError: ge, captureVisitorEmail: _e, openWidget: ve, closeWidget: ye, sendMessage: be, setVoiceMode: xe, startTyping: Se, stopTyping: Ce, updateTypingDraft: we } = Xt(), [Te, Ee] = s(""), [De, Oe] = s(null), [ke, Ae] = s(null), [je, Me] = s(null), [Ne, Pe] = s(0), [x, Fe] = s(h || ""), [Ie, Le] = s(""), S = t?.widgetSettings || {}, Re = n?.widgetSettings || {}, ze = {
22680
- ...S.branding || {},
22681
- ...Re.branding || {}
22697
+ ...Re.branding || {},
22698
+ ...S.branding || {}
22682
22699
  }, Be = {
22683
- ...S.theme || {},
22684
- ...Re.theme || {}
22700
+ ...Re.theme || {},
22701
+ ...S.theme || {}
22685
22702
  }, Ve = Be.primaryColor || "#3B82F6", He = Be.accentColor || "#1D4ED8", Ue = (Be.position || "bottom-right") === "bottom-left" ? {
22686
22703
  left: "1.5rem",
22687
22704
  bottom: "1.5rem"
@@ -22697,7 +22714,7 @@ function ug() {
22697
22714
  outline: "none",
22698
22715
  fontFamily: "ui-sans-serif, system-ui, sans-serif",
22699
22716
  ...c ? {} : Ue
22700
- }, Ge = Re.recommendations?.[ue] || S.recommendations?.[ue] || cg, Ke = Re.greetings?.[ue] || S.greetings?.[ue], qe = ze.chatButtonText || "Chat with us", Je = ze.headerName || t?.websiteName || "OpenSense Labs", C = ze.logoUrl || null, w = ze.hideWatermark || !1, T = Re.elevenLabsAgentId || t?.elevenLabsAgentId || null, Ye = t?.siteId || n?.siteId || null, Xe = t?.apiBaseUrl || "", Ze = ze.fallbackAgentName || "Agent", Qe = ze.botLabel || "AI", $e = m && String(m).trim() || t?.ownerProfileImageUrl && String(t.ownerProfileImageUrl).trim() || null, et = ae?.agentName || p || Ze, tt = o.some((e) => e.sender === "user"), nt = a(() => {
22717
+ }, Ge = S.recommendations?.[ue] || Re.recommendations?.[ue] || lg, Ke = S.greetings?.[ue] || Re.greetings?.[ue], qe = ze.chatButtonText || "Chat with us", Je = ze.headerName || t?.websiteName || "OpenSense Labs", C = ze.logoUrl || null, w = ze.hideWatermark || !1, T = Re.elevenLabsAgentId || t?.elevenLabsAgentId || null, Ye = t?.siteId || n?.siteId || null, Xe = t?.apiBaseUrl || "", Ze = ze.fallbackAgentName || "Agent", Qe = ze.botLabel || "AI", $e = m && String(m).trim() || t?.ownerProfileImageUrl && String(t.ownerProfileImageUrl).trim() || null, et = ae?.agentName || p || Ze, tt = o.some((e) => e.sender === "user"), nt = a(() => {
22701
22718
  let e = o.findIndex((e) => e.sender === "user");
22702
22719
  return e === -1 ? !1 : o.slice(e + 1).some((e) => e.sender === "bot" || e.sender === "ai" || e.sender === "agent");
22703
22720
  }, [o]), rt = !h && tt && nt;
@@ -22825,7 +22842,7 @@ function ug() {
22825
22842
  flexDirection: "column"
22826
22843
  },
22827
22844
  className: "fe-screen-fade-in",
22828
- children: /* @__PURE__ */ l(sg, {
22845
+ children: /* @__PURE__ */ l(cg, {
22829
22846
  agentId: T,
22830
22847
  chatId: r,
22831
22848
  siteId: Ye,
@@ -22858,7 +22875,7 @@ function ug() {
22858
22875
  isAiTyping: ee,
22859
22876
  isAgentTyping: g,
22860
22877
  setReplyContext: Me,
22861
- TypingDots: lg,
22878
+ TypingDots: ug,
22862
22879
  primaryColor: Ve,
22863
22880
  agentHeadshot: $e,
22864
22881
  agentDisplayName: p || Ze
@@ -22937,4 +22954,4 @@ function ug() {
22937
22954
  }) : null;
22938
22955
  }
22939
22956
  //#endregion
22940
- export { mn as FlowEngageProvider, ug as FlowEngageWidget, Xt as useFlowEngage };
22957
+ export { mn as FlowEngageProvider, dg as FlowEngageWidget, Xt as useFlowEngage };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowengage/react-chatbot",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
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",