@eshal-bot/chat-widget 0.1.13 → 0.1.15

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.
@@ -613,6 +613,8 @@
613
613
  }
614
614
  };
615
615
 
616
+ const _excluded$2 = ["prompts"];
617
+
616
618
  // ============================================================================
617
619
  // TYPES & INTERFACES
618
620
  // ============================================================================
@@ -728,18 +730,48 @@
728
730
  };
729
731
 
730
732
  /**
731
- * Updates the last assistant message with final content
733
+ * Normalizes prompts from stream (array of { type?, text, confidence? })
734
+ * @param {any} raw - Raw prompts from API
735
+ * @returns {Array<{ type: string, text: string, confidence?: number }>|undefined}
736
+ */
737
+ const normalizePrompts = raw => {
738
+ if (!Array.isArray(raw) || raw.length === 0) return undefined;
739
+ const normalized = raw.map(p => ({
740
+ type: p.type || 'prompt',
741
+ text: typeof p.text === 'string' ? p.text : '',
742
+ confidence: typeof p.confidence === 'number' ? p.confidence : undefined
743
+ })).filter(p => p.text);
744
+ return normalized.length ? normalized : undefined;
745
+ };
746
+
747
+ /**
748
+ * Updates the last assistant message with final content and optional metadata.
749
+ * Combines both: generic extra fields (e.g. conclusionDetected) and prompts.
750
+ *
732
751
  * @param {function} setMessages - React state setter for messages
733
752
  * @param {string} content - Final content to set
753
+ * @param {{
754
+ * prompts?: Array<{ type?: string, text: string, confidence?: number }>,
755
+ * [key: string]: any
756
+ * }} [metadata] - Optional metadata (extra fields + prompts)
734
757
  */
735
- const updateFinalMessage = (setMessages, content) => {
758
+ const updateFinalMessage = function (setMessages, content) {
759
+ let metadata = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
736
760
  setMessages(prev => {
737
761
  const updatedMessages = [...(prev || [])];
738
762
  const lastMessage = updatedMessages[updatedMessages.length - 1];
739
763
  if ((lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.role) === 'assistant') {
740
- updatedMessages[updatedMessages.length - 1] = _objectSpread2(_objectSpread2({}, lastMessage), {}, {
764
+ const _ref = metadata || {},
765
+ {
766
+ prompts
767
+ } = _ref,
768
+ extraFields = _objectWithoutProperties$1(_ref, _excluded$2);
769
+ updatedMessages[updatedMessages.length - 1] = _objectSpread2(_objectSpread2(_objectSpread2({}, lastMessage), extraFields), {}, {
770
+ // e.g. conclusionDetected or other flags
741
771
  content,
742
772
  isProcessing: false
773
+ }, prompts != null && {
774
+ prompts: normalizePrompts(prompts)
743
775
  });
744
776
  }
745
777
  return updatedMessages;
@@ -815,7 +847,18 @@
815
847
  case StreamEventType.COMPLETE:
816
848
  {
817
849
  const finalContent = streamEvent.finalContent || accumulatedText.current;
818
- updateFinalMessage(setMessages, finalContent);
850
+
851
+ // Map conclusion flag from stream event (supports snake_case and camelCase)
852
+ const extraFields = {};
853
+ if (typeof streamEvent.conclusionDetected === 'boolean') {
854
+ extraFields.conclusionDetected = streamEvent.conclusionDetected;
855
+ } else if (typeof streamEvent.conclusion_detected === 'boolean') {
856
+ extraFields.conclusionDetected = streamEvent.conclusion_detected;
857
+ }
858
+ const metadata = _objectSpread2(_objectSpread2({}, extraFields), {}, {
859
+ prompts: streamEvent.prompts
860
+ });
861
+ updateFinalMessage(setMessages, finalContent, metadata);
819
862
  break;
820
863
  }
821
864
  case StreamEventType.ERROR:
@@ -880,7 +923,7 @@
880
923
  const segments = buffer.split(/\r?\n\r?\n/);
881
924
  buffer = segments.pop() || '';
882
925
  for (const segment of segments) {
883
- var _parsed$choices2, _parsed$choices3;
926
+ var _parsed$choices3, _parsed$choices4;
884
927
  const lines = segment.split(/\r?\n/).map(line => line.trim()).filter(Boolean);
885
928
  if (lines.length === 0) {
886
929
  continue;
@@ -938,14 +981,47 @@
938
981
 
939
982
  // Handle complete events
940
983
  if (parsed.type === 'complete') {
941
- // Finalize the message
942
- const finalContent = parsed.finalContent || accumulatedText.current;
943
- if (finalContent) {
984
+ var _ref2, _parsed$Sources, _ref5, _parsed$choices$0$del, _parsed$choices2;
985
+ // Normalize Sources from stream (API may send "Sources" or "sources")
986
+ const rawSources = (_ref2 = (_parsed$Sources = parsed.Sources) !== null && _parsed$Sources !== void 0 ? _parsed$Sources : parsed.sources) !== null && _ref2 !== void 0 ? _ref2 : [];
987
+ const sources = Array.isArray(rawSources) ? rawSources.map(s => {
988
+ var _ref3, _s$source_type, _s$sourceid, _ref4, _s$source_name;
989
+ return {
990
+ source_type: (_ref3 = (_s$source_type = s.source_type) !== null && _s$source_type !== void 0 ? _s$source_type : s.sourceType) !== null && _ref3 !== void 0 ? _ref3 : 'website',
991
+ source_id: (_s$sourceid = s.sourceid) !== null && _s$sourceid !== void 0 ? _s$sourceid : s.source_id,
992
+ source_name: (_ref4 = (_s$source_name = s.source_name) !== null && _s$source_name !== void 0 ? _s$source_name : s.sourceName) !== null && _ref4 !== void 0 ? _ref4 : '',
993
+ url: s.url
994
+ };
995
+ }).filter(s => s.source_id || s.url) : [];
996
+
997
+ // Finalize the message content
998
+ const finalContent = (_ref5 = (_parsed$choices$0$del = (_parsed$choices2 = parsed.choices) === null || _parsed$choices2 === void 0 || (_parsed$choices2 = _parsed$choices2[0]) === null || _parsed$choices2 === void 0 || (_parsed$choices2 = _parsed$choices2.delta) === null || _parsed$choices2 === void 0 ? void 0 : _parsed$choices2.content) !== null && _parsed$choices$0$del !== void 0 ? _parsed$choices$0$del : parsed.finalContent) !== null && _ref5 !== void 0 ? _ref5 : accumulatedText.current;
999
+
1000
+ // Map conclusion flag from payload (supports snake_case and camelCase)
1001
+ const extraFields = {};
1002
+ if (typeof parsed.conclusionDetected === 'boolean') {
1003
+ extraFields.conclusionDetected = parsed.conclusionDetected;
1004
+ } else if (typeof parsed.conclusion_detected === 'boolean') {
1005
+ extraFields.conclusionDetected = parsed.conclusion_detected;
1006
+ }
1007
+
1008
+ // Prompts metadata (for suggestion buttons)
1009
+ const metadata = _objectSpread2(_objectSpread2({}, extraFields), {}, {
1010
+ prompts: parsed.prompts
1011
+ });
1012
+
1013
+ // Finalize message with content + prompts + conclusionDetected
1014
+ updateFinalMessage(setMessages, finalContent, metadata);
1015
+
1016
+ // Attach sources to the last assistant message if present
1017
+ if (sources.length > 0) {
944
1018
  setMessages(prev => {
945
1019
  const updatedMessages = [...(prev || [])];
946
1020
  const lastMessage = updatedMessages[updatedMessages.length - 1];
947
1021
  if ((lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.role) === 'assistant') {
948
1022
  updatedMessages[updatedMessages.length - 1] = _objectSpread2(_objectSpread2({}, lastMessage), {}, {
1023
+ sources,
1024
+ // Ensure final state is fully consistent
949
1025
  content: finalContent,
950
1026
  isProcessing: false
951
1027
  });
@@ -953,17 +1029,6 @@
953
1029
  return updatedMessages;
954
1030
  });
955
1031
  }
956
- // Remove processing state
957
- setMessages(prev => {
958
- const updatedMessages = [...(prev || [])];
959
- const lastMessage = updatedMessages[updatedMessages.length - 1];
960
- if (lastMessage !== null && lastMessage !== void 0 && lastMessage.isProcessing) {
961
- updatedMessages[updatedMessages.length - 1] = _objectSpread2(_objectSpread2({}, lastMessage), {}, {
962
- isProcessing: false
963
- });
964
- }
965
- return updatedMessages;
966
- });
967
1032
  continue;
968
1033
  }
969
1034
 
@@ -993,7 +1058,7 @@
993
1058
  }
994
1059
 
995
1060
  // Handle OpenAI format without type field (fallback)
996
- if (parsed.object === 'chat.completion.chunk' && (_parsed$choices2 = parsed.choices) !== null && _parsed$choices2 !== void 0 && (_parsed$choices2 = _parsed$choices2[0]) !== null && _parsed$choices2 !== void 0 && (_parsed$choices2 = _parsed$choices2.delta) !== null && _parsed$choices2 !== void 0 && _parsed$choices2.content) {
1061
+ if (parsed.object === 'chat.completion.chunk' && (_parsed$choices3 = parsed.choices) !== null && _parsed$choices3 !== void 0 && (_parsed$choices3 = _parsed$choices3[0]) !== null && _parsed$choices3 !== void 0 && (_parsed$choices3 = _parsed$choices3.delta) !== null && _parsed$choices3 !== void 0 && _parsed$choices3.content) {
997
1062
  // Create skeleton on first chunk if not already created
998
1063
  if (!hasReceivedFirstChunk.current) {
999
1064
  hasReceivedFirstChunk.current = true;
@@ -1012,17 +1077,11 @@
1012
1077
  }
1013
1078
 
1014
1079
  // Handle finish_reason (stream complete)
1015
- if ((_parsed$choices3 = parsed.choices) !== null && _parsed$choices3 !== void 0 && (_parsed$choices3 = _parsed$choices3[0]) !== null && _parsed$choices3 !== void 0 && _parsed$choices3.finish_reason && parsed.choices[0].finish_reason !== null) {
1016
- setMessages(prev => {
1017
- const updatedMessages = [...(prev || [])];
1018
- const lastMessage = updatedMessages[updatedMessages.length - 1];
1019
- if (lastMessage !== null && lastMessage !== void 0 && lastMessage.isProcessing) {
1020
- updatedMessages[updatedMessages.length - 1] = _objectSpread2(_objectSpread2({}, lastMessage), {}, {
1021
- isProcessing: false
1022
- });
1023
- }
1024
- return updatedMessages;
1025
- });
1080
+ if ((_parsed$choices4 = parsed.choices) !== null && _parsed$choices4 !== void 0 && (_parsed$choices4 = _parsed$choices4[0]) !== null && _parsed$choices4 !== void 0 && _parsed$choices4.finish_reason && parsed.choices[0].finish_reason !== null) {
1081
+ const metadata = {
1082
+ prompts: parsed.prompts
1083
+ };
1084
+ updateFinalMessage(setMessages, accumulatedText.current, metadata);
1026
1085
  }
1027
1086
  }
1028
1087
  }
@@ -1211,6 +1270,24 @@
1211
1270
  });
1212
1271
  };
1213
1272
 
1273
+ // Field order for onboarding form: name → email → phone (then any others)
1274
+ // Lower number = earlier in the form. Name first, then email, then phone.
1275
+ // Keys are lowercase so getOnboardingFieldOrder(fieldType) works for any casing.
1276
+ const ONBOARDING_FIELD_ORDER = {
1277
+ fullname: 0,
1278
+ name: 0,
1279
+ username: 0,
1280
+ email: 1,
1281
+ phone: 2,
1282
+ mobileno: 2
1283
+ };
1284
+ const getOnboardingFieldOrder = fieldType => {
1285
+ var _ONBOARDING_FIELD_ORD;
1286
+ if (!fieldType) return 99;
1287
+ const key = String(fieldType).toLowerCase();
1288
+ return (_ONBOARDING_FIELD_ORD = ONBOARDING_FIELD_ORDER[key]) !== null && _ONBOARDING_FIELD_ORD !== void 0 ? _ONBOARDING_FIELD_ORD : 99;
1289
+ };
1290
+
1214
1291
  const createMessage = _ref => {
1215
1292
  let {
1216
1293
  id,
@@ -1236,9 +1313,6 @@
1236
1313
  }
1237
1314
  return [];
1238
1315
  };
1239
- const getOnboardingIntro = collectionPrompt => {
1240
- return collectionPrompt || "Before we proceed, I need to collect some information.";
1241
- };
1242
1316
  const validateOnboardingAnswer = (question, answer) => {
1243
1317
  var _question$fieldType;
1244
1318
  if (!answer.trim()) {
@@ -1319,7 +1393,7 @@
1319
1393
  const widgetRef = reactExports.useRef(null);
1320
1394
  const messageIdRef = reactExports.useRef(1);
1321
1395
 
1322
- // Onboarding state
1396
+ // Onboarding state: show form first when onboarding is enabled (no message required)
1323
1397
  const [onboardingActive, setOnboardingActive] = reactExports.useState(false);
1324
1398
  const [onboardingCompleted, setOnboardingCompleted] = reactExports.useState(false);
1325
1399
  const [currentQuestionIndex, setCurrentQuestionIndex] = reactExports.useState(0);
@@ -1380,6 +1454,15 @@
1380
1454
  setIsDark(darkMode);
1381
1455
  }, [darkMode]);
1382
1456
 
1457
+ // When onboarding is enabled, show the form as the first screen (no message required)
1458
+ reactExports.useEffect(() => {
1459
+ if (!onboardingEnabled || onboardingCompleted) return;
1460
+ const questions = getOnboardingQuestions(onboardingQuestions);
1461
+ if (questions.length > 0) {
1462
+ setOnboardingActive(true);
1463
+ }
1464
+ }, [onboardingEnabled, onboardingCompleted, onboardingQuestions]);
1465
+
1383
1466
  // Sync welcome message updates
1384
1467
  reactExports.useEffect(() => {
1385
1468
  if (!welcomeMessage) {
@@ -1462,7 +1545,15 @@
1462
1545
  role: "user",
1463
1546
  content: trimmed
1464
1547
  });
1465
- setMessages(prev => [...(prev || []), userMessage]);
1548
+ setMessages(prev => {
1549
+ const cleared = (prev || []).map(msg => {
1550
+ var _msg$prompts;
1551
+ return msg.role === 'assistant' && (_msg$prompts = msg.prompts) !== null && _msg$prompts !== void 0 && _msg$prompts.length ? _objectSpread2(_objectSpread2({}, msg), {}, {
1552
+ prompts: undefined
1553
+ }) : msg;
1554
+ });
1555
+ return [...cleared, userMessage];
1556
+ });
1466
1557
  setInputValue("");
1467
1558
  setIsLoading(true);
1468
1559
  } else {
@@ -1562,28 +1653,50 @@
1562
1653
  }
1563
1654
  setOnboardingActive(true);
1564
1655
  setCurrentQuestionIndex(0);
1565
- const introText = getOnboardingIntro(collectionPrompt);
1566
- const introMessage = createMessage({
1567
- id: getNextMessageId(),
1568
- role: "assistant",
1569
- content: introText,
1570
- isProcessing: false
1571
- });
1572
- setMessages(prev => [...prev, introMessage]);
1656
+ // Form UI shows all questions at once; no intro/first-question messages
1657
+ }, [onboardingQuestions]);
1658
+ const handleOnboardingFormSubmit = reactExports.useCallback(async answers => {
1659
+ const questions = getOnboardingQuestions(onboardingQuestions);
1660
+ if (questions.length === 0) return;
1661
+ const sorted = [...questions].sort((a, b) => getOnboardingFieldOrder(a.fieldType) - getOnboardingFieldOrder(b.fieldType));
1662
+ for (const q of sorted) {
1663
+ var _answers$key;
1664
+ const key = q.fieldType || "question";
1665
+ const value = ((_answers$key = answers[key]) !== null && _answers$key !== void 0 ? _answers$key : "").trim();
1666
+ if (!value) continue;
1667
+ const res = await sendMessage(value, key);
1668
+ if (!(res !== null && res !== void 0 && res.success)) {
1669
+ const errorMsg = createMessage({
1670
+ id: getNextMessageId(),
1671
+ role: "assistant",
1672
+ content: (res === null || res === void 0 ? void 0 : res.error) || "Something went wrong. Please try again.",
1673
+ isProcessing: false
1674
+ });
1675
+ setMessages(prev => [...prev, errorMsg]);
1676
+ return;
1677
+ }
1678
+ }
1679
+ setOnboardingActive(false);
1680
+ setOnboardingCompleted(true);
1681
+ setOnboardingAnswers(prev => _objectSpread2(_objectSpread2({}, prev), answers));
1573
1682
 
1574
- // Show first question after a delay
1575
- setTimeout(() => {
1576
- var _firstQuestion$askToT;
1577
- const firstQuestion = questions[0];
1578
- const questionMessage = createMessage({
1579
- id: getNextMessageId(),
1580
- role: "assistant",
1581
- content: (_firstQuestion$askToT = firstQuestion.askToType) !== null && _firstQuestion$askToT !== void 0 ? _firstQuestion$askToT : firstQuestion,
1582
- isProcessing: false
1583
- });
1584
- setMessages(prev => [...prev, questionMessage]);
1585
- }, 800);
1586
- }, [onboardingQuestions, collectionPrompt, getNextMessageId]);
1683
+ // Confirmation message disabled - no need to show after onboarding
1684
+ // const successMessage = createMessage({
1685
+ // id: getNextMessageId(),
1686
+ // role: "assistant",
1687
+ // content: "Thank you! I've received your information.",
1688
+ // isProcessing: false,
1689
+ // });
1690
+ // setMessages((prev) => [...prev, successMessage]);
1691
+
1692
+ if (pendingUserIntent && !pendingIntentProcessedRef.current) {
1693
+ pendingIntentProcessedRef.current = true;
1694
+ setTimeout(() => {
1695
+ setInputValue(pendingUserIntent);
1696
+ setPendingUserIntent(null);
1697
+ }, 500);
1698
+ }
1699
+ }, [onboardingQuestions, sendMessage, getNextMessageId, pendingUserIntent]);
1587
1700
  const handleOnboardingAnswer = reactExports.useCallback(async answer => {
1588
1701
  if (isProcessingAnswer) {
1589
1702
  return;
@@ -1659,13 +1772,14 @@
1659
1772
  setOnboardingCompleted(true);
1660
1773
  setIsProcessingAnswer(false);
1661
1774
  setTimeout(() => {
1662
- const successMessage = createMessage({
1663
- id: getNextMessageId(),
1664
- role: "assistant",
1665
- content: "Thank you! I've received your information.",
1666
- isProcessing: false
1667
- });
1668
- setMessages(prev => [...prev, successMessage]);
1775
+ // Confirmation message disabled - no need to show after onboarding
1776
+ // const successMessage = createMessage({
1777
+ // id: getNextMessageId(),
1778
+ // role: "assistant",
1779
+ // content: "Thank you! I've received your information.",
1780
+ // isProcessing: false,
1781
+ // });
1782
+ // setMessages((prev) => [...prev, successMessage]);
1669
1783
 
1670
1784
  // If there's a pending user intent, pre-fill input
1671
1785
  if (pendingUserIntent && !pendingIntentProcessedRef.current) {
@@ -2693,6 +2807,8 @@
2693
2807
  }
2694
2808
  }, [bidiMessages, isVoiceSessionActive]);
2695
2809
  return {
2810
+ // Identifiers
2811
+ conversationId: bidiSessionId,
2696
2812
  // State
2697
2813
  isOpen,
2698
2814
  isMinimized,
@@ -2710,6 +2826,7 @@
2710
2826
  onboardingQuestions,
2711
2827
  onboardingActive,
2712
2828
  onboardingCompleted,
2829
+ handleOnboardingFormSubmit,
2713
2830
  // Actions
2714
2831
  setInputValue,
2715
2832
  handleSend,
@@ -2727,7 +2844,52 @@
2727
2844
  };
2728
2845
 
2729
2846
  /**
2730
- * @license lucide-react v0.303.0 - ISC
2847
+ * @license lucide-react v0.575.0 - ISC
2848
+ *
2849
+ * This source code is licensed under the ISC license.
2850
+ * See the LICENSE file in the root directory of this source tree.
2851
+ */
2852
+
2853
+ const mergeClasses = (...classes) => classes.filter((className, index, array) => {
2854
+ return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index;
2855
+ }).join(" ").trim();
2856
+
2857
+ /**
2858
+ * @license lucide-react v0.575.0 - ISC
2859
+ *
2860
+ * This source code is licensed under the ISC license.
2861
+ * See the LICENSE file in the root directory of this source tree.
2862
+ */
2863
+
2864
+ const toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
2865
+
2866
+ /**
2867
+ * @license lucide-react v0.575.0 - ISC
2868
+ *
2869
+ * This source code is licensed under the ISC license.
2870
+ * See the LICENSE file in the root directory of this source tree.
2871
+ */
2872
+
2873
+ const toCamelCase = (string) => string.replace(
2874
+ /^([A-Z])|[\s-_]+(\w)/g,
2875
+ (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()
2876
+ );
2877
+
2878
+ /**
2879
+ * @license lucide-react v0.575.0 - ISC
2880
+ *
2881
+ * This source code is licensed under the ISC license.
2882
+ * See the LICENSE file in the root directory of this source tree.
2883
+ */
2884
+
2885
+
2886
+ const toPascalCase = (string) => {
2887
+ const camelCase = toCamelCase(string);
2888
+ return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
2889
+ };
2890
+
2891
+ /**
2892
+ * @license lucide-react v0.575.0 - ISC
2731
2893
  *
2732
2894
  * This source code is licensed under the ISC license.
2733
2895
  * See the LICENSE file in the root directory of this source tree.
@@ -2746,113 +2908,252 @@
2746
2908
  };
2747
2909
 
2748
2910
  /**
2749
- * @license lucide-react v0.303.0 - ISC
2911
+ * @license lucide-react v0.575.0 - ISC
2912
+ *
2913
+ * This source code is licensed under the ISC license.
2914
+ * See the LICENSE file in the root directory of this source tree.
2915
+ */
2916
+
2917
+ const hasA11yProp = (props) => {
2918
+ for (const prop in props) {
2919
+ if (prop.startsWith("aria-") || prop === "role" || prop === "title") {
2920
+ return true;
2921
+ }
2922
+ }
2923
+ return false;
2924
+ };
2925
+
2926
+ /**
2927
+ * @license lucide-react v0.575.0 - ISC
2928
+ *
2929
+ * This source code is licensed under the ISC license.
2930
+ * See the LICENSE file in the root directory of this source tree.
2931
+ */
2932
+
2933
+
2934
+ const Icon = reactExports.forwardRef(
2935
+ ({
2936
+ color = "currentColor",
2937
+ size = 24,
2938
+ strokeWidth = 2,
2939
+ absoluteStrokeWidth,
2940
+ className = "",
2941
+ children,
2942
+ iconNode,
2943
+ ...rest
2944
+ }, ref) => reactExports.createElement(
2945
+ "svg",
2946
+ {
2947
+ ref,
2948
+ ...defaultAttributes,
2949
+ width: size,
2950
+ height: size,
2951
+ stroke: color,
2952
+ strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,
2953
+ className: mergeClasses("lucide", className),
2954
+ ...!children && !hasA11yProp(rest) && { "aria-hidden": "true" },
2955
+ ...rest
2956
+ },
2957
+ [
2958
+ ...iconNode.map(([tag, attrs]) => reactExports.createElement(tag, attrs)),
2959
+ ...Array.isArray(children) ? children : [children]
2960
+ ]
2961
+ )
2962
+ );
2963
+
2964
+ /**
2965
+ * @license lucide-react v0.575.0 - ISC
2750
2966
  *
2751
2967
  * This source code is licensed under the ISC license.
2752
2968
  * See the LICENSE file in the root directory of this source tree.
2753
2969
  */
2754
2970
 
2755
2971
 
2756
- const toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase().trim();
2757
2972
  const createLucideIcon = (iconName, iconNode) => {
2758
2973
  const Component = reactExports.forwardRef(
2759
- ({ color = "currentColor", size = 24, strokeWidth = 2, absoluteStrokeWidth, className = "", children, ...rest }, ref) => reactExports.createElement(
2760
- "svg",
2761
- {
2762
- ref,
2763
- ...defaultAttributes,
2764
- width: size,
2765
- height: size,
2766
- stroke: color,
2767
- strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,
2768
- className: ["lucide", `lucide-${toKebabCase(iconName)}`, className].join(" "),
2769
- ...rest
2770
- },
2771
- [
2772
- ...iconNode.map(([tag, attrs]) => reactExports.createElement(tag, attrs)),
2773
- ...Array.isArray(children) ? children : [children]
2774
- ]
2775
- )
2974
+ ({ className, ...props }, ref) => reactExports.createElement(Icon, {
2975
+ ref,
2976
+ iconNode,
2977
+ className: mergeClasses(
2978
+ `lucide-${toKebabCase(toPascalCase(iconName))}`,
2979
+ `lucide-${iconName}`,
2980
+ className
2981
+ ),
2982
+ ...props
2983
+ })
2776
2984
  );
2777
- Component.displayName = `${iconName}`;
2985
+ Component.displayName = toPascalCase(iconName);
2778
2986
  return Component;
2779
2987
  };
2780
2988
 
2781
2989
  /**
2782
- * @license lucide-react v0.303.0 - ISC
2990
+ * @license lucide-react v0.575.0 - ISC
2783
2991
  *
2784
2992
  * This source code is licensed under the ISC license.
2785
2993
  * See the LICENSE file in the root directory of this source tree.
2786
2994
  */
2787
2995
 
2788
2996
 
2789
- const AudioLines = createLucideIcon("AudioLines", [
2997
+ const __iconNode$b = [
2790
2998
  ["path", { d: "M2 10v3", key: "1fnikh" }],
2791
2999
  ["path", { d: "M6 6v11", key: "11sgs0" }],
2792
3000
  ["path", { d: "M10 3v18", key: "yhl04a" }],
2793
3001
  ["path", { d: "M14 8v7", key: "3a1oy3" }],
2794
3002
  ["path", { d: "M18 5v13", key: "123xd1" }],
2795
3003
  ["path", { d: "M22 10v3", key: "154ddg" }]
2796
- ]);
3004
+ ];
3005
+ const AudioLines = createLucideIcon("audio-lines", __iconNode$b);
2797
3006
 
2798
3007
  /**
2799
- * @license lucide-react v0.303.0 - ISC
3008
+ * @license lucide-react v0.575.0 - ISC
2800
3009
  *
2801
3010
  * This source code is licensed under the ISC license.
2802
3011
  * See the LICENSE file in the root directory of this source tree.
2803
3012
  */
2804
3013
 
2805
3014
 
2806
- const Loader2 = createLucideIcon("Loader2", [
2807
- ["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]
2808
- ]);
3015
+ const __iconNode$a = [
3016
+ ["path", { d: "M12 15V3", key: "m9g1x1" }],
3017
+ ["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }],
3018
+ ["path", { d: "m7 10 5 5 5-5", key: "brsn70" }]
3019
+ ];
3020
+ const Download = createLucideIcon("download", __iconNode$a);
2809
3021
 
2810
3022
  /**
2811
- * @license lucide-react v0.303.0 - ISC
3023
+ * @license lucide-react v0.575.0 - ISC
2812
3024
  *
2813
3025
  * This source code is licensed under the ISC license.
2814
3026
  * See the LICENSE file in the root directory of this source tree.
2815
3027
  */
2816
3028
 
2817
3029
 
2818
- const MessageCircle = createLucideIcon("MessageCircle", [
2819
- ["path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z", key: "vv11sd" }]
2820
- ]);
3030
+ const __iconNode$9 = [
3031
+ ["path", { d: "M15 3h6v6", key: "1q9fwt" }],
3032
+ ["path", { d: "M10 14 21 3", key: "gplh6r" }],
3033
+ ["path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6", key: "a6xqqp" }]
3034
+ ];
3035
+ const ExternalLink = createLucideIcon("external-link", __iconNode$9);
2821
3036
 
2822
3037
  /**
2823
- * @license lucide-react v0.303.0 - ISC
3038
+ * @license lucide-react v0.575.0 - ISC
2824
3039
  *
2825
3040
  * This source code is licensed under the ISC license.
2826
3041
  * See the LICENSE file in the root directory of this source tree.
2827
3042
  */
2828
3043
 
2829
3044
 
2830
- const Moon = createLucideIcon("Moon", [
2831
- ["path", { d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z", key: "a7tn18" }]
2832
- ]);
3045
+ const __iconNode$8 = [
3046
+ [
3047
+ "path",
3048
+ {
3049
+ d: "M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",
3050
+ key: "1oefj6"
3051
+ }
3052
+ ],
3053
+ ["path", { d: "M14 2v5a1 1 0 0 0 1 1h5", key: "wfsgrz" }],
3054
+ ["path", { d: "M10 9H8", key: "b1mrlr" }],
3055
+ ["path", { d: "M16 13H8", key: "t4e002" }],
3056
+ ["path", { d: "M16 17H8", key: "z1uh3a" }]
3057
+ ];
3058
+ const FileText = createLucideIcon("file-text", __iconNode$8);
2833
3059
 
2834
3060
  /**
2835
- * @license lucide-react v0.303.0 - ISC
3061
+ * @license lucide-react v0.575.0 - ISC
2836
3062
  *
2837
3063
  * This source code is licensed under the ISC license.
2838
3064
  * See the LICENSE file in the root directory of this source tree.
2839
3065
  */
2840
3066
 
2841
3067
 
2842
- const Send = createLucideIcon("Send", [
2843
- ["path", { d: "m22 2-7 20-4-9-9-4Z", key: "1q3vgg" }],
2844
- ["path", { d: "M22 2 11 13", key: "nzbqef" }]
2845
- ]);
3068
+ const __iconNode$7 = [
3069
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
3070
+ ["path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20", key: "13o1zl" }],
3071
+ ["path", { d: "M2 12h20", key: "9i4pu4" }]
3072
+ ];
3073
+ const Globe = createLucideIcon("globe", __iconNode$7);
3074
+
3075
+ /**
3076
+ * @license lucide-react v0.575.0 - ISC
3077
+ *
3078
+ * This source code is licensed under the ISC license.
3079
+ * See the LICENSE file in the root directory of this source tree.
3080
+ */
3081
+
3082
+
3083
+ const __iconNode$6 = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
3084
+ const LoaderCircle = createLucideIcon("loader-circle", __iconNode$6);
3085
+
3086
+ /**
3087
+ * @license lucide-react v0.575.0 - ISC
3088
+ *
3089
+ * This source code is licensed under the ISC license.
3090
+ * See the LICENSE file in the root directory of this source tree.
3091
+ */
3092
+
3093
+
3094
+ const __iconNode$5 = [
3095
+ [
3096
+ "path",
3097
+ {
3098
+ d: "M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719",
3099
+ key: "1sd12s"
3100
+ }
3101
+ ]
3102
+ ];
3103
+ const MessageCircle = createLucideIcon("message-circle", __iconNode$5);
3104
+
3105
+ /**
3106
+ * @license lucide-react v0.575.0 - ISC
3107
+ *
3108
+ * This source code is licensed under the ISC license.
3109
+ * See the LICENSE file in the root directory of this source tree.
3110
+ */
3111
+
3112
+
3113
+ const __iconNode$4 = [
3114
+ [
3115
+ "path",
3116
+ {
3117
+ d: "M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",
3118
+ key: "1ffxy3"
3119
+ }
3120
+ ],
3121
+ ["path", { d: "m21.854 2.147-10.94 10.939", key: "12cjpa" }]
3122
+ ];
3123
+ const Send = createLucideIcon("send", __iconNode$4);
3124
+
3125
+ /**
3126
+ * @license lucide-react v0.575.0 - ISC
3127
+ *
3128
+ * This source code is licensed under the ISC license.
3129
+ * See the LICENSE file in the root directory of this source tree.
3130
+ */
3131
+
3132
+
3133
+ const __iconNode$3 = [
3134
+ ["path", { d: "M12 2v2", key: "tus03m" }],
3135
+ [
3136
+ "path",
3137
+ {
3138
+ d: "M14.837 16.385a6 6 0 1 1-7.223-7.222c.624-.147.97.66.715 1.248a4 4 0 0 0 5.26 5.259c.589-.255 1.396.09 1.248.715",
3139
+ key: "xlf6rm"
3140
+ }
3141
+ ],
3142
+ ["path", { d: "M16 12a4 4 0 0 0-4-4", key: "6vsxu" }],
3143
+ ["path", { d: "m19 5-1.256 1.256", key: "1yg6a6" }],
3144
+ ["path", { d: "M20 12h2", key: "1q8mjw" }]
3145
+ ];
3146
+ const SunMoon = createLucideIcon("sun-moon", __iconNode$3);
2846
3147
 
2847
3148
  /**
2848
- * @license lucide-react v0.303.0 - ISC
3149
+ * @license lucide-react v0.575.0 - ISC
2849
3150
  *
2850
3151
  * This source code is licensed under the ISC license.
2851
3152
  * See the LICENSE file in the root directory of this source tree.
2852
3153
  */
2853
3154
 
2854
3155
 
2855
- const Sun = createLucideIcon("Sun", [
3156
+ const __iconNode$2 = [
2856
3157
  ["circle", { cx: "12", cy: "12", r: "4", key: "4exip2" }],
2857
3158
  ["path", { d: "M12 2v2", key: "tus03m" }],
2858
3159
  ["path", { d: "M12 20v2", key: "1lh1kg" }],
@@ -2862,33 +3163,36 @@
2862
3163
  ["path", { d: "M20 12h2", key: "1q8mjw" }],
2863
3164
  ["path", { d: "m6.34 17.66-1.41 1.41", key: "1m8zz5" }],
2864
3165
  ["path", { d: "m19.07 4.93-1.41 1.41", key: "1shlcs" }]
2865
- ]);
3166
+ ];
3167
+ const Sun = createLucideIcon("sun", __iconNode$2);
2866
3168
 
2867
3169
  /**
2868
- * @license lucide-react v0.303.0 - ISC
3170
+ * @license lucide-react v0.575.0 - ISC
2869
3171
  *
2870
3172
  * This source code is licensed under the ISC license.
2871
3173
  * See the LICENSE file in the root directory of this source tree.
2872
3174
  */
2873
3175
 
2874
3176
 
2875
- const User = createLucideIcon("User", [
3177
+ const __iconNode$1 = [
2876
3178
  ["path", { d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2", key: "975kel" }],
2877
3179
  ["circle", { cx: "12", cy: "7", r: "4", key: "17ys0d" }]
2878
- ]);
3180
+ ];
3181
+ const User = createLucideIcon("user", __iconNode$1);
2879
3182
 
2880
3183
  /**
2881
- * @license lucide-react v0.303.0 - ISC
3184
+ * @license lucide-react v0.575.0 - ISC
2882
3185
  *
2883
3186
  * This source code is licensed under the ISC license.
2884
3187
  * See the LICENSE file in the root directory of this source tree.
2885
3188
  */
2886
3189
 
2887
3190
 
2888
- const X = createLucideIcon("X", [
3191
+ const __iconNode = [
2889
3192
  ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
2890
3193
  ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
2891
- ]);
3194
+ ];
3195
+ const X = createLucideIcon("x", __iconNode);
2892
3196
 
2893
3197
  function ok$2() {}
2894
3198
 
@@ -56758,8 +57062,8 @@
56758
57062
  }, [content, isStreaming]);
56759
57063
  return /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
56760
57064
  className: "relative",
57065
+ dir: "auto",
56761
57066
  style: {
56762
- direction: isRtl ? "rtl" : "ltr",
56763
57067
  textAlign: isRtl ? "right" : "left"
56764
57068
  },
56765
57069
  children: [/*#__PURE__*/jsxRuntimeExports.jsx(Markdown, {
@@ -56780,7 +57084,10 @@
56780
57084
  } = _ref2,
56781
57085
  props = _objectWithoutProperties$1(_ref2, _excluded);
56782
57086
  return /*#__PURE__*/jsxRuntimeExports.jsx("a", _objectSpread2(_objectSpread2({
56783
- className: isDark ? "text-blue-400 hover:text-blue-300 hover:underline" : "text-blue-600 hover:underline",
57087
+ className: "hover:underline",
57088
+ style: {
57089
+ color: textColor || (isDark ? "#f3f4f6" : "#1A1A1A")
57090
+ },
56784
57091
  target: "_blank",
56785
57092
  rel: "noopener noreferrer"
56786
57093
  }, props), {}, {
@@ -57011,15 +57318,161 @@
57011
57318
  });
57012
57319
  };
57013
57320
 
57321
+ // Sources section: citations and file downloads from stream complete chunk
57322
+ const MessageSources = _ref14 => {
57323
+ let {
57324
+ sources = [],
57325
+ apiBaseUrl,
57326
+ organizationId,
57327
+ isDark,
57328
+ textColor,
57329
+ fontFamily,
57330
+ fontSize
57331
+ } = _ref14;
57332
+ const [downloadingId, setDownloadingId] = reactExports.useState(null);
57333
+ const handleFileDownload = async source => {
57334
+ if (!apiBaseUrl || !organizationId || !source.source_id) return;
57335
+ setDownloadingId(source.source_id);
57336
+ try {
57337
+ const base = apiBaseUrl.replace(/\/$/, "");
57338
+ const url = "".concat(base, "/api/v1/support/file-download");
57339
+ const res = await fetch(url, {
57340
+ method: "POST",
57341
+ headers: {
57342
+ "Content-Type": "application/json",
57343
+ "x-eshal-org": organizationId
57344
+ },
57345
+ credentials: "include",
57346
+ body: JSON.stringify({
57347
+ org_id: organizationId,
57348
+ source_id: source.source_id
57349
+ })
57350
+ });
57351
+ if (!res.ok) {
57352
+ const err = await res.json().catch(() => ({}));
57353
+ throw new Error(err.details || err.error || res.statusText);
57354
+ }
57355
+ const blob = await res.blob();
57356
+ const disposition = res.headers.get("content-disposition");
57357
+ let filename = source.source_name || "download";
57358
+ const match = disposition && /filename\*?=(?:UTF-8'')?["']?([^"'\s;]+)["']?/i.exec(disposition);
57359
+ if (match) filename = decodeURIComponent(match[1].replace(/\\"/g, '"'));
57360
+ const a = document.createElement("a");
57361
+ a.href = URL.createObjectURL(blob);
57362
+ a.download = filename;
57363
+ a.click();
57364
+ URL.revokeObjectURL(a.href);
57365
+ } catch (e) {
57366
+ console.error("File download failed:", e);
57367
+ } finally {
57368
+ setDownloadingId(null);
57369
+ }
57370
+ };
57371
+ if (!(sources !== null && sources !== void 0 && sources.length)) return null;
57372
+ const color = textColor !== null && textColor !== void 0 ? textColor : isDark ? "#f3f4f6" : "#1A1A1A";
57373
+ const iconSize = 14;
57374
+ const decodedName = name => {
57375
+ if (!name) return "";
57376
+ try {
57377
+ return decodeURIComponent(String(name));
57378
+ } catch (_unused) {
57379
+ return name;
57380
+ }
57381
+ };
57382
+ return /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
57383
+ className: "mt-3 min-w-0 max-w-full overflow-hidden",
57384
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("p", {
57385
+ className: "font-semibold mb-2",
57386
+ style: {
57387
+ color,
57388
+ fontFamily: fontFamily || "Inter",
57389
+ fontSize: fontSize || "14px"
57390
+ },
57391
+ children: "Sources"
57392
+ }), /*#__PURE__*/jsxRuntimeExports.jsx("ul", {
57393
+ className: "space-y-2 list-none p-0 m-0 min-w-0 w-full max-w-full overflow-hidden",
57394
+ children: sources.map((source, i) => /*#__PURE__*/jsxRuntimeExports.jsx("li", {
57395
+ className: "flex items-center gap-2 min-w-0 w-full max-w-full overflow-hidden",
57396
+ children: source.source_type === "file" ? /*#__PURE__*/jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
57397
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx(FileText, {
57398
+ className: "flex-shrink-0 text-current opacity-80",
57399
+ size: iconSize,
57400
+ strokeWidth: 2,
57401
+ "aria-hidden": true
57402
+ }), /*#__PURE__*/jsxRuntimeExports.jsx("span", {
57403
+ className: "truncate min-w-0 flex-1",
57404
+ style: {
57405
+ color,
57406
+ fontFamily: fontFamily || "Inter",
57407
+ fontSize: fontSize || "14px",
57408
+ overflow: "hidden",
57409
+ textOverflow: "ellipsis",
57410
+ whiteSpace: "nowrap"
57411
+ },
57412
+ title: decodedName(source.source_name) || "File",
57413
+ children: decodedName(source.source_name) || "File"
57414
+ }), /*#__PURE__*/jsxRuntimeExports.jsx("button", {
57415
+ type: "button",
57416
+ onClick: () => handleFileDownload(source),
57417
+ disabled: downloadingId === source.source_id,
57418
+ className: "flex-shrink-0 p-1 rounded bg-transparent border-0 hover:bg-transparent disabled:opacity-50 transition-opacity focus:outline-none focus-visible:outline-none cursor-pointer disabled:cursor-not-allowed",
57419
+ style: {
57420
+ color
57421
+ },
57422
+ "aria-label": downloadingId === source.source_id ? "Downloading…" : "Download file",
57423
+ title: downloadingId === source.source_id ? "Downloading…" : "Download",
57424
+ children: downloadingId === source.source_id ? /*#__PURE__*/jsxRuntimeExports.jsx(LoaderCircle, {
57425
+ size: iconSize,
57426
+ strokeWidth: 2,
57427
+ className: "animate-spin"
57428
+ }) : /*#__PURE__*/jsxRuntimeExports.jsx(Download, {
57429
+ size: iconSize,
57430
+ strokeWidth: 2
57431
+ })
57432
+ })]
57433
+ }) : /*#__PURE__*/jsxRuntimeExports.jsxs("a", {
57434
+ href: source.url || "#",
57435
+ target: "_blank",
57436
+ rel: "noopener noreferrer",
57437
+ className: "flex items-center gap-2 min-w-0 flex-1 hover:underline",
57438
+ style: {
57439
+ color,
57440
+ fontFamily: fontFamily || "Inter",
57441
+ fontSize: fontSize || "14px"
57442
+ },
57443
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx(Globe, {
57444
+ className: "flex-shrink-0 opacity-80",
57445
+ size: iconSize,
57446
+ strokeWidth: 2,
57447
+ "aria-hidden": true
57448
+ }), /*#__PURE__*/jsxRuntimeExports.jsx("span", {
57449
+ className: "truncate min-w-0",
57450
+ style: {
57451
+ overflow: "hidden",
57452
+ textOverflow: "ellipsis",
57453
+ whiteSpace: "nowrap"
57454
+ },
57455
+ title: source.source_name || source.url || "Link",
57456
+ children: source.source_name || source.url || "Link"
57457
+ }), /*#__PURE__*/jsxRuntimeExports.jsx(ExternalLink, {
57458
+ className: "w-3.5 h-3.5 flex-shrink-0",
57459
+ "aria-hidden": true
57460
+ })]
57461
+ })
57462
+ }, source.source_id || source.url || i))
57463
+ })]
57464
+ });
57465
+ };
57466
+
57014
57467
  // Decision widget component for HITL (Human-in-the-Loop)
57015
- const DecisionWidget = _ref14 => {
57468
+ const DecisionWidget = _ref16 => {
57016
57469
  let {
57017
57470
  question,
57018
57471
  options,
57019
57472
  onDecision,
57020
57473
  disabled,
57021
57474
  isDark = false
57022
- } = _ref14;
57475
+ } = _ref16;
57023
57476
  return /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
57024
57477
  className: "mt-3 p-3 rounded-lg border ".concat(isDark ? "bg-blue-900/30 border-blue-700/50" : "bg-blue-50 border-blue-200"),
57025
57478
  children: [/*#__PURE__*/jsxRuntimeExports.jsx("p", {
@@ -57036,7 +57489,8 @@
57036
57489
  })]
57037
57490
  });
57038
57491
  };
57039
- const AssistantMessage = _ref15 => {
57492
+ const AssistantMessage = _ref17 => {
57493
+ var _message$sources, _message$sources2;
57040
57494
  let {
57041
57495
  message,
57042
57496
  formatTime,
@@ -57053,8 +57507,11 @@
57053
57507
  onDecision,
57054
57508
  companyLogo,
57055
57509
  conciergeName,
57056
- companyName
57057
- } = _ref15;
57510
+ companyName,
57511
+ apiBaseUrl,
57512
+ organizationId,
57513
+ onPromptSuggestionClick
57514
+ } = _ref17;
57058
57515
  const displayContent = typeof message.content === "string" ? message.content : "";
57059
57516
  const isTypingMessage = message.isProcessing && (!displayContent || displayContent.length === 0);
57060
57517
  const bubbleColor = agentMessageBubbleColor !== undefined && agentMessageBubbleColor !== null ? agentMessageBubbleColor : isDark ? "#1f2937" : "#FFFFFF";
@@ -57069,7 +57526,7 @@
57069
57526
  children: /*#__PURE__*/jsxRuntimeExports.jsx("div", {
57070
57527
  className: "w-8 h-8 rounded-full flex items-center justify-center overflow-hidden ".concat(isDark ? "bg-gray-700" : "bg-gray-200"),
57071
57528
  children: companyLogo ? /*#__PURE__*/jsxRuntimeExports.jsx("div", {
57072
- className: "w-full h-full flex items-center justify-center",
57529
+ className: " flex items-center justify-center",
57073
57530
  children: /*#__PURE__*/jsxRuntimeExports.jsx("img", {
57074
57531
  src: companyLogo,
57075
57532
  alt: "Company logo",
@@ -57080,25 +57537,23 @@
57080
57537
  }
57081
57538
  })
57082
57539
  }) : /*#__PURE__*/jsxRuntimeExports.jsx("div", {
57083
- className: "w-full h-full flex items-center justify-center text-white font-semibold",
57540
+ className: "w-full h-full flex items-center justify-center",
57084
57541
  style: {
57085
- backgroundColor: primaryColor,
57086
- fontSize: "14px",
57542
+ fontSize: "18px",
57087
57543
  fontFamily: fontFamily || "Inter"
57088
57544
  },
57089
57545
  children: (conciergeName || "A").charAt(0).toUpperCase()
57090
57546
  })
57091
57547
  })
57092
57548
  }), /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
57093
- className: "flex flex-col items-start max-w-[75%]",
57549
+ className: "flex flex-col items-start min-w-0 max-w-[75%]",
57094
57550
  children: [/*#__PURE__*/jsxRuntimeExports.jsx("div", {
57095
- className: "rounded-2xl px-4 py-2.5 shadow-sm border rounded-tl-sm ".concat(isDark ? "border-gray-700" : "border-gray-200"),
57551
+ className: "rounded-2xl px-4 py-2.5 shadow-sm border rounded-tl-sm rtl:rounded-tl-2xl rtl:rounded-tr-sm min-w-0 max-w-full overflow-hidden ".concat(isDark ? "border-gray-700" : "border-gray-200"),
57096
57552
  style: {
57097
57553
  backgroundColor: bubbleColor,
57098
57554
  color: messageTextColor,
57099
57555
  fontFamily: messageFontFamily,
57100
57556
  fontSize: messageFontSize,
57101
- direction: isRtl ? "rtl" : "ltr",
57102
57557
  textAlign: isRtl ? "right" : "left"
57103
57558
  },
57104
57559
  children: isTypingMessage ? /*#__PURE__*/jsxRuntimeExports.jsx(TypingIndicator, {
@@ -57125,26 +57580,58 @@
57125
57580
  }), message.decisionResponse && /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
57126
57581
  className: "mt-2 text-xs ".concat(isDark ? "text-gray-400" : "text-gray-500"),
57127
57582
  children: ["Selected: ", message.decisionResponse.selectedOption]
57583
+ }), ((_message$sources = message.sources) === null || _message$sources === void 0 ? void 0 : _message$sources.length) > 0 && /*#__PURE__*/jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
57584
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("div", {
57585
+ className: "mt-3",
57586
+ style: {
57587
+ borderTop: "1px solid ".concat(messageTextColor)
57588
+ }
57589
+ }), /*#__PURE__*/jsxRuntimeExports.jsx(MessageSources, {
57590
+ sources: message.sources,
57591
+ apiBaseUrl: apiBaseUrl,
57592
+ organizationId: organizationId,
57593
+ isDark: isDark,
57594
+ textColor: messageTextColor,
57595
+ fontFamily: messageFontFamily,
57596
+ fontSize: messageFontSize
57597
+ })]
57598
+ })]
57599
+ }) : displayContent ? /*#__PURE__*/jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
57600
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx(StreamingMarkdown, {
57601
+ content: displayContent,
57602
+ isStreaming: message.isProcessing,
57603
+ isDark: isDark,
57604
+ isRtl: isRtl,
57605
+ textColor: messageTextColor,
57606
+ fontFamily: messageFontFamily,
57607
+ fontSize: messageFontSize
57608
+ }), ((_message$sources2 = message.sources) === null || _message$sources2 === void 0 ? void 0 : _message$sources2.length) > 0 && /*#__PURE__*/jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
57609
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("div", {
57610
+ className: "mt-3",
57611
+ style: {
57612
+ borderTop: "1px solid ".concat(messageTextColor)
57613
+ }
57614
+ }), /*#__PURE__*/jsxRuntimeExports.jsx(MessageSources, {
57615
+ sources: message.sources,
57616
+ apiBaseUrl: apiBaseUrl,
57617
+ organizationId: organizationId,
57618
+ isDark: isDark,
57619
+ textColor: messageTextColor,
57620
+ fontFamily: messageFontFamily,
57621
+ fontSize: messageFontSize
57622
+ })]
57128
57623
  })]
57129
- }) : displayContent ? /*#__PURE__*/jsxRuntimeExports.jsx(StreamingMarkdown, {
57130
- content: displayContent,
57131
- isStreaming: message.isProcessing,
57132
- isDark: isDark,
57133
- isRtl: isRtl,
57134
- textColor: messageTextColor,
57135
- fontFamily: messageFontFamily,
57136
- fontSize: messageFontSize
57137
57624
  }) : null
57138
57625
  })
57139
57626
  }), /*#__PURE__*/jsxRuntimeExports.jsx("p", {
57140
57627
  className: "text-[11px] mt-1.5 px-1 ".concat(isDark ? "text-gray-500" : "text-gray-400"),
57141
- dir: "ltr",
57628
+ dir: "auto",
57142
57629
  children: formatTime(message.timestamp)
57143
57630
  })]
57144
57631
  })]
57145
57632
  });
57146
57633
  };
57147
- const UserMessage = _ref16 => {
57634
+ const UserMessage = _ref18 => {
57148
57635
  let {
57149
57636
  message,
57150
57637
  formatTime,
@@ -57158,7 +57645,7 @@
57158
57645
  fontSize,
57159
57646
  isDark,
57160
57647
  isRtl
57161
- } = _ref16;
57648
+ } = _ref18;
57162
57649
  const primary = userMessageBoxColor !== undefined && userMessageBoxColor !== null ? userMessageBoxColor : primaryColor !== undefined && primaryColor !== null ? primaryColor : "#2563eb";
57163
57650
  const messageTextColor = userTextColor !== undefined && userTextColor !== null ? userTextColor : textColor !== undefined && textColor !== null ? textColor : "#FFFFFF";
57164
57651
  const messageFontFamily = userMessageBubbleFontFamily !== undefined && userMessageBubbleFontFamily !== null ? userMessageBubbleFontFamily : fontFamily !== undefined && fontFamily !== null ? fontFamily : "Inter";
@@ -57177,15 +57664,16 @@
57177
57664
  }), /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
57178
57665
  className: "flex flex-col items-end max-w-[75%]",
57179
57666
  children: [/*#__PURE__*/jsxRuntimeExports.jsx("div", {
57180
- className: "rounded-2xl px-4 py-2.5 shadow-lg rounded-tr-sm",
57667
+ className: "rounded-2xl px-4 py-2.5 shadow-lg ".concat(isRtl ? "rounded-tl-sm" : "rounded-tr-sm"),
57668
+ dir: "auto",
57181
57669
  style: {
57182
57670
  background: "linear-gradient(135deg, ".concat(primary, " 0%, ").concat(primary, "dd 100%)"),
57183
57671
  fontFamily: messageFontFamily,
57184
- textAlign: isRtl ? "right" : "left",
57185
- direction: isRtl ? "rtl" : "ltr"
57672
+ textAlign: isRtl ? "right" : "left"
57186
57673
  },
57187
57674
  children: /*#__PURE__*/jsxRuntimeExports.jsx("p", {
57188
57675
  className: "whitespace-pre-wrap break-words",
57676
+ dir: "auto",
57189
57677
  style: {
57190
57678
  color: messageTextColor,
57191
57679
  fontFamily: messageFontFamily,
@@ -57199,13 +57687,13 @@
57199
57687
  })
57200
57688
  }), /*#__PURE__*/jsxRuntimeExports.jsx("p", {
57201
57689
  className: "text-[11px] mt-1.5 px-1 ".concat(isDark ? "text-gray-500" : "text-gray-400"),
57202
- dir: "ltr",
57690
+ dir: "auto",
57203
57691
  children: formatTime(message.timestamp)
57204
57692
  })]
57205
57693
  })]
57206
57694
  });
57207
57695
  };
57208
- const MessageBubble = _ref17 => {
57696
+ const MessageBubble = _ref19 => {
57209
57697
  let {
57210
57698
  message,
57211
57699
  isDark,
@@ -57226,8 +57714,11 @@
57226
57714
  onDecision,
57227
57715
  companyLogo,
57228
57716
  conciergeName,
57229
- companyName
57230
- } = _ref17;
57717
+ companyName,
57718
+ apiBaseUrl,
57719
+ organizationId,
57720
+ onPromptSuggestionClick
57721
+ } = _ref19;
57231
57722
  if (!message) {
57232
57723
  return null;
57233
57724
  }
@@ -57263,7 +57754,10 @@
57263
57754
  onDecision: onDecision,
57264
57755
  companyLogo: companyLogo,
57265
57756
  conciergeName: conciergeName,
57266
- companyName: companyName
57757
+ companyName: companyName,
57758
+ apiBaseUrl: apiBaseUrl,
57759
+ organizationId: organizationId,
57760
+ onPromptSuggestionClick: onPromptSuggestionClick
57267
57761
  });
57268
57762
  };
57269
57763
 
@@ -57594,7 +58088,10 @@
57594
58088
  messagesContainerRef,
57595
58089
  companyLogo,
57596
58090
  conciergeName,
57597
- companyName
58091
+ companyName,
58092
+ apiBaseUrl,
58093
+ organizationId,
58094
+ onPromptSuggestionClick
57598
58095
  } = _ref;
57599
58096
  const messagesEndRef = reactExports.useRef(null);
57600
58097
  const shouldAutoScrollRef = reactExports.useRef(true);
@@ -57645,10 +58142,9 @@
57645
58142
  children: [disclaimerText && disclaimerPosition === "top" && /*#__PURE__*/jsxRuntimeExports.jsx("div", {
57646
58143
  className: "flex justify-center",
57647
58144
  children: /*#__PURE__*/jsxRuntimeExports.jsx("div", {
57648
- className: "rounded-lg px-2 py-1 max-w-[85%] border",
58145
+ className: "rounded-lg px-2 py-1 max-w-[85%] ",
57649
58146
  style: {
57650
- backgroundColor: agentMessageBubbleColor !== undefined && agentMessageBubbleColor !== null ? agentMessageBubbleColor : resolvedAgentBubbleColor || "#F5F5F5",
57651
- color: assistantTextColor !== undefined && assistantTextColor !== null ? assistantTextColor : "#1A1A1A",
58147
+ color: isDark ? "#d1d5db" : "#6b7280",
57652
58148
  fontFamily: fontFamily !== undefined && fontFamily !== null ? fontFamily : "Inter",
57653
58149
  fontSize: fontSize !== undefined && fontSize !== null ? "calc(".concat(fontSize, " - 2px)") : "12px",
57654
58150
  direction: isRtl ? "rtl" : "ltr",
@@ -57684,9 +58180,12 @@
57684
58180
  formatTime: formatTime,
57685
58181
  isRtl: isRtl,
57686
58182
  onDecision: onDecision,
58183
+ onPromptSuggestionClick: onPromptSuggestionClick,
57687
58184
  companyLogo: companyLogo,
57688
58185
  conciergeName: conciergeName,
57689
- companyName: companyName
58186
+ companyName: companyName,
58187
+ apiBaseUrl: apiBaseUrl,
58188
+ organizationId: organizationId
57690
58189
  }, message.id)), (() => {
57691
58190
  const lastMessage = messages[messages.length - 1];
57692
58191
  const isWaitingForFirstChunk = isLoading && (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.role) === 'user';
@@ -57712,7 +58211,9 @@
57712
58211
  onDecision: onDecision,
57713
58212
  companyLogo: companyLogo,
57714
58213
  conciergeName: conciergeName,
57715
- companyName: companyName
58214
+ companyName: companyName,
58215
+ apiBaseUrl: apiBaseUrl,
58216
+ organizationId: organizationId
57716
58217
  }, "skeleton-waiting");
57717
58218
  }
57718
58219
  return null;
@@ -57739,7 +58240,15 @@
57739
58240
  });
57740
58241
  };
57741
58242
 
57742
- const ESHAL_LOGO_URL = "https://app.eshal.ai/brand/logos/full/logo-full-light.svg";
58243
+ const ASSETS = {
58244
+ BRAND: {
58245
+ LOGOS: {
58246
+ FULL: {
58247
+ LIGHT: "https://app.eshal.ai/brand/logos/full/logo-full-light.svg"
58248
+ }
58249
+ }
58250
+ }
58251
+ };
57743
58252
  const ChatInput = _ref => {
57744
58253
  let {
57745
58254
  inputValue,
@@ -57767,7 +58276,13 @@
57767
58276
  onboardingQuestions = [],
57768
58277
  onboardingActive = false,
57769
58278
  onboardingCompleted = false,
57770
- userMessageBubbleFontFamily
58279
+ userMessageBubbleFontFamily,
58280
+ onboardingEnabled = false,
58281
+ userMessageBubbleFontSize,
58282
+ userMessageBoxColor,
58283
+ userTextColor,
58284
+ promptSuggestions,
58285
+ onPromptSuggestionClick
57771
58286
  } = _ref;
57772
58287
  const [isFocused, setIsFocused] = reactExports.useState(false);
57773
58288
  const [showTooltip, setShowTooltip] = reactExports.useState(false);
@@ -57777,7 +58292,6 @@
57777
58292
  placement: "top",
57778
58293
  arrowOffset: 0
57779
58294
  });
57780
- const [logoImageLoaded, setLogoImageLoaded] = reactExports.useState(false);
57781
58295
  const [logoImageError, setLogoImageError] = reactExports.useState(false);
57782
58296
  const tooltipTimeoutRef = reactExports.useRef(null);
57783
58297
  const textareaRef = reactExports.useRef(null);
@@ -57824,7 +58338,7 @@
57824
58338
  // Check if onboarding flow exists and is not completed
57825
58339
  const hasOnboardingQuestions = onboardingQuestions && onboardingQuestions.length > 0;
57826
58340
  const isOnboardingIncomplete = hasOnboardingQuestions && !onboardingCompleted;
57827
- const isVoiceButtonDisabled = isOnboardingIncomplete || voiceStatus === "connecting";
58341
+ const isVoiceButtonDisabled = onboardingEnabled && isOnboardingIncomplete || voiceStatus === "connecting";
57828
58342
 
57829
58343
  // Determine tooltip message
57830
58344
  const getTooltipMessage = () => {
@@ -57950,12 +58464,36 @@
57950
58464
  }
57951
58465
  };
57952
58466
  }, []);
58467
+
58468
+ // Match UserMessage styling for prompt suggestion pills
58469
+ const promptPrimary = userMessageBoxColor !== undefined && userMessageBoxColor !== null ? userMessageBoxColor : primaryColor !== undefined && primaryColor !== null ? primaryColor : "#2563eb";
58470
+ const promptTextColor = userTextColor !== undefined && userTextColor !== null ? userTextColor : textColor !== undefined && textColor !== null ? textColor : "#FFFFFF";
58471
+ const promptFontFamily = userMessageBubbleFontFamily !== undefined && userMessageBubbleFontFamily !== null ? userMessageBubbleFontFamily : fontFamily !== undefined && fontFamily !== null ? fontFamily : "Inter";
58472
+ const promptFontSize = userMessageBubbleFontSize !== undefined && userMessageBubbleFontSize !== null ? userMessageBubbleFontSize : fontSize !== undefined && fontSize !== null ? fontSize : "14px";
57953
58473
  return /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
57954
58474
  className: "px-5 py-4 flex-shrink-0 relative ".concat(isDark ? "bg-gray-900" : "bg-white"),
57955
58475
  style: {
57956
58476
  overflow: "visible"
57957
58477
  },
57958
- children: [/*#__PURE__*/jsxRuntimeExports.jsxs("div", {
58478
+ children: [promptSuggestions.length > 0 && onPromptSuggestionClick && /*#__PURE__*/jsxRuntimeExports.jsx("div", {
58479
+ className: "mb-2 -mx-1 px-1",
58480
+ children: /*#__PURE__*/jsxRuntimeExports.jsx("div", {
58481
+ className: "flex gap-2 overflow-x-auto scrollbar-hide pb-1",
58482
+ children: promptSuggestions.map((p, index) => /*#__PURE__*/jsxRuntimeExports.jsx("button", {
58483
+ type: "button",
58484
+ onClick: () => onPromptSuggestionClick(p.text || p),
58485
+ dir: "auto",
58486
+ className: "inline-flex items-center rounded-full px-4 py-1.5 whitespace-nowrap flex-shrink-0 border-0 transition-transform duration-150 active:scale-95",
58487
+ style: {
58488
+ background: "linear-gradient(135deg, ".concat(promptPrimary, " 0%, ").concat(promptPrimary, "dd 100%)"),
58489
+ color: promptTextColor,
58490
+ fontFamily: promptFontFamily,
58491
+ fontSize: promptFontSize
58492
+ },
58493
+ children: p.text || p
58494
+ }, "".concat(p.text || p, "-").concat(index)))
58495
+ })
58496
+ }), /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
57959
58497
  className: "flex items-center gap-1.5",
57960
58498
  children: [/*#__PURE__*/jsxRuntimeExports.jsx("div", {
57961
58499
  className: "flex-1 flex items-center min-h-[48px] ".concat(isDark ? "bg-gray-800" : "bg-gray-50", " rounded-2xl transition-all duration-200"),
@@ -58006,7 +58544,7 @@
58006
58544
  onClick: onVoiceToggle,
58007
58545
  className: "h-10 w-10 rounded-xl flex items-center justify-center transition-all duration-200 shadow-md ".concat(isVoiceSessionActive ? "bg-red-500 text-white hover:bg-red-600" : isDark ? "bg-gray-800 text-gray-200 hover:bg-gray-700" : "bg-white text-gray-600 hover:bg-gray-100", " ").concat(isVoiceButtonDisabled ? "opacity-60 cursor-not-allowed shadow-none" : ""),
58008
58546
  disabled: isVoiceButtonDisabled,
58009
- children: voiceStatus === "connecting" ? /*#__PURE__*/jsxRuntimeExports.jsx(Loader2, {
58547
+ children: voiceStatus === "connecting" ? /*#__PURE__*/jsxRuntimeExports.jsx(LoaderCircle, {
58010
58548
  className: "w-4 h-4 animate-spin"
58011
58549
  }) : /*#__PURE__*/jsxRuntimeExports.jsx(AudioLines, {
58012
58550
  className: "w-4 h-4"
@@ -58116,61 +58654,37 @@
58116
58654
  }), disclaimerText && disclaimerPosition === "footer" && /*#__PURE__*/jsxRuntimeExports.jsx("p", {
58117
58655
  className: "text-xs mt-2 text-center",
58118
58656
  style: {
58119
- color: isDark ? "#FFFFFF" : "#000000",
58657
+ color: isDark ? "#d1d5db" : "#6b7280",
58120
58658
  fontFamily: fontFamily || "Inter",
58121
58659
  fontSize: fontSize ? "calc(".concat(fontSize, " - 2px)") : "12px",
58122
58660
  direction: isRtl ? "rtl" : "ltr"
58123
58661
  },
58124
58662
  dir: isRtl ? "rtl" : "ltr",
58125
58663
  children: disclaimerText
58126
- }), showPoweredBy && /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
58127
- className: "mt-1.5 flex justify-center relative",
58128
- style: {
58129
- direction: isRtl ? "rtl" : "ltr",
58130
- fontFamily: "Inter"
58131
- },
58664
+ }), showPoweredBy && /*#__PURE__*/jsxRuntimeExports.jsx("div", {
58665
+ className: "mt-1.5 flex justify-center",
58132
58666
  dir: isRtl ? "rtl" : "ltr",
58133
- children: [!logoImageLoaded && !logoImageError && /*#__PURE__*/jsxRuntimeExports.jsx("img", {
58134
- src: ESHAL_LOGO_URL,
58135
- alt: "",
58136
- "aria-hidden": true,
58137
- className: "absolute opacity-0 pointer-events-none",
58138
- style: {
58139
- width: 0,
58140
- height: 0
58141
- },
58142
- onLoad: () => setLogoImageLoaded(true),
58143
- onError: () => setLogoImageError(true)
58144
- }), (logoImageLoaded || logoImageError) && /*#__PURE__*/jsxRuntimeExports.jsxs("span", {
58145
- className: "inline-flex items-center gap-1.5 rounded-lg py-2 px-3",
58146
- style: {
58147
- backgroundColor: "#000000"
58148
- },
58149
- children: [/*#__PURE__*/jsxRuntimeExports.jsx("span", {
58150
- style: {
58151
- color: "#ffffff",
58152
- fontFamily: "Inter",
58153
- fontSize: "12px",
58154
- fontWeight: 500
58155
- },
58156
- children: "Powered by"
58157
- }), logoImageError ? /*#__PURE__*/jsxRuntimeExports.jsx("span", {
58158
- style: {
58159
- color: "#ffffff",
58160
- fontFamily: "Inter",
58161
- fontSize: "12px",
58162
- fontWeight: 500
58163
- },
58164
- children: "ESHAL"
58165
- }) : /*#__PURE__*/jsxRuntimeExports.jsx("img", {
58166
- src: ESHAL_LOGO_URL,
58167
- alt: "ESHAL",
58168
- className: "h-3.5 w-auto",
58169
- style: {
58170
- filter: "brightness(0) invert(1)"
58171
- }
58172
- })]
58173
- })]
58667
+ children: /*#__PURE__*/jsxRuntimeExports.jsx("a", {
58668
+ href: "https://eshal.ai",
58669
+ target: "_blank",
58670
+ rel: "noopener noreferrer",
58671
+ className: "no-underline",
58672
+ children: /*#__PURE__*/jsxRuntimeExports.jsxs("span", {
58673
+ className: cn("inline-flex items-center gap-1.5 rounded-lg py-1.5 px-3 transition-colors", isDark ? "bg-gray-800/50 border border-gray-700/50 hover:bg-gray-800/80" : "bg-gray-100/80 border border-gray-200/50 hover:bg-gray-100"),
58674
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("span", {
58675
+ className: cn("font-sans text-[10px] font-medium", isDark ? "text-gray-400" : "text-gray-500"),
58676
+ children: "Powered by"
58677
+ }), !logoImageError ? /*#__PURE__*/jsxRuntimeExports.jsx("img", {
58678
+ src: ASSETS.BRAND.LOGOS.FULL.LIGHT,
58679
+ alt: "ESHAL",
58680
+ className: cn("h-3", isDark ? "brightness-0 invert opacity-60" : "brightness-0 opacity-50"),
58681
+ onError: () => setLogoImageError(true)
58682
+ }) : /*#__PURE__*/jsxRuntimeExports.jsx("span", {
58683
+ className: cn("font-sans text-[10px] font-semibold", isDark ? "text-gray-300" : "text-gray-600"),
58684
+ children: "ESHAL"
58685
+ })]
58686
+ })
58687
+ })
58174
58688
  })]
58175
58689
  });
58176
58690
  };
@@ -58328,8 +58842,8 @@
58328
58842
  children: isDark ? /*#__PURE__*/jsxRuntimeExports.jsx(Sun, {
58329
58843
  className: "w-3.5 h-3.5",
58330
58844
  strokeWidth: 1.6
58331
- }) : /*#__PURE__*/jsxRuntimeExports.jsx(Moon, {
58332
- className: "w-3.5 h-3.5",
58845
+ }) : /*#__PURE__*/jsxRuntimeExports.jsx(SunMoon, {
58846
+ className: "w-4 h-4",
58333
58847
  strokeWidth: 1.6
58334
58848
  })
58335
58849
  }), /*#__PURE__*/jsxRuntimeExports.jsx("span", {
@@ -58353,6 +58867,149 @@
58353
58867
  });
58354
58868
  };
58355
58869
 
58870
+ const OnboardingForm = _ref => {
58871
+ let {
58872
+ questions = [],
58873
+ collapsiblePrompt,
58874
+ onSubmit,
58875
+ primaryColor = "#2563eb",
58876
+ isRtl = false,
58877
+ isDark = false
58878
+ } = _ref;
58879
+ const [formData, setFormData] = reactExports.useState({});
58880
+ const [errors, setErrors] = reactExports.useState({});
58881
+ const [isSubmitting, setIsSubmitting] = reactExports.useState(false);
58882
+ const sortedQuestions = [...questions].sort((a, b) => getOnboardingFieldOrder(a.fieldType) - getOnboardingFieldOrder(b.fieldType));
58883
+ const handleChange = (key, value) => {
58884
+ setFormData(prev => _objectSpread2(_objectSpread2({}, prev), {}, {
58885
+ [key]: value
58886
+ }));
58887
+ if (errors[key]) {
58888
+ setErrors(prev => {
58889
+ const next = _objectSpread2({}, prev);
58890
+ delete next[key];
58891
+ return next;
58892
+ });
58893
+ }
58894
+ };
58895
+ const validate = () => {
58896
+ const newErrors = {};
58897
+ let isValid = true;
58898
+ sortedQuestions.forEach(q => {
58899
+ var _formData$key;
58900
+ const key = q.fieldType || "question";
58901
+ const value = ((_formData$key = formData[key]) !== null && _formData$key !== void 0 ? _formData$key : "").trim();
58902
+ const label = q.collectionPrompt || q.askToType || q.question || q.label || key;
58903
+ const isRequired = q.required === true || q.required === "true";
58904
+ if (!value) {
58905
+ if (isRequired) {
58906
+ if (key === "email") newErrors[key] = "Email is required";else if (key === "fullName" || key === "name") newErrors[key] = "Name is required";else if (key === "phone" || key === "mobileno") newErrors[key] = "Phone number is required";else newErrors[key] = "".concat(label, " is required");
58907
+ isValid = false;
58908
+ }
58909
+ } else {
58910
+ if (key === "fullName" || key === "name") {
58911
+ if (value.length < 2) {
58912
+ newErrors[key] = "Please enter a valid name";
58913
+ isValid = false;
58914
+ }
58915
+ }
58916
+ if (key === "email" && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
58917
+ newErrors[key] = "Please enter a valid email address";
58918
+ isValid = false;
58919
+ }
58920
+ if ((key === "phone" || key === "mobileno") && !/^[+]?[\d\s-]{8,15}$/.test(value)) {
58921
+ newErrors[key] = "Please enter a valid phone number";
58922
+ isValid = false;
58923
+ }
58924
+ }
58925
+ });
58926
+ setErrors(newErrors);
58927
+ return isValid;
58928
+ };
58929
+ const handleSubmit = async e => {
58930
+ e.preventDefault();
58931
+ if (!validate()) return;
58932
+ setIsSubmitting(true);
58933
+ try {
58934
+ await onSubmit(formData);
58935
+ } finally {
58936
+ setIsSubmitting(false);
58937
+ }
58938
+ };
58939
+ return /*#__PURE__*/jsxRuntimeExports.jsx("div", {
58940
+ className: "flex flex-col items-center justify-center p-5 h-full min-h-0 z-50 relative ".concat(isDark ? "" : "bg-gray-50"),
58941
+ style: isDark ? {
58942
+ backgroundColor: "#10141C"
58943
+ } : undefined,
58944
+ children: /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
58945
+ className: "w-full max-w-sm rounded-2xl p-6 transition-colors duration-300 ".concat(isDark ? "shadow-lg" : "bg-white shadow-[0_4px_20px_rgba(0,0,0,0.08)] border border-gray-100"),
58946
+ style: isDark ? {
58947
+ backgroundColor: "#1E232B",
58948
+ border: "1px solid #2A303C",
58949
+ borderRadius: "14px"
58950
+ } : undefined,
58951
+ children: [collapsiblePrompt && /*#__PURE__*/jsxRuntimeExports.jsx("div", {
58952
+ className: "mb-5 text-left",
58953
+ children: /*#__PURE__*/jsxRuntimeExports.jsx("h3", {
58954
+ className: "transition-colors duration-300 ".concat(isDark ? "text-white font-bold text-lg" : "text-base font-medium text-[#4A5568]"),
58955
+ children: collapsiblePrompt
58956
+ })
58957
+ }), /*#__PURE__*/jsxRuntimeExports.jsxs("form", {
58958
+ onSubmit: handleSubmit,
58959
+ className: "space-y-4",
58960
+ noValidate: true,
58961
+ children: [sortedQuestions.map((q, index) => {
58962
+ var _formData$key2;
58963
+ const key = q.fieldType || "question_".concat(index);
58964
+ const label = q.collectionPrompt || q.askToType || q.question || q.label;
58965
+ if (!(label !== null && label !== void 0 && label.trim())) return null;
58966
+ let type = "text";
58967
+ if (key === "email") type = "email";
58968
+ if (key === "phone" || key === "mobileno") type = "tel";
58969
+ const hasError = errors[key];
58970
+ const inputBase = "w-full h-12 rounded-lg text-[15px] px-4 outline-none border transition-colors focus:ring-0 ".concat(isDark ? "text-white placeholder:text-[#A2A9B2] focus:border-[#5A6069]" : "bg-white text-gray-900 placeholder:text-[#8C8C8C] focus:border-[#B0B0B0]");
58971
+ const inputError = hasError ? "!border-red-500 focus:!border-red-500" : "";
58972
+ return /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
58973
+ className: "space-y-1",
58974
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("input", {
58975
+ placeholder: label,
58976
+ type: type,
58977
+ value: (_formData$key2 = formData[key]) !== null && _formData$key2 !== void 0 ? _formData$key2 : "",
58978
+ onChange: e => handleChange(key, e.target.value),
58979
+ className: "".concat(inputBase, " ").concat(inputError),
58980
+ style: _objectSpread2({
58981
+ direction: isRtl ? "rtl" : "ltr"
58982
+ }, isDark ? {
58983
+ backgroundColor: "#272C35",
58984
+ borderWidth: "1px",
58985
+ borderStyle: "solid",
58986
+ borderColor: hasError ? undefined : "#3F444C"
58987
+ } : {
58988
+ borderWidth: "1px",
58989
+ borderStyle: "solid",
58990
+ borderColor: hasError ? undefined : "#E0E0E0"
58991
+ })
58992
+ }), hasError && /*#__PURE__*/jsxRuntimeExports.jsx("p", {
58993
+ className: "text-xs text-red-500 px-1",
58994
+ children: errors[key]
58995
+ })]
58996
+ }, key);
58997
+ }), /*#__PURE__*/jsxRuntimeExports.jsx("button", {
58998
+ type: "submit",
58999
+ disabled: isSubmitting,
59000
+ className: "w-full h-12 text-sm border-none font-semibold shadow-lg hover:shadow-xl hover:scale-[1.02] active:scale-[0.98] transition-all rounded-xl mt-4 text-white",
59001
+ style: {
59002
+ backgroundColor: primaryColor
59003
+ },
59004
+ children: isSubmitting ? /*#__PURE__*/jsxRuntimeExports.jsx(LoaderCircle, {
59005
+ className: "w-5 h-5 animate-spin"
59006
+ }) : "Start Chat"
59007
+ })]
59008
+ })]
59009
+ })
59010
+ });
59011
+ };
59012
+
58356
59013
  /**
58357
59014
  * Auto-scroll hook that scrolls to bottom when dependencies change
58358
59015
  */
@@ -58399,6 +59056,174 @@
58399
59056
  }, [containerRef, enabled, threshold, behavior, delay, ...dependencies]);
58400
59057
  }
58401
59058
 
59059
+ const EMOJI_RATINGS = [{
59060
+ value: "😡",
59061
+ label: "😡",
59062
+ bg: "bg-red-200"
59063
+ }, {
59064
+ value: "😕",
59065
+ label: "😕",
59066
+ bg: "bg-orange-200"
59067
+ }, {
59068
+ value: "😐",
59069
+ label: "😐",
59070
+ bg: "bg-yellow-200"
59071
+ }, {
59072
+ value: "😊",
59073
+ label: "😊",
59074
+ bg: "bg-green-200"
59075
+ }, {
59076
+ value: "😍",
59077
+ label: "😍",
59078
+ bg: "bg-pink-200"
59079
+ }];
59080
+ const THUMBS_RATINGS = [{
59081
+ value: "positive",
59082
+ label: "👍"
59083
+ }, {
59084
+ value: "negative",
59085
+ label: "👎"
59086
+ }];
59087
+ const NUMERIC_RATINGS = [{
59088
+ value: "1",
59089
+ label: "1"
59090
+ }, {
59091
+ value: "2",
59092
+ label: "2"
59093
+ }, {
59094
+ value: "3",
59095
+ label: "3"
59096
+ }, {
59097
+ value: "4",
59098
+ label: "4"
59099
+ }, {
59100
+ value: "5",
59101
+ label: "5"
59102
+ }];
59103
+ const STARS_RATINGS = [{
59104
+ value: "1",
59105
+ label: "⭐"
59106
+ }, {
59107
+ value: "2",
59108
+ label: "⭐"
59109
+ }, {
59110
+ value: "3",
59111
+ label: "⭐"
59112
+ }, {
59113
+ value: "4",
59114
+ label: "⭐"
59115
+ }, {
59116
+ value: "5",
59117
+ label: "⭐"
59118
+ }];
59119
+ const CSATWidget = _ref => {
59120
+ let {
59121
+ format = "EMOJI",
59122
+ prompt = "How was your experience?",
59123
+ onRating,
59124
+ disabled = false,
59125
+ isDark = false,
59126
+ primaryColor = "#2563eb",
59127
+ agentMessageBubbleFontSize = "14px",
59128
+ agentMessageBubbleFontFamily = "Inter"
59129
+ } = _ref;
59130
+ const [selectedRating, setSelectedRating] = reactExports.useState(null);
59131
+ const [isSubmitting, setIsSubmitting] = reactExports.useState(false);
59132
+ const selectedRatingNumber = selectedRating ? Number(selectedRating) : 0;
59133
+ const getRatings = () => {
59134
+ switch (format) {
59135
+ case "THUMBS":
59136
+ return THUMBS_RATINGS;
59137
+ case "NUMERIC":
59138
+ return NUMERIC_RATINGS;
59139
+ case "STARS":
59140
+ return STARS_RATINGS;
59141
+ case "EMOJI":
59142
+ default:
59143
+ return EMOJI_RATINGS;
59144
+ }
59145
+ };
59146
+ const handleRating = async value => {
59147
+ if (disabled || isSubmitting) return;
59148
+ setSelectedRating(value);
59149
+ setIsSubmitting(true);
59150
+ try {
59151
+ if (onRating) {
59152
+ onRating(value, format);
59153
+ }
59154
+ } finally {
59155
+ setIsSubmitting(false);
59156
+ }
59157
+ };
59158
+ const ratings = getRatings();
59159
+ return /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
59160
+ className: cn("transition-all duration-200 rounded-xl px-4 ", isDark ? "bg-slate-800/50" : "bg-slate-50/50"),
59161
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("p", {
59162
+ className: cn("text-sm font-semibold text-center mb-3", isDark ? "text-gray-300" : "text-gray-500/80"),
59163
+ style: {
59164
+ fontFamily: agentMessageBubbleFontFamily,
59165
+ fontSize: agentMessageBubbleFontSize
59166
+ },
59167
+ children: prompt
59168
+ }), /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
59169
+ className: "flex justify-center items-center",
59170
+ children: [format === "EMOJI" && /*#__PURE__*/jsxRuntimeExports.jsx("div", {
59171
+ className: "flex gap-2 justify-center items-center",
59172
+ children: ratings.map(rating => /*#__PURE__*/jsxRuntimeExports.jsx("button", {
59173
+ onClick: () => handleRating(rating.value),
59174
+ disabled: disabled || isSubmitting,
59175
+ className: cn("flex items-center justify-center text-2xl transition-transform", "bg-transparent border-0 p-0 cursor-pointer", "hover:scale-110 active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed", "focus:outline-none focus:ring-0", selectedRating === rating.value ? "" : "opacity-80"),
59176
+ style: {},
59177
+ children: /*#__PURE__*/jsxRuntimeExports.jsx("span", {
59178
+ role: "img",
59179
+ "aria-label": "emoji",
59180
+ children: rating.label
59181
+ })
59182
+ }, rating.value))
59183
+ }), format === "THUMBS" && /*#__PURE__*/jsxRuntimeExports.jsx("div", {
59184
+ className: "flex gap-6 justify-center items-center",
59185
+ children: ratings.map(rating => /*#__PURE__*/jsxRuntimeExports.jsx("button", {
59186
+ onClick: () => handleRating(rating.value),
59187
+ disabled: disabled || isSubmitting,
59188
+ className: cn("w-10 h-10 rounded-xl border flex items-center justify-center shadow-md text-2xl transition-all", "hover:scale-105 active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed", "drop-shadow-md", isDark ? "bg-gray-700 border-gray-600 hover:bg-gray-600" : "bg-white border-gray-100 hover:bg-gray-50", selectedRating === rating.value && "ring-2 ring-blue-300 scale-110"),
59189
+ style: {
59190
+ borderColor: selectedRating === rating.value ? primaryColor : undefined
59191
+ },
59192
+ children: /*#__PURE__*/jsxRuntimeExports.jsx("span", {
59193
+ className: "drop-shadow-md",
59194
+ children: rating.label
59195
+ })
59196
+ }, rating.value))
59197
+ }), format === "NUMERIC" && /*#__PURE__*/jsxRuntimeExports.jsx("div", {
59198
+ className: "flex gap-2 justify-center items-center",
59199
+ children: ratings.map(rating => /*#__PURE__*/jsxRuntimeExports.jsx("button", {
59200
+ onClick: () => handleRating(rating.value),
59201
+ disabled: disabled || isSubmitting,
59202
+ className: cn("w-10 h-10 rounded-lg flex items-center justify-center text-sm font-semibold transition-all", "hover:scale-105 active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed", selectedRating === rating.value ? "ring-2 scale-110 shadow-md text-white" : isDark ? "bg-gray-700 border border-gray-600 text-gray-300 hover:bg-gray-600" : "bg-white border border-gray-200 text-gray-700 hover:bg-gray-50"),
59203
+ style: {
59204
+ backgroundColor: selectedRating === rating.value ? primaryColor : undefined,
59205
+ borderColor: selectedRating === rating.value ? primaryColor : undefined
59206
+ },
59207
+ children: rating.label
59208
+ }, rating.value))
59209
+ }), format === "STARS" && /*#__PURE__*/jsxRuntimeExports.jsx("div", {
59210
+ className: "flex gap-2 justify-center items-center",
59211
+ children: ratings.map(rating => /*#__PURE__*/jsxRuntimeExports.jsx("button", {
59212
+ onClick: () => handleRating(rating.value),
59213
+ disabled: disabled || isSubmitting,
59214
+ className: cn("flex items-center justify-center text-2xl transition-all duration-200", "bg-transparent border-0 p-0 cursor-pointer focus:outline-none", "hover:scale-125 active:scale-110 disabled:opacity-50 disabled:cursor-not-allowed", selectedRatingNumber >= Number(rating.value) ? "text-yellow-400 drop-shadow-sm" : "text-gray-300"),
59215
+ children: /*#__PURE__*/jsxRuntimeExports.jsx("span", {
59216
+ children: rating.label
59217
+ })
59218
+ }, rating.value))
59219
+ })]
59220
+ }), isSubmitting && /*#__PURE__*/jsxRuntimeExports.jsx("p", {
59221
+ className: cn("text-xs mt-3 text-center", isDark ? "text-slate-400" : "text-slate-500"),
59222
+ children: "Submitting feedback..."
59223
+ })]
59224
+ });
59225
+ };
59226
+
58402
59227
  const DEFAULT_AGENT_BUBBLE_COLOR = "#ffffff";
58403
59228
  const DEFAULT_USER_MESSAGE_COLOR = "#f5f5f5";
58404
59229
  const DEFAULT_TEXT_COLOR = "#000000";
@@ -58440,6 +59265,7 @@
58440
59265
  onMinimize,
58441
59266
  onClose,
58442
59267
  quickQuestions = [],
59268
+ quickQuestionsEnabled,
58443
59269
  onQuickQuestion,
58444
59270
  quickQuestionsLayout = "vertical",
58445
59271
  agentMessageBubbleColor,
@@ -58468,12 +59294,26 @@
58468
59294
  apiBaseUrl,
58469
59295
  apiKey,
58470
59296
  organizationId,
59297
+ conversationId,
59298
+ conciergeId,
58471
59299
  onboardingQuestions = [],
58472
59300
  onboardingActive = false,
58473
- onboardingCompleted = false
59301
+ onboardingCompleted = false,
59302
+ onOnboardingFormSubmit,
59303
+ collectionPrompt,
59304
+ // CSAT configuration
59305
+ csatEnabled = false,
59306
+ csatFormat = "EMOJI",
59307
+ csatPrompt = "How was your experience?",
59308
+ csatTriggerType = "ON_END",
59309
+ csatIdleTimeoutMins = 30,
59310
+ onPromptSuggestionClick,
59311
+ onboardingEnabled = false
58474
59312
  } = _ref;
58475
59313
  useGoogleFont(fontFamily);
58476
59314
  const messagesContainerRef = reactExports.useRef(null);
59315
+ const [showCsat, setShowCsat] = reactExports.useState(false);
59316
+ const [csatSubmitted, setCsatSubmitted] = reactExports.useState(false);
58477
59317
 
58478
59318
  // Auto-scroll hook
58479
59319
  useAutoScroll(messagesContainerRef, [messages, isLoading], {
@@ -58511,13 +59351,64 @@
58511
59351
  }
58512
59352
  return userMessageBoxColor || DEFAULT_USER_MESSAGE_COLOR;
58513
59353
  }, [isDark, primaryColor, userMessageBoxColor]);
58514
- const placeholder = isRtlLanguage ? "اكتب رسالتك هنا..." : "Try Your Own Message...";
59354
+ const placeholder = isRtlLanguage ? "اكتب رسالتك هنا" : "Type your message here";
58515
59355
  const hasUserMessages = messages === null || messages === void 0 || (_messages$some = messages.some) === null || _messages$some === void 0 ? void 0 : _messages$some.call(messages, msg => msg.role === "user");
58516
- const shouldShowQuickQuestions = !hasUserMessages && quickQuestions.length > 0;
59356
+ const shouldShowQuickQuestions = !hasUserMessages && quickQuestions.length > 0 && quickQuestionsEnabled;
59357
+
59358
+ // Show CSAT when the last assistant message is marked as concluded
59359
+ reactExports.useEffect(() => {
59360
+ if (!csatEnabled) return;
59361
+ if (csatSubmitted) return;
59362
+ if (!messages || messages.length === 0) return;
59363
+ const lastMessage = messages[messages.length - 1];
59364
+ if (lastMessage && lastMessage.role === "assistant" && lastMessage.conclusionDetected && !showCsat && csatTriggerType === "ON_END") {
59365
+ setShowCsat(true);
59366
+ }
59367
+ }, [messages, csatEnabled, csatSubmitted, showCsat, csatTriggerType]);
59368
+ const handleCsatRating = async (rating, format) => {
59369
+ setCsatSubmitted(true); // optimistic UI
59370
+ setShowCsat(false);
59371
+ try {
59372
+ const headers = {
59373
+ "Content-Type": "application/json"
59374
+ };
59375
+ if (organizationId) {
59376
+ headers["x-eshal-org"] = organizationId;
59377
+ }
59378
+ const response = await fetch("".concat(apiBaseUrl.replace(/\/$/, ""), "/api/v1/support/csat"), {
59379
+ method: "POST",
59380
+ headers,
59381
+ credentials: "include",
59382
+ body: JSON.stringify({
59383
+ conversationId,
59384
+ rating,
59385
+ ratingFormat: format,
59386
+ organizationId,
59387
+ conciergeId
59388
+ })
59389
+ });
59390
+ if (!response.ok) {
59391
+ console.error("CSAT submission failed:", await response.text());
59392
+ }
59393
+ } catch (error) {
59394
+ console.error("CSAT submission error:", error);
59395
+ }
59396
+ };
59397
+ const latestPromptSuggestions = reactExports.useMemo(() => {
59398
+ if (!messages || !Array.isArray(messages)) return [];
59399
+ for (let i = messages.length - 1; i >= 0; i -= 1) {
59400
+ const msg = messages[i];
59401
+ if ((msg === null || msg === void 0 ? void 0 : msg.role) === "assistant" && Array.isArray(msg.prompts) && msg.prompts.length > 0) {
59402
+ return msg.prompts;
59403
+ }
59404
+ }
59405
+ return [];
59406
+ }, [messages]);
58517
59407
  if (!isOpen) {
58518
59408
  return null;
58519
59409
  }
58520
59410
  return /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
59411
+ dir: isRtlLanguage ? "rtl" : "ltr",
58521
59412
  className: "".concat(isMinimized ? "w-80" : "w-[380px]", " max-w-[92vw] flex-shrink-0 border rounded-2xl shadow-2xl bg-white border-gray-200 flex flex-col ").concat(isMinimized ? "h-auto" : "h-[650px] max-h-[85vh]", " overflow-hidden z-50 ").concat(isDark ? "bg-gray-900 border-gray-700" : ""),
58522
59413
  children: [/*#__PURE__*/jsxRuntimeExports.jsx(ChatHeader, {
58523
59414
  conciergeName: conciergeName,
@@ -58535,10 +59426,18 @@
58535
59426
  headerTextBold: headerTextBold,
58536
59427
  headerTextItalic: headerTextItalic
58537
59428
  }), !isMinimized && /*#__PURE__*/jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
58538
- children: [/*#__PURE__*/jsxRuntimeExports.jsx("div", {
59429
+ children: [/*#__PURE__*/jsxRuntimeExports.jsxs("div", {
58539
59430
  ref: messagesContainerRef,
58540
59431
  className: "chat-messages flex-1 overflow-y-auto px-5 py-4 space-y-4 ".concat(isDark ? "bg-gray-900" : "bg-gradient-to-b from-gray-50/50 to-white", " break-words"),
58541
- children: /*#__PURE__*/jsxRuntimeExports.jsx(MessageList, {
59432
+ children: [onboardingActive && !onboardingCompleted && onOnboardingFormSubmit ? /*#__PURE__*/jsxRuntimeExports.jsx(OnboardingForm, {
59433
+ questions: onboardingQuestions,
59434
+ onPromptSuggestionClick: onPromptSuggestionClick !== null && onPromptSuggestionClick !== void 0 ? onPromptSuggestionClick : text => onDirectSend === null || onDirectSend === void 0 ? void 0 : onDirectSend(text),
59435
+ collapsiblePrompt: collectionPrompt,
59436
+ onSubmit: onOnboardingFormSubmit,
59437
+ primaryColor: primaryColor,
59438
+ isRtl: isRtlLanguage,
59439
+ isDark: isDark
59440
+ }) : /*#__PURE__*/jsxRuntimeExports.jsx(MessageList, {
58542
59441
  messages: messages,
58543
59442
  isDark: isDark,
58544
59443
  primaryColor: primaryColor,
@@ -58571,9 +59470,30 @@
58571
59470
  messagesContainerRef: messagesContainerRef,
58572
59471
  companyLogo: companyLogo,
58573
59472
  conciergeName: conciergeName,
58574
- companyName: companyName
58575
- })
58576
- }), /*#__PURE__*/jsxRuntimeExports.jsx(ChatInput, {
59473
+ companyName: companyName,
59474
+ apiBaseUrl: apiBaseUrl,
59475
+ organizationId: organizationId
59476
+ }), showCsat && csatEnabled && !csatSubmitted && /*#__PURE__*/jsxRuntimeExports.jsx("div", {
59477
+ className: "",
59478
+ children: /*#__PURE__*/jsxRuntimeExports.jsx(CSATWidget, {
59479
+ format: (() => {
59480
+ const fmt = csatFormat || "Emoji";
59481
+ if (fmt === "Emoji") return "EMOJI";
59482
+ if (fmt === "Thumbs") return "THUMBS";
59483
+ if (fmt === "Stars") return "STARS";
59484
+ if (fmt === "Numeric") return "NUMERIC";
59485
+ return (fmt || "EMOJI").toString().toUpperCase();
59486
+ })(),
59487
+ prompt: csatPrompt || "How was your experience?",
59488
+ onRating: handleCsatRating,
59489
+ disabled: false,
59490
+ isDark: isDark,
59491
+ primaryColor: primaryColor,
59492
+ agentMessageBubbleFontSize: agentMessageBubbleFontSize || fontSize,
59493
+ agentMessageBubbleFontFamily: agentMessageBubbleFontFamily || fontFamily
59494
+ })
59495
+ })]
59496
+ }), !(onboardingActive && !onboardingCompleted) && /*#__PURE__*/jsxRuntimeExports.jsx(ChatInput, {
58577
59497
  inputValue: inputValue,
58578
59498
  setInputValue: setInputValue,
58579
59499
  onSend: onSend,
@@ -58600,7 +59520,12 @@
58600
59520
  showPoweredBy: showPoweredBy,
58601
59521
  onboardingQuestions: onboardingQuestions,
58602
59522
  onboardingActive: onboardingActive,
58603
- onboardingCompleted: onboardingCompleted
59523
+ onboardingCompleted: onboardingCompleted,
59524
+ onboardingEnabled: onboardingEnabled,
59525
+ userMessageBoxColor: userMessageBoxColor,
59526
+ userTextColor: userTextColor,
59527
+ promptSuggestions: latestPromptSuggestions,
59528
+ onPromptSuggestionClick: onPromptSuggestionClick !== null && onPromptSuggestionClick !== void 0 ? onPromptSuggestionClick : text => onDirectSend === null || onDirectSend === void 0 ? void 0 : onDirectSend(text)
58604
59529
  })]
58605
59530
  })]
58606
59531
  });
@@ -58700,6 +59625,7 @@
58700
59625
  };
58701
59626
 
58702
59627
  const ChatWidget = _ref => {
59628
+ var _agentConfig$concierg;
58703
59629
  let {
58704
59630
  // Required props for dynamic config
58705
59631
  orgId,
@@ -58713,6 +59639,7 @@
58713
59639
  companyLogo,
58714
59640
  welcomeMessage,
58715
59641
  quickQuestions,
59642
+ quickQuestionsEnabled,
58716
59643
  quickQuestionsLayout = "vertical",
58717
59644
  textColor,
58718
59645
  agentMessageBubbleColor,
@@ -58771,7 +59698,7 @@
58771
59698
 
58772
59699
  // Map API response to widget props (use props as overrides if provided)
58773
59700
  const widgetConfig = reactExports.useMemo(() => {
58774
- var _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9, _ref0, _ref1, _ref10, _ref11, _ref12, _ref13, _ref14, _ref15, _ref16, _ref17, _ref18, _ref19, _ref20, _ref21, _ref22, _ref23, _ref24, _ref25, _ref26, _ref27, _ref28, _ref29, _ref30, _ref31, _ref32, _ref33, _ref34, _ref35;
59701
+ var _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9, _ref0, _ref1, _ref10, _ref11, _ref12, _ref13, _ref14, _ref15, _ref16, _ref17, _ref18, _ref19, _ref20, _ref21, _ref22, _ref23, _ref24, _ref25, _ref26, _ref27, _ref28, _ref29, _ref30, _ref31, _ref32, _ref33, _ref34, _ref35, _agentConfig$csatEnab, _agentConfig$csatForm, _agentConfig$csatProm, _agentConfig$csatTrig, _agentConfig$csatIdle, _agentConfig$csatFoll, _agentConfig$csatFoll2;
58775
59702
  if (!agentConfig) {
58776
59703
  return null;
58777
59704
  }
@@ -58784,6 +59711,7 @@
58784
59711
  companyLogo: (_ref5 = companyLogo !== null && companyLogo !== void 0 ? companyLogo : agentConfig.avatar) !== null && _ref5 !== void 0 ? _ref5 : null,
58785
59712
  welcomeMessage: (_ref6 = welcomeMessage !== null && welcomeMessage !== void 0 ? welcomeMessage : agentConfig.welcomeMessage) !== null && _ref6 !== void 0 ? _ref6 : "Hi! How can we help?",
58786
59713
  quickQuestions: (_ref7 = quickQuestions !== null && quickQuestions !== void 0 ? quickQuestions : agentConfig.quickQuestions) !== null && _ref7 !== void 0 ? _ref7 : [],
59714
+ quickQuestionsEnabled: quickQuestionsEnabled !== null && quickQuestionsEnabled !== void 0 ? quickQuestionsEnabled : agentConfig.quickQuestionsEnabled,
58787
59715
  textColor: (_ref8 = textColor !== null && textColor !== void 0 ? textColor : agentConfig.textColor) !== null && _ref8 !== void 0 ? _ref8 : "#000000",
58788
59716
  agentMessageBubbleColor: agentMessageBubbleColor !== null && agentMessageBubbleColor !== void 0 ? agentMessageBubbleColor : agentConfig.agentMessageBubbleColor,
58789
59717
  userMessageBoxColor: userMessageBoxColor !== null && userMessageBoxColor !== void 0 ? userMessageBoxColor : agentConfig.userMessageBoxColor,
@@ -58807,9 +59735,20 @@
58807
59735
  agentMessageBubbleFontFamily: (_ref24 = (_ref25 = (_ref26 = agentMessageBubbleFontFamily !== null && agentMessageBubbleFontFamily !== void 0 ? agentMessageBubbleFontFamily : agentConfig.agentMessageBubbleFontFamily) !== null && _ref26 !== void 0 ? _ref26 : fontFamily) !== null && _ref25 !== void 0 ? _ref25 : agentConfig.fontFamily) !== null && _ref24 !== void 0 ? _ref24 : "Inter",
58808
59736
  agentMessageBubbleFontSize: (_ref27 = (_ref28 = (_ref29 = agentMessageBubbleFontSize !== null && agentMessageBubbleFontSize !== void 0 ? agentMessageBubbleFontSize : agentConfig.agentMessageBubbleFontSize) !== null && _ref29 !== void 0 ? _ref29 : fontSize) !== null && _ref28 !== void 0 ? _ref28 : agentConfig.fontSize) !== null && _ref27 !== void 0 ? _ref27 : "14px",
58809
59737
  userMessageBubbleFontFamily: (_ref30 = (_ref31 = (_ref32 = userMessageBubbleFontFamily !== null && userMessageBubbleFontFamily !== void 0 ? userMessageBubbleFontFamily : agentConfig.userMessageBubbleFontFamily) !== null && _ref32 !== void 0 ? _ref32 : fontFamily) !== null && _ref31 !== void 0 ? _ref31 : agentConfig.fontFamily) !== null && _ref30 !== void 0 ? _ref30 : "Inter",
58810
- userMessageBubbleFontSize: (_ref33 = (_ref34 = (_ref35 = userMessageBubbleFontSize !== null && userMessageBubbleFontSize !== void 0 ? userMessageBubbleFontSize : agentConfig.userMessageBubbleFontSize) !== null && _ref35 !== void 0 ? _ref35 : fontSize) !== null && _ref34 !== void 0 ? _ref34 : agentConfig.fontSize) !== null && _ref33 !== void 0 ? _ref33 : "14px"
59738
+ userMessageBubbleFontSize: (_ref33 = (_ref34 = (_ref35 = userMessageBubbleFontSize !== null && userMessageBubbleFontSize !== void 0 ? userMessageBubbleFontSize : agentConfig.userMessageBubbleFontSize) !== null && _ref35 !== void 0 ? _ref35 : fontSize) !== null && _ref34 !== void 0 ? _ref34 : agentConfig.fontSize) !== null && _ref33 !== void 0 ? _ref33 : "14px",
59739
+ // CSAT configuration (feature flags + text)
59740
+ csatEnabled: (_agentConfig$csatEnab = agentConfig.csatEnabled) !== null && _agentConfig$csatEnab !== void 0 ? _agentConfig$csatEnab : false,
59741
+ csatFormat: (_agentConfig$csatForm = agentConfig.csatFormat) !== null && _agentConfig$csatForm !== void 0 ? _agentConfig$csatForm : "EMOJI",
59742
+ csatPrompt: (_agentConfig$csatProm = agentConfig.csatPrompt) !== null && _agentConfig$csatProm !== void 0 ? _agentConfig$csatProm : "How was your experience?",
59743
+ csatTriggerType: (_agentConfig$csatTrig = agentConfig.csatTriggerType) !== null && _agentConfig$csatTrig !== void 0 ? _agentConfig$csatTrig : "ON_END",
59744
+ csatIdleTimeoutMins: (_agentConfig$csatIdle = agentConfig.csatIdleTimeoutMins) !== null && _agentConfig$csatIdle !== void 0 ? _agentConfig$csatIdle : 30,
59745
+ csatFollowUpEnabled: (_agentConfig$csatFoll = agentConfig.csatFollowUpEnabled) !== null && _agentConfig$csatFoll !== void 0 ? _agentConfig$csatFoll : false,
59746
+ csatFollowUpPrompt: (_agentConfig$csatFoll2 = agentConfig.csatFollowUpPrompt) !== null && _agentConfig$csatFoll2 !== void 0 ? _agentConfig$csatFoll2 : null
58811
59747
  };
58812
- }, [agentConfig, darkMode, primaryColor, position, companyName, conciergeName, companyLogo, welcomeMessage, quickQuestions, textColor, agentMessageBubbleColor, userMessageBoxColor, assistantTextColor, userTextColor, fontFamily, fontSize, defaultLanguage, orgId, headerTextBold, headerTextItalic, enableVoiceInteraction, disclaimerText, disclaimerPosition, showPoweredBy, onboardingQuestions, onboardingEnabled, collectionPrompt, allowedDomains, agentMessageBubbleFontFamily, agentMessageBubbleFontSize, userMessageBubbleFontFamily, userMessageBubbleFontSize]);
59748
+ }, [agentConfig, darkMode, primaryColor, position, companyName, conciergeName, companyLogo, welcomeMessage, quickQuestions, quickQuestionsEnabled, textColor, agentMessageBubbleColor, userMessageBoxColor, assistantTextColor, userTextColor, fontFamily, fontSize, defaultLanguage, orgId, headerTextBold, headerTextItalic, enableVoiceInteraction, disclaimerText, disclaimerPosition, showPoweredBy, onboardingQuestions, onboardingEnabled, collectionPrompt, allowedDomains, agentMessageBubbleFontFamily, agentMessageBubbleFontSize, userMessageBubbleFontFamily, userMessageBubbleFontSize
59749
+ // CSAT dependencies
59750
+ // (kept minimal because these come from agentConfig)
59751
+ ]);
58813
59752
 
58814
59753
  // Check if current domain is allowed
58815
59754
  const isAllowed = reactExports.useMemo(() => {
@@ -58859,7 +59798,9 @@
58859
59798
  handleVoiceToggle,
58860
59799
  sendBidiTextMessage,
58861
59800
  onboardingActive,
58862
- onboardingCompleted
59801
+ onboardingCompleted,
59802
+ handleOnboardingFormSubmit,
59803
+ conversationId
58863
59804
  } = useChatState(widgetConfig ? {
58864
59805
  welcomeMessage: widgetConfig.welcomeMessage,
58865
59806
  quickQuestions: widgetConfig.quickQuestions,
@@ -58927,6 +59868,7 @@
58927
59868
  onMinimize: toggleMinimize,
58928
59869
  onClose: closeChat,
58929
59870
  quickQuestions: widgetConfig.quickQuestions,
59871
+ quickQuestionsEnabled: widgetConfig.quickQuestionsEnabled,
58930
59872
  onQuickQuestion: handleQuickQuestion,
58931
59873
  quickQuestionsLayout: quickQuestionsLayout,
58932
59874
  agentMessageBubbleColor: widgetConfig.agentMessageBubbleColor,
@@ -58955,9 +59897,19 @@
58955
59897
  apiBaseUrl: apiBaseUrl,
58956
59898
  apiKey: apiKey,
58957
59899
  organizationId: widgetConfig.organizationId,
59900
+ conversationId: conversationId,
59901
+ conciergeId: (_agentConfig$concierg = agentConfig === null || agentConfig === void 0 ? void 0 : agentConfig.conciergeId) !== null && _agentConfig$concierg !== void 0 ? _agentConfig$concierg : agentConfig === null || agentConfig === void 0 ? void 0 : agentConfig.id,
58958
59902
  onboardingQuestions: widgetConfig.onboardingQuestions,
58959
59903
  onboardingActive: onboardingActive,
58960
- onboardingCompleted: onboardingCompleted
59904
+ onboardingCompleted: onboardingCompleted,
59905
+ onOnboardingFormSubmit: handleOnboardingFormSubmit,
59906
+ collectionPrompt: widgetConfig.collectionPrompt,
59907
+ csatEnabled: widgetConfig.csatEnabled,
59908
+ csatFormat: widgetConfig.csatFormat,
59909
+ csatPrompt: widgetConfig.csatPrompt,
59910
+ csatTriggerType: widgetConfig.csatTriggerType,
59911
+ csatIdleTimeoutMins: widgetConfig.csatIdleTimeoutMins,
59912
+ onboardingEnabled: widgetConfig.onboardingEnabled
58961
59913
  }), !isOpen && /*#__PURE__*/jsxRuntimeExports.jsx(ToggleButton, {
58962
59914
  isOpen: isOpen,
58963
59915
  isDark: isDark,
@@ -59015,9 +59967,9 @@
59015
59967
  onClose: null
59016
59968
  };
59017
59969
  const API = {
59018
- /**
59019
- * Initialize the chat widget
59020
- * @param {Object} options - Configuration options
59970
+ /**
59971
+ * Initialize the chat widget
59972
+ * @param {Object} options - Configuration options
59021
59973
  */
59022
59974
  init: async function () {
59023
59975
  let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -59129,17 +60081,17 @@
59129
60081
  }
59130
60082
  return API;
59131
60083
  },
59132
- /**
59133
- * Update configuration
59134
- * @param {Object} newConfig - New configuration options
60084
+ /**
60085
+ * Update configuration
60086
+ * @param {Object} newConfig - New configuration options
59135
60087
  */
59136
60088
  updateConfig: function (newConfig) {
59137
60089
  config = _objectSpread2(_objectSpread2({}, config), newConfig);
59138
60090
  this.init(config);
59139
60091
  return API;
59140
60092
  },
59141
- /**
59142
- * Open the chat widget
60093
+ /**
60094
+ * Open the chat widget
59143
60095
  */
59144
60096
  open: function () {
59145
60097
  // Trigger open by updating config
@@ -59150,8 +60102,8 @@
59150
60102
  if (config.onOpen) config.onOpen();
59151
60103
  return API;
59152
60104
  },
59153
- /**
59154
- * Close the chat widget
60105
+ /**
60106
+ * Close the chat widget
59155
60107
  */
59156
60108
  close: function () {
59157
60109
  this.updateConfig({
@@ -59160,8 +60112,8 @@
59160
60112
  if (config.onClose) config.onClose();
59161
60113
  return API;
59162
60114
  },
59163
- /**
59164
- * Toggle dark mode
60115
+ /**
60116
+ * Toggle dark mode
59165
60117
  */
59166
60118
  toggleTheme: function () {
59167
60119
  config.darkMode = !config.darkMode;
@@ -59170,8 +60122,8 @@
59170
60122
  });
59171
60123
  return API;
59172
60124
  },
59173
- /**
59174
- * Destroy the widget
60125
+ /**
60126
+ * Destroy the widget
59175
60127
  */
59176
60128
  destroy: function () {
59177
60129
  if (root) {
@@ -59186,8 +60138,8 @@
59186
60138
  config = {};
59187
60139
  return API;
59188
60140
  },
59189
- /**
59190
- * Get current configuration
60141
+ /**
60142
+ * Get current configuration
59191
60143
  */
59192
60144
  getConfig: function () {
59193
60145
  return _objectSpread2({}, config);