@eshal-bot/chat-widget 0.2.43 → 0.2.44

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.
@@ -1 +1 @@
1
- export{S as default}from"./chat-widget-index-DrYC7TkS.esm.js";import"react";import"react-dom/client";import"react/jsx-runtime";import"react-dom";
1
+ export{S as default}from"./chat-widget-index-BkrOfMLF.esm.js";import"react";import"react-dom/client";import"react/jsx-runtime";import"react-dom";
@@ -12627,6 +12627,8 @@
12627
12627
 
12628
12628
  const SESSION_KEY$1 = 'eshal_chat_session';
12629
12629
  const SESSION_MSG_KEY = 'eshal_chat_session_messages';
12630
+ // EV-4956: the ids of the messages a hand-off to the team came after (below).
12631
+ const HANDOFF_POINTS_KEY = 'eshal_chat_handoff_points';
12630
12632
 
12631
12633
  // Defaults used when the deploy-agent payload hasn't resolved yet (first paint
12632
12634
  // race) or doesn't include `messageLimits` (older backend). The authoritative
@@ -12744,10 +12746,35 @@
12744
12746
  if (!orgId || !conversationId) return;
12745
12747
  try {
12746
12748
  localStorage.removeItem(`${SESSION_MSG_KEY}_${orgId}_${conversationId}`);
12749
+ localStorage.removeItem(`${HANDOFF_POINTS_KEY}_${orgId}_${conversationId}`);
12747
12750
  } catch {
12748
12751
  // ignore
12749
12752
  }
12750
12753
  };
12754
+
12755
+ // EV-4956: where the conversation passed to the team (the ids of the messages
12756
+ // the hand-off came after), kept beside the transcript so the "passed to our
12757
+ // team" line is still there after a reload. Before, the header kept its
12758
+ // status on a reload but the line was gone.
12759
+ const MAX_HANDOFF_POINTS = 20;
12760
+ const saveHandoffPoints = (orgId, conversationId, points) => {
12761
+ if (!orgId || !conversationId) return;
12762
+ try {
12763
+ const ids = (Array.isArray(points) ? points : []).filter(id => typeof id === 'string' && id).slice(-MAX_HANDOFF_POINTS);
12764
+ if (ids.length === 0) localStorage.removeItem(`${HANDOFF_POINTS_KEY}_${orgId}_${conversationId}`);else localStorage.setItem(`${HANDOFF_POINTS_KEY}_${orgId}_${conversationId}`, JSON.stringify(ids));
12765
+ } catch {
12766
+ // Quota / private mode: only the line after a reload is lost.
12767
+ }
12768
+ };
12769
+ const getHandoffPoints = (orgId, conversationId) => {
12770
+ if (!orgId || !conversationId) return [];
12771
+ try {
12772
+ const parsed = JSON.parse(localStorage.getItem(`${HANDOFF_POINTS_KEY}_${orgId}_${conversationId}`) || '[]');
12773
+ return Array.isArray(parsed) ? parsed.filter(id => typeof id === 'string' && id).slice(-MAX_HANDOFF_POINTS) : [];
12774
+ } catch {
12775
+ return [];
12776
+ }
12777
+ };
12751
12778
  const getTimeoutMs = (value, unit) => {
12752
12779
  if (value === undefined || value === null || !unit) return null;
12753
12780
  const multipliers = {
@@ -13749,6 +13776,12 @@
13749
13776
  setMessages(stored);
13750
13777
  }
13751
13778
 
13779
+ // EV-4956: put the "passed to our team" line back where it was. Only
13780
+ // points whose message is still in the restored transcript.
13781
+ const storedIds = new Set(stored.map(m => m.id));
13782
+ const savedPoints = getHandoffPoints(organizationId, bidiSessionId).filter(id => storedIds.has(id));
13783
+ if (savedPoints.length > 0) setHandoffPoints(savedPoints);
13784
+
13752
13785
  // If no message in the restored transcript carries prompt
13753
13786
  // suggestions, fall back to the legacy per-org bucket. Preserves
13754
13787
  // the "prompts survive refresh" UX even when the persistence layer
@@ -13932,6 +13965,14 @@
13932
13965
  saveSessionMessages(organizationId, bidiSessionId, mergeTranscript(messages, bidiMessages), resolvedMessageLimits);
13933
13966
  }, [messages, bidiMessages, organizationId, bidiSessionId, isConversationLoading, isLoading, resolvedMessageLimits]);
13934
13967
 
13968
+ // EV-4956: keep where the hand-off happened beside the transcript, so the
13969
+ // "passed to our team" line survives a reload. Only once the stored
13970
+ // transcript has been read back, so the empty start cannot wipe it.
13971
+ reactExports.useEffect(() => {
13972
+ if (!organizationId || !bidiSessionId || !historyLoadedRef.current) return;
13973
+ saveHandoffPoints(organizationId, bidiSessionId, handoffPoints);
13974
+ }, [handoffPoints, organizationId, bidiSessionId]);
13975
+
13935
13976
  // Show the onboarding form on first load; bypass it if already completed (persisted in session)
13936
13977
  reactExports.useEffect(() => {
13937
13978
  if (!onboardingEnabled || onboardingCompleted) return;
@@ -23595,7 +23636,7 @@
23595
23636
  * value by its own test (that constant sat at 0.1.113 while this package was
23596
23637
  * at 0.2.2 precisely because nothing enforced it - EV-2431).
23597
23638
  */
23598
- const WIDGET_VERSION = '0.2.43';
23639
+ const WIDGET_VERSION = '0.2.44';
23599
23640
 
23600
23641
  /**
23601
23642
  * API utility functions