@flowengage/react-chatbot 0.2.8 → 0.2.9

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.
@@ -21678,7 +21678,16 @@ var hh = class extends Bm {
21678
21678
  function $(...e) {
21679
21679
  Yt() && console.log("[FlowEngage:voice-tools]", ...e);
21680
21680
  }
21681
- function gh(e) {
21681
+ var gh = "#flowengage-root, .flowengage-shell";
21682
+ function _h(e) {
21683
+ if (!e || typeof e.closest != "function") return !1;
21684
+ try {
21685
+ return !!e.closest(gh);
21686
+ } catch {
21687
+ return !1;
21688
+ }
21689
+ }
21690
+ function vh(e) {
21682
21691
  if (e.labels && e.labels.length) return e.labels[0].textContent?.trim() || null;
21683
21692
  let t = e.id;
21684
21693
  if (t) try {
@@ -21695,8 +21704,9 @@ function gh(e) {
21695
21704
  }
21696
21705
  return null;
21697
21706
  }
21698
- function _h() {
21707
+ function yh() {
21699
21708
  return Array.from(document.querySelectorAll("input, select, textarea")).filter((e) => {
21709
+ if (_h(e)) return !1;
21700
21710
  let t = (e.type || "").toLowerCase();
21701
21711
  if ([
21702
21712
  "hidden",
@@ -21711,21 +21721,21 @@ function _h() {
21711
21721
  return !0;
21712
21722
  });
21713
21723
  }
21714
- function vh() {
21715
- return _h().map((e, t) => ({
21724
+ function bh() {
21725
+ return yh().map((e, t) => ({
21716
21726
  formIndex: 0,
21717
21727
  fieldIndex: t,
21718
21728
  tag: e.tagName,
21719
21729
  type: e.type || "text",
21720
21730
  name: e.name || null,
21721
21731
  id: e.id || null,
21722
- label: gh(e),
21732
+ label: vh(e),
21723
21733
  placeholder: e.placeholder || null
21724
21734
  }));
21725
21735
  }
21726
- function yh() {
21736
+ function xh() {
21727
21737
  return Array.from(document.querySelectorAll("button, [role=\"button\"], input[type=\"submit\"], input[type=\"button\"]")).filter((e) => {
21728
- if (e.disabled) return !1;
21738
+ if (_h(e) || e.disabled) return !1;
21729
21739
  try {
21730
21740
  let t = window.getComputedStyle(e);
21731
21741
  if (t.display === "none" || t.visibility === "hidden") return !1;
@@ -21738,14 +21748,14 @@ function yh() {
21738
21748
  type: e.type || e.tagName
21739
21749
  }));
21740
21750
  }
21741
- function bh(e, t) {
21751
+ function Sh(e, t) {
21742
21752
  let n = String(t || "").toLowerCase().trim();
21743
21753
  if (!n) return 0;
21744
21754
  let r = [
21745
21755
  e.name,
21746
21756
  e.id,
21747
21757
  e.placeholder,
21748
- gh(e),
21758
+ vh(e),
21749
21759
  e.getAttribute("aria-label"),
21750
21760
  e.getAttribute("title"),
21751
21761
  e.getAttribute("data-testid")
@@ -21764,15 +21774,44 @@ function bh(e, t) {
21764
21774
  }
21765
21775
  return i;
21766
21776
  }
21767
- function xh(e, t) {
21777
+ var Ch = 28;
21778
+ function wh(e, t) {
21768
21779
  let n = null, r = 0;
21769
21780
  for (let i of e) {
21770
- let e = bh(i, t);
21781
+ let e = Sh(i, t);
21771
21782
  e > r && (r = e, n = i);
21772
21783
  }
21773
- return !n || r < 38 ? null : n;
21784
+ return !n || r < Ch ? null : n;
21774
21785
  }
21775
- function Sh(e, t) {
21786
+ function Th(e, t, n) {
21787
+ let r = String(t || "").toLowerCase().trim(), i = String(n || "").trim();
21788
+ if (!(/^https?:\/\//i.test(i) || /\.\w{2,}(\/|\s|$)/.test(i) || r.includes("url") || r.includes("website") || r.includes("domain") || r.includes("site"))) return null;
21789
+ let a = null, o = 0;
21790
+ for (let t of e) {
21791
+ if (t.tagName !== "INPUT" && t.tagName !== "TEXTAREA") continue;
21792
+ let e = (t.type || "").toLowerCase();
21793
+ if ([
21794
+ "hidden",
21795
+ "submit",
21796
+ "button",
21797
+ "checkbox",
21798
+ "radio"
21799
+ ].includes(e)) continue;
21800
+ let n = 0;
21801
+ (e === "url" || e === "text" || e === "search") && (n += 45);
21802
+ let r = [
21803
+ t.name,
21804
+ t.id,
21805
+ t.placeholder,
21806
+ vh(t),
21807
+ t.getAttribute("aria-label"),
21808
+ t.getAttribute("autocomplete")
21809
+ ].filter(Boolean).join(" ").toLowerCase();
21810
+ /(website|url|domain|site\s*url)/.test(r) && (n += 55), n > o && (o = n, a = t);
21811
+ }
21812
+ return !a || o < 50 ? null : a;
21813
+ }
21814
+ function Eh(e, t) {
21776
21815
  let n = String(t || "").toLowerCase().trim();
21777
21816
  if (!n) return 0;
21778
21817
  let r = [
@@ -21788,9 +21827,9 @@ function Sh(e, t) {
21788
21827
  for (let e of i) r.includes(e) && (a += 1);
21789
21828
  return a / i.length * 92;
21790
21829
  }
21791
- function Ch(e) {
21830
+ function Dh(e) {
21792
21831
  let t = Array.from(document.querySelectorAll("button, [role=\"button\"], input[type=\"submit\"], input[type=\"button\"]")).filter((e) => {
21793
- if (e.disabled) return !1;
21832
+ if (_h(e) || e.disabled) return !1;
21794
21833
  try {
21795
21834
  let t = window.getComputedStyle(e);
21796
21835
  if (t.display === "none" || t.visibility === "hidden") return !1;
@@ -21798,12 +21837,12 @@ function Ch(e) {
21798
21837
  return !0;
21799
21838
  }), n = null, r = 0;
21800
21839
  for (let i of t) {
21801
- let t = Sh(i, e);
21840
+ let t = Eh(i, e);
21802
21841
  t > r && (r = t, n = i);
21803
21842
  }
21804
21843
  return !n || r < 36 ? null : n;
21805
21844
  }
21806
- function wh(e) {
21845
+ function Oh(e) {
21807
21846
  if (e == null) return {};
21808
21847
  if (typeof e == "string") {
21809
21848
  let t = e.trim();
@@ -21816,17 +21855,34 @@ function wh(e) {
21816
21855
  }
21817
21856
  return e;
21818
21857
  }
21819
- function Th(e) {
21858
+ function kh(e) {
21820
21859
  if (!e || typeof e != "object") return null;
21821
21860
  let t = e.url ?? e.target_url ?? e.page_url ?? e.pageUrl ?? e.link ?? e.href ?? e.path;
21822
21861
  return t == null ? null : String(t).trim() || null;
21823
21862
  }
21824
- function Eh(e) {
21863
+ function Ah(e) {
21825
21864
  if (!e || typeof e != "object") return null;
21826
21865
  let t = e.query ?? e.q ?? e.search ?? e.text ?? e.keywords;
21827
21866
  return t == null ? null : String(t).trim() || null;
21828
21867
  }
21829
- function Dh(e, t) {
21868
+ function jh(e, t) {
21869
+ try {
21870
+ e.scrollIntoView({
21871
+ block: "center",
21872
+ inline: "nearest"
21873
+ });
21874
+ } catch {
21875
+ try {
21876
+ e.scrollIntoView(!0);
21877
+ } catch {}
21878
+ }
21879
+ try {
21880
+ e.focus({ preventScroll: !0 });
21881
+ } catch {
21882
+ try {
21883
+ e.focus();
21884
+ } catch {}
21885
+ }
21830
21886
  let n = e.tagName, r = (e.type || "").toLowerCase();
21831
21887
  if (n === "SELECT") return e.value = String(t), e.dispatchEvent(new Event("input", { bubbles: !0 })), e.dispatchEvent(new Event("change", { bubbles: !0 })), !0;
21832
21888
  if (r === "checkbox" || r === "radio") return e.checked = [
@@ -21840,14 +21896,24 @@ function Dh(e, t) {
21840
21896
  let t = n === "TEXTAREA" ? window.HTMLTextAreaElement.prototype : window.HTMLInputElement.prototype, r = Object.getOwnPropertyDescriptor(t, "value");
21841
21897
  r?.set ? r.set.call(e, i) : e.value = i;
21842
21898
  } else e.value = i;
21843
- return e.dispatchEvent(new Event("input", { bubbles: !0 })), e.dispatchEvent(new Event("change", { bubbles: !0 })), !0;
21899
+ try {
21900
+ e.dispatchEvent(new InputEvent("input", {
21901
+ bubbles: !0,
21902
+ cancelable: !0,
21903
+ inputType: "insertText",
21904
+ data: i
21905
+ }));
21906
+ } catch {
21907
+ e.dispatchEvent(new Event("input", { bubbles: !0 }));
21908
+ }
21909
+ return e.dispatchEvent(new Event("change", { bubbles: !0 })), !0;
21844
21910
  }
21845
- function Oh(e) {
21911
+ function Mh(e) {
21846
21912
  let t = e.siteId || null, n = (e.apiBaseUrl || "").replace(/\/$/, "");
21847
21913
  return {
21848
21914
  navigate_to_page: async (e) => {
21849
21915
  $("navigate_to_page ▶ raw parameters:", e);
21850
- let t = wh(e), n = Th(t), r = t.section_text ?? t.sectionText ?? t.section;
21916
+ let t = Oh(e), n = kh(t), r = t.section_text ?? t.sectionText ?? t.section;
21851
21917
  if ($("navigate_to_page · coerced:", {
21852
21918
  url: n,
21853
21919
  sectionText: r
@@ -21872,12 +21938,12 @@ function Oh(e) {
21872
21938
  },
21873
21939
  highlight_on_page: async (e) => {
21874
21940
  $("highlight_on_page ▶", e);
21875
- let t = wh(e), n = t?.section_id || t?.sectionId, r = t?.section_text || t?.sectionText, i = Qt(n || null, r || null);
21941
+ let t = Oh(e), n = t?.section_id || t?.sectionId, r = t?.section_text || t?.sectionText, i = Qt(n || null, r || null);
21876
21942
  return i ? ($t(i), $("highlight_on_page ✓"), "Highlighted the section.") : ($("highlight_on_page ✖ no element"), "Could not find that section on the page.");
21877
21943
  },
21878
21944
  search_site_content: async (e) => {
21879
21945
  $("search_site_content ▶", e);
21880
- let r = Eh(wh(e));
21946
+ let r = Ah(Oh(e));
21881
21947
  if ($("search_site_content · query:", r, "siteId:", t, "apiBase:", n || "(empty)"), !r) return $("search_site_content ✖ missing query"), "Missing query parameter.";
21882
21948
  if (!t) return $("search_site_content ✖ no siteId"), "Site is not configured for search.";
21883
21949
  if (!n) return $("search_site_content ✖ no api base"), "API base URL is missing; cannot search.";
@@ -21905,7 +21971,7 @@ function Oh(e) {
21905
21971
  }
21906
21972
  },
21907
21973
  list_page_forms: async () => {
21908
- let e = vh(), t = yh();
21974
+ let e = bh(), t = xh();
21909
21975
  return $("list_page_forms ✓", `${e.length} field(s)`, `${t.length} button(s)`), JSON.stringify({
21910
21976
  fields: e,
21911
21977
  buttons: t,
@@ -21913,26 +21979,39 @@ function Oh(e) {
21913
21979
  });
21914
21980
  },
21915
21981
  fill_form_fields: async (e) => {
21916
- let t = wh(e)?.fields;
21917
- if ($("fill_form_fields ▶", { fieldCount: Array.isArray(t) ? t.length : 0 }), !Array.isArray(t) || t.length === 0) return "No fields provided. Use list_page_forms first.";
21918
- let n = _h(), r = [];
21919
- for (let e of t) {
21920
- let t = e?.field_key ?? e?.fieldKey, i = e?.value;
21921
- if (t == null || i == null) continue;
21922
- let a = xh(n, String(t));
21923
- a && (Dh(a, i), r.push(String(t)));
21982
+ try {
21983
+ let t = Oh(e), n = t?.fields;
21984
+ if (!n && Array.isArray(t) && t.length > 0 && t[0]?.field_key != null && (n = t), $("fill_form_fields ▶", { fieldCount: Array.isArray(n) ? n.length : 0 }), !Array.isArray(n) || n.length === 0) return "No fields provided. Use list_page_forms first.";
21985
+ let r = [];
21986
+ for (let e of n) {
21987
+ let t = e?.field_key ?? e?.fieldKey, n = e?.value;
21988
+ if (t == null || n == null) continue;
21989
+ let i = yh(), a = wh(i, String(t));
21990
+ a ||= Th(i, String(t), n), a && (jh(a, n), r.push(String(t)));
21991
+ }
21992
+ if (!r.length) return $("fill_form_fields ✖ no matches"), "Could not match any fields. Call list_page_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.";
21993
+ let i = `Filled fields: ${r.join(", ")}`;
21994
+ return $("fill_form_fields ✓", i), i;
21995
+ } catch (e) {
21996
+ let t = `fill_form_fields error: ${e?.message || String(e)}`;
21997
+ return $("fill_form_fields ✖", t), t;
21924
21998
  }
21925
- if (!r.length) return $("fill_form_fields ✖ no matches"), "Could not match any fields. Call list_page_forms and use field_key values that match placeholder, label, name, or id (e.g. website url, Enter Website URL).";
21926
- let i = `Filled fields: ${r.join(", ")}`;
21927
- return $("fill_form_fields ✓", i), i;
21928
21999
  },
21929
22000
  click_page_button: async (e) => {
21930
- let t = wh(e), n = (t.button_text ?? t.buttonText ?? t.text ?? "").trim();
22001
+ let t = Oh(e), n = (t.button_text ?? t.buttonText ?? t.text ?? "").trim();
21931
22002
  if ($("click_page_button ▶", n), !n) return "Missing button_text: pass the visible label, e.g. Conduct Audit.";
21932
- let r = Ch(n);
22003
+ let r = Dh(n);
21933
22004
  if (!r) return $("click_page_button ✖ no match"), `Could not find a button matching "${n}". Call list_page_forms to see button texts.`;
21934
22005
  try {
21935
- r.click();
22006
+ try {
22007
+ r.scrollIntoView({
22008
+ block: "center",
22009
+ inline: "nearest"
22010
+ });
22011
+ } catch {
22012
+ r.scrollIntoView(!0);
22013
+ }
22014
+ r.focus?.(), r.click();
21936
22015
  let e = `OK_CLICK ${(r.textContent || r.value || r.getAttribute("aria-label") || "").trim().slice(0, 80) || "button"}`;
21937
22016
  return $("click_page_button ✓", e), e;
21938
22017
  } catch (e) {
@@ -21944,18 +22023,18 @@ function Oh(e) {
21944
22023
  }
21945
22024
  //#endregion
21946
22025
  //#region src/components/VoiceInterface.jsx
21947
- var kh = {
22026
+ var Nh = {
21948
22027
  idle: "rgba(99,102,241,0.18)",
21949
22028
  listening: "rgba(16,185,129,0.25)",
21950
22029
  speaking: "rgba(245,158,11,0.25)",
21951
22030
  error: "rgba(239,68,68,0.2)"
21952
- }, Ah = {
22031
+ }, Ph = {
21953
22032
  idle: "#6366f1",
21954
22033
  listening: "#10b981",
21955
22034
  speaking: "#f59e0b",
21956
22035
  error: "#ef4444"
21957
22036
  };
21958
- function jh({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, historyRef: d, hasSyncedRef: f, onMessageSync: p, onStartSync: m }) {
22037
+ function Fh({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, historyRef: d, hasSyncedRef: f, onMessageSync: p, onStartSync: m }) {
21959
22038
  let [ee, te] = s("idle"), [h, ne] = s(null), [re, ie] = s(!1), [ae, oe] = s([]), se = o(null), g = o(null);
21960
22039
  i(() => {
21961
22040
  let t = !1, n = null;
@@ -21963,7 +22042,7 @@ function jh({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
21963
22042
  try {
21964
22043
  if (await navigator.mediaDevices.getUserMedia({ audio: !0 }), t) return;
21965
22044
  oe([]);
21966
- let i = Oh({
22045
+ let i = Mh({
21967
22046
  siteId: r || null,
21968
22047
  apiBaseUrl: a || null
21969
22048
  }), o = await hh.startSession({
@@ -22027,7 +22106,7 @@ function jh({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
22027
22106
  d,
22028
22107
  p,
22029
22108
  c
22030
- ]), le = ee === "listening" || ee === "speaking", _ = Ah[ee] || Ah.idle, ue = kh[ee] || kh.idle;
22109
+ ]), le = ee === "listening" || ee === "speaking", _ = Ph[ee] || Ph.idle, ue = Nh[ee] || Nh.idle;
22031
22110
  return /* @__PURE__ */ u("div", {
22032
22111
  ref: g,
22033
22112
  style: {
@@ -22162,7 +22241,7 @@ function jh({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
22162
22241
  }
22163
22242
  //#endregion
22164
22243
  //#region src/components/FlowEngageWidget.jsx
22165
- var Mh = [
22244
+ var Ih = [
22166
22245
  {
22167
22246
  key: "become_client",
22168
22247
  label: "Become a Client"
@@ -22183,7 +22262,7 @@ var Mh = [
22183
22262
  key: "looking_for_job",
22184
22263
  label: "Looking for a Job"
22185
22264
  }
22186
- ], Nh = () => /* @__PURE__ */ l("div", {
22265
+ ], Lh = () => /* @__PURE__ */ l("div", {
22187
22266
  style: {
22188
22267
  display: "flex",
22189
22268
  marginBottom: "12px",
@@ -22214,7 +22293,7 @@ var Mh = [
22214
22293
  } }, 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 " })]
22215
22294
  })
22216
22295
  });
22217
- function Ph() {
22296
+ function Rh() {
22218
22297
  let { status: e, runtimeConfig: t, resolvedConfig: n, chatId: r, chatHistory: a, isOpen: o, activeScreen: c, isHumanHandled: d, agentName: f, visitorEmail: p, isAgentTyping: m, isAiTyping: ee, isLoading: te, isVoiceMode: h, isRateLimited: ne, rateLimitMessage: re, isConversationEnded: ie, incomingCall: ae, activeCallId: oe, callConnectionState: se, callConnectedAt: g, isCallMuted: ce, webRTCError: le, language: _, historyRef: ue, onMessageSync: v, endConversation: y, acceptCall: de, rejectCall: fe, endWebRTCCall: pe, toggleCallMute: me, dismissCallError: he, captureVisitorEmail: ge, openWidget: _e, closeWidget: ve, sendMessage: ye, setVoiceMode: be, startTyping: xe, stopTyping: Se, updateTypingDraft: Ce } = Jt(), [we, Te] = s(""), [Ee, De] = s(null), [Oe, ke] = s(null), [Ae, je] = s(null), [Me, b] = s(0), [Ne, Pe] = s(p || ""), [Fe, Ie] = s(""), x = t?.widgetSettings || {}, Le = n?.widgetSettings || {}, Re = {
22219
22298
  ...x.branding || {},
22220
22299
  ...Le.branding || {}
@@ -22236,7 +22315,7 @@ function Ph() {
22236
22315
  outline: "none",
22237
22316
  fontFamily: "ui-sans-serif, system-ui, sans-serif",
22238
22317
  ...o ? {} : He
22239
- }, We = Le.recommendations?.[_] || x.recommendations?.[_] || Mh, Ge = Le.greetings?.[_] || x.greetings?.[_], Ke = Re.chatButtonText || "Chat with us", qe = Re.headerName || t?.websiteName || "OpenSense Labs", S = Re.logoUrl || null, C = Re.hideWatermark || !1, w = Le.elevenLabsAgentId || t?.elevenLabsAgentId || null, Je = t?.siteId || n?.siteId || null, Ye = t?.apiBaseUrl || "", Xe = Re.fallbackAgentName || "Agent", Ze = Re.botLabel || "AI", Qe = ae?.agentName || f || Xe, $e = !p && a.length === 0;
22318
+ }, We = Le.recommendations?.[_] || x.recommendations?.[_] || Ih, Ge = Le.greetings?.[_] || x.greetings?.[_], Ke = Re.chatButtonText || "Chat with us", qe = Re.headerName || t?.websiteName || "OpenSense Labs", S = Re.logoUrl || null, C = Re.hideWatermark || !1, w = Le.elevenLabsAgentId || t?.elevenLabsAgentId || null, Je = t?.siteId || n?.siteId || null, Ye = t?.apiBaseUrl || "", Xe = Re.fallbackAgentName || "Agent", Ze = Re.botLabel || "AI", Qe = ae?.agentName || f || Xe, $e = !p && a.length === 0;
22240
22319
  i(() => {
22241
22320
  Pe(p || ""), p && Ie("");
22242
22321
  }, [p]), i(() => {
@@ -22359,7 +22438,7 @@ function Ph() {
22359
22438
  flexDirection: "column"
22360
22439
  },
22361
22440
  className: "fe-screen-fade-in",
22362
- children: /* @__PURE__ */ l(jh, {
22441
+ children: /* @__PURE__ */ l(Fh, {
22363
22442
  agentId: w,
22364
22443
  chatId: r,
22365
22444
  siteId: Je,
@@ -22399,7 +22478,7 @@ function Ph() {
22399
22478
  isAiTyping: ee,
22400
22479
  isAgentTyping: m,
22401
22480
  setReplyContext: je,
22402
- TypingDots: Nh
22481
+ TypingDots: Lh
22403
22482
  })
22404
22483
  }, "history")
22405
22484
  }),
@@ -22475,4 +22554,4 @@ function Ph() {
22475
22554
  }) : null;
22476
22555
  }
22477
22556
  //#endregion
22478
- export { un as FlowEngageProvider, Ph as FlowEngageWidget, Jt as useFlowEngage };
22557
+ export { un as FlowEngageProvider, Rh as FlowEngageWidget, Jt as useFlowEngage };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowengage/react-chatbot",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
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",