@terryavg/neptune-ai-chatbot 1.0.0 → 1.0.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.
Files changed (60) hide show
  1. package/README.md +151 -0
  2. package/dist/chat-input-42V4ESQB.mjs +478 -0
  3. package/dist/chat-input-4T42R7FR.mjs +481 -0
  4. package/dist/chat-input-BJVIIYOP.mjs +484 -0
  5. package/dist/chat-input-HT47ZLQN.mjs +456 -0
  6. package/dist/chat-input-JFGPZBBQ.mjs +495 -0
  7. package/dist/chat-input-JQ7PSHNW.mjs +515 -0
  8. package/dist/chat-input-USWVSAYY.mjs +461 -0
  9. package/dist/chat-input-VTCTV5ED.mjs +495 -0
  10. package/dist/chat-input-WJMGLQJI.mjs +495 -0
  11. package/dist/chat-message-2VQW74CO.mjs +2230 -0
  12. package/dist/chat-message-35ZWSSQV.mjs +1926 -0
  13. package/dist/chat-message-3CUUWTZG.mjs +2429 -0
  14. package/dist/chat-message-3NHSJNKL.mjs +2241 -0
  15. package/dist/chat-message-3Z7B2WYC.mjs +2228 -0
  16. package/dist/chat-message-564AHZHH.mjs +2186 -0
  17. package/dist/chat-message-5QLTW4K7.mjs +2122 -0
  18. package/dist/chat-message-7EH2TDZG.mjs +1910 -0
  19. package/dist/chat-message-7QHJRHQG.mjs +1909 -0
  20. package/dist/chat-message-AAXNH5TF.mjs +2088 -0
  21. package/dist/chat-message-D36YF274.mjs +1910 -0
  22. package/dist/chat-message-DVCXEL4Z.mjs +2111 -0
  23. package/dist/chat-message-E6KB3AST.mjs +1906 -0
  24. package/dist/chat-message-G2NWPAXK.mjs +1904 -0
  25. package/dist/chat-message-H62Z3DW5.mjs +2368 -0
  26. package/dist/chat-message-HIEZ7B5R.mjs +2190 -0
  27. package/dist/chat-message-I6AKFPK6.mjs +2156 -0
  28. package/dist/chat-message-IKYSAVAB.mjs +1918 -0
  29. package/dist/chat-message-IZL6JHV2.mjs +2429 -0
  30. package/dist/chat-message-J7PVUQO6.mjs +1878 -0
  31. package/dist/chat-message-K6QILTW5.mjs +1897 -0
  32. package/dist/chat-message-MDORLI2R.mjs +2228 -0
  33. package/dist/chat-message-MFUY6KOE.mjs +1910 -0
  34. package/dist/chat-message-MYKOR5OF.mjs +1890 -0
  35. package/dist/chat-message-NKMTAMGG.mjs +1906 -0
  36. package/dist/chat-message-NNGD3FUH.mjs +2168 -0
  37. package/dist/chat-message-QAPRO542.mjs +1915 -0
  38. package/dist/chat-message-R4IJ3MXU.mjs +2146 -0
  39. package/dist/chat-message-U7UCBLHI.mjs +2145 -0
  40. package/dist/chat-message-UKXGFKUR.mjs +1903 -0
  41. package/dist/chat-message-UNIBCF3T.mjs +1900 -0
  42. package/dist/chat-message-UXLPL76T.mjs +1890 -0
  43. package/dist/chat-message-VB54UOHB.mjs +2306 -0
  44. package/dist/chat-message-WUNUZLKI.mjs +2228 -0
  45. package/dist/chat-message-WYN5UZRD.mjs +1927 -0
  46. package/dist/chat-message-Y5OJSR2O.mjs +2228 -0
  47. package/dist/chat-message-YPDHL6WW.mjs +2114 -0
  48. package/dist/chunk-26656QB3.mjs +406 -0
  49. package/dist/chunk-2RXQ2EZ2.mjs +295 -0
  50. package/dist/chunk-DVWFDUN4.mjs +407 -0
  51. package/dist/chunk-JLRHY3SB.mjs +405 -0
  52. package/dist/chunk-XFSEOBLD.mjs +432 -0
  53. package/dist/index.css +174 -43
  54. package/dist/index.d.mts +218 -1
  55. package/dist/index.d.ts +218 -1
  56. package/dist/index.js +2088 -1400
  57. package/dist/index.mjs +606 -413
  58. package/dist/styles.css +1 -1
  59. package/package.json +3 -2
  60. package/README +0 -16
package/dist/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
- import {
2
- chatClient,
3
- configureChatClient
4
- } from "./chunk-5VL3YPMQ.mjs";
5
1
  import {
6
2
  ToolExecutionIndicator,
7
3
  ToolExecutionWidget
8
- } from "./chunk-C2VGAYER.mjs";
4
+ } from "./chunk-2RXQ2EZ2.mjs";
5
+ import {
6
+ chatClient,
7
+ configureChatClient
8
+ } from "./chunk-XFSEOBLD.mjs";
9
9
  import {
10
10
  __spreadProps,
11
11
  __spreadValues
@@ -17,7 +17,8 @@ import {
17
17
  useEffect as useEffect4,
18
18
  useRef as useRef2,
19
19
  useLayoutEffect,
20
- useCallback as useCallback2
20
+ useCallback as useCallback2,
21
+ startTransition as startTransition2
21
22
  } from "react";
22
23
  import {
23
24
  Trash2,
@@ -29,6 +30,7 @@ import {
29
30
  PanelRightOpen,
30
31
  MoreHorizontal
31
32
  } from "lucide-react";
33
+ import { motion as motion2, AnimatePresence as AnimatePresence2 } from "framer-motion";
32
34
 
33
35
  // app/components/chat-content.tsx
34
36
  import {
@@ -38,9 +40,11 @@ import {
38
40
  useMemo as useMemo2,
39
41
  useCallback,
40
42
  lazy,
41
- Suspense
43
+ Suspense,
44
+ startTransition
42
45
  } from "react";
43
46
  import { X as X2, ArrowDownCircle } from "lucide-react";
47
+ import { motion, AnimatePresence } from "framer-motion";
44
48
 
45
49
  // app/components/analytics-panel.tsx
46
50
  import { useState, useMemo, useEffect } from "react";
@@ -1267,8 +1271,8 @@ function AnalyticsPanel({
1267
1271
 
1268
1272
  // app/components/chat-content.tsx
1269
1273
  import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
1270
- var ChatInput = lazy(() => import("./chat-input-L5LIF4NP.mjs"));
1271
- var DynamicChatMessage = lazy(() => import("./chat-message-FTACCRMO.mjs"));
1274
+ var ChatInput = lazy(() => import("./chat-input-JQ7PSHNW.mjs"));
1275
+ var DynamicChatMessage = lazy(() => import("./chat-message-VB54UOHB.mjs"));
1272
1276
  var SCROLL_BOTTOM_THRESHOLD = 50;
1273
1277
  function ChatContent({
1274
1278
  conversation,
@@ -1279,7 +1283,26 @@ function ChatContent({
1279
1283
  onAppStateChange,
1280
1284
  onSidebarToggle,
1281
1285
  isReadOnly = false,
1282
- onThreadCreated
1286
+ onThreadCreated,
1287
+ messageBubbleColor,
1288
+ accentColor,
1289
+ scrollButtonColor = "#6366F1",
1290
+ streamingText = "NAIA is working on it...",
1291
+ streamingTextColor = "#2563EB",
1292
+ welcomeMessagePrimary = "How can I help you today?",
1293
+ welcomeMessageSecondary = "Feel free to ask any question you like \u2014 just be precise, as if you're speaking to a real person.",
1294
+ welcomeIcon,
1295
+ welcomeIconSize = "4rem",
1296
+ streaming = true,
1297
+ inputBackgroundColor = "#ffffff",
1298
+ inputBackgroundColorDark = "#303030",
1299
+ vectorColor,
1300
+ vectorColorDark,
1301
+ onToolStart,
1302
+ onToolInput,
1303
+ onToolFinish,
1304
+ onChunk,
1305
+ onFinish
1283
1306
  }) {
1284
1307
  const messagesEndRef = useRef(null);
1285
1308
  const scrollContainerRef = useRef(null);
@@ -1433,14 +1456,16 @@ function ChatContent({
1433
1456
  }, []);
1434
1457
  const handleAddUserMessage = useCallback(
1435
1458
  (message) => {
1436
- setMessages((prev) => [...prev, message]);
1437
- setUserHasScrolledUp(false);
1438
- setShowScrollToBottomButton(false);
1459
+ startTransition(() => {
1460
+ setMessages((prev) => [...prev, message]);
1461
+ setUserHasScrolledUp(false);
1462
+ setShowScrollToBottomButton(false);
1463
+ });
1439
1464
  setTimeout(() => {
1440
- scrollToBottom("smooth");
1441
- }, 50);
1465
+ scrollToBottom(messages.length === 0 ? "instant" : "smooth");
1466
+ }, messages.length === 0 ? 600 : 50);
1442
1467
  },
1443
- [scrollToBottom]
1468
+ [messages.length, scrollToBottom]
1444
1469
  );
1445
1470
  const handleStreamStart = useCallback(() => {
1446
1471
  const newStreamingMessage = {
@@ -1454,8 +1479,10 @@ function ChatContent({
1454
1479
  role: newStreamingMessage.role,
1455
1480
  createdAt: newStreamingMessage.createdAt
1456
1481
  };
1457
- setStreamingMessage(newStreamingMessage);
1458
- setIsStreaming(true);
1482
+ startTransition(() => {
1483
+ setStreamingMessage(newStreamingMessage);
1484
+ setIsStreaming(true);
1485
+ });
1459
1486
  }, []);
1460
1487
  const handleToolExecutionStart = useCallback((toolName) => {
1461
1488
  setStreamingMessage((prev) => {
@@ -1541,7 +1568,6 @@ function ChatContent({
1541
1568
  []
1542
1569
  );
1543
1570
  const handleError = useCallback((details) => {
1544
- console.log("handleError called with:", details);
1545
1571
  setIsStreaming(false);
1546
1572
  setStreamingMessage(null);
1547
1573
  streamingMessageRef.current = null;
@@ -1549,7 +1575,6 @@ function ChatContent({
1549
1575
  setShowScrollToBottomButton(false);
1550
1576
  }, []);
1551
1577
  const handleStopStreaming = useCallback(() => {
1552
- console.log("Stop streaming requested");
1553
1578
  setIsStreaming(false);
1554
1579
  setStreamingMessage(null);
1555
1580
  streamingMessageRef.current = null;
@@ -1821,139 +1846,231 @@ function ChatContent({
1821
1846
  style: hasOpenPanel ? { width: `${chatWidth}%` } : {},
1822
1847
  children: [
1823
1848
  isResizingChatApp && /* @__PURE__ */ jsx2("div", { className: "absolute inset-0 z-40 bg-transparent cursor-col-resize" }),
1824
- hasMessages ? (
1825
- // Standard layout with messages and input at bottom
1826
- /* @__PURE__ */ jsxs2(Fragment2, { children: [
1827
- /* @__PURE__ */ jsx2(
1828
- "div",
1829
- {
1830
- ref: scrollContainerRef,
1831
- className: `flex-1 overflow-y-auto py-6 relative ${hasOpenPanel ? "px-2 sm:px-4" : "px-4 sm:px-8"}`,
1832
- "data-ref": "scrollContainerRef",
1833
- "data-main-chat-scroll": "true",
1834
- children: /* @__PURE__ */ jsxs2("div", { className: "space-y-2", children: [
1835
- allMessages.map((message, index) => {
1836
- const isCurrentlyStreaming = isStreaming && (streamingMessage == null ? void 0 : streamingMessage.id) === message.id;
1837
- return (
1838
- // @ts-ignore - Typescript doesn't recognize dynamic imports properly
1849
+ /* @__PURE__ */ jsxs2(Fragment2, { children: [
1850
+ /* @__PURE__ */ jsxs2(
1851
+ "div",
1852
+ {
1853
+ ref: scrollContainerRef,
1854
+ className: `flex-1 overflow-y-auto py-6 relative ${hasOpenPanel ? "px-2 sm:px-4" : "px-4 sm:px-8"} ${!hasMessages ? "flex flex-col items-center justify-center" : ""}`,
1855
+ "data-ref": "scrollContainerRef",
1856
+ "data-main-chat-scroll": "true",
1857
+ children: [
1858
+ /* @__PURE__ */ jsx2(AnimatePresence, { mode: "wait", children: !hasMessages && !isReadOnly && /* @__PURE__ */ jsxs2(
1859
+ motion.div,
1860
+ {
1861
+ initial: { opacity: 0, y: 20 },
1862
+ animate: { opacity: 1, y: 0 },
1863
+ exit: { opacity: 0, y: -20 },
1864
+ transition: { duration: 0.6, type: "spring", bounce: 0.15 },
1865
+ className: "flex flex-col items-center w-full max-w-4xl mx-auto",
1866
+ children: [
1867
+ welcomeIcon && /* @__PURE__ */ jsx2(
1868
+ motion.div,
1869
+ {
1870
+ initial: { scale: 0.8, opacity: 0 },
1871
+ animate: { scale: 1, opacity: 1 },
1872
+ transition: { delay: 0.1, duration: 0.5 },
1873
+ className: "mb-4",
1874
+ children: /* @__PURE__ */ jsx2(
1875
+ "img",
1876
+ {
1877
+ src: welcomeIcon,
1878
+ alt: "Welcome icon",
1879
+ style: {
1880
+ width: welcomeIconSize,
1881
+ height: welcomeIconSize
1882
+ },
1883
+ className: "object-contain"
1884
+ }
1885
+ )
1886
+ }
1887
+ ),
1839
1888
  /* @__PURE__ */ jsx2(
1840
- DynamicChatMessage,
1889
+ motion.h2,
1841
1890
  {
1842
- message,
1843
- isStreaming: isCurrentlyStreaming,
1844
- theme,
1845
- onAppOpen: handleAppOpen,
1846
- onAnalyticOpen: handleAnalyticOpen,
1847
- onWidgetSubmit: handleWidgetSubmit,
1848
- onWidgetCancel: handleWidgetCancel
1849
- },
1850
- message.id || index
1891
+ initial: { opacity: 0, y: 10 },
1892
+ animate: { opacity: 1, y: 0 },
1893
+ transition: { delay: 0.2, duration: 0.5 },
1894
+ className: `mb-2 font-bold ${hasOpenPanel ? "text-lg" : "text-2xl"}`,
1895
+ children: welcomeMessagePrimary
1896
+ }
1897
+ ),
1898
+ /* @__PURE__ */ jsx2(
1899
+ motion.p,
1900
+ {
1901
+ initial: { opacity: 0, y: 10 },
1902
+ animate: { opacity: 1, y: 0 },
1903
+ transition: { delay: 0.3, duration: 0.5 },
1904
+ className: `text-center text-gray-500 mb-8 ${hasOpenPanel ? "text-sm max-w-xs" : "max-w-md"}`,
1905
+ children: welcomeMessageSecondary
1906
+ }
1907
+ ),
1908
+ /* @__PURE__ */ jsx2(
1909
+ motion.div,
1910
+ {
1911
+ initial: { opacity: 0, y: 10 },
1912
+ animate: { opacity: 1, y: 0 },
1913
+ transition: { delay: 0.4, duration: 0.5 },
1914
+ className: `w-full ${hasOpenPanel ? "max-w-xs" : "max-w-xl"}`,
1915
+ children: /* @__PURE__ */ jsx2(Suspense, { fallback: null, children: /* @__PURE__ */ jsx2(
1916
+ ChatInput,
1917
+ {
1918
+ conversationId: conversation.id,
1919
+ agentId,
1920
+ debug,
1921
+ onAddUserMessage: handleAddUserMessage,
1922
+ onStreamStart: handleStreamStart,
1923
+ onStreamUpdate: handleStreamUpdate,
1924
+ onStreamEnd: handleStreamEnd,
1925
+ onError: handleError,
1926
+ messages: [],
1927
+ isStreaming,
1928
+ onStopStreaming: handleStopStreaming,
1929
+ disabled: isWaitingForInput,
1930
+ onThreadCreated,
1931
+ onToolExecutionStart: handleToolExecutionStart,
1932
+ onToolExecutionEnd: handleToolExecutionEnd,
1933
+ onToolStart,
1934
+ onToolInput,
1935
+ onToolFinish,
1936
+ onChunk,
1937
+ onFinish,
1938
+ accentColor,
1939
+ streaming,
1940
+ theme,
1941
+ inputBackgroundColor,
1942
+ inputBackgroundColorDark
1943
+ }
1944
+ ) })
1945
+ }
1851
1946
  )
1852
- );
1853
- }),
1854
- /* @__PURE__ */ jsx2(
1855
- "div",
1856
- {
1857
- ref: messagesEndRef,
1858
- "data-ref": "messagesEndRef"
1859
- }
1860
- )
1861
- ] })
1862
- }
1863
- ),
1864
- !isReadOnly && /* @__PURE__ */ jsxs2(
1865
- "div",
1866
- {
1867
- className: `border-t border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 ${hasOpenPanel ? "p-2 sm:p-3" : "p-4 sm:p-6"}`,
1868
- children: [
1869
- isWaitingForInput && /* @__PURE__ */ jsxs2("div", { className: "mb-4 p-3 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-lg", children: [
1870
- /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
1871
- /* @__PURE__ */ jsxs2("div", { className: "flex space-x-1", children: [
1872
- /* @__PURE__ */ jsx2("div", { className: "w-2 h-2 bg-amber-500 rounded-full animate-pulse" }),
1873
- /* @__PURE__ */ jsx2(
1874
- "div",
1947
+ ]
1948
+ },
1949
+ "welcome-state"
1950
+ ) }),
1951
+ !hasMessages && isReadOnly && /* @__PURE__ */ jsxs2("div", { className: "text-center", children: [
1952
+ /* @__PURE__ */ jsx2("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2", children: "Log View" }),
1953
+ /* @__PURE__ */ jsx2("p", { className: "text-gray-500 dark:text-gray-400", children: "This log contains no messages." })
1954
+ ] }),
1955
+ hasMessages && /* @__PURE__ */ jsxs2(
1956
+ motion.div,
1957
+ {
1958
+ initial: { opacity: 0, y: 20 },
1959
+ animate: { opacity: 1, y: 0 },
1960
+ exit: { opacity: 0, y: -20 },
1961
+ transition: { duration: 0.4, ease: "easeOut" },
1962
+ className: "space-y-2",
1963
+ children: [
1964
+ allMessages.map((message, index) => {
1965
+ const isCurrentlyStreaming = isStreaming && (streamingMessage == null ? void 0 : streamingMessage.id) === message.id;
1966
+ return /* @__PURE__ */ jsx2(
1967
+ motion.div,
1875
1968
  {
1876
- className: "w-2 h-2 bg-amber-500 rounded-full animate-pulse",
1877
- style: {
1878
- animationDelay: "0.2s"
1879
- }
1969
+ initial: { opacity: 0, x: -20 },
1970
+ animate: { opacity: 1, x: 0 },
1971
+ transition: {
1972
+ duration: isCurrentlyStreaming ? 0 : 0.3,
1973
+ delay: isCurrentlyStreaming ? 0 : index * 0.05,
1974
+ ease: "easeOut"
1975
+ },
1976
+ children: /* @__PURE__ */ jsx2(
1977
+ DynamicChatMessage,
1978
+ {
1979
+ message,
1980
+ isStreaming: isCurrentlyStreaming,
1981
+ theme,
1982
+ onAnalyticOpen: handleAnalyticOpen,
1983
+ messageBubbleColor,
1984
+ streamingText,
1985
+ streamingTextColor,
1986
+ vectorColor,
1987
+ vectorColorDark,
1988
+ agentId,
1989
+ onFeedbackChange: (messageId, feedbackPositive) => {
1990
+ setMessages((prev) => prev.map(
1991
+ (msg) => msg.id === messageId ? __spreadProps(__spreadValues({}, msg), {
1992
+ metadata: __spreadProps(__spreadValues({}, msg.metadata), {
1993
+ feedbackPositive
1994
+ })
1995
+ }) : msg
1996
+ ));
1997
+ }
1998
+ }
1999
+ )
2000
+ },
2001
+ message.id || index
2002
+ );
2003
+ }),
2004
+ /* @__PURE__ */ jsx2(
2005
+ "div",
2006
+ {
2007
+ ref: messagesEndRef,
2008
+ "data-ref": "messagesEndRef"
2009
+ }
2010
+ )
2011
+ ]
2012
+ },
2013
+ conversation.id
2014
+ )
2015
+ ]
2016
+ }
2017
+ ),
2018
+ !isReadOnly && hasMessages && /* @__PURE__ */ jsx2(
2019
+ motion.div,
2020
+ {
2021
+ layout: true,
2022
+ initial: false,
2023
+ transition: {
2024
+ layout: { duration: 0.6, type: "spring", bounce: 0.15 }
2025
+ },
2026
+ className: "relative border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 z-20",
2027
+ children: /* @__PURE__ */ jsxs2("div", { className: hasOpenPanel ? "p-2 sm:p-3 w-full" : "p-4 sm:p-6 w-full max-w-4xl mx-auto", children: [
2028
+ isWaitingForInput && /* @__PURE__ */ jsxs2("div", { className: "mb-4 p-3 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-lg", children: [
2029
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
2030
+ /* @__PURE__ */ jsxs2("div", { className: "flex space-x-1", children: [
2031
+ /* @__PURE__ */ jsx2("div", { className: "w-2 h-2 bg-amber-500 rounded-full animate-pulse" }),
2032
+ /* @__PURE__ */ jsx2(
2033
+ "div",
2034
+ {
2035
+ className: "w-2 h-2 bg-amber-500 rounded-full animate-pulse",
2036
+ style: {
2037
+ animationDelay: "0.2s"
1880
2038
  }
1881
- ),
1882
- /* @__PURE__ */ jsx2(
1883
- "div",
1884
- {
1885
- className: "w-2 h-2 bg-amber-500 rounded-full animate-pulse",
1886
- style: {
1887
- animationDelay: "0.4s"
1888
- }
2039
+ }
2040
+ ),
2041
+ /* @__PURE__ */ jsx2(
2042
+ "div",
2043
+ {
2044
+ className: "w-2 h-2 bg-amber-500 rounded-full animate-pulse",
2045
+ style: {
2046
+ animationDelay: "0.4s"
1889
2047
  }
1890
- )
1891
- ] }),
1892
- /* @__PURE__ */ jsx2("p", { className: "text-sm text-amber-800 dark:text-amber-200 font-medium", children: "Waiting for form input..." })
2048
+ }
2049
+ )
1893
2050
  ] }),
1894
- /* @__PURE__ */ jsx2("p", { className: "text-xs text-amber-700 dark:text-amber-300 mt-1", children: "Complete the form above or click Cancel to continue without data capture." })
2051
+ /* @__PURE__ */ jsx2("p", { className: "text-sm text-amber-800 dark:text-amber-200 font-medium", children: "Waiting for form input..." })
1895
2052
  ] }),
1896
- showScrollToBottomButton && /* @__PURE__ */ jsx2("div", { className: "absolute bottom-22 left-1/2 transform -translate-x-1/2 z-10", children: /* @__PURE__ */ jsx2(
1897
- "button",
1898
- {
1899
- onClick: () => scrollToBottom("smooth"),
1900
- className: "bg-indigo-600 hover:bg-indigo-700 text-white rounded-full p-3 shadow-lg transition-opacity duration-200 ease-in-out animate-bounce",
1901
- title: "Scroll to bottom",
1902
- children: /* @__PURE__ */ jsx2(ArrowDownCircle, { size: 24 })
1903
- }
1904
- ) }),
1905
- /* @__PURE__ */ jsx2(Suspense, { fallback: null, children: /* @__PURE__ */ jsx2(
1906
- ChatInput,
1907
- {
1908
- conversationId: conversation.id,
1909
- agentId,
1910
- debug,
1911
- onAddUserMessage: handleAddUserMessage,
1912
- onStreamStart: handleStreamStart,
1913
- onStreamUpdate: handleStreamUpdate,
1914
- onStreamEnd: handleStreamEnd,
1915
- onError: handleError,
1916
- messages,
1917
- isStreaming,
1918
- onStopStreaming: handleStopStreaming,
1919
- disabled: isWaitingForInput,
1920
- onThreadCreated,
1921
- onToolExecutionStart: handleToolExecutionStart,
1922
- onToolExecutionEnd: handleToolExecutionEnd
1923
- }
1924
- ) })
1925
- ]
1926
- }
1927
- )
1928
- ] })
1929
- ) : (
1930
- // Empty state with centered input - or read-only message for log mode
1931
- /* @__PURE__ */ jsx2("div", { className: "flex h-full flex-col items-center justify-center p-4", children: isReadOnly ? /* @__PURE__ */ jsxs2("div", { className: "text-center", children: [
1932
- /* @__PURE__ */ jsx2("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2", children: "Log View" }),
1933
- /* @__PURE__ */ jsx2("p", { className: "text-gray-500 dark:text-gray-400", children: "This log contains no messages." })
1934
- ] }) : /* @__PURE__ */ jsxs2(Fragment2, { children: [
1935
- /* @__PURE__ */ jsxs2("div", { className: "mb-8 flex flex-col items-center", children: [
1936
- /* @__PURE__ */ jsx2("div", { className: "mb-4 text-gray-500" }),
1937
- /* @__PURE__ */ jsx2(
1938
- "h2",
1939
- {
1940
- className: `mb-2 font-bold ${hasOpenPanel ? "text-lg" : "text-2xl"}`,
1941
- children: "How can I help you today?"
1942
- }
1943
- ),
1944
- /* @__PURE__ */ jsx2(
1945
- "p",
1946
- {
1947
- className: `text-center text-gray-500 ${hasOpenPanel ? "text-sm max-w-xs" : "max-w-md"}`,
1948
- children: "Feel free to ask any question you like \u2014 just be precise, as if you're speaking to a real person."
1949
- }
1950
- )
1951
- ] }),
1952
- /* @__PURE__ */ jsx2(
1953
- "div",
1954
- {
1955
- className: `w-full ${hasOpenPanel ? "max-w-sm" : "max-w-2xl"} px-4`,
1956
- children: /* @__PURE__ */ jsx2(Suspense, { fallback: null, children: /* @__PURE__ */ jsx2(
2053
+ /* @__PURE__ */ jsx2("p", { className: "text-xs text-amber-700 dark:text-amber-300 mt-1", children: "Complete the form above or click Cancel to continue without data capture." })
2054
+ ] }),
2055
+ showScrollToBottomButton && /* @__PURE__ */ jsx2("div", { className: "absolute bottom-22 left-1/2 transform -translate-x-1/2 z-10", children: /* @__PURE__ */ jsx2(
2056
+ "button",
2057
+ {
2058
+ onClick: () => scrollToBottom("smooth"),
2059
+ className: "text-white rounded-full p-3 shadow-lg transition-all duration-200 ease-in-out animate-bounce",
2060
+ style: {
2061
+ backgroundColor: scrollButtonColor
2062
+ },
2063
+ onMouseEnter: (e) => {
2064
+ e.currentTarget.style.filter = "brightness(0.85)";
2065
+ },
2066
+ onMouseLeave: (e) => {
2067
+ e.currentTarget.style.filter = "brightness(1)";
2068
+ },
2069
+ title: "Scroll to bottom",
2070
+ children: /* @__PURE__ */ jsx2(ArrowDownCircle, { size: 24 })
2071
+ }
2072
+ ) }),
2073
+ /* @__PURE__ */ jsx2(Suspense, { fallback: null, children: /* @__PURE__ */ jsx2(
1957
2074
  ChatInput,
1958
2075
  {
1959
2076
  conversationId: conversation.id,
@@ -1964,18 +2081,29 @@ function ChatContent({
1964
2081
  onStreamUpdate: handleStreamUpdate,
1965
2082
  onStreamEnd: handleStreamEnd,
1966
2083
  onError: handleError,
1967
- messages: [],
2084
+ messages,
1968
2085
  isStreaming,
1969
2086
  onStopStreaming: handleStopStreaming,
2087
+ disabled: isWaitingForInput,
1970
2088
  onThreadCreated,
1971
2089
  onToolExecutionStart: handleToolExecutionStart,
1972
- onToolExecutionEnd: handleToolExecutionEnd
2090
+ onToolExecutionEnd: handleToolExecutionEnd,
2091
+ onToolStart,
2092
+ onToolInput,
2093
+ onToolFinish,
2094
+ onChunk,
2095
+ onFinish,
2096
+ accentColor,
2097
+ streaming,
2098
+ theme,
2099
+ inputBackgroundColor,
2100
+ inputBackgroundColorDark
1973
2101
  }
1974
2102
  ) })
1975
- }
1976
- )
1977
- ] }) })
1978
- )
2103
+ ] })
2104
+ }
2105
+ )
2106
+ ] })
1979
2107
  ]
1980
2108
  }
1981
2109
  ),
@@ -2151,7 +2279,35 @@ function NeptuneChatBot({
2151
2279
  agentId: propAgentId,
2152
2280
  debug: propDebug = false,
2153
2281
  theme: propTheme = "light",
2154
- localDebug: propLocalDebug
2282
+ localDebug: propLocalDebug,
2283
+ title: propTitle = "Naia",
2284
+ messageBubbleColor = "#E5E3F8",
2285
+ messageBubbleColorDark = "rgba(168, 140, 250, 0.3)",
2286
+ accentColor = "#8B7FD9",
2287
+ accentColorDark = "#A88CFA",
2288
+ scrollButtonColor = "#6366F1",
2289
+ scrollButtonColorDark = "#818CF8",
2290
+ streamingText = "NAIA is working on it...",
2291
+ streamingTextColor = "#2563EB",
2292
+ streamingTextColorDark = "#60A5FA",
2293
+ welcomeMessagePrimary = "How can I help you today?",
2294
+ welcomeMessageSecondary = "Feel free to ask any question you like \u2014 just be precise, as if you're speaking to a real person.",
2295
+ welcomeIcon,
2296
+ welcomeIconSize = "4rem",
2297
+ streaming = true,
2298
+ sidebarBackgroundColor = "#f9f9f9",
2299
+ onToolStart,
2300
+ onToolInput,
2301
+ onToolFinish,
2302
+ onChunk,
2303
+ onFinish,
2304
+ sidebarBackgroundColorDark = "#171717",
2305
+ inputBackgroundColor = "#ffffff",
2306
+ inputBackgroundColorDark = "#303030",
2307
+ headerBackgroundColor = "#ffffff",
2308
+ headerBackgroundColorDark = "#171717",
2309
+ vectorColor = "#9333EA",
2310
+ vectorColorDark = "#A855F7"
2155
2311
  }) {
2156
2312
  const [conversations, setConversations] = useState4([]);
2157
2313
  const [selectedConversationId, setSelectedConversationId] = useState4(null);
@@ -2260,7 +2416,7 @@ function NeptuneChatBot({
2260
2416
  };
2261
2417
  conversations2.forEach((conversation) => {
2262
2418
  try {
2263
- const convDate = new Date(parseInt(conversation.updatedAt));
2419
+ const convDate = new Date(conversation.updatedAt);
2264
2420
  if (convDate >= today) {
2265
2421
  groups["Today"].push(conversation);
2266
2422
  } else if (convDate >= yesterday) {
@@ -2278,27 +2434,13 @@ function NeptuneChatBot({
2278
2434
  });
2279
2435
  Object.keys(groups).forEach((key) => {
2280
2436
  groups[key].sort(
2281
- (a, b) => new Date(parseInt(b.updatedAt)).getTime() - new Date(parseInt(a.updatedAt)).getTime()
2437
+ (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
2282
2438
  );
2283
2439
  });
2284
2440
  return groups;
2285
2441
  },
2286
2442
  []
2287
2443
  );
2288
- const isJson = useCallback2((content) => {
2289
- if (typeof content === "object" && content !== null) {
2290
- return Array.isArray(content) || Object.prototype.toString.call(content) === "[object Object]";
2291
- }
2292
- if (typeof content === "string") {
2293
- try {
2294
- const parsed = JSON.parse(content);
2295
- return typeof parsed === "object" && parsed !== null;
2296
- } catch (e) {
2297
- return false;
2298
- }
2299
- }
2300
- return false;
2301
- }, []);
2302
2444
  useEffect4(() => {
2303
2445
  const fetchConversations = async () => {
2304
2446
  if (!initialAssistantIdChecked || hasFetchedRef.current) {
@@ -2318,42 +2460,15 @@ function NeptuneChatBot({
2318
2460
  }
2319
2461
  setConversations(data);
2320
2462
  if (data.length > 0) {
2321
- const validConversations = data.filter(
2322
- (conv) => conv && conv.updatedAt
2323
- );
2324
- if (validConversations.length > 0) {
2325
- try {
2326
- const mostRecent = [...validConversations].sort(
2327
- (a, b) => new Date(parseInt(b.updatedAt)).getTime() - new Date(parseInt(a.updatedAt)).getTime()
2328
- )[0];
2329
- selectConversation(mostRecent.id);
2330
- } catch (sortError) {
2331
- console.error(
2332
- "Error sorting conversations:",
2333
- sortError
2334
- );
2335
- selectConversation(validConversations[0].id);
2336
- }
2337
- }
2338
- } else {
2339
- if (agentId && !isCreatingConversation) {
2340
- try {
2341
- setIsCreatingConversation(true);
2342
- const newConversation = await chatClient.conversations.create(
2343
- "New Chat",
2344
- agentId
2345
- );
2346
- setConversations([newConversation]);
2347
- selectConversation(newConversation.id);
2348
- } catch (createError) {
2349
- } finally {
2350
- setIsCreatingConversation(false);
2351
- }
2352
- } else {
2353
- console.warn(
2354
- "Cannot create conversation: agentId not available or already creating"
2355
- );
2356
- }
2463
+ const tempConversation = {
2464
+ id: `temp-${Date.now()}`,
2465
+ title: "New Chat",
2466
+ messages: [],
2467
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2468
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
2469
+ isTemporary: true
2470
+ };
2471
+ setSelectedConversation(tempConversation);
2357
2472
  }
2358
2473
  } catch (error) {
2359
2474
  console.error("Failed to fetch conversations:", error);
@@ -2429,7 +2544,6 @@ function NeptuneChatBot({
2429
2544
  };
2430
2545
  setSelectedConversationId(tempConversation.id);
2431
2546
  setSelectedConversation(tempConversation);
2432
- setConversations((prev) => [tempConversation, ...prev]);
2433
2547
  setHasOpenApp(false);
2434
2548
  } catch (error) {
2435
2549
  console.error("Failed to create new conversation:", error);
@@ -2437,28 +2551,34 @@ function NeptuneChatBot({
2437
2551
  };
2438
2552
  const handleThreadCreated = useCallback2(
2439
2553
  async (oldId, newId) => {
2440
- console.log(`Thread created: ${oldId} -> ${newId}`);
2441
- setConversations(
2442
- (prev) => prev.map(
2443
- (conv) => conv.id === oldId ? __spreadProps(__spreadValues({}, conv), { id: newId, isTemporary: false }) : conv
2444
- )
2445
- );
2446
- if (selectedConversationId === oldId) {
2447
- setSelectedConversationId(newId);
2448
- try {
2449
- const updatedConv = await chatClient.conversations.get(
2450
- newId
2451
- );
2554
+ try {
2555
+ const updatedConv = await chatClient.conversations.get(newId);
2556
+ startTransition2(() => {
2557
+ setConversations((prev) => {
2558
+ const existingIndex = prev.findIndex(
2559
+ (conv) => conv.id === oldId || conv.id === newId
2560
+ );
2561
+ if (existingIndex !== -1) {
2562
+ const updated = [...prev];
2563
+ updated[existingIndex] = __spreadProps(__spreadValues({}, updatedConv), {
2564
+ isTemporary: false
2565
+ });
2566
+ return updated;
2567
+ } else {
2568
+ return [
2569
+ __spreadProps(__spreadValues({}, updatedConv), { isTemporary: false }),
2570
+ ...prev
2571
+ ];
2572
+ }
2573
+ });
2574
+ setSelectedConversationId(newId);
2452
2575
  setSelectedConversation(updatedConv);
2453
- } catch (error) {
2454
- console.error(
2455
- "Failed to fetch updated conversation:",
2456
- error
2457
- );
2458
- }
2576
+ });
2577
+ } catch (error) {
2578
+ console.error("Failed to fetch updated conversation:", error);
2459
2579
  }
2460
2580
  },
2461
- [selectedConversationId]
2581
+ []
2462
2582
  );
2463
2583
  const deleteConversation = async (id) => {
2464
2584
  try {
@@ -2468,27 +2588,16 @@ function NeptuneChatBot({
2468
2588
  );
2469
2589
  setConversations(updatedConversations);
2470
2590
  if (selectedConversationId === id) {
2471
- if (updatedConversations.length > 0) {
2472
- selectConversation(updatedConversations[0].id);
2473
- } else {
2474
- setSelectedConversationId(null);
2475
- setSelectedConversation(null);
2476
- if (agentId) {
2477
- try {
2478
- const newConversation = await chatClient.conversations.create(
2479
- "New Chat",
2480
- agentId
2481
- );
2482
- setConversations([newConversation]);
2483
- selectConversation(newConversation.id);
2484
- } catch (error) {
2485
- console.error(
2486
- "Failed to create new conversation after deletion:",
2487
- error
2488
- );
2489
- }
2490
- }
2491
- }
2591
+ const tempConversation = {
2592
+ id: `temp-${Date.now()}`,
2593
+ title: "New Chat",
2594
+ messages: [],
2595
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2596
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
2597
+ isTemporary: true
2598
+ };
2599
+ setSelectedConversationId(tempConversation.id);
2600
+ setSelectedConversation(tempConversation);
2492
2601
  }
2493
2602
  } catch (error) {
2494
2603
  console.error("Failed to delete conversation:", error);
@@ -2636,190 +2745,255 @@ function NeptuneChatBot({
2636
2745
  )
2637
2746
  ] })
2638
2747
  ] }) }),
2639
- sidebarOpen && /* @__PURE__ */ jsx4(
2640
- "div",
2748
+ /* @__PURE__ */ jsx4(AnimatePresence2, { children: sidebarOpen && /* @__PURE__ */ jsx4(
2749
+ motion2.div,
2641
2750
  {
2751
+ initial: { opacity: 0 },
2752
+ animate: { opacity: 1 },
2753
+ exit: { opacity: 0 },
2754
+ transition: { duration: 0.3 },
2642
2755
  className: "lg:hidden fixed inset-0 bg-black bg-opacity-50 z-10",
2643
2756
  onClick: () => setSidebarOpen(false),
2644
2757
  "aria-hidden": "true"
2645
2758
  }
2646
- ),
2647
- /* @__PURE__ */ jsx4(
2648
- "div",
2759
+ ) }),
2760
+ /* @__PURE__ */ jsx4(AnimatePresence2, { children: sidebarOpen && /* @__PURE__ */ jsx4(
2761
+ motion2.div,
2649
2762
  {
2650
- className: `bg-[#f9f9f9] dark:bg-gray-900 dark:!bg-gray-900 border-r border-gray-200 dark:border-gray-700 h-full relative z-20 ${sidebarOpen ? "block" : "hidden"}`,
2651
- style: {
2652
- width: sidebarOpen ? `${sidebarWidth}px` : "0"
2763
+ initial: { width: 0, opacity: 0 },
2764
+ animate: { width: sidebarWidth, opacity: 1 },
2765
+ exit: { width: 0, opacity: 0 },
2766
+ transition: {
2767
+ duration: 0.3,
2768
+ ease: [0.4, 0, 0.2, 1]
2653
2769
  },
2654
- children: /* @__PURE__ */ jsx4("div", { className: "flex flex-col h-full", children: /* @__PURE__ */ jsx4("div", { className: "flex-1 overflow-y-auto p-2 bg-[#f9f9f9] dark:bg-[#171717]", children: /* @__PURE__ */ jsx4("div", { className: "flex-1", children: isLoading ? /* @__PURE__ */ jsx4("div", { className: "space-y-4" }) : conversations.length > 0 ? /* @__PURE__ */ jsx4("div", { className: "space-y-0", children: (() => {
2655
- const groupedConversations = categorizeConversationsByDate(
2656
- conversations
2657
- );
2658
- return Object.entries(
2659
- groupedConversations
2660
- ).map(
2661
- ([
2662
- groupName,
2663
- groupConversations
2664
- ]) => {
2665
- if (groupConversations.length === 0)
2666
- return null;
2667
- return /* @__PURE__ */ jsxs4(
2668
- "div",
2669
- {
2670
- className: "mb-4",
2671
- children: [
2672
- /* @__PURE__ */ jsx4("div", { className: "text-xs font-medium text-gray-500 dark:text-gray-400 px-2 py-2 uppercase tracking-wide", children: groupName }),
2673
- /* @__PURE__ */ jsx4("div", { className: "space-y-0", children: groupConversations.map(
2674
- (conversation) => {
2675
- var _a;
2676
- const hasWaitingMessages = conversation.waiting === true || ((_a = conversation.messages) == null ? void 0 : _a.some(
2677
- (message) => message.waiting === true
2678
- )) || false;
2679
- return /* @__PURE__ */ jsxs4(
2680
- "div",
2681
- {
2682
- onClick: () => {
2683
- selectConversation(
2684
- conversation.id
2685
- );
2686
- if (window.innerWidth < 1024) {
2687
- setSidebarOpen(
2688
- false
2689
- );
2690
- }
2691
- },
2692
- className: `flex items-center w-full pl-4 pr-2 py-2 mb-1 rounded-xl text-left group cursor-pointer ${selectedConversationId === conversation.id ? "bg-naia-200 text-gray-800 dark:text-gray-200" : "text-gray-800 dark:text-gray-100 conversation-item-background"}`,
2693
- children: [
2694
- /* @__PURE__ */ jsx4("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
2695
- /* @__PURE__ */ jsx4("div", { className: "font-medium overflow-hidden text-ellipsis whitespace-nowrap", children: conversation.title || "New Chat" }),
2696
- hasWaitingMessages && /* @__PURE__ */ jsx4("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx4(
2697
- "div",
2698
- {
2699
- className: "w-2 h-2 bg-amber-500 dark:bg-amber-400 rounded-full animate-pulse",
2700
- title: "Waiting for input"
2770
+ className: "bg-[#f9f9f9] dark:bg-gray-900 dark:!bg-gray-900 border-r border-gray-200 dark:border-gray-700 h-full relative z-20 overflow-hidden",
2771
+ children: /* @__PURE__ */ jsx4("div", { className: "flex flex-col h-full", children: /* @__PURE__ */ jsx4(
2772
+ "div",
2773
+ {
2774
+ className: "flex-1 overflow-y-auto p-2",
2775
+ style: {
2776
+ backgroundColor: theme === "dark" ? sidebarBackgroundColorDark : sidebarBackgroundColor
2777
+ },
2778
+ children: /* @__PURE__ */ jsx4("div", { className: "flex-1", children: isLoading ? /* @__PURE__ */ jsx4("div", { className: "space-y-4" }) : conversations.length > 0 ? /* @__PURE__ */ jsx4("div", { className: "space-y-0", children: (() => {
2779
+ const groupedConversations = categorizeConversationsByDate(
2780
+ conversations
2781
+ );
2782
+ return Object.entries(
2783
+ groupedConversations
2784
+ ).map(
2785
+ ([
2786
+ groupName,
2787
+ groupConversations
2788
+ ]) => {
2789
+ if (groupConversations.length === 0)
2790
+ return null;
2791
+ return /* @__PURE__ */ jsxs4(
2792
+ "div",
2793
+ {
2794
+ className: "mb-4",
2795
+ children: [
2796
+ /* @__PURE__ */ jsx4("div", { className: "text-xs font-medium text-gray-500 dark:text-gray-400 px-2 py-2 uppercase tracking-wide", children: groupName }),
2797
+ /* @__PURE__ */ jsx4("div", { className: "space-y-0", children: groupConversations.map(
2798
+ (conversation) => {
2799
+ var _a;
2800
+ const hasWaitingMessages = conversation.waiting === true || ((_a = conversation.messages) == null ? void 0 : _a.some(
2801
+ (message) => message.waiting === true
2802
+ )) || false;
2803
+ return /* @__PURE__ */ jsxs4(
2804
+ "div",
2805
+ {
2806
+ onClick: () => {
2807
+ selectConversation(
2808
+ conversation.id
2809
+ );
2810
+ if (window.innerWidth < 1024) {
2811
+ setSidebarOpen(
2812
+ false
2813
+ );
2701
2814
  }
2702
- ) })
2703
- ] }) }),
2704
- !conversation.isTemporary && /* @__PURE__ */ jsxs4("div", { className: "relative", children: [
2705
- /* @__PURE__ */ jsx4(
2706
- "button",
2707
- {
2708
- onClick: (e) => toggleConversationMenu(
2709
- e,
2710
- conversation.id
2711
- ),
2712
- className: "p-1.5 cursor-pointer rounded-full text-gray-500 hover:text-gray-700 dark:hover:text-gray-300 opacity-0 hover:bg-gray-300 dark:hover:bg-gray-700 group-hover:opacity-100 transition-opacity",
2713
- "aria-label": "More options",
2714
- children: /* @__PURE__ */ jsx4(
2715
- MoreHorizontal,
2815
+ },
2816
+ className: `flex items-center w-full pl-4 pr-2 py-2 mb-1 rounded-xl text-left group cursor-pointer ${selectedConversationId === conversation.id ? "text-gray-800 dark:text-gray-200" : "text-gray-800 dark:text-gray-100 conversation-item-background"}`,
2817
+ style: selectedConversationId === conversation.id ? {
2818
+ backgroundColor: theme === "dark" ? messageBubbleColorDark : messageBubbleColor
2819
+ } : void 0,
2820
+ children: [
2821
+ /* @__PURE__ */ jsx4("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
2822
+ /* @__PURE__ */ jsx4("div", { className: "font-medium overflow-hidden text-ellipsis whitespace-nowrap", children: conversation.title || "New Chat" }),
2823
+ hasWaitingMessages && /* @__PURE__ */ jsx4("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx4(
2824
+ "div",
2716
2825
  {
2717
- size: 16
2826
+ className: "w-2 h-2 bg-amber-500 dark:bg-amber-400 rounded-full animate-pulse",
2827
+ title: "Waiting for input"
2718
2828
  }
2719
- )
2720
- }
2721
- ),
2722
- openMenuId === conversation.id && /* @__PURE__ */ jsxs4("div", { className: "absolute right-0 top-10 w-40 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl shadow-lg z-50 p-2", children: [
2723
- /* @__PURE__ */ jsxs4(
2724
- "button",
2725
- {
2726
- onClick: (e) => handleRenameClick(
2727
- e,
2728
- conversation
2729
- ),
2730
- className: "w-full text-left px-3 py-2 text-md flex cursor-pointer items-center gap-2 hover:bg-gray-300 dark:hover:bg-gray-700 rounded-md",
2731
- children: [
2732
- /* @__PURE__ */ jsx4(
2733
- Edit,
2734
- {
2735
- size: 14
2736
- }
2829
+ ) })
2830
+ ] }) }),
2831
+ !conversation.isTemporary && /* @__PURE__ */ jsxs4("div", { className: "relative", children: [
2832
+ /* @__PURE__ */ jsx4(
2833
+ "button",
2834
+ {
2835
+ onClick: (e) => toggleConversationMenu(
2836
+ e,
2837
+ conversation.id
2737
2838
  ),
2738
- "Rename"
2739
- ]
2740
- }
2741
- ),
2742
- /* @__PURE__ */ jsxs4(
2743
- "button",
2744
- {
2745
- onClick: (e) => handleDeleteClick(
2746
- e,
2747
- conversation.id
2748
- ),
2749
- className: "w-full text-left px-3 py-2 text-md text-red-600 cursor-pointer flex items-center gap-2 hover:bg-gray-300 dark:hover:bg-gray-700 rounded-md",
2750
- children: [
2751
- /* @__PURE__ */ jsx4(
2752
- Trash2,
2839
+ className: "p-1.5 cursor-pointer rounded-full text-gray-500 hover:text-gray-700 dark:hover:text-gray-300 opacity-0 hover:bg-gray-300 dark:hover:bg-gray-700 group-hover:opacity-100 transition-opacity",
2840
+ "aria-label": "More options",
2841
+ children: /* @__PURE__ */ jsx4(
2842
+ MoreHorizontal,
2753
2843
  {
2754
- size: 14
2844
+ size: 16
2755
2845
  }
2756
- ),
2757
- "Delete"
2758
- ]
2759
- }
2760
- )
2761
- ] })
2762
- ] })
2763
- ]
2764
- },
2765
- conversation.id
2766
- );
2767
- }
2768
- ) })
2769
- ]
2770
- },
2771
- groupName
2772
- );
2773
- }
2774
- ).filter(Boolean);
2775
- })() }) : /* @__PURE__ */ jsx4("div", { className: "text-center py-8 text-gray-500", children: "No conversations yet" }) }) }) })
2846
+ )
2847
+ }
2848
+ ),
2849
+ openMenuId === conversation.id && /* @__PURE__ */ jsxs4("div", { className: "absolute right-0 top-10 w-40 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl shadow-lg z-50 p-2", children: [
2850
+ /* @__PURE__ */ jsxs4(
2851
+ "button",
2852
+ {
2853
+ onClick: (e) => handleRenameClick(
2854
+ e,
2855
+ conversation
2856
+ ),
2857
+ className: "w-full text-left px-3 py-2 text-md flex cursor-pointer items-center gap-2 hover:bg-gray-300 dark:hover:bg-gray-700 rounded-md",
2858
+ children: [
2859
+ /* @__PURE__ */ jsx4(
2860
+ Edit,
2861
+ {
2862
+ size: 14
2863
+ }
2864
+ ),
2865
+ "Rename"
2866
+ ]
2867
+ }
2868
+ ),
2869
+ /* @__PURE__ */ jsxs4(
2870
+ "button",
2871
+ {
2872
+ onClick: (e) => handleDeleteClick(
2873
+ e,
2874
+ conversation.id
2875
+ ),
2876
+ className: "w-full text-left px-3 py-2 text-md text-red-600 cursor-pointer flex items-center gap-2 hover:bg-gray-300 dark:hover:bg-gray-700 rounded-md",
2877
+ children: [
2878
+ /* @__PURE__ */ jsx4(
2879
+ Trash2,
2880
+ {
2881
+ size: 14
2882
+ }
2883
+ ),
2884
+ "Delete"
2885
+ ]
2886
+ }
2887
+ )
2888
+ ] })
2889
+ ] })
2890
+ ]
2891
+ },
2892
+ conversation.id
2893
+ );
2894
+ }
2895
+ ) })
2896
+ ]
2897
+ },
2898
+ groupName
2899
+ );
2900
+ }
2901
+ ).filter(Boolean);
2902
+ })() }) : /* @__PURE__ */ jsx4("div", { className: "text-center py-8 text-gray-500", children: "No conversations yet" }) })
2903
+ }
2904
+ ) })
2776
2905
  }
2777
- ),
2778
- sidebarOpen && /* @__PURE__ */ jsx4(
2779
- "div",
2906
+ ) }),
2907
+ /* @__PURE__ */ jsx4(AnimatePresence2, { children: sidebarOpen && /* @__PURE__ */ jsx4(
2908
+ motion2.div,
2780
2909
  {
2781
- ref: resizeHandleRef,
2782
- onMouseDown: startResizing,
2783
- className: "w-1 hover:w-2 bg-gray-300 dark:bg-gray-700 h-full cursor-col-resize transition-all hover:bg-indigo-500 dark:hover:bg-indigo-400 z-30 relative",
2784
- title: "Drag to resize"
2785
- }
2786
- ),
2787
- /* @__PURE__ */ jsxs4("div", { className: "flex-1 flex flex-col overflow-hidden", children: [
2788
- /* @__PURE__ */ jsxs4("header", { className: "h-14 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between px-4 bg-white dark:bg-gray-900", children: [
2789
- /* @__PURE__ */ jsx4("div", { className: "flex items-center", children: /* @__PURE__ */ jsxs4(Fragment3, { children: [
2790
- /* @__PURE__ */ jsx4(
2791
- "button",
2792
- {
2793
- onClick: () => setSidebarOpen(!sidebarOpen),
2794
- className: "p-2 cursor-pointer rounded-lg text-gray-500 hover:bg-naia-hover disabled:opacity-50 transition-colors",
2795
- title: "Toggle Sidebar",
2796
- "aria-label": "Toggle Sidebar",
2797
- children: sidebarOpen ? /* @__PURE__ */ jsx4(PanelRightOpen, { size: 20 }) : /* @__PURE__ */ jsx4(PanelRightClose, { size: 20 })
2798
- }
2799
- ),
2800
- /* @__PURE__ */ jsx4(
2801
- "button",
2802
- {
2803
- onClick: createNewConversation,
2804
- className: "p-2 cursor-pointer rounded-lg text-gray-500 hover:bg-naia-hover disabled:opacity-50 transition-colors",
2805
- title: "New Chat",
2806
- "aria-label": "New Chat",
2807
- children: /* @__PURE__ */ jsx4(MessageCirclePlus, { size: 20 })
2808
- }
2809
- )
2810
- ] }) }),
2811
- /* @__PURE__ */ jsx4("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx4("div", { className: "relative flex items-center", children: /* @__PURE__ */ jsx4("span", { className: "text-2xl font-bold mr-1", children: "Naia" }) }) }),
2812
- /* @__PURE__ */ jsx4("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx4(
2813
- "button",
2910
+ initial: { opacity: 0 },
2911
+ animate: { opacity: 1 },
2912
+ exit: { opacity: 0 },
2913
+ transition: { duration: 0.3 },
2914
+ children: /* @__PURE__ */ jsx4(
2915
+ "div",
2814
2916
  {
2815
- onClick: toggleTheme,
2816
- className: "p-2 cursor-pointer rounded-lg text-gray-500 hover:bg-naia-hover transition-colors",
2817
- title: `Switch to ${theme === "dark" ? "light" : "dark"} mode`,
2818
- "aria-label": `Switch to ${theme === "dark" ? "light" : "dark"} mode`,
2819
- children: theme === "dark" ? /* @__PURE__ */ jsx4(Sun, { size: 20 }) : /* @__PURE__ */ jsx4(Moon, { size: 20 })
2917
+ ref: resizeHandleRef,
2918
+ onMouseDown: startResizing,
2919
+ className: "w-1 hover:w-2 bg-gray-300 dark:bg-gray-700 h-full cursor-col-resize transition-all hover:bg-indigo-500 dark:hover:bg-indigo-400 z-30 relative",
2920
+ title: "Drag to resize"
2820
2921
  }
2821
- ) })
2822
- ] }),
2922
+ )
2923
+ }
2924
+ ) }),
2925
+ /* @__PURE__ */ jsxs4("div", { className: "flex-1 flex flex-col overflow-hidden", children: [
2926
+ /* @__PURE__ */ jsxs4(
2927
+ "header",
2928
+ {
2929
+ className: "h-14 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between px-4",
2930
+ style: {
2931
+ backgroundColor: theme === "dark" ? headerBackgroundColorDark : headerBackgroundColor
2932
+ },
2933
+ children: [
2934
+ /* @__PURE__ */ jsx4("div", { className: "flex items-center", children: /* @__PURE__ */ jsxs4(Fragment3, { children: [
2935
+ /* @__PURE__ */ jsx4(
2936
+ "button",
2937
+ {
2938
+ onClick: () => setSidebarOpen(!sidebarOpen),
2939
+ className: "p-2 cursor-pointer rounded-lg text-gray-500 disabled:opacity-50 transition-colors",
2940
+ style: {
2941
+ backgroundColor: "transparent"
2942
+ },
2943
+ onMouseEnter: (e) => {
2944
+ e.currentTarget.style.backgroundColor = theme === "dark" ? messageBubbleColorDark : messageBubbleColor;
2945
+ },
2946
+ onMouseLeave: (e) => {
2947
+ e.currentTarget.style.backgroundColor = "transparent";
2948
+ },
2949
+ title: "Toggle Sidebar",
2950
+ "aria-label": "Toggle Sidebar",
2951
+ children: sidebarOpen ? /* @__PURE__ */ jsx4(PanelRightOpen, { size: 20 }) : /* @__PURE__ */ jsx4(PanelRightClose, { size: 20 })
2952
+ }
2953
+ ),
2954
+ /* @__PURE__ */ jsx4(
2955
+ "button",
2956
+ {
2957
+ onClick: createNewConversation,
2958
+ className: "p-2 cursor-pointer rounded-lg text-gray-500 disabled:opacity-50 transition-colors",
2959
+ style: {
2960
+ backgroundColor: "transparent"
2961
+ },
2962
+ onMouseEnter: (e) => {
2963
+ e.currentTarget.style.backgroundColor = theme === "dark" ? messageBubbleColorDark : messageBubbleColor;
2964
+ },
2965
+ onMouseLeave: (e) => {
2966
+ e.currentTarget.style.backgroundColor = "transparent";
2967
+ },
2968
+ title: "New Chat",
2969
+ "aria-label": "New Chat",
2970
+ children: /* @__PURE__ */ jsx4(MessageCirclePlus, { size: 20 })
2971
+ }
2972
+ )
2973
+ ] }) }),
2974
+ /* @__PURE__ */ jsx4("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx4("div", { className: "relative flex items-center", children: /* @__PURE__ */ jsx4("span", { className: "text-2xl font-bold mr-1", children: propTitle }) }) }),
2975
+ /* @__PURE__ */ jsx4("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx4(
2976
+ "button",
2977
+ {
2978
+ onClick: toggleTheme,
2979
+ className: "p-2 cursor-pointer rounded-lg text-gray-500 transition-colors",
2980
+ style: {
2981
+ backgroundColor: "transparent"
2982
+ },
2983
+ onMouseEnter: (e) => {
2984
+ e.currentTarget.style.backgroundColor = theme === "dark" ? messageBubbleColorDark : messageBubbleColor;
2985
+ },
2986
+ onMouseLeave: (e) => {
2987
+ e.currentTarget.style.backgroundColor = "transparent";
2988
+ },
2989
+ title: `Switch to ${theme === "dark" ? "light" : "dark"} mode`,
2990
+ "aria-label": `Switch to ${theme === "dark" ? "light" : "dark"} mode`,
2991
+ children: theme === "dark" ? /* @__PURE__ */ jsx4(Sun, { size: 20 }) : /* @__PURE__ */ jsx4(Moon, { size: 20 })
2992
+ }
2993
+ ) })
2994
+ ]
2995
+ }
2996
+ ),
2823
2997
  /* @__PURE__ */ jsx4(
2824
2998
  "div",
2825
2999
  {
@@ -2847,7 +3021,26 @@ function NeptuneChatBot({
2847
3021
  theme,
2848
3022
  onAppStateChange: handleAppStateChange,
2849
3023
  onSidebarToggle: () => setSidebarOpen(false),
2850
- onThreadCreated: handleThreadCreated
3024
+ onThreadCreated: handleThreadCreated,
3025
+ messageBubbleColor: theme === "dark" ? messageBubbleColorDark : messageBubbleColor,
3026
+ accentColor: theme === "dark" ? accentColorDark : accentColor,
3027
+ scrollButtonColor: theme === "dark" ? scrollButtonColorDark : scrollButtonColor,
3028
+ streamingText,
3029
+ streamingTextColor: theme === "dark" ? streamingTextColorDark : streamingTextColor,
3030
+ welcomeMessagePrimary,
3031
+ welcomeMessageSecondary,
3032
+ welcomeIcon,
3033
+ welcomeIconSize,
3034
+ streaming,
3035
+ inputBackgroundColor,
3036
+ inputBackgroundColorDark,
3037
+ vectorColor,
3038
+ vectorColorDark,
3039
+ onToolStart,
3040
+ onToolInput,
3041
+ onToolFinish,
3042
+ onChunk,
3043
+ onFinish
2851
3044
  }
2852
3045
  ) : (
2853
3046
  // Show loading while the useEffect handles conversation creation