@flowengage/react-chatbot 1.0.2 → 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.
@@ -1947,19 +1947,21 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
1947
1947
  let c = a(() => e ? {
1948
1948
  ...t || {},
1949
1949
  siteId: e
1950
- } : t || null, [e, t]), u = a(() => pn([c?.widgetSettings?.branding?.fallbackAgentName, c?.widgetSettings?.branding?.headerName], "Agent"), [c]), [d, f] = s("booting"), [m, h] = s(null), [_, ne] = s(null), [v, ce] = s(""), [y, b] = s([]), [de, fe] = s(ie().isOpen), [pe, me] = s(ie().activeScreen), [he, ge] = s(ie().isHumanHandled), [_e, ve] = s(ie().agentName), [ye, be] = s(ie().agentHeadshot), [xe, Se] = s(() => oe(c?.siteId)), [Ce, we] = s(!1), [Te, Ee] = s(!1), [De, Oe] = s("idle"), [ke, Ae] = s(!1), [je, Me] = s(!1), [Ne, Pe] = s(""), [x, Fe] = s(!1), [Ie, Le] = s(!1), [S, Re] = s(null), [ze, Be] = s(null), [Ve, He] = s("idle"), [Ue, We] = s(null), [Ge, Ke] = s(!1), [qe, Je] = s(""), C = o(null), w = o(null), T = o(""), Ye = o(null), Xe = o(null), Ze = o(null), Qe = o(null), $e = o(null), et = o([]), tt = o(null), nt = o(null), rt = o(!1), it = o(!1), at = o(""), ot = o([]), st = o(!1), ct = o({
1950
+ } : t || null, [e, t]), u = a(() => pn([c?.widgetSettings?.branding?.fallbackAgentName, c?.widgetSettings?.branding?.headerName], "Agent"), [c]), [d, f] = s("booting"), [m, h] = s(null), [_, ne] = s(null), [v, ce] = s(""), [y, b] = s([]), [de, fe] = s(ie().isOpen), [pe, me] = s(ie().activeScreen), [he, ge] = s(ie().isHumanHandled), [_e, ve] = s(ie().agentName), [ye, be] = s(ie().agentHeadshot), [xe, Se] = s(() => oe(c?.siteId)), [Ce, we] = s(!1), [Te, Ee] = s(!1), [De, Oe] = s("idle"), [ke, Ae] = s(!1), [je, Me] = s(!1), [Ne, Pe] = s(""), [x, Fe] = s(!1), [Ie, Le] = s(!1), [S, Re] = s(null), [ze, Be] = s(null), [Ve, He] = s("idle"), [Ue, We] = s(null), [Ge, Ke] = s(!1), [qe, Je] = s(""), C = o(null), w = o(null), T = o(""), Ye = o(null), Xe = o(null), Ze = o(null), Qe = o(null), $e = o(null), et = o([]), tt = o(null), nt = o(null), rt = o(!1), it = o(!1), at = o(""), ot = o(_e), st = o([]), ct = o(!1), lt = o({
1951
1951
  notifyRouteChange: () => {},
1952
1952
  cleanup: () => {}
1953
- }), lt = a(() => {
1953
+ }), ut = a(() => {
1954
1954
  let e = _?.widgetSettings?.call?.maxDurationSeconds ?? c?.widgetSettings?.call?.maxDurationSeconds ?? c?.callMaxDurationSeconds, t = Number(e);
1955
1955
  return Number.isFinite(t) && t > 0 ? t : ee;
1956
1956
  }, [c, _]);
1957
1957
  i(() => {
1958
1958
  Ye.current = S;
1959
- }, [S]);
1960
- let ut = () => {
1959
+ }, [S]), i(() => {
1960
+ ot.current = _e;
1961
+ }, [_e]);
1962
+ let dt = () => {
1961
1963
  Je("");
1962
- }, dt = (e) => {
1964
+ }, ft = (e) => {
1963
1965
  let t = typeof e == "string" ? e.trim().toLowerCase() : "";
1964
1966
  return Se(t), se(t, c?.siteId), t;
1965
1967
  };
@@ -1967,9 +1969,9 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
1967
1969
  let e = c?.siteId;
1968
1970
  e && Se(oe(e));
1969
1971
  }, [c?.siteId]);
1970
- let ft = () => {
1972
+ let pt = () => {
1971
1973
  Xe.current &&= (Xe.current.close(), null), Ze.current &&= (Ze.current.getTracks().forEach((e) => e.stop()), null), Qe.current &&= (Qe.current.srcObject = null, Qe.current.remove(), null), $e.current = null, et.current = [], tt.current = null, nt.current = null, rt.current = !1, Ke(!1), Re(null), Be(null), He("idle"), We(null);
1972
- }, pt = (e = (/* @__PURE__ */ new Date()).toISOString()) => {
1974
+ }, mt = (e = (/* @__PURE__ */ new Date()).toISOString()) => {
1973
1975
  let t = C.current, n = tt.current || $e.current?.callId;
1974
1976
  if (!t?.connected || !n || rt.current) {
1975
1977
  console.log("[FlowEngageProvider] skipping call:connected emit", {
@@ -1989,7 +1991,7 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
1989
1991
  chatId: T.current,
1990
1992
  connectedAt: e
1991
1993
  });
1992
- }, mt = (e = {}) => {
1994
+ }, ht = (e = {}) => {
1993
1995
  if (!e.callId) return;
1994
1996
  let t = nt.current === e.callId, n = tt.current === e.callId, r = Ye.current?.callId === e.callId;
1995
1997
  if (!(!t && !n && !r)) {
@@ -2005,7 +2007,7 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2005
2007
  }
2006
2008
  He("idle");
2007
2009
  }
2008
- }, ht = (e = {}) => {
2010
+ }, gt = (e = {}) => {
2009
2011
  if (!e.callId) return;
2010
2012
  let t = nt.current === e.callId, n = tt.current === e.callId, r = Ye.current?.callId === e.callId;
2011
2013
  if (!(!t && !n && !r)) {
@@ -2017,12 +2019,12 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2017
2019
  isIncomingHere: r,
2018
2020
  reason: e.reason || e.status || null
2019
2021
  }), n) {
2020
- ft();
2022
+ pt();
2021
2023
  return;
2022
2024
  }
2023
2025
  nt.current = null, $e.current = null, et.current = [], Re(null), He("idle");
2024
2026
  }
2025
- }, gt = async (e = {}) => {
2027
+ }, _t = async (e = {}) => {
2026
2028
  let t = Xe.current, n = C.current, r = e.sdpOffer || e.offer?.sdp;
2027
2029
  if (!t || !n?.connected || !r || !e.callId) {
2028
2030
  console.log("[FlowEngageProvider] deferring remote offer until peer/socket ready", {
@@ -2179,7 +2181,7 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2179
2181
  let t = pn([
2180
2182
  e.agent?.name,
2181
2183
  e.agentName,
2182
- _e
2184
+ ot.current
2183
2185
  ], u);
2184
2186
  ge(!1), me("ai"), b((e) => [...e, {
2185
2187
  id: `agent-left-${Date.now()}`,
@@ -2192,7 +2194,7 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2192
2194
  let t = pn([
2193
2195
  e.agent?.name,
2194
2196
  e.agentName,
2195
- _e
2197
+ ot.current
2196
2198
  ], u);
2197
2199
  ge(!1), me("ai"), b((e) => [...e, {
2198
2200
  id: `agent-left-${Date.now()}`,
@@ -2234,7 +2236,7 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2234
2236
  callId: e.callId,
2235
2237
  chatId: T.current,
2236
2238
  agentName: t
2237
- }), ut(), rt.current = !1, Re({
2239
+ }), dt(), rt.current = !1, Re({
2238
2240
  callId: e.callId,
2239
2241
  from: e.from || "owner",
2240
2242
  agentId: e.agentId || null,
@@ -2247,7 +2249,7 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2247
2249
  offerLength: (e.sdpOffer || e.offer?.sdp || "").length
2248
2250
  }), $e.current = e;
2249
2251
  try {
2250
- await gt(e);
2252
+ await _t(e);
2251
2253
  } catch (e) {
2252
2254
  console.error("[FlowEngageProvider] failed to apply remote offer", e);
2253
2255
  }
@@ -2285,35 +2287,35 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2285
2287
  console.error("[FlowEngageProvider] failed to add ICE candidate", e);
2286
2288
  }
2287
2289
  }), o.on("call:ended", () => {
2288
- ut(), ft();
2290
+ dt(), pt();
2289
2291
  }), o.on("call:accepted", (e = {}) => {
2290
2292
  console.log("[FlowEngageProvider] received call:accepted", {
2291
2293
  callId: e.callId,
2292
2294
  chatId: e.chatId || T.current
2293
- }), mt(e);
2295
+ }), ht(e);
2294
2296
  }), o.on("call:accepted_by_other", (e = {}) => {
2295
2297
  console.log("[FlowEngageProvider] received call:accepted_by_other", {
2296
2298
  callId: e.callId,
2297
2299
  chatId: e.chatId || T.current
2298
- }), mt(e);
2300
+ }), ht(e);
2299
2301
  }), o.on("call:rejected", (e = {}) => {
2300
2302
  console.log("[FlowEngageProvider] received call:rejected", {
2301
2303
  callId: e.callId,
2302
2304
  chatId: e.chatId || T.current,
2303
2305
  reason: e.reason
2304
- }), ht(e);
2306
+ }), gt(e);
2305
2307
  }), o.on("call:missed", (e = {}) => {
2306
2308
  console.log("[FlowEngageProvider] received call:missed", {
2307
2309
  callId: e.callId,
2308
2310
  chatId: e.chatId || T.current,
2309
2311
  reason: e.reason
2310
- }), ht(e);
2312
+ }), gt(e);
2311
2313
  }), o.on("call:failed", (e = {}) => {
2312
2314
  console.log("[FlowEngageProvider] received call:failed", {
2313
2315
  callId: e.callId,
2314
2316
  chatId: e.chatId || T.current,
2315
2317
  reason: e.reason
2316
- }), ht(e);
2318
+ }), gt(e);
2317
2319
  }), o.on("call:connected", (e = {}) => {
2318
2320
  if (!e.callId) return;
2319
2321
  let t = nt.current === e.callId, n = tt.current === e.callId, r = Ye.current?.callId === e.callId;
@@ -2331,9 +2333,9 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2331
2333
  }
2332
2334
  rt.current = !0, nt.current = null, tt.current = e.callId, Be(e.callId), Re(null), He("connected"), We(e.connectedAt || (/* @__PURE__ */ new Date()).toISOString()), fe(!0);
2333
2335
  }), o.on("call:unavailable", (e = {}) => {
2334
- ft(), Je(un(e, "This visitor is not available for a call right now.")), fe(!0);
2336
+ pt(), Je(un(e, "This visitor is not available for a call right now.")), fe(!0);
2335
2337
  }), o.on("call:error", (e = {}) => {
2336
- ft(), Je(un(e, "We couldn't connect the call right now.")), fe(!0);
2338
+ pt(), Je(un(e, "We couldn't connect the call right now.")), fe(!0);
2337
2339
  }), o.on("visitor:navigate", async ({ url: e, section: n, highlight: r } = {}) => {
2338
2340
  if (e) {
2339
2341
  if (console.log("[FlowEngageProvider] visitor:navigate", {
@@ -2365,7 +2367,7 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2365
2367
  n && tn(n);
2366
2368
  }), o.on("visitor:clear_highlight", () => {
2367
2369
  nn();
2368
- }), ct.current = Jt({
2370
+ }), lt.current = Jt({
2369
2371
  socket: o,
2370
2372
  chatId: i
2371
2373
  }), console.log("[FlowEngageProvider] tracking started", { chatId: i });
@@ -2377,12 +2379,12 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2377
2379
  console.error("[FlowEngageProvider] boot failed", t), h(t), f("error");
2378
2380
  }
2379
2381
  })(), () => {
2380
- e = !1, ct.current?.cleanup?.(), ft(), C.current?.disconnect();
2382
+ e = !1, lt.current?.cleanup?.(), pt(), C.current?.disconnect();
2381
2383
  };
2382
2384
  }, [c, r]), i(() => () => {
2383
- if (x && !st.current && ot.current.length > 0) {
2384
- let e = T.current, t = ot.current, n = w.current, r = _?.apiBaseUrl || "", i = _?.userId || "";
2385
- n && e && t.length > 0 && (console.log("[FlowEngageProvider] safety-net: syncing voice transcript on unmount"), n.beaconSyncVoice(r, i, e, t) || n.syncVoice(e, t).catch(() => {}), st.current = !0);
2385
+ if (x && !ct.current && st.current.length > 0) {
2386
+ let e = T.current, t = st.current, n = w.current, r = _?.apiBaseUrl || "", i = _?.userId || "";
2387
+ n && e && t.length > 0 && (console.log("[FlowEngageProvider] safety-net: syncing voice transcript on unmount"), n.beaconSyncVoice(r, i, e, t) || n.syncVoice(e, t).catch(() => {}), ct.current = !0);
2386
2388
  }
2387
2389
  }, [x, _]), i(() => {
2388
2390
  if (!w.current || !v || d !== "ready" || he) return;
@@ -2398,9 +2400,9 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2398
2400
  d,
2399
2401
  he
2400
2402
  ]);
2401
- let _t = async () => {
2403
+ let vt = async () => {
2402
2404
  if (!(!S?.callId || !w.current || !C.current || !v)) {
2403
- ut(), nt.current = S.callId, console.log("[FlowEngageProvider] acceptCall started", {
2405
+ dt(), nt.current = S.callId, console.log("[FlowEngageProvider] acceptCall started", {
2404
2406
  callId: S?.callId,
2405
2407
  chatId: v,
2406
2408
  socketConnected: !!C.current?.connected,
@@ -2424,7 +2426,7 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2424
2426
  signalingState: t.signalingState
2425
2427
  }), e === "connected") {
2426
2428
  let e = (/* @__PURE__ */ new Date()).toISOString();
2427
- He("connected"), We((t) => t || e), pt(e);
2429
+ He("connected"), We((t) => t || e), mt(e);
2428
2430
  return;
2429
2431
  }
2430
2432
  e === "connecting" && He((e) => e === "connected" ? e : "connecting");
@@ -2438,7 +2440,7 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2438
2440
  signalingState: t.signalingState
2439
2441
  }), e === "connected" || e === "completed") {
2440
2442
  let e = (/* @__PURE__ */ new Date()).toISOString();
2441
- He("connected"), We((t) => t || e), pt(e);
2443
+ He("connected"), We((t) => t || e), mt(e);
2442
2444
  return;
2443
2445
  }
2444
2446
  (e === "checking" || e === "new") && He((e) => e === "connected" ? e : "connecting");
@@ -2479,7 +2481,7 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2479
2481
  n && (console.log("[FlowEngageProvider] found pending remote offer during accept", {
2480
2482
  callId: n.callId || S.callId,
2481
2483
  chatId: v
2482
- }), await gt({
2484
+ }), await _t({
2483
2485
  ...n,
2484
2486
  callId: n.callId || S.callId
2485
2487
  })), await w.current.acceptCall(S.callId, v), console.log("[FlowEngageProvider] acceptCall API succeeded", {
@@ -2487,7 +2489,7 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2487
2489
  chatId: v
2488
2490
  }), tt.current = S.callId, Be(S.callId), He("connecting"), Re(null), fe(!0);
2489
2491
  } catch (e) {
2490
- if (console.error("[FlowEngageProvider] acceptCall failed", e), nt.current = null, ft(), e?.status === 404 || e?.status === 409 || e?.status === 422) {
2492
+ if (console.error("[FlowEngageProvider] acceptCall failed", e), nt.current = null, pt(), e?.status === 404 || e?.status === 409 || e?.status === 422) {
2491
2493
  Je(un(e, "This visitor call is no longer available."));
2492
2494
  return;
2493
2495
  }
@@ -2503,41 +2505,41 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2503
2505
  Je("We couldn't connect the call right now. Please try again.");
2504
2506
  }
2505
2507
  }
2506
- }, vt = async () => {
2508
+ }, yt = async () => {
2507
2509
  if (!S?.callId || !w.current || !v) {
2508
- ft();
2510
+ pt();
2509
2511
  return;
2510
2512
  }
2511
- ut();
2513
+ dt();
2512
2514
  try {
2513
2515
  await w.current.rejectCall(S.callId, v);
2514
2516
  } catch (e) {
2515
2517
  console.error("[FlowEngageProvider] rejectCall failed", e), Je(un(e, "We couldn't decline the call cleanly."));
2516
2518
  } finally {
2517
- ft();
2519
+ pt();
2518
2520
  }
2519
- }, yt = o(vt);
2520
- yt.current = vt, i(() => {
2521
+ }, bt = o(yt);
2522
+ bt.current = yt, i(() => {
2521
2523
  if (!S?.callId || ze) return;
2522
2524
  let e = S.callId, t = window.setTimeout(() => {
2523
- Ye.current?.callId === e && yt.current();
2525
+ Ye.current?.callId === e && bt.current();
2524
2526
  }, te);
2525
2527
  return () => window.clearTimeout(t);
2526
2528
  }, [S?.callId, ze]);
2527
- let bt = async () => {
2529
+ let xt = async () => {
2528
2530
  if (!ze || !w.current || !v) {
2529
- ft();
2531
+ pt();
2530
2532
  return;
2531
2533
  }
2532
- ut();
2534
+ dt();
2533
2535
  try {
2534
2536
  await w.current.endWebRTCCall(ze, v);
2535
2537
  } catch (e) {
2536
2538
  console.error("[FlowEngageProvider] endWebRTCCall failed", e), Je(un(e, "The call ended locally, but the server could not be updated."));
2537
2539
  } finally {
2538
- ft();
2540
+ pt();
2539
2541
  }
2540
- }, xt = () => {
2542
+ }, St = () => {
2541
2543
  let e = Ze.current?.getAudioTracks?.() || [], t = Xe.current?.getSenders?.().map((e) => e.track).filter((e) => e?.kind === "audio") || [], n = [...e, ...t].filter(Boolean);
2542
2544
  if (n.length === 0) {
2543
2545
  console.warn("[FlowEngageProvider] no local audio tracks available for mute");
@@ -2550,7 +2552,7 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2550
2552
  nextMuted: r,
2551
2553
  trackCount: n.length
2552
2554
  }), Ke(r);
2553
- }, St = async (e = {}) => {
2555
+ }, Ct = async (e = {}) => {
2554
2556
  let t = e.notifyChatInitiated === !0;
2555
2557
  if (fe(!0), !(!t || !w.current || !v || typeof window > "u")) {
2556
2558
  try {
@@ -2563,8 +2565,8 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2563
2565
  await w.current.updateChatStatus(v, "open");
2564
2566
  } catch {}
2565
2567
  }
2566
- }, Ct = async (e) => {
2567
- let t = dt(e);
2568
+ }, wt = async (e) => {
2569
+ let t = ft(e);
2568
2570
  if (!t || !w.current || !T.current) return t;
2569
2571
  try {
2570
2572
  await w.current.trackVisitor({
@@ -2576,7 +2578,7 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2576
2578
  console.error("[FlowEngageProvider] failed to persist visitor email", e);
2577
2579
  }
2578
2580
  return t;
2579
- }, wt = () => {
2581
+ }, Tt = () => {
2580
2582
  if (!v || !C.current?.connected || it.current) {
2581
2583
  console.log("[FlowEngageProvider] skipped typing:start emit", {
2582
2584
  chatId: v,
@@ -2592,7 +2594,7 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2592
2594
  chatId: v,
2593
2595
  sender: "user"
2594
2596
  });
2595
- }, Tt = () => {
2597
+ }, Et = () => {
2596
2598
  if (v && C.current?.connected && at.current !== "" && (console.log("[FlowEngageProvider] clearing typing draft", {
2597
2599
  chatId: v,
2598
2600
  sender: "user"
@@ -2615,7 +2617,7 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2615
2617
  chatId: v,
2616
2618
  sender: "user"
2617
2619
  });
2618
- }, Et = (e = "") => {
2620
+ }, Dt = (e = "") => {
2619
2621
  let t = typeof e == "string" ? e : "";
2620
2622
  if (!v || !C.current?.connected) {
2621
2623
  console.log("[FlowEngageProvider] skipped typing:update emit", {
@@ -2634,9 +2636,9 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2634
2636
  sender: "user",
2635
2637
  text: t
2636
2638
  }));
2637
- }, Dt = async (e, t = "", n = null) => {
2639
+ }, Ot = async (e, t = "", n = null) => {
2638
2640
  if (!e.trim() || !w.current || !v || d !== "ready" || Ie) return;
2639
- Tt();
2641
+ Et();
2640
2642
  let i = `pending-user-${Date.now()}`, a = {
2641
2643
  id: i,
2642
2644
  sender: "user",
@@ -2669,7 +2671,7 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2669
2671
  } finally {
2670
2672
  Ae(!1);
2671
2673
  }
2672
- }, Ot = async (e) => {
2674
+ }, kt = async (e) => {
2673
2675
  if (!(!w.current || !v)) {
2674
2676
  try {
2675
2677
  let t = e ? "voice" : "text";
@@ -2677,24 +2679,28 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2677
2679
  } catch (e) {
2678
2680
  console.error("[FlowEngageProvider] setVoiceMode failed", e);
2679
2681
  }
2680
- Fe(e), e && (st.current = !1);
2682
+ Fe(e), e && (ct.current = !1);
2681
2683
  }
2682
- }, kt = async (e) => {
2683
- if (!st.current) {
2684
- if (st.current = !0, !w.current || !v || !e?.length) {
2684
+ }, At = async (e) => {
2685
+ if (!ct.current) {
2686
+ if (ct.current = !0, !w.current || !v || !e?.length) {
2685
2687
  Fe(!1);
2686
2688
  return;
2687
2689
  }
2688
2690
  try {
2689
2691
  let t = await w.current.syncVoice(v, e);
2690
- 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 {}
2691
2697
  } catch {} finally {
2692
2698
  Fe(!1);
2693
2699
  }
2694
2700
  }
2695
- }, At = async () => {
2701
+ }, E = async () => {
2696
2702
  if (!(!w.current || !v)) {
2697
- x && !st.current && ot.current.length > 0 && await kt(ot.current);
2703
+ x && !ct.current && st.current.length > 0 && await At(st.current);
2698
2704
  try {
2699
2705
  await w.current.endConversation(v);
2700
2706
  } catch {
@@ -2712,9 +2718,9 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2712
2718
  }
2713
2719
  };
2714
2720
  i(() => {
2715
- if (Ve !== "connected" || !ze || !v || !Ue || !lt) return;
2716
- let e = new Date(Ue).getTime(), t = Number.isFinite(e) ? Date.now() - e : 0, n = Math.max(0, lt * 1e3 - t), r = window.setTimeout(() => {
2717
- Je("The call ended because it reached the time limit."), bt();
2721
+ if (Ve !== "connected" || !ze || !v || !Ue || !ut) return;
2722
+ let e = new Date(Ue).getTime(), t = Number.isFinite(e) ? Date.now() - e : 0, n = Math.max(0, ut * 1e3 - t), r = window.setTimeout(() => {
2723
+ Je("The call ended because it reached the time limit."), xt();
2718
2724
  }, n);
2719
2725
  return () => window.clearTimeout(r);
2720
2726
  }, [
@@ -2722,8 +2728,8 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2722
2728
  Ue,
2723
2729
  Ve,
2724
2730
  v,
2725
- bt,
2726
- lt
2731
+ xt,
2732
+ ut
2727
2733
  ]), i(() => {
2728
2734
  let e = () => {
2729
2735
  let e = T.current, t = w.current;
@@ -2739,7 +2745,7 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2739
2745
  window.removeEventListener("pagehide", e), window.removeEventListener("beforeunload", e);
2740
2746
  };
2741
2747
  }, []);
2742
- let E = a(() => ({
2748
+ let jt = a(() => ({
2743
2749
  status: d,
2744
2750
  error: m,
2745
2751
  runtimeConfig: _,
@@ -2767,34 +2773,34 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2767
2773
  isCallMuted: Ge,
2768
2774
  webRTCError: qe,
2769
2775
  language: r,
2770
- historyRef: ot,
2771
- hasSyncedRef: st,
2772
- dismissCallError: ut,
2773
- captureVisitorEmail: Ct,
2774
- startTyping: wt,
2775
- stopTyping: Tt,
2776
- updateTypingDraft: Et,
2777
- notifyRouteChange: () => ct.current?.notifyRouteChange?.(),
2778
- openWidget: St,
2776
+ historyRef: st,
2777
+ hasSyncedRef: ct,
2778
+ dismissCallError: dt,
2779
+ captureVisitorEmail: wt,
2780
+ startTyping: Tt,
2781
+ stopTyping: Et,
2782
+ updateTypingDraft: Dt,
2783
+ notifyRouteChange: () => lt.current?.notifyRouteChange?.(),
2784
+ openWidget: Ct,
2779
2785
  closeWidget: () => fe(!1),
2780
2786
  toggleWidget: () => {
2781
2787
  if (de) {
2782
2788
  fe(!1);
2783
2789
  return;
2784
2790
  }
2785
- St({ notifyChatInitiated: !0 });
2791
+ Ct({ notifyChatInitiated: !0 });
2786
2792
  },
2787
- sendMessage: Dt,
2788
- setVoiceMode: Ot,
2789
- onMessageSync: kt,
2790
- endConversation: At,
2791
- acceptCall: _t,
2792
- rejectCall: vt,
2793
- endWebRTCCall: bt,
2794
- toggleCallMute: xt,
2795
- startTyping: wt,
2796
- stopTyping: Tt,
2797
- updateTypingDraft: Et
2793
+ sendMessage: Ot,
2794
+ setVoiceMode: kt,
2795
+ onMessageSync: At,
2796
+ endConversation: E,
2797
+ acceptCall: vt,
2798
+ rejectCall: yt,
2799
+ endWebRTCCall: xt,
2800
+ toggleCallMute: St,
2801
+ startTyping: Tt,
2802
+ stopTyping: Et,
2803
+ updateTypingDraft: Dt
2798
2804
  }), [
2799
2805
  d,
2800
2806
  m,
@@ -2823,23 +2829,23 @@ function mn({ siteId: e, config: t, children: n, language: r = "en" }) {
2823
2829
  Ge,
2824
2830
  qe,
2825
2831
  r,
2826
- Ct,
2827
2832
  wt,
2828
2833
  Tt,
2829
2834
  Et,
2830
- _t,
2835
+ Dt,
2831
2836
  vt,
2832
- bt,
2837
+ yt,
2833
2838
  xt,
2834
2839
  St,
2835
- Dt,
2840
+ Ct,
2836
2841
  Ot,
2837
2842
  kt,
2838
2843
  At,
2839
- ut
2844
+ E,
2845
+ dt
2840
2846
  ]);
2841
2847
  return /* @__PURE__ */ l(Yt.Provider, {
2842
- value: E,
2848
+ value: jt,
2843
2849
  children: n
2844
2850
  });
2845
2851
  }
@@ -22344,6 +22350,7 @@ function rg(e) {
22344
22350
  return $("search_site_content ✖", t), t;
22345
22351
  }
22346
22352
  },
22353
+ end_voice_session: async () => ($("end_voice_session ▶"), typeof e.requestEndSession == "function" && e.requestEndSession(), "Voice session is ending."),
22347
22354
  list_page_forms: async () => {
22348
22355
  let e = Mh(), t = Nh();
22349
22356
  return $("list_page_forms ✓", `${e.length} field(s)`, `${t.length} button(s)`), JSON.stringify({
@@ -22411,6 +22418,7 @@ function rg(e) {
22411
22418
  navigateToPage: a.navigate_to_page,
22412
22419
  highlightOnPage: a.highlight_on_page,
22413
22420
  searchSiteContent: a.search_site_content,
22421
+ endVoiceSession: a.end_voice_session,
22414
22422
  listPageForms: a.list_page_forms,
22415
22423
  fillFormFields: a.fill_form_fields,
22416
22424
  clickPageButton: a.click_page_button
@@ -22439,18 +22447,36 @@ var ag = {
22439
22447
  speaking: "#f59e0b",
22440
22448
  error: "#ef4444"
22441
22449
  };
22442
- function sg({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, historyRef: d, hasSyncedRef: f, onMessageSync: p, onStartSync: m }) {
22443
- let [h, g] = s("idle"), [ee, te] = s(null), [_, ne] = s(!1), re = o(null), ie = o(null), ae = o("");
22444
- 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(() => {
22445
22466
  let t = !1, n = null;
22446
22467
  return (async () => {
22447
22468
  try {
22448
22469
  if (await navigator.mediaDevices.getUserMedia({ audio: !0 }), t) return;
22449
- d.current = [], ae.current = "";
22470
+ d.current = [], ae.current = "", se.current = !1;
22450
22471
  let i = ig(rg({
22451
22472
  siteId: r || null,
22452
22473
  apiBaseUrl: a || null,
22453
- getLastUserVoiceText: () => ae.current
22474
+ getLastUserVoiceText: () => ae.current,
22475
+ requestEndSession: () => {
22476
+ queueMicrotask(() => {
22477
+ se.current || (se.current = !0, oe.current?.());
22478
+ });
22479
+ }
22454
22480
  })), o = await wh.startSession({
22455
22481
  agentId: e,
22456
22482
  clientTools: i,
@@ -22469,7 +22495,9 @@ function sg({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
22469
22495
  message: r,
22470
22496
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
22471
22497
  };
22472
- 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
+ });
22473
22501
  },
22474
22502
  onError: (e) => {
22475
22503
  t || (console.error("[VoiceInterface] ElevenLabs error", e), g("error"), te("Voice session encountered an error."));
@@ -22490,7 +22518,7 @@ function sg({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
22490
22518
  } catch {
22491
22519
  t = "[]";
22492
22520
  }
22493
- 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.`);
22494
22522
  } catch {}
22495
22523
  typeof m == "function" && m();
22496
22524
  } catch (e) {
@@ -22506,16 +22534,7 @@ function sg({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
22506
22534
  d,
22507
22535
  m
22508
22536
  ]);
22509
- let oe = n(async () => {
22510
- try {
22511
- await re.current?.endSession?.();
22512
- } catch {}
22513
- re.current = null, ne(!1), g("idle"), typeof p == "function" && await p(d.current), typeof c == "function" && c();
22514
- }, [
22515
- d,
22516
- p,
22517
- c
22518
- ]), 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;
22519
22538
  return /* @__PURE__ */ u("div", {
22520
22539
  ref: ie,
22521
22540
  style: {
@@ -22539,19 +22558,19 @@ function sg({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
22539
22558
  justifyContent: "center"
22540
22559
  },
22541
22560
  children: [
22542
- se && /* @__PURE__ */ l("div", { style: {
22561
+ ce && /* @__PURE__ */ l("div", { style: {
22543
22562
  position: "absolute",
22544
22563
  inset: "-16px",
22545
22564
  borderRadius: "50%",
22546
- border: `2px solid ${v}`,
22565
+ border: `2px solid ${le}`,
22547
22566
  animation: "fe-orb-pulse 1.4s ease-in-out infinite",
22548
22567
  opacity: .6
22549
22568
  } }),
22550
- se && /* @__PURE__ */ l("div", { style: {
22569
+ ce && /* @__PURE__ */ l("div", { style: {
22551
22570
  position: "absolute",
22552
22571
  inset: "-8px",
22553
22572
  borderRadius: "50%",
22554
- border: `2px solid ${v}`,
22573
+ border: `2px solid ${le}`,
22555
22574
  animation: "fe-orb-pulse 1.4s ease-in-out 0.35s infinite",
22556
22575
  opacity: .4
22557
22576
  } }),
@@ -22560,18 +22579,18 @@ function sg({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
22560
22579
  width: "140px",
22561
22580
  height: "140px",
22562
22581
  borderRadius: "50%",
22563
- background: ce,
22564
- border: `3px solid ${v}`,
22582
+ background: ue,
22583
+ border: `3px solid ${le}`,
22565
22584
  display: "flex",
22566
22585
  alignItems: "center",
22567
22586
  justifyContent: "center",
22568
22587
  transition: "all 0.35s ease",
22569
22588
  transform: h === "speaking" ? "scale(1.08)" : "scale(1)",
22570
- 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)`
22571
22590
  },
22572
22591
  children: /* @__PURE__ */ l(_n, {
22573
22592
  size: 44,
22574
- color: v
22593
+ color: le
22575
22594
  })
22576
22595
  })
22577
22596
  ]
@@ -22592,7 +22611,7 @@ function sg({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
22592
22611
  ]
22593
22612
  }),
22594
22613
  /* @__PURE__ */ u("button", {
22595
- onClick: oe,
22614
+ onClick: v,
22596
22615
  style: {
22597
22616
  display: "flex",
22598
22617
  alignItems: "center",
@@ -22621,7 +22640,7 @@ function sg({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
22621
22640
  }
22622
22641
  //#endregion
22623
22642
  //#region src/components/FlowEngageWidget.jsx
22624
- var cg = [
22643
+ var lg = [
22625
22644
  {
22626
22645
  key: "become_client",
22627
22646
  label: "Become a Client"
@@ -22642,7 +22661,7 @@ var cg = [
22642
22661
  key: "looking_for_job",
22643
22662
  label: "Looking for a Job"
22644
22663
  }
22645
- ], lg = () => /* @__PURE__ */ l("div", {
22664
+ ], ug = () => /* @__PURE__ */ l("div", {
22646
22665
  style: {
22647
22666
  display: "flex",
22648
22667
  marginBottom: "12px",
@@ -22673,13 +22692,13 @@ var cg = [
22673
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 " })]
22674
22693
  })
22675
22694
  });
22676
- function ug() {
22695
+ function dg() {
22677
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 = {
22678
- ...S.branding || {},
22679
- ...Re.branding || {}
22697
+ ...Re.branding || {},
22698
+ ...S.branding || {}
22680
22699
  }, Be = {
22681
- ...S.theme || {},
22682
- ...Re.theme || {}
22700
+ ...Re.theme || {},
22701
+ ...S.theme || {}
22683
22702
  }, Ve = Be.primaryColor || "#3B82F6", He = Be.accentColor || "#1D4ED8", Ue = (Be.position || "bottom-right") === "bottom-left" ? {
22684
22703
  left: "1.5rem",
22685
22704
  bottom: "1.5rem"
@@ -22695,7 +22714,7 @@ function ug() {
22695
22714
  outline: "none",
22696
22715
  fontFamily: "ui-sans-serif, system-ui, sans-serif",
22697
22716
  ...c ? {} : Ue
22698
- }, 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(() => {
22699
22718
  let e = o.findIndex((e) => e.sender === "user");
22700
22719
  return e === -1 ? !1 : o.slice(e + 1).some((e) => e.sender === "bot" || e.sender === "ai" || e.sender === "agent");
22701
22720
  }, [o]), rt = !h && tt && nt;
@@ -22823,7 +22842,7 @@ function ug() {
22823
22842
  flexDirection: "column"
22824
22843
  },
22825
22844
  className: "fe-screen-fade-in",
22826
- children: /* @__PURE__ */ l(sg, {
22845
+ children: /* @__PURE__ */ l(cg, {
22827
22846
  agentId: T,
22828
22847
  chatId: r,
22829
22848
  siteId: Ye,
@@ -22856,7 +22875,7 @@ function ug() {
22856
22875
  isAiTyping: ee,
22857
22876
  isAgentTyping: g,
22858
22877
  setReplyContext: Me,
22859
- TypingDots: lg,
22878
+ TypingDots: ug,
22860
22879
  primaryColor: Ve,
22861
22880
  agentHeadshot: $e,
22862
22881
  agentDisplayName: p || Ze
@@ -22935,4 +22954,4 @@ function ug() {
22935
22954
  }) : null;
22936
22955
  }
22937
22956
  //#endregion
22938
- export { mn as FlowEngageProvider, ug as FlowEngageWidget, Xt as useFlowEngage };
22957
+ export { mn as FlowEngageProvider, dg as FlowEngageWidget, Xt as useFlowEngage };