@huskel/sdk 0.4.1 → 0.4.2

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.
package/dist/index.mjs CHANGED
@@ -521,6 +521,7 @@ function useChat() {
521
521
  if (!query.trim() || loading) return;
522
522
  (_a = abortRef.current) == null ? void 0 : _a.abort();
523
523
  abortRef.current = new AbortController();
524
+ const signal = abortRef.current.signal;
524
525
  const userMsg = { role: "user", content: query };
525
526
  setMessages((prev) => [...prev, userMsg]);
526
527
  setLoading(true);
@@ -528,20 +529,42 @@ function useChat() {
528
529
  try {
529
530
  const history = messages.map((m) => ({ role: m.role, content: m.content }));
530
531
  const res = await client.api.chat(query, history);
531
- const assistantMsg = { role: "assistant", content: res.answer };
532
- setMessages((prev) => [...prev, assistantMsg]);
532
+ if (signal.aborted) return;
533
+ const fullAnswer = res.answer || "";
534
+ const words = fullAnswer.split(/(\s+)/);
535
+ setMessages((prev) => [...prev, { role: "assistant", content: "" }]);
536
+ let currentContent = "";
537
+ for (const word of words) {
538
+ if (signal.aborted) return;
539
+ currentContent += word;
540
+ setMessages((prev) => {
541
+ const next = [...prev];
542
+ if (next.length > 0) {
543
+ next[next.length - 1] = { role: "assistant", content: currentContent };
544
+ }
545
+ return next;
546
+ });
547
+ await new Promise((resolve) => setTimeout(resolve, 25));
548
+ }
549
+ if (signal.aborted) return;
533
550
  setSources((_b = res.sources) != null ? _b : []);
534
551
  } catch (e) {
552
+ if (signal.aborted) return;
535
553
  setError((_c = e == null ? void 0 : e.message) != null ? _c : "Chat request failed");
536
554
  setMessages((prev) => prev.slice(0, -1));
537
555
  } finally {
538
- setLoading(false);
556
+ if (!signal.aborted) {
557
+ setLoading(false);
558
+ }
539
559
  }
540
560
  }, [client, messages, loading]);
541
561
  const reset = useCallback3(() => {
562
+ var _a;
563
+ (_a = abortRef.current) == null ? void 0 : _a.abort();
542
564
  setMessages([]);
543
565
  setSources([]);
544
566
  setError(null);
567
+ setLoading(false);
545
568
  }, []);
546
569
  return { messages, sources, loading, error, send, reset };
547
570
  }
@@ -830,18 +853,105 @@ function Sparkle({
830
853
 
831
854
  // src/components/ChatWidget.tsx
832
855
  import { useState as useState6, useRef as useRef8, useEffect as useEffect5 } from "react";
833
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
834
- var SparkleIcon2 = () => /* @__PURE__ */ jsx4("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx4("path", { d: "m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z" }) });
856
+
857
+ // src/utils/markdown.tsx
858
+ import { Fragment as Fragment2, jsx as jsx4 } from "react/jsx-runtime";
859
+ var parseInline = (text, keyPrefix) => {
860
+ const tokenRegex = /(\[[^\]]+\]\([^)]+\)|\*\*[^*]+\*\*|`[^`]+`)/g;
861
+ const parts = text.split(tokenRegex);
862
+ return parts.map((part, index) => {
863
+ if (!part) return null;
864
+ const key = `${keyPrefix}-inline-${index}`;
865
+ if (part.startsWith("`") && part.endsWith("`")) {
866
+ return /* @__PURE__ */ jsx4("code", { className: "hsk-markdown-code", children: part.slice(1, -1) }, key);
867
+ }
868
+ if (part.startsWith("**") && part.endsWith("**")) {
869
+ return /* @__PURE__ */ jsx4("strong", { children: parseInline(part.slice(2, -2), key) }, key);
870
+ }
871
+ const linkMatch = part.match(/^\[([^\]]+)\]\(([^)]+)\)$/);
872
+ if (linkMatch) {
873
+ const url = linkMatch[2];
874
+ const isSafeUrl = /^(https?|mailto|tel):/i.test(url) || url.startsWith("/");
875
+ if (isSafeUrl) {
876
+ return /* @__PURE__ */ jsx4("a", { href: url, target: "_blank", rel: "noopener noreferrer", className: "hsk-markdown-link", children: parseInline(linkMatch[1], key) }, key);
877
+ }
878
+ return /* @__PURE__ */ jsx4("span", { children: parseInline(linkMatch[1], key) }, key);
879
+ }
880
+ return part;
881
+ });
882
+ };
883
+ function renderMarkdown(content) {
884
+ const lines = content.split("\n");
885
+ const elements = [];
886
+ let i = 0;
887
+ while (i < lines.length) {
888
+ const line = lines[i];
889
+ const key = `md-line-${i}`;
890
+ if (!line.trim()) {
891
+ i++;
892
+ continue;
893
+ }
894
+ const headerMatch = line.match(/^(#{1,3})\s+(.*)/);
895
+ if (headerMatch) {
896
+ const level = headerMatch[1].length;
897
+ const Tag = `h${level + 3}`;
898
+ elements.push(/* @__PURE__ */ jsx4(Tag, { className: `hsk-markdown-h${level}`, children: parseInline(headerMatch[2], key) }, key));
899
+ i++;
900
+ continue;
901
+ }
902
+ if (line.match(/^[-*]\s+/)) {
903
+ const listItems = [];
904
+ while (i < lines.length && lines[i].match(/^[-*]\s+/)) {
905
+ const itemText = lines[i].replace(/^[-*]\s+/, "");
906
+ listItems.push(/* @__PURE__ */ jsx4("li", { children: parseInline(itemText, `li-${i}`) }, `li-${i}`));
907
+ i++;
908
+ }
909
+ elements.push(/* @__PURE__ */ jsx4("ul", { className: "hsk-markdown-list", children: listItems }, `ul-${key}`));
910
+ continue;
911
+ }
912
+ if (line.trim().startsWith("|")) {
913
+ const tableRows = [];
914
+ let isHeader = true;
915
+ while (i < lines.length && lines[i].trim().startsWith("|")) {
916
+ const rowLine = lines[i].trim();
917
+ if (rowLine.match(/^\|[-:| ]+\|$/)) {
918
+ i++;
919
+ isHeader = false;
920
+ continue;
921
+ }
922
+ const cells = rowLine.split("|").slice(1, -1).map((c) => c.trim());
923
+ const Tag = isHeader ? "th" : "td";
924
+ tableRows.push(
925
+ /* @__PURE__ */ jsx4("tr", { children: cells.map((cell, cIdx) => /* @__PURE__ */ jsx4(Tag, { children: parseInline(cell, `td-${i}-${cIdx}`) }, `td-${i}-${cIdx}`)) }, `tr-${i}`)
926
+ );
927
+ i++;
928
+ }
929
+ elements.push(
930
+ /* @__PURE__ */ jsx4("div", { className: "hsk-table-wrapper", children: /* @__PURE__ */ jsx4("table", { className: "hsk-markdown-table", children: /* @__PURE__ */ jsx4("tbody", { children: tableRows }) }) }, `table-wrapper-${key}`)
931
+ );
932
+ continue;
933
+ }
934
+ elements.push(
935
+ /* @__PURE__ */ jsx4("p", { className: "hsk-markdown-p", children: parseInline(line, key) }, key)
936
+ );
937
+ i++;
938
+ }
939
+ return /* @__PURE__ */ jsx4(Fragment2, { children: elements });
940
+ }
941
+
942
+ // src/components/ChatWidget.tsx
943
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
944
+ var SparkleIcon2 = () => /* @__PURE__ */ jsx5("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx5("path", { d: "m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z" }) });
835
945
  var ArrowUpIcon = () => /* @__PURE__ */ jsxs3("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
836
- /* @__PURE__ */ jsx4("path", { d: "m5 12 7-7 7 7" }),
837
- /* @__PURE__ */ jsx4("path", { d: "M12 19V5" })
946
+ /* @__PURE__ */ jsx5("path", { d: "m5 12 7-7 7 7" }),
947
+ /* @__PURE__ */ jsx5("path", { d: "M12 19V5" })
838
948
  ] });
839
949
  function SourceCard({ source, defaultCurrency, onSelect }) {
840
950
  var _a;
841
951
  return /* @__PURE__ */ jsxs3("div", { className: "hsk-source-card", onClick: () => onSelect == null ? void 0 : onSelect(source), children: [
842
- source.image && /* @__PURE__ */ jsx4("img", { src: source.image, alt: source.name, className: "hsk-source-img" }),
952
+ source.image && /* @__PURE__ */ jsx5("img", { src: source.image, alt: source.name, className: "hsk-source-img" }),
843
953
  /* @__PURE__ */ jsxs3("div", { style: { flex: 1, minWidth: 0 }, children: [
844
- /* @__PURE__ */ jsx4("div", { className: "hsk-source-name", children: source.name }),
954
+ /* @__PURE__ */ jsx5("div", { className: "hsk-source-name", children: source.name }),
845
955
  source.price && /* @__PURE__ */ jsxs3("div", { className: "hsk-source-price", children: [
846
956
  (_a = source.currency) != null ? _a : defaultCurrency,
847
957
  " ",
@@ -896,36 +1006,36 @@ function ChatWidget({
896
1006
  style: customStyles,
897
1007
  children: [
898
1008
  /* @__PURE__ */ jsxs3("div", { className: `hsk-chat-header ${classNames.header || ""}`, children: [
899
- /* @__PURE__ */ jsx4("span", { className: "hsk-chat-header-icon", children: /* @__PURE__ */ jsx4(SparkleIcon2, {}) }),
900
- /* @__PURE__ */ jsx4("span", { className: "hsk-chat-title", children: title }),
901
- /* @__PURE__ */ jsx4("span", { className: "hsk-chat-badge", children: "AI" }),
902
- messages.length > 0 && /* @__PURE__ */ jsx4("button", { className: "hsk-chat-reset", onClick: reset, style: { marginLeft: "auto" }, children: "Clear" })
1009
+ /* @__PURE__ */ jsx5("span", { className: "hsk-chat-header-icon", children: /* @__PURE__ */ jsx5(SparkleIcon2, {}) }),
1010
+ /* @__PURE__ */ jsx5("span", { className: "hsk-chat-title", children: title }),
1011
+ /* @__PURE__ */ jsx5("span", { className: "hsk-chat-badge", children: "AI" }),
1012
+ messages.length > 0 && /* @__PURE__ */ jsx5("button", { className: "hsk-chat-reset", onClick: reset, style: { marginLeft: "auto" }, children: "Clear" })
903
1013
  ] }),
904
1014
  /* @__PURE__ */ jsxs3("div", { className: "hsk-chat-messages", children: [
905
1015
  messages.length === 0 ? /* @__PURE__ */ jsxs3("div", { className: "hsk-chat-empty", children: [
906
- /* @__PURE__ */ jsx4("div", { className: "hsk-chat-empty-icon", children: /* @__PURE__ */ jsx4(SparkleIcon2, {}) }),
907
- /* @__PURE__ */ jsx4("div", { children: emptyStateText }),
908
- /* @__PURE__ */ jsx4("div", { className: "hsk-chat-empty-suggestions", children: emptyStateSuggestions })
1016
+ /* @__PURE__ */ jsx5("div", { className: "hsk-chat-empty-icon", children: /* @__PURE__ */ jsx5(SparkleIcon2, {}) }),
1017
+ /* @__PURE__ */ jsx5("div", { children: emptyStateText }),
1018
+ /* @__PURE__ */ jsx5("div", { className: "hsk-chat-empty-suggestions", children: emptyStateSuggestions })
909
1019
  ] }) : messages.map((msg, idx) => /* @__PURE__ */ jsxs3("div", { children: [
910
1020
  /* @__PURE__ */ jsxs3("div", { className: `hsk-msg-row ${msg.role}`, children: [
911
- /* @__PURE__ */ jsx4("div", { className: `hsk-msg-avatar ${msg.role === "assistant" ? "ai" : "user"}`, children: msg.role === "assistant" ? /* @__PURE__ */ jsx4(SparkleIcon2, {}) : "U" }),
912
- /* @__PURE__ */ jsx4("div", { className: `hsk-msg-bubble ${msg.role} ${classNames.messageBubble || ""}`, children: msg.content })
1021
+ /* @__PURE__ */ jsx5("div", { className: `hsk-msg-avatar ${msg.role === "assistant" ? "ai" : "user"}`, children: msg.role === "assistant" ? /* @__PURE__ */ jsx5(SparkleIcon2, {}) : "U" }),
1022
+ /* @__PURE__ */ jsx5("div", { className: `hsk-msg-bubble ${msg.role} ${classNames.messageBubble || ""}`, children: renderMarkdown(msg.content) })
913
1023
  ] }),
914
- msg.role === "assistant" && idx === messages.length - 1 && sources.length > 0 && /* @__PURE__ */ jsx4("div", { className: "hsk-sources-container", children: /* @__PURE__ */ jsx4("div", { className: "hsk-sources", children: sources.map((src, si) => /* @__PURE__ */ jsx4(SourceCard, { source: src, defaultCurrency, onSelect: onSelectSource }, si)) }) })
1024
+ msg.role === "assistant" && idx === messages.length - 1 && sources.length > 0 && /* @__PURE__ */ jsx5("div", { className: "hsk-sources-container", children: /* @__PURE__ */ jsx5("div", { className: "hsk-sources", children: sources.map((src, si) => /* @__PURE__ */ jsx5(SourceCard, { source: src, defaultCurrency, onSelect: onSelectSource }, si)) }) })
915
1025
  ] }, idx)),
916
1026
  loading && /* @__PURE__ */ jsxs3("div", { className: "hsk-msg-row", children: [
917
- /* @__PURE__ */ jsx4("div", { className: "hsk-msg-avatar ai", children: /* @__PURE__ */ jsx4(SparkleIcon2, {}) }),
1027
+ /* @__PURE__ */ jsx5("div", { className: "hsk-msg-avatar ai", children: /* @__PURE__ */ jsx5(SparkleIcon2, {}) }),
918
1028
  /* @__PURE__ */ jsxs3("div", { className: "hsk-typing", children: [
919
- /* @__PURE__ */ jsx4("div", { className: "hsk-typing-dot" }),
920
- /* @__PURE__ */ jsx4("div", { className: "hsk-typing-dot" }),
921
- /* @__PURE__ */ jsx4("div", { className: "hsk-typing-dot" })
1029
+ /* @__PURE__ */ jsx5("div", { className: "hsk-typing-dot" }),
1030
+ /* @__PURE__ */ jsx5("div", { className: "hsk-typing-dot" }),
1031
+ /* @__PURE__ */ jsx5("div", { className: "hsk-typing-dot" })
922
1032
  ] })
923
1033
  ] }),
924
- error && /* @__PURE__ */ jsx4("div", { className: "hsk-chat-error", children: error }),
925
- /* @__PURE__ */ jsx4("div", { ref: bottomRef })
1034
+ error && /* @__PURE__ */ jsx5("div", { className: "hsk-chat-error", children: error }),
1035
+ /* @__PURE__ */ jsx5("div", { ref: bottomRef })
926
1036
  ] }),
927
1037
  /* @__PURE__ */ jsxs3("div", { className: "hsk-chat-input-area", children: [
928
- /* @__PURE__ */ jsx4(
1038
+ /* @__PURE__ */ jsx5(
929
1039
  "textarea",
930
1040
  {
931
1041
  ref: textareaRef,
@@ -938,14 +1048,14 @@ function ChatWidget({
938
1048
  disabled: loading
939
1049
  }
940
1050
  ),
941
- /* @__PURE__ */ jsx4(
1051
+ /* @__PURE__ */ jsx5(
942
1052
  "button",
943
1053
  {
944
1054
  className: "hsk-chat-send",
945
1055
  onClick: handleSend,
946
1056
  disabled: !input.trim() || loading,
947
1057
  "aria-label": "Send message",
948
- children: /* @__PURE__ */ jsx4(ArrowUpIcon, {})
1058
+ children: /* @__PURE__ */ jsx5(ArrowUpIcon, {})
949
1059
  }
950
1060
  )
951
1061
  ] })
@@ -957,17 +1067,17 @@ function ChatWidget({
957
1067
  // src/components/AIChatButton.tsx
958
1068
  import { useState as useState7, useEffect as useEffect6, useRef as useRef9, useCallback as useCallback4 } from "react";
959
1069
  import { createPortal as createPortal2 } from "react-dom";
960
- import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
961
- var SparkleIcon3 = ({ className }) => /* @__PURE__ */ jsx5("svg", { className, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx5("path", { d: "m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z" }) });
1070
+ import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
1071
+ var SparkleIcon3 = ({ className }) => /* @__PURE__ */ jsx6("svg", { className, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx6("path", { d: "m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z" }) });
962
1072
  var ArrowUpIcon2 = () => /* @__PURE__ */ jsxs4("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
963
- /* @__PURE__ */ jsx5("path", { d: "m5 12 7-7 7 7" }),
964
- /* @__PURE__ */ jsx5("path", { d: "M12 19V5" })
1073
+ /* @__PURE__ */ jsx6("path", { d: "m5 12 7-7 7 7" }),
1074
+ /* @__PURE__ */ jsx6("path", { d: "M12 19V5" })
965
1075
  ] });
966
1076
  var CloseIcon2 = () => /* @__PURE__ */ jsxs4("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
967
- /* @__PURE__ */ jsx5("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
968
- /* @__PURE__ */ jsx5("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1077
+ /* @__PURE__ */ jsx6("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1078
+ /* @__PURE__ */ jsx6("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
969
1079
  ] });
970
- var ChevronRightIcon = () => /* @__PURE__ */ jsx5("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx5("path", { d: "m9 18 6-6-6-6" }) });
1080
+ var ChevronRightIcon = () => /* @__PURE__ */ jsx6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx6("path", { d: "m9 18 6-6-6-6" }) });
971
1081
  var DEFAULT_CHIPS = [
972
1082
  "Cheapest smartphone",
973
1083
  "Smart TV under KSh 20,000",
@@ -1000,7 +1110,7 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource }) {
1000
1110
  (_a = railRef.current) == null ? void 0 : _a.scrollBy({ left: 170, behavior: "smooth" });
1001
1111
  };
1002
1112
  return /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-sources-wrap", children: [
1003
- /* @__PURE__ */ jsx5("div", { className: "hsk-cb-sources", ref: railRef, children: sources.map((src, si) => {
1113
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-sources", ref: railRef, children: sources.map((src, si) => {
1004
1114
  var _a;
1005
1115
  return /* @__PURE__ */ jsxs4(
1006
1116
  "div",
@@ -1009,9 +1119,9 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource }) {
1009
1119
  style: { animationDelay: `${si * 50}ms` },
1010
1120
  onClick: () => onSelectSource == null ? void 0 : onSelectSource(src),
1011
1121
  children: [
1012
- src.image ? /* @__PURE__ */ jsx5("div", { className: "hsk-cb-src-imgwrap", children: /* @__PURE__ */ jsx5("img", { src: src.image, alt: src.name, loading: "lazy" }) }) : /* @__PURE__ */ jsx5("div", { className: "hsk-cb-src-imgwrap-empty", children: /* @__PURE__ */ jsx5(SparkleIcon3, {}) }),
1122
+ src.image ? /* @__PURE__ */ jsx6("div", { className: "hsk-cb-src-imgwrap", children: /* @__PURE__ */ jsx6("img", { src: src.image, alt: src.name, loading: "lazy" }) }) : /* @__PURE__ */ jsx6("div", { className: "hsk-cb-src-imgwrap-empty", children: /* @__PURE__ */ jsx6(SparkleIcon3, {}) }),
1013
1123
  /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-src-info", children: [
1014
- /* @__PURE__ */ jsx5("div", { className: "hsk-cb-src-name", children: src.name }),
1124
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-src-name", children: src.name }),
1015
1125
  src.price && /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-src-price", children: [
1016
1126
  (_a = src.currency) != null ? _a : defaultCurrency,
1017
1127
  " ",
@@ -1023,15 +1133,15 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource }) {
1023
1133
  si
1024
1134
  );
1025
1135
  }) }),
1026
- showNext && /* @__PURE__ */ jsxs4(Fragment2, { children: [
1027
- /* @__PURE__ */ jsx5(
1136
+ showNext && /* @__PURE__ */ jsxs4(Fragment3, { children: [
1137
+ /* @__PURE__ */ jsx6(
1028
1138
  "div",
1029
1139
  {
1030
1140
  className: "hsk-cb-sources-fade",
1031
1141
  style: { background: "linear-gradient(to right, transparent, var(--hsk-fade-bg, #0e0e0f))" }
1032
1142
  }
1033
1143
  ),
1034
- /* @__PURE__ */ jsx5("button", { className: "hsk-cb-sources-next", onClick: scrollNext, "aria-label": "See more", children: /* @__PURE__ */ jsx5(ChevronRightIcon, {}) })
1144
+ /* @__PURE__ */ jsx6("button", { className: "hsk-cb-sources-next", onClick: scrollNext, "aria-label": "See more", children: /* @__PURE__ */ jsx6(ChevronRightIcon, {}) })
1035
1145
  ] })
1036
1146
  ] });
1037
1147
  }
@@ -1095,7 +1205,7 @@ function ChatModal({
1095
1205
  };
1096
1206
  const blurVal = typeof backdropBlur === "number" ? `${backdropBlur}px` : backdropBlur != null ? backdropBlur : "20px";
1097
1207
  const customStyles = __spreadValues(__spreadValues(__spreadValues(__spreadValues({}, (theme == null ? void 0 : theme.primaryColor) && { "--hsk-primary": theme.primaryColor }), (theme == null ? void 0 : theme.backgroundColor) && { "--hsk-bg": theme.backgroundColor }), (theme == null ? void 0 : theme.textColor) && { "--hsk-text": theme.textColor }), (theme == null ? void 0 : theme.fontFamily) && { "--hsk-font": theme.fontFamily });
1098
- return /* @__PURE__ */ jsx5(
1208
+ return /* @__PURE__ */ jsx6(
1099
1209
  "div",
1100
1210
  {
1101
1211
  className: `hsk-cb-overlay ${classNames.overlay || ""}`,
@@ -1107,23 +1217,23 @@ function ChatModal({
1107
1217
  children: /* @__PURE__ */ jsxs4("div", { className: `hsk-cb-panel ${classNames.panel || ""}`, onClick: (e) => e.stopPropagation(), children: [
1108
1218
  /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-topbar", children: [
1109
1219
  /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-topbar-left", children: [
1110
- /* @__PURE__ */ jsx5("span", { className: "hsk-cb-topbar-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx5(SparkleIcon3, {}) }),
1220
+ /* @__PURE__ */ jsx6("span", { className: "hsk-cb-topbar-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx6(SparkleIcon3, {}) }),
1111
1221
  /* @__PURE__ */ jsxs4("div", { children: [
1112
- /* @__PURE__ */ jsx5("div", { className: "hsk-cb-topbar-title", children: title }),
1113
- /* @__PURE__ */ jsx5("div", { className: "hsk-cb-topbar-sub", children: "Powered by Huskel AI \xB7 searches the whole catalogue" })
1222
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-topbar-title", children: title }),
1223
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-topbar-sub", children: "Powered by Huskel AI \xB7 searches the whole catalogue" })
1114
1224
  ] })
1115
1225
  ] }),
1116
1226
  /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-topbar-actions", children: [
1117
- messages.length > 0 && /* @__PURE__ */ jsx5("button", { className: "hsk-cb-topbar-btn", onClick: reset, children: "Clear chat" }),
1118
- /* @__PURE__ */ jsx5("button", { className: "hsk-cb-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx5(CloseIcon2, {}) })
1227
+ messages.length > 0 && /* @__PURE__ */ jsx6("button", { className: "hsk-cb-topbar-btn", onClick: reset, children: "Clear chat" }),
1228
+ /* @__PURE__ */ jsx6("button", { className: "hsk-cb-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx6(CloseIcon2, {}) })
1119
1229
  ] })
1120
1230
  ] }),
1121
1231
  /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-msgs", children: [
1122
1232
  messages.length === 0 ? /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-empty", children: [
1123
- /* @__PURE__ */ jsx5("div", { className: "hsk-cb-empty-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx5(SparkleIcon3, {}) }),
1124
- /* @__PURE__ */ jsx5("div", { className: "hsk-cb-empty-title", children: "What can I help you find?" }),
1125
- /* @__PURE__ */ jsx5("div", { className: "hsk-cb-empty-sub", children: "Ask about products, budgets, gift ideas, specs \u2014 I'll search the entire catalogue for you." }),
1126
- /* @__PURE__ */ jsx5("div", { className: "hsk-cb-chips", children: chips.map((chip) => /* @__PURE__ */ jsx5(
1233
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-empty-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx6(SparkleIcon3, {}) }),
1234
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-empty-title", children: "What can I help you find?" }),
1235
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-empty-sub", children: "Ask about products, budgets, gift ideas, specs \u2014 I'll search the entire catalogue for you." }),
1236
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-chips", children: chips.map((chip) => /* @__PURE__ */ jsx6(
1127
1237
  "button",
1128
1238
  {
1129
1239
  className: "hsk-cb-chip",
@@ -1135,11 +1245,11 @@ function ChatModal({
1135
1245
  ] }) : messages.map((msg, idx) => {
1136
1246
  const isLast = idx === messages.length - 1;
1137
1247
  const isUser = msg.role === "user";
1138
- return /* @__PURE__ */ jsx5("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ jsx5("div", { className: "hsk-cb-user-msg", children: /* @__PURE__ */ jsx5("div", { className: "hsk-cb-user-bubble", children: msg.content }) }) : /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-ai-msg", children: [
1139
- /* @__PURE__ */ jsx5("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx5(SparkleIcon3, {}) }),
1248
+ return /* @__PURE__ */ jsx6("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ jsx6("div", { className: "hsk-cb-user-msg", children: /* @__PURE__ */ jsx6("div", { className: "hsk-cb-user-bubble", children: msg.content }) }) : /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-ai-msg", children: [
1249
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx6(SparkleIcon3, {}) }),
1140
1250
  /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-ai-body", children: [
1141
- /* @__PURE__ */ jsx5("div", { className: "hsk-cb-ai-text", children: msg.content }),
1142
- isLast && sources.length > 0 && /* @__PURE__ */ jsx5(
1251
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-ai-text", children: renderMarkdown(msg.content) }),
1252
+ isLast && sources.length > 0 && /* @__PURE__ */ jsx6(
1143
1253
  SourcesCarousel,
1144
1254
  {
1145
1255
  sources,
@@ -1156,9 +1266,9 @@ function ChatModal({
1156
1266
  className: "hsk-cb-selected-product",
1157
1267
  onClick: () => selectedProduct.url && window.open(selectedProduct.url, "_blank"),
1158
1268
  children: [
1159
- selectedProduct.image && /* @__PURE__ */ jsx5("img", { className: "hsk-cb-selected-img", src: selectedProduct.image, alt: selectedProduct.name }),
1269
+ selectedProduct.image && /* @__PURE__ */ jsx6("img", { className: "hsk-cb-selected-img", src: selectedProduct.image, alt: selectedProduct.name }),
1160
1270
  /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-selected-info", children: [
1161
- /* @__PURE__ */ jsx5("div", { className: "hsk-cb-selected-name", children: selectedProduct.name }),
1271
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-selected-name", children: selectedProduct.name }),
1162
1272
  selectedProduct.price && /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-selected-price", children: [
1163
1273
  (_a = selectedProduct.currency) != null ? _a : defaultCurrency,
1164
1274
  " ",
@@ -1169,19 +1279,19 @@ function ChatModal({
1169
1279
  }
1170
1280
  ),
1171
1281
  loading && /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-typing-row", children: [
1172
- /* @__PURE__ */ jsx5("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx5(SparkleIcon3, {}) }),
1282
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx6(SparkleIcon3, {}) }),
1173
1283
  /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-typing", children: [
1174
- /* @__PURE__ */ jsx5("div", { className: "hsk-cb-dot" }),
1175
- /* @__PURE__ */ jsx5("div", { className: "hsk-cb-dot" }),
1176
- /* @__PURE__ */ jsx5("div", { className: "hsk-cb-dot" })
1284
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-dot" }),
1285
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-dot" }),
1286
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-dot" })
1177
1287
  ] })
1178
1288
  ] }),
1179
- error && /* @__PURE__ */ jsx5("div", { className: "hsk-cb-error", children: error }),
1180
- /* @__PURE__ */ jsx5("div", { ref: bottomRef, style: { height: 1 } })
1289
+ error && /* @__PURE__ */ jsx6("div", { className: "hsk-cb-error", children: error }),
1290
+ /* @__PURE__ */ jsx6("div", { ref: bottomRef, style: { height: 1 } })
1181
1291
  ] }),
1182
1292
  /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-input-wrap", children: [
1183
1293
  /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-input-box", children: [
1184
- /* @__PURE__ */ jsx5(
1294
+ /* @__PURE__ */ jsx6(
1185
1295
  "textarea",
1186
1296
  {
1187
1297
  ref: textareaRef,
@@ -1195,18 +1305,18 @@ function ChatModal({
1195
1305
  autoFocus: true
1196
1306
  }
1197
1307
  ),
1198
- /* @__PURE__ */ jsx5(
1308
+ /* @__PURE__ */ jsx6(
1199
1309
  "button",
1200
1310
  {
1201
1311
  className: `hsk-cb-send ${classNames.sendButton || ""}`,
1202
1312
  onClick: () => handleSend(),
1203
1313
  disabled: !input.trim() || loading,
1204
1314
  "aria-label": "Send message",
1205
- children: /* @__PURE__ */ jsx5(ArrowUpIcon2, {})
1315
+ children: /* @__PURE__ */ jsx6(ArrowUpIcon2, {})
1206
1316
  }
1207
1317
  )
1208
1318
  ] }),
1209
- /* @__PURE__ */ jsx5("div", { className: "hsk-cb-hint", children: "Huskel AI \xB7 searches the whole catalogue in real time" })
1319
+ /* @__PURE__ */ jsx6("div", { className: "hsk-cb-hint", children: "Huskel AI \xB7 searches the whole catalogue in real time" })
1210
1320
  ] })
1211
1321
  ] })
1212
1322
  }
@@ -1231,7 +1341,7 @@ function AIChatButton({
1231
1341
  setMounted(true);
1232
1342
  }, []);
1233
1343
  const customStyles = __spreadValues(__spreadValues(__spreadValues(__spreadValues({}, (theme == null ? void 0 : theme.primaryColor) && { "--hsk-primary": theme.primaryColor }), (theme == null ? void 0 : theme.backgroundColor) && { "--hsk-bg": theme.backgroundColor }), (theme == null ? void 0 : theme.textColor) && { "--hsk-text": theme.textColor }), (theme == null ? void 0 : theme.fontFamily) && { "--hsk-font": theme.fontFamily });
1234
- return /* @__PURE__ */ jsxs4(Fragment2, { children: [
1344
+ return /* @__PURE__ */ jsxs4(Fragment3, { children: [
1235
1345
  /* @__PURE__ */ jsxs4(
1236
1346
  "button",
1237
1347
  {
@@ -1240,13 +1350,13 @@ function AIChatButton({
1240
1350
  style: customStyles,
1241
1351
  "aria-label": "Open AI chat",
1242
1352
  children: [
1243
- /* @__PURE__ */ jsx5("span", { className: "hsk-cb-btn-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx5(SparkleIcon3, {}) }),
1353
+ /* @__PURE__ */ jsx6("span", { className: "hsk-cb-btn-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx6(SparkleIcon3, {}) }),
1244
1354
  label !== void 0 ? label : null
1245
1355
  ]
1246
1356
  }
1247
1357
  ),
1248
1358
  open && mounted && createPortal2(
1249
- /* @__PURE__ */ jsx5(
1359
+ /* @__PURE__ */ jsx6(
1250
1360
  ChatModal,
1251
1361
  {
1252
1362
  title,