reachat 3.1.0 → 3.2.0

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.
@@ -13,9 +13,9 @@ import Mention from "@tiptap/extension-mention";
13
13
  import { Slot } from "@radix-ui/react-slot";
14
14
  import { motion, AnimatePresence } from "motion/react";
15
15
  import ReactMarkdown from "react-markdown";
16
- import { Prism } from "react-syntax-highlighter";
17
16
  import rehypeKatex from "rehype-katex";
18
17
  import rehypeRaw from "rehype-raw";
18
+ import { Prism } from "react-syntax-highlighter";
19
19
  import { SparklineChart, RadialAreaChart, RadialAreaSeries, RadialBarChart, RadialBarSeries, PieChart, PieArcSeries, AreaChart, AreaSeries, LinearYAxis, LinearXAxis, LineChart, LineSeries, BarChart, BarSeries } from "reaviz";
20
20
  import { findAndReplace } from "mdast-util-find-and-replace";
21
21
  import debounce from "lodash/debounce.js";
@@ -35,6 +35,7 @@ const ChatContext = createContext({
35
35
  const SvgPaperclip = (props) => /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1, strokeLinecap: "round", strokeLinejoin: "round", className: "lucide lucide-paperclip", ...props }, /* @__PURE__ */ React.createElement("path", { d: "m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48" }));
36
36
  const FileInput = ({
37
37
  allowedFiles,
38
+ multiple,
38
39
  onFileUpload,
39
40
  isLoading,
40
41
  disabled,
@@ -50,6 +51,7 @@ const FileInput = ({
50
51
  ref: fileInputRef,
51
52
  className: "hidden",
52
53
  accept: allowedFiles.join(","),
54
+ multiple,
53
55
  onChange: (e) => {
54
56
  onFileUpload(e);
55
57
  if (fileInputRef.current) {
@@ -180,17 +182,25 @@ const chatTheme = {
180
182
  }
181
183
  },
182
184
  markdown: {
185
+ hr: "my-4 border-t border-stroke-neutral-4",
183
186
  copy: "sticky py-1 [&>svg]:w-4 [&>svg]:h-4 opacity-50",
184
187
  p: "mb-2",
185
- a: "text-blue-400 underline",
188
+ a: "text-buttons-colors-link-primary-text-resting underline",
186
189
  table: "table-auto w-full m-2",
187
- th: "px-4 py-2 text-left font-bold border-b border-gray-500",
190
+ th: "px-4 py-2 text-left font-bold border-b border-stroke-neutral-4",
188
191
  td: "px-4 py-2",
189
192
  code: "m-2 rounded-b relative",
190
- toolbar: "text-xs dark:bg-gray-700/50 flex items-center justify-between px-2 py-1 rounded-t sticky top-0 backdrop-blur-md bg-gray-200 ",
193
+ inlineCode: "bg-gradient-neutral-200 p-1 rounded",
194
+ toolbar: "text-xs flex items-center justify-between px-2 py-1 rounded-t sticky top-0 backdrop-blur-md bg-gradient-neutral-500/50",
191
195
  li: "mb-2 ml-6",
192
196
  ul: "mb-4 list-disc",
193
- ol: "mb-4 list-decimal"
197
+ ol: "mb-4 list-decimal",
198
+ h1: "text-4xl font-bold mb-4 mt-6",
199
+ h2: "text-3xl font-bold mb-3 mt-5",
200
+ h3: "text-2xl font-bold mb-3 mt-4",
201
+ h4: "text-xl font-bold mb-2 mt-3",
202
+ h5: "text-lg font-bold mb-2 mt-2",
203
+ h6: "text-base font-bold mb-2 mt-2"
194
204
  },
195
205
  footer: {
196
206
  base: "mt-3 flex gap-1.5",
@@ -651,6 +661,7 @@ const ChatInput = forwardRef(
651
661
  ({
652
662
  allowedFiles,
653
663
  placeholder = "Type a message...",
664
+ allowMultipleFiles = false,
654
665
  defaultValue,
655
666
  sendIcon = /* @__PURE__ */ jsx(SvgSend, {}),
656
667
  stopIcon = /* @__PURE__ */ jsx(SvgStop, {}),
@@ -713,15 +724,12 @@ const ChatInput = forwardRef(
713
724
  const handleChange = useCallback((value) => {
714
725
  setMessage(value);
715
726
  }, []);
716
- const handleFileUpload = useCallback(
717
- (event) => {
718
- const file = event.target.files?.[0];
719
- if (file && fileUpload) {
720
- fileUpload(file);
721
- }
722
- },
723
- [fileUpload]
724
- );
727
+ const handleFileUpload = (event) => {
728
+ const files = event.target.files;
729
+ if (files?.length && fileUpload) {
730
+ fileUpload(allowMultipleFiles ? Array.from(files) : files[0]);
731
+ }
732
+ };
725
733
  const mentionsConfig = useMemo(
726
734
  () => mentions ? { ...mentions, trigger: mentions.trigger || "@" } : void 0,
727
735
  [mentions]
@@ -753,6 +761,7 @@ const ChatInput = forwardRef(
753
761
  FileInput,
754
762
  {
755
763
  allowedFiles,
764
+ multiple: allowMultipleFiles,
756
765
  onFileUpload: handleFileUpload,
757
766
  isLoading,
758
767
  disabled,
@@ -1853,14 +1862,17 @@ const light = {
1853
1862
  const CodeHighlighter = ({
1854
1863
  className,
1855
1864
  children,
1865
+ inlineClassName,
1856
1866
  copyClassName,
1857
1867
  copyIcon = /* @__PURE__ */ jsx(SvgCopy, {}),
1858
1868
  language,
1859
1869
  toolbarClassName,
1860
- theme = dark
1870
+ theme = dark,
1871
+ ...props
1861
1872
  }) => {
1862
1873
  const match = language?.match(/language-(\w+)/);
1863
1874
  const lang = match ? match[1] : "text";
1875
+ const isInline = !match;
1864
1876
  const handleCopy = (text) => {
1865
1877
  navigator.clipboard.writeText(text).then(() => {
1866
1878
  console.log("Text copied to clipboard");
@@ -1868,6 +1880,9 @@ const CodeHighlighter = ({
1868
1880
  console.error("Could not copy text: ", err);
1869
1881
  });
1870
1882
  };
1883
+ if (isInline) {
1884
+ return /* @__PURE__ */ jsx("code", { className: cn(inlineClassName), ...props, children });
1885
+ }
1871
1886
  return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
1872
1887
  /* @__PURE__ */ jsxs("div", { className: cn(toolbarClassName), children: [
1873
1888
  /* @__PURE__ */ jsx("div", { children: lang }),
@@ -1883,14 +1898,7 @@ const CodeHighlighter = ({
1883
1898
  }
1884
1899
  )
1885
1900
  ] }),
1886
- /* @__PURE__ */ jsx(
1887
- Prism,
1888
- {
1889
- language: lang,
1890
- style: theme,
1891
- children
1892
- }
1893
- )
1901
+ /* @__PURE__ */ jsx(Prism, { language: lang, style: theme, children })
1894
1902
  ] });
1895
1903
  };
1896
1904
  const TableComponent = ({ children, ...props }) => /* @__PURE__ */ jsx("table", { ...props, children });
@@ -1900,16 +1908,19 @@ const Markdown = ({
1900
1908
  children,
1901
1909
  remarkPlugins,
1902
1910
  rehypePlugins = [rehypeRaw, rehypeKatex],
1911
+ theme: themeProp,
1903
1912
  customComponents
1904
1913
  }) => {
1905
- const { theme, markdownComponents } = useContext(ChatContext);
1914
+ const { theme: contextTheme, markdownComponents } = useContext(ChatContext);
1915
+ const theme = themeProp || contextTheme;
1906
1916
  const components = useMemo(() => {
1907
1917
  const defaultComponents = {
1908
1918
  code: ({ className, children: children2, ...props }) => /* @__PURE__ */ jsx(
1909
1919
  CodeHighlighter,
1910
1920
  {
1911
1921
  ...props,
1912
- language: className,
1922
+ language: cn(className),
1923
+ inlineClassName: cn(theme.messages.message.markdown.inlineCode),
1913
1924
  className: cn(theme.messages.message.markdown.code, className),
1914
1925
  copyClassName: cn(theme.messages.message.markdown.copy),
1915
1926
  toolbarClassName: cn(theme.messages.message.markdown.toolbar),
@@ -1938,10 +1949,17 @@ const Markdown = ({
1938
1949
  }
1939
1950
  ),
1940
1951
  a: (props) => /* @__PURE__ */ jsx("a", { ...props, className: cn(theme.messages.message.markdown.a) }),
1952
+ hr: (props) => /* @__PURE__ */ jsx("hr", { ...props, className: cn(theme.messages.message.markdown.hr) }),
1941
1953
  p: (props) => /* @__PURE__ */ jsx("p", { ...props, className: cn(theme.messages.message.markdown.p) }),
1942
1954
  li: (props) => /* @__PURE__ */ jsx("li", { ...props, className: cn(theme.messages.message.markdown.li) }),
1943
1955
  ul: (props) => /* @__PURE__ */ jsx("ul", { ...props, className: cn(theme.messages.message.markdown.ul) }),
1944
1956
  ol: (props) => /* @__PURE__ */ jsx("ol", { ...props, className: cn(theme.messages.message.markdown.ol) }),
1957
+ h1: (props) => /* @__PURE__ */ jsx("h1", { ...props, className: cn(theme.messages.message.markdown.h1) }),
1958
+ h2: (props) => /* @__PURE__ */ jsx("h2", { ...props, className: cn(theme.messages.message.markdown.h2) }),
1959
+ h3: (props) => /* @__PURE__ */ jsx("h3", { ...props, className: cn(theme.messages.message.markdown.h3) }),
1960
+ h4: (props) => /* @__PURE__ */ jsx("h4", { ...props, className: cn(theme.messages.message.markdown.h4) }),
1961
+ h5: (props) => /* @__PURE__ */ jsx("h5", { ...props, className: cn(theme.messages.message.markdown.h5) }),
1962
+ h6: (props) => /* @__PURE__ */ jsx("h6", { ...props, className: cn(theme.messages.message.markdown.h6) }),
1945
1963
  // 'redact' is a custom element created by remarkRedact, not a standard
1946
1964
  // HTML tag, so it falls outside react-markdown's Components type.
1947
1965
  redact: ((props) => /* @__PURE__ */ jsx(
@@ -2160,8 +2178,8 @@ const commonRedactMatchers = [
2160
2178
  bitcoinMatcher
2161
2179
  ];
2162
2180
  const SvgFile = (props) => /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 16, height: 16, viewBox: "0 0 16 16", fill: "currentColor", ...props }, /* @__PURE__ */ React.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M2.7036 1.37034C3.04741 1.02653 3.51373 0.833374 3.99996 0.833374H9.33329H9.33331C9.47275 0.833374 9.59885 0.890449 9.68954 0.98251L13.6843 4.97722C13.7763 5.0679 13.8333 5.19398 13.8333 5.33337L13.8333 5.3379V13.3334C13.8333 13.8196 13.6401 14.2859 13.2963 14.6297C12.9525 14.9736 12.4862 15.1667 12 15.1667H3.99996C3.51373 15.1667 3.04741 14.9736 2.7036 14.6297C2.35978 14.2859 2.16663 13.8196 2.16663 13.3334V2.66671C2.16663 2.18048 2.35978 1.71416 2.7036 1.37034ZM3.99996 1.83337H8.83331V5.33337C8.83331 5.60952 9.05717 5.83337 9.33331 5.83337H12.8333V13.3334C12.8333 13.5544 12.7455 13.7663 12.5892 13.9226C12.4329 14.0789 12.221 14.1667 12 14.1667H3.99996C3.77895 14.1667 3.56698 14.0789 3.4107 13.9226C3.25442 13.7663 3.16663 13.5544 3.16663 13.3334V2.66671C3.16663 2.44569 3.25442 2.23373 3.4107 2.07745C3.56698 1.92117 3.77895 1.83337 3.99996 1.83337ZM9.83331 2.5405L12.1262 4.83337H9.83331V2.5405ZM5.33331 8.16663C5.05717 8.16663 4.83331 8.39048 4.83331 8.66663C4.83331 8.94277 5.05717 9.16663 5.33331 9.16663H10.6666C10.9428 9.16663 11.1666 8.94277 11.1666 8.66663C11.1666 8.39048 10.9428 8.16663 10.6666 8.16663H5.33331ZM4.83331 11.3334C4.83331 11.0572 5.05717 10.8334 5.33331 10.8334H10.6666C10.9428 10.8334 11.1666 11.0572 11.1666 11.3334C11.1666 11.6095 10.9428 11.8334 10.6666 11.8334H5.33331C5.05717 11.8334 4.83331 11.6095 4.83331 11.3334ZM5.33331 5.5C5.05717 5.5 4.83331 5.72386 4.83331 6C4.83331 6.27614 5.05717 6.5 5.33331 6.5H6.66665C6.94279 6.5 7.16665 6.27614 7.16665 6C7.16665 5.72386 6.94279 5.5 6.66665 5.5H5.33331Z" }));
2163
- const DefaultFileRenderer = lazy(() => import("./DefaultFileRenderer-Day12qYs.js"));
2164
- const CSVFileRenderer = lazy(() => import("./CSVFileRenderer-C2E4Xnkz.js"));
2181
+ const DefaultFileRenderer = lazy(() => import("./DefaultFileRenderer-BrFdb4JQ.js"));
2182
+ const CSVFileRenderer = lazy(() => import("./CSVFileRenderer-Darm68BZ.js"));
2165
2183
  const ImageFileRenderer = lazy(() => import("./ImageFileRenderer-C8tVW3I8.js"));
2166
2184
  const PDFFileRenderer = lazy(() => import("./PDFFileRenderer-DQdFS2l6.js"));
2167
2185
  const FILE_TYPE_RENDERER_MAP = {
@@ -2281,7 +2299,7 @@ const MessageQuestion = memo(
2281
2299
  ...props,
2282
2300
  children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
2283
2301
  /* @__PURE__ */ jsx(MessageFiles, { files }),
2284
- /* @__PURE__ */ jsx(Markdown, { remarkPlugins, children: question }),
2302
+ /* @__PURE__ */ jsx(Markdown, { remarkPlugins, theme, children: question }),
2285
2303
  isLong && !expanded && /* @__PURE__ */ jsx(
2286
2304
  Button,
2287
2305
  {
@@ -2308,7 +2326,7 @@ const MessageResponse = memo(
2308
2326
  "data-compact": isCompact,
2309
2327
  className: cn(theme.messages.message.response),
2310
2328
  children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
2311
- /* @__PURE__ */ jsx(Markdown, { remarkPlugins, children: response }),
2329
+ /* @__PURE__ */ jsx(Markdown, { remarkPlugins, theme, children: response }),
2312
2330
  isLoading && /* @__PURE__ */ jsx(
2313
2331
  motion.div,
2314
2332
  {
@@ -2326,7 +2344,6 @@ const MessageResponse = memo(
2326
2344
  );
2327
2345
  }
2328
2346
  );
2329
- MessageResponse.displayName = "MessageResponse";
2330
2347
  const MessageSource = ({ title, url, image, limit = 50 }) => {
2331
2348
  const { theme, isCompact } = useContext(ChatContext);
2332
2349
  return /* @__PURE__ */ jsxs(
@@ -2458,9 +2475,9 @@ const messageVariants = {
2458
2475
  }
2459
2476
  };
2460
2477
  const SessionMessage = memo(
2461
- ({ conversation, isLast, children }) => {
2478
+ ({ conversation, isLast, children, className }) => {
2462
2479
  const { theme, isLoading } = useContext(ChatContext);
2463
- return /* @__PURE__ */ jsx(motion.div, { variants: messageVariants, children: /* @__PURE__ */ jsx(Card, { className: cn(theme.messages.message.base), children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
2480
+ return /* @__PURE__ */ jsx(motion.div, { variants: messageVariants, children: /* @__PURE__ */ jsx(Card, { className: cn(theme.messages.message.base, className), children: children || /* @__PURE__ */ jsxs(Fragment, { children: [
2464
2481
  /* @__PURE__ */ jsx(
2465
2482
  MessageQuestion,
2466
2483
  {
@@ -2501,8 +2518,14 @@ const SessionMessages = ({
2501
2518
  children,
2502
2519
  newSessionContent,
2503
2520
  limit = 10,
2521
+ className,
2504
2522
  showMoreText = "Show more",
2505
- showScrollBottomButton = false
2523
+ autoScroll = true,
2524
+ showLoadMoreButton = false,
2525
+ showScrollBottomButton,
2526
+ loadMoreButtonDisabled,
2527
+ onScroll,
2528
+ onLoadMore
2506
2529
  }) => {
2507
2530
  const { activeSession, theme } = useContext(ChatContext);
2508
2531
  const contentRef = useRef(null);
@@ -2525,12 +2548,12 @@ const SessionMessages = ({
2525
2548
  return () => currentRef.removeEventListener("scroll", handleScroll);
2526
2549
  }, [showScrollBottomButton]);
2527
2550
  useEffect(() => {
2528
- if (contentRef.current) {
2551
+ if (contentRef.current && autoScroll) {
2529
2552
  requestAnimationFrame(
2530
2553
  () => contentRef.current.scrollTop = contentRef.current.scrollHeight
2531
2554
  );
2532
2555
  }
2533
- }, [activeSession, isAnimating]);
2556
+ }, [activeSession, autoScroll, isAnimating]);
2534
2557
  const handleShowMore = () => {
2535
2558
  showNext(limit);
2536
2559
  requestAnimationFrame(() => contentRef.current.scrollTop = 0);
@@ -2556,21 +2579,23 @@ const SessionMessages = ({
2556
2579
  if (!activeSession) {
2557
2580
  return /* @__PURE__ */ jsx(SessionEmpty, { children: newSessionContent });
2558
2581
  }
2559
- return /* @__PURE__ */ jsxs("div", { className: "relative flex-1 overflow-y-hidden", children: [
2582
+ return /* @__PURE__ */ jsxs("div", { className: cn("relative flex-1 overflow-y-hidden", className), children: [
2560
2583
  /* @__PURE__ */ jsxs(
2561
2584
  "div",
2562
2585
  {
2563
- className: cn(theme.messages.content, "h-full"),
2586
+ className: cn(theme.messages.content, className, "h-full"),
2564
2587
  ref: contentRef,
2565
2588
  id: activeSession?.id,
2589
+ onScrollCapture: onScroll,
2566
2590
  children: [
2567
- hasMore && /* @__PURE__ */ jsx(
2591
+ (showLoadMoreButton || hasMore) && /* @__PURE__ */ jsx(
2568
2592
  Button,
2569
2593
  {
2594
+ disabled: loadMoreButtonDisabled,
2570
2595
  variant: "outline",
2571
2596
  className: cn(theme.messages.showMore),
2572
2597
  fullWidth: true,
2573
- onClick: handleShowMore,
2598
+ onClick: onLoadMore ?? handleShowMore,
2574
2599
  children: showMoreText
2575
2600
  }
2576
2601
  ),
@@ -2583,7 +2608,7 @@ const SessionMessages = ({
2583
2608
  animate: "visible",
2584
2609
  onAnimationComplete: () => requestAnimationFrame(() => {
2585
2610
  setIsAnimating(false);
2586
- if (contentRef.current) {
2611
+ if (contentRef.current && autoScroll) {
2587
2612
  contentRef.current.scrollTop = contentRef.current.scrollHeight;
2588
2613
  }
2589
2614
  }),
@@ -2614,7 +2639,7 @@ const SessionMessages = ({
2614
2639
  {
2615
2640
  onClick: handleScrollToBottom,
2616
2641
  className: theme.messages?.message?.scrollToBottom?.button,
2617
- size: "sm",
2642
+ size: "small",
2618
2643
  children: /* @__PURE__ */ jsx(SvgArrowDown, {})
2619
2644
  }
2620
2645
  )
@@ -3927,7 +3952,7 @@ function createChartComponentDef() {
3927
3952
  };
3928
3953
  }
3929
3954
  export {
3930
- remarkRedact as $,
3955
+ remarkCve as $,
3931
3956
  AgUiEventType as A,
3932
3957
  SessionMessages as B,
3933
3958
  ChartRenderer as C,
@@ -3952,13 +3977,14 @@ export {
3952
3977
  creditCardMatcher as V,
3953
3978
  dark as W,
3954
3979
  generatePrompt as X,
3955
- light as Y,
3956
- remarkComponent as Z,
3957
- remarkCve as _,
3980
+ groupSessionsByDate as Y,
3981
+ light as Z,
3982
+ remarkComponent as _,
3958
3983
  SvgCopy as a,
3959
- ssnMatcher as a0,
3960
- useAgUi as a1,
3961
- validateSpec as a2,
3984
+ remarkRedact as a0,
3985
+ ssnMatcher as a1,
3986
+ useAgUi as a2,
3987
+ validateSpec as a3,
3962
3988
  AppBar as b,
3963
3989
  Chat as c,
3964
3990
  ChatBubble as d,
@@ -3985,4 +4011,4 @@ export {
3985
4011
  SessionMessage as y,
3986
4012
  SessionMessagePanel as z
3987
4013
  };
3988
- //# sourceMappingURL=index-CZSBRZbI.js.map
4014
+ //# sourceMappingURL=index-iuJAmrEE.js.map