@retrivora-ai/rag-engine 0.4.5 → 1.0.1

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 (74) hide show
  1. package/README.md +32 -57
  2. package/dist/{ChromaDBProvider-GI7TB7GJ.mjs → ChromaDBProvider-MIDOR4FW.mjs} +2 -2
  3. package/dist/{DocumentChunker-3yElxTO3.d.mts → DocumentChunker-C-sCZPhi.d.mts} +6 -6
  4. package/dist/{DocumentChunker-3yElxTO3.d.ts → DocumentChunker-C-sCZPhi.d.ts} +6 -6
  5. package/dist/{MilvusProvider-WDVTFB7D.mjs → MilvusProvider-U7SKC27V.mjs} +2 -2
  6. package/dist/{MongoDBProvider-RE3Q5S5B.mjs → MongoDBProvider-Z6ALOVDN.mjs} +2 -2
  7. package/dist/{PineconeProvider-BE2JWSPD.mjs → PineconeProvider-QZNRKTN2.mjs} +2 -2
  8. package/dist/{PostgreSQLProvider-5HHTK4SU.mjs → PostgreSQLProvider-BMOETDZA.mjs} +2 -2
  9. package/dist/{QdrantProvider-XVDVBNIG.mjs → QdrantProvider-YNUNEOZH.mjs} +2 -2
  10. package/dist/{RagConfig-BgRDL9Vy.d.mts → RagConfig-DRJO4hGU.d.mts} +12 -1
  11. package/dist/{RagConfig-BgRDL9Vy.d.ts → RagConfig-DRJO4hGU.d.ts} +12 -1
  12. package/dist/{RedisProvider-EK2R2PQH.mjs → RedisProvider-SR65SCKV.mjs} +2 -2
  13. package/dist/{SimpleGraphProvider-M6T7SE7D.mjs → SimpleGraphProvider-SLOXO4M7.mjs} +1 -1
  14. package/dist/{UniversalVectorProvider-YIDRX6VT.mjs → UniversalVectorProvider-IN67OS56.mjs} +3 -3
  15. package/dist/{WeaviateProvider-4CAPQ7UY.mjs → WeaviateProvider-5FWDFITI.mjs} +2 -2
  16. package/dist/{chunk-5KNBWQM6.mjs → chunk-3DSHW676.mjs} +5 -1
  17. package/dist/{chunk-PRC5CZIZ.mjs → chunk-5W2YWFT3.mjs} +1248 -1361
  18. package/dist/{chunk-H6RKMU7W.mjs → chunk-5YGUXK7Z.mjs} +1 -1
  19. package/dist/{chunk-PQKTC73Y.mjs → chunk-CD6TSNL4.mjs} +67 -6
  20. package/dist/{chunk-RK2UDJA2.mjs → chunk-CFVEZTBJ.mjs} +1 -1
  21. package/dist/{chunk-LJWWPTWE.mjs → chunk-FLOSGE6A.mjs} +76 -14
  22. package/dist/{chunk-GQT5LF4G.mjs → chunk-LR3VMDVK.mjs} +2 -2
  23. package/dist/{chunk-KTS3LLHY.mjs → chunk-M6JSPGAR.mjs} +5 -5
  24. package/dist/{chunk-3QWAK3RZ.mjs → chunk-U55XRW3U.mjs} +6 -2
  25. package/dist/{chunk-XCNXPECE.mjs → chunk-VUQJVIJT.mjs} +55 -1
  26. package/dist/chunk-X4TOT24V.mjs +89 -0
  27. package/dist/{chunk-EDLTMSNY.mjs → chunk-YLTMFW4M.mjs} +1 -1
  28. package/dist/handlers/index.d.mts +2 -2
  29. package/dist/handlers/index.d.ts +2 -2
  30. package/dist/handlers/index.js +1488 -1371
  31. package/dist/handlers/index.mjs +5 -3
  32. package/dist/index-B2mutkgp.d.ts +116 -0
  33. package/dist/index-Bjy0es5a.d.mts +116 -0
  34. package/dist/index.d.mts +17 -11
  35. package/dist/index.d.ts +17 -11
  36. package/dist/index.js +253 -363
  37. package/dist/index.mjs +243 -353
  38. package/dist/server.d.mts +108 -158
  39. package/dist/server.d.ts +108 -158
  40. package/dist/server.js +1452 -1386
  41. package/dist/server.mjs +12 -12
  42. package/package.json +5 -1
  43. package/src/config/RagConfig.ts +7 -0
  44. package/src/core/ConfigValidator.ts +66 -492
  45. package/src/core/LangChainAgent.ts +78 -0
  46. package/src/core/Pipeline.ts +210 -240
  47. package/src/core/ProviderHealthCheck.ts +35 -406
  48. package/src/core/ProviderInterfaces.ts +37 -0
  49. package/src/core/ProviderRegistry.ts +70 -55
  50. package/src/core/QueryProcessor.ts +173 -0
  51. package/src/core/VectorPlugin.ts +7 -0
  52. package/src/handlers/index.ts +45 -0
  53. package/src/llm/ILLMProvider.ts +10 -0
  54. package/src/llm/LLMFactory.ts +33 -13
  55. package/src/llm/providers/AnthropicProvider.ts +55 -15
  56. package/src/llm/providers/GeminiProvider.ts +51 -0
  57. package/src/llm/providers/OllamaProvider.ts +100 -15
  58. package/src/llm/providers/OpenAIProvider.ts +60 -11
  59. package/src/providers/vectordb/BaseVectorProvider.ts +11 -0
  60. package/src/providers/vectordb/MilvusProvider.ts +4 -0
  61. package/src/providers/vectordb/MongoDBProvider.ts +72 -8
  62. package/src/providers/vectordb/PineconeProvider.ts +60 -5
  63. package/src/providers/vectordb/PostgreSQLProvider.ts +84 -14
  64. package/src/providers/vectordb/QdrantProvider.ts +4 -0
  65. package/src/providers/vectordb/WeaviateProvider.ts +8 -4
  66. package/src/rag/DocumentChunker.ts +15 -19
  67. package/src/rag/EntityExtractor.ts +3 -0
  68. package/src/rag/LlamaIndexIngestor.ts +61 -0
  69. package/src/rag/Reranker.ts +20 -0
  70. package/src/server.ts +1 -1
  71. package/src/types/index.ts +9 -0
  72. package/dist/chunk-FWCSY2DS.mjs +0 -37
  73. package/dist/index-7qeLTPBL.d.mts +0 -114
  74. package/dist/index-DowY4_K0.d.ts +0 -114
package/dist/index.js CHANGED
@@ -59,11 +59,11 @@ __export(index_exports, {
59
59
  module.exports = __toCommonJS(index_exports);
60
60
 
61
61
  // src/components/ChatWidget.tsx
62
- var import_react6 = require("react");
62
+ var import_react7 = __toESM(require("react"));
63
63
  var import_lucide_react5 = require("lucide-react");
64
64
 
65
65
  // src/components/ChatWindow.tsx
66
- var import_react5 = require("react");
66
+ var import_react6 = __toESM(require("react"));
67
67
  var import_lucide_react4 = require("lucide-react");
68
68
 
69
69
  // src/components/MessageBubble.tsx
@@ -75,7 +75,6 @@ var import_remark_gfm = __toESM(require("remark-gfm"));
75
75
  // src/components/SourceCard.tsx
76
76
  var import_react = __toESM(require("react"));
77
77
  var import_lucide_react = require("lucide-react");
78
- var import_jsx_runtime = require("react/jsx-runtime");
79
78
  function SourceCard({ source, index }) {
80
79
  var _a, _b;
81
80
  const [expanded, setExpanded] = import_react.default.useState(false);
@@ -84,37 +83,19 @@ function SourceCard({ source, index }) {
84
83
  const scoreBg = source.score >= 0.8 ? "bg-emerald-50 border-emerald-100 dark:bg-emerald-400/10 dark:border-emerald-400/20" : source.score >= 0.6 ? "bg-amber-50 border-amber-100 dark:bg-amber-400/10 dark:border-amber-400/20" : "bg-rose-50 border-rose-100 dark:bg-rose-400/10 dark:border-rose-400/20";
85
84
  const preview = source.content.slice(0, 120);
86
85
  const hasMore = source.content.length > 120;
87
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
86
+ return /* @__PURE__ */ import_react.default.createElement(
88
87
  "div",
89
88
  {
90
89
  className: `rounded-xl border backdrop-blur-sm p-3 transition-all duration-200 hover:scale-[1.01] cursor-pointer ${scoreBg}`,
91
- onClick: () => setExpanded((e) => !e),
92
- children: [
93
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-start justify-between gap-2", children: [
94
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2 min-w-0", children: [
95
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "flex-shrink-0 w-5 h-5 rounded-full bg-slate-200 dark:bg-white/10 flex items-center justify-center text-[10px] font-bold text-slate-500 dark:text-white/60", children: index + 1 }),
96
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-xs text-slate-500 dark:text-white/50 truncate font-mono", children: (_b = (_a = source.metadata) == null ? void 0 : _a.docId) != null ? _b : source.id })
97
- ] }),
98
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: `flex-shrink-0 text-xs font-semibold ${scoreColor} tabular-nums`, children: [
99
- scorePercent,
100
- "%"
101
- ] })
102
- ] }),
103
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mt-2 text-xs text-slate-600 dark:text-white/70 leading-relaxed", children: expanded ? source.content : `${preview}${hasMore && !expanded ? "\u2026" : ""}` }),
104
- hasMore && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "mt-1 text-[10px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-0.5", children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
105
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ChevronUp, { className: "w-3 h-3" }),
106
- " Show less"
107
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
108
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ChevronDown, { className: "w-3 h-3" }),
109
- " Show more"
110
- ] }) })
111
- ]
112
- }
90
+ onClick: () => setExpanded((e) => !e)
91
+ },
92
+ /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-start justify-between gap-2" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-center gap-2 min-w-0" }, /* @__PURE__ */ import_react.default.createElement("span", { className: "flex-shrink-0 w-5 h-5 rounded-full bg-slate-200 dark:bg-white/10 flex items-center justify-center text-[10px] font-bold text-slate-500 dark:text-white/60" }, index + 1), /* @__PURE__ */ import_react.default.createElement("span", { className: "text-xs text-slate-500 dark:text-white/50 truncate font-mono" }, (_b = (_a = source.metadata) == null ? void 0 : _a.docId) != null ? _b : source.id)), /* @__PURE__ */ import_react.default.createElement("span", { className: `flex-shrink-0 text-xs font-semibold ${scoreColor} tabular-nums` }, scorePercent, "%")),
93
+ /* @__PURE__ */ import_react.default.createElement("p", { className: "mt-2 text-xs text-slate-600 dark:text-white/70 leading-relaxed" }, expanded ? source.content : `${preview}${hasMore && !expanded ? "\u2026" : ""}`),
94
+ hasMore && /* @__PURE__ */ import_react.default.createElement("button", { className: "mt-1 text-[10px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-0.5" }, expanded ? /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement(import_lucide_react.ChevronUp, { className: "w-3 h-3" }), " Show less") : /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement(import_lucide_react.ChevronDown, { className: "w-3 h-3" }), " Show more"))
113
95
  );
114
96
  }
115
97
 
116
98
  // src/components/MessageBubble.tsx
117
- var import_jsx_runtime2 = require("react/jsx-runtime");
118
99
  function MessageBubble({
119
100
  message,
120
101
  sources,
@@ -124,51 +105,36 @@ function MessageBubble({
124
105
  }) {
125
106
  const isUser = message.role === "user";
126
107
  const [showSources, setShowSources] = import_react2.default.useState(false);
127
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `flex gap-3 ${isUser ? "flex-row-reverse" : "flex-row"} items-start`, children: [
128
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
129
- "div",
130
- {
131
- className: `flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center shadow-lg ${isUser ? "text-white" : "bg-slate-100 dark:bg-white/10 text-slate-700 dark:text-white/80"}`,
132
- style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {},
133
- children: isUser ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.User, { className: "w-4 h-4 text-white" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Bot, { className: "w-4 h-4" })
134
- }
135
- ),
136
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `flex flex-col gap-1 max-w-[75%] ${isUser ? "items-end" : "items-start"}`, children: [
137
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
138
- "div",
139
- {
140
- className: `relative px-4 py-3 rounded-2xl text-sm leading-relaxed shadow-sm dark:shadow-lg ${isUser ? "text-white rounded-tr-sm" : "bg-white dark:bg-white/5 border border-slate-200 dark:border-white/10 text-slate-800 dark:text-white/90 rounded-tl-sm"}`,
141
- style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {},
142
- children: isStreaming ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "flex items-center gap-1", children: [
143
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:0ms]" }),
144
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:150ms]" }),
145
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:300ms]" })
146
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: `prose prose-sm max-w-none ${isUser ? "prose-invert" : "dark:prose-invert"}`, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default], children: message.content }) })
147
- }
148
- ),
149
- !isUser && sources && sources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "w-full", children: [
150
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
151
- "button",
152
- {
153
- onClick: () => setShowSources((s) => !s),
154
- className: "text-[11px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-1 mt-1",
155
- children: [
156
- showSources ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.ChevronDown, { className: "w-3 h-3" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.ChevronRight, { className: "w-3 h-3" }),
157
- sources.length,
158
- " source",
159
- sources.length !== 1 ? "s" : "",
160
- " used"
161
- ]
162
- }
163
- ),
164
- showSources && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "mt-2 flex flex-col gap-2", children: sources.map((src, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SourceCard, { source: src, index: i }, src.id)) })
165
- ] })
166
- ] })
167
- ] });
108
+ return /* @__PURE__ */ import_react2.default.createElement("div", { className: `flex gap-3 ${isUser ? "flex-row-reverse" : "flex-row"} items-start` }, /* @__PURE__ */ import_react2.default.createElement(
109
+ "div",
110
+ {
111
+ className: `flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center shadow-lg ${isUser ? "text-white" : "bg-slate-100 dark:bg-white/10 text-slate-700 dark:text-white/80"}`,
112
+ style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
113
+ },
114
+ isUser ? /* @__PURE__ */ import_react2.default.createElement(import_lucide_react2.User, { className: "w-4 h-4 text-white" }) : /* @__PURE__ */ import_react2.default.createElement(import_lucide_react2.Bot, { className: "w-4 h-4" })
115
+ ), /* @__PURE__ */ import_react2.default.createElement("div", { className: `flex flex-col gap-1 max-w-[75%] ${isUser ? "items-end" : "items-start"}` }, /* @__PURE__ */ import_react2.default.createElement(
116
+ "div",
117
+ {
118
+ className: `relative px-4 py-3 rounded-2xl text-sm leading-relaxed shadow-sm dark:shadow-lg ${isUser ? "text-white rounded-tr-sm" : "bg-white dark:bg-white/5 border border-slate-200 dark:border-white/10 text-slate-800 dark:text-white/90 rounded-tl-sm"}`,
119
+ style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
120
+ },
121
+ isStreaming ? /* @__PURE__ */ import_react2.default.createElement("span", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react2.default.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:0ms]" }), /* @__PURE__ */ import_react2.default.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:150ms]" }), /* @__PURE__ */ import_react2.default.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:300ms]" })) : /* @__PURE__ */ import_react2.default.createElement("div", { className: `prose prose-sm max-w-none ${isUser ? "prose-invert" : "dark:prose-invert"}` }, /* @__PURE__ */ import_react2.default.createElement(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default] }, message.content))
122
+ ), !isUser && sources && sources.length > 0 && /* @__PURE__ */ import_react2.default.createElement("div", { className: "w-full" }, /* @__PURE__ */ import_react2.default.createElement(
123
+ "button",
124
+ {
125
+ onClick: () => setShowSources((s) => !s),
126
+ className: "text-[11px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-1 mt-1"
127
+ },
128
+ showSources ? /* @__PURE__ */ import_react2.default.createElement(import_lucide_react2.ChevronDown, { className: "w-3 h-3" }) : /* @__PURE__ */ import_react2.default.createElement(import_lucide_react2.ChevronRight, { className: "w-3 h-3" }),
129
+ sources.length,
130
+ " source",
131
+ sources.length !== 1 ? "s" : "",
132
+ " used"
133
+ ), showSources && /* @__PURE__ */ import_react2.default.createElement("div", { className: "mt-2 flex flex-col gap-2" }, sources.map((src, i) => /* @__PURE__ */ import_react2.default.createElement(SourceCard, { key: src.id, source: src, index: i }))))));
168
134
  }
169
135
 
170
136
  // src/components/ConfigProvider.tsx
171
- var import_react3 = require("react");
137
+ var import_react3 = __toESM(require("react"));
172
138
 
173
139
  // src/utils/templateUtils.ts
174
140
  function mergeDefined(base, override) {
@@ -185,7 +151,6 @@ function mergeDefined(base, override) {
185
151
  }
186
152
 
187
153
  // src/components/ConfigProvider.tsx
188
- var import_jsx_runtime3 = require("react/jsx-runtime");
189
154
  var defaultConfig = {
190
155
  projectId: "default",
191
156
  ui: {
@@ -213,7 +178,7 @@ function ConfigProvider({
213
178
  projectId: (config == null ? void 0 : config.projectId) || defaultConfig.projectId,
214
179
  ui: mergeDefined(defaultConfig.ui, config == null ? void 0 : config.ui)
215
180
  };
216
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ConfigContext.Provider, { value: merged, children });
181
+ return /* @__PURE__ */ import_react3.default.createElement(ConfigContext.Provider, { value: merged }, children);
217
182
  }
218
183
  function useConfig() {
219
184
  return (0, import_react3.useContext)(ConfigContext);
@@ -341,8 +306,8 @@ function useRagChat(projectId, options = {}) {
341
306
  }
342
307
 
343
308
  // src/app/constants.tsx
309
+ var import_react5 = __toESM(require("react"));
344
310
  var import_lucide_react3 = require("lucide-react");
345
- var import_jsx_runtime4 = require("react/jsx-runtime");
346
311
  var CHAT_SUGGESTIONS = [
347
312
  "What can you help me with?",
348
313
  "Summarise the key topics",
@@ -358,29 +323,25 @@ var BORDER_RADIUS_MAP = {
358
323
  };
359
324
 
360
325
  // src/components/ChatWindow.tsx
361
- var import_jsx_runtime5 = (
362
- // eslint-disable-next-line @next/next/no-img-element
363
- require("react/jsx-runtime")
364
- );
365
326
  function ChatWindow({ className = "", style, onClose, showClose = false }) {
366
327
  const { ui, projectId } = useConfig();
367
- const [input, setInput] = (0, import_react5.useState)("");
368
- const [mounted, setMounted] = (0, import_react5.useState)(false);
369
- const bottomRef = (0, import_react5.useRef)(null);
370
- const inputRef = (0, import_react5.useRef)(null);
328
+ const [input, setInput] = (0, import_react6.useState)("");
329
+ const [mounted, setMounted] = (0, import_react6.useState)(false);
330
+ const bottomRef = (0, import_react6.useRef)(null);
331
+ const inputRef = (0, import_react6.useRef)(null);
371
332
  const { messages, send, clear, isLoading, error } = useRagChat(projectId, {
372
333
  namespace: projectId
373
334
  });
374
- (0, import_react5.useEffect)(() => {
335
+ (0, import_react6.useEffect)(() => {
375
336
  setMounted(true);
376
337
  }, []);
377
- (0, import_react5.useEffect)(() => {
338
+ (0, import_react6.useEffect)(() => {
378
339
  var _a;
379
340
  if (messages.length > 0 || isLoading) {
380
341
  (_a = bottomRef.current) == null ? void 0 : _a.scrollIntoView({ behavior: "smooth" });
381
342
  }
382
343
  }, [messages, isLoading]);
383
- const sendMessage = (0, import_react5.useCallback)(async () => {
344
+ const sendMessage = (0, import_react6.useCallback)(async () => {
384
345
  const text = input.trim();
385
346
  if (!text || isLoading) return;
386
347
  setInput("");
@@ -402,159 +363,123 @@ function ChatWindow({ className = "", style, onClose, showClose = false }) {
402
363
  const isEmpty = messages.length === 0;
403
364
  const currentRadius = BORDER_RADIUS_MAP[ui.borderRadius || "xl"];
404
365
  const isGlass = ui.visualStyle !== "solid";
405
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
366
+ return /* @__PURE__ */ import_react6.default.createElement(
406
367
  "div",
407
368
  {
408
369
  className: `flex flex-col border border-slate-200 dark:border-white/10 shadow-2xl transition-all duration-300 ${currentRadius} ${isGlass ? "bg-white/90 dark:bg-[#0f0f1a]/90 backdrop-blur-xl" : "bg-white dark:bg-[#0f0f1a]"} ${className}`,
409
- style: __spreadValues({ "--primary": ui.primaryColor, "--accent": ui.accentColor }, style),
410
- children: [
411
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
412
- "div",
370
+ style: __spreadValues({ "--primary": ui.primaryColor, "--accent": ui.accentColor }, style)
371
+ },
372
+ /* @__PURE__ */ import_react6.default.createElement(
373
+ "div",
374
+ {
375
+ className: "flex items-center justify-between px-5 py-4 border-b border-slate-200 dark:border-white/10",
376
+ style: { background: `linear-gradient(135deg, ${ui.primaryColor}15, ${ui.accentColor}10)` }
377
+ },
378
+ /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex items-center gap-3" }, ui.logoUrl ? (
379
+ // eslint-disable-next-line @next/next/no-img-element
380
+ /* @__PURE__ */ import_react6.default.createElement("img", { src: ui.logoUrl, alt: "logo", className: "w-8 h-8 rounded-lg object-cover" })
381
+ ) : /* @__PURE__ */ import_react6.default.createElement(
382
+ "div",
383
+ {
384
+ className: `w-9 h-9 flex items-center justify-center shadow-md ${ui.borderRadius === "full" ? "rounded-full" : "rounded-xl"}`,
385
+ style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
386
+ },
387
+ /* @__PURE__ */ import_react6.default.createElement(import_lucide_react4.Bot, { className: "w-5 h-5 text-white" })
388
+ ), /* @__PURE__ */ import_react6.default.createElement("div", null, /* @__PURE__ */ import_react6.default.createElement("h2", { className: "text-slate-900 dark:text-white font-semibold text-sm leading-tight" }, ui.title), ui.poweredBy && /* @__PURE__ */ import_react6.default.createElement("p", { className: "text-slate-500 dark:text-white/40 text-[11px] leading-tight" }, `Powered by ${ui.poweredBy}`))),
389
+ /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react6.default.createElement("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400" }, /* @__PURE__ */ import_react6.default.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-emerald-500 dark:bg-emerald-400 animate-pulse" }), "Online"), mounted && messages.length > 0 && /* @__PURE__ */ import_react6.default.createElement(
390
+ "button",
391
+ {
392
+ onClick: clearHistory,
393
+ title: "Clear conversation",
394
+ className: "w-7 h-7 rounded-lg flex items-center justify-center text-slate-400 hover:text-slate-600 dark:text-white/40 dark:hover:text-white/70 hover:bg-slate-100 dark:hover:bg-white/10 transition-all cursor-pointer"
395
+ },
396
+ /* @__PURE__ */ import_react6.default.createElement(import_lucide_react4.Trash2, { className: "w-3.5 h-3.5" })
397
+ ), showClose && onClose && /* @__PURE__ */ import_react6.default.createElement(
398
+ "button",
399
+ {
400
+ onClick: onClose,
401
+ title: "Close chat",
402
+ className: "w-7 h-7 rounded-lg flex items-center justify-center text-slate-400 hover:text-slate-600 dark:text-white/40 dark:hover:text-white/70 hover:bg-slate-100 dark:hover:bg-white/10 transition-all cursor-pointer"
403
+ },
404
+ /* @__PURE__ */ import_react6.default.createElement(import_lucide_react4.X, { className: "w-4 h-4" })
405
+ ))
406
+ ),
407
+ /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex-1 overflow-y-auto px-4 py-4 space-y-5 scrollbar-thin scrollbar-thumb-slate-200 dark:scrollbar-thumb-white/10 scrollbar-track-transparent min-h-0 bg-slate-50 dark:bg-transparent" }, !mounted || isEmpty ? (
408
+ /* Welcome state */
409
+ /* @__PURE__ */ import_react6.default.createElement("div", { className: "h-full flex flex-col items-center justify-center text-center gap-4 px-6 py-12" }, /* @__PURE__ */ import_react6.default.createElement(
410
+ "div",
411
+ {
412
+ className: `w-16 h-16 flex items-center justify-center shadow-lg ${ui.borderRadius === "full" ? "rounded-full" : "rounded-2xl"}`,
413
+ style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
414
+ },
415
+ /* @__PURE__ */ import_react6.default.createElement(import_lucide_react4.Sparkles, { className: "w-8 h-8 text-white" })
416
+ ), /* @__PURE__ */ import_react6.default.createElement("div", null, /* @__PURE__ */ import_react6.default.createElement("p", { className: "text-slate-800 dark:text-white/80 font-medium leading-relaxed" }, ui.welcomeMessage), /* @__PURE__ */ import_react6.default.createElement("p", { className: "text-slate-500 dark:text-white/30 text-sm mt-2" }, "Ask a question to get started")), /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex flex-wrap gap-2 justify-center mt-2" }, CHAT_SUGGESTIONS.map(
417
+ (suggestion) => /* @__PURE__ */ import_react6.default.createElement(
418
+ "button",
413
419
  {
414
- className: "flex items-center justify-between px-5 py-4 border-b border-slate-200 dark:border-white/10",
415
- style: { background: `linear-gradient(135deg, ${ui.primaryColor}15, ${ui.accentColor}10)` },
416
- children: [
417
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-3", children: [
418
- ui.logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { src: ui.logoUrl, alt: "logo", className: "w-8 h-8 rounded-lg object-cover" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
419
- "div",
420
- {
421
- className: `w-9 h-9 flex items-center justify-center shadow-md ${ui.borderRadius === "full" ? "rounded-full" : "rounded-xl"}`,
422
- style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
423
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.Bot, { className: "w-5 h-5 text-white" })
424
- }
425
- ),
426
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
427
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { className: "text-slate-900 dark:text-white font-semibold text-sm leading-tight", children: ui.title }),
428
- ui.poweredBy && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-slate-500 dark:text-white/40 text-[11px] leading-tight", children: `Powered by ${ui.poweredBy}` })
429
- ] })
430
- ] }),
431
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-2", children: [
432
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400", children: [
433
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-emerald-500 dark:bg-emerald-400 animate-pulse" }),
434
- "Online"
435
- ] }),
436
- mounted && messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
437
- "button",
438
- {
439
- onClick: clearHistory,
440
- title: "Clear conversation",
441
- className: "w-7 h-7 rounded-lg flex items-center justify-center text-slate-400 hover:text-slate-600 dark:text-white/40 dark:hover:text-white/70 hover:bg-slate-100 dark:hover:bg-white/10 transition-all cursor-pointer",
442
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.Trash2, { className: "w-3.5 h-3.5" })
443
- }
444
- ),
445
- showClose && onClose && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
446
- "button",
447
- {
448
- onClick: onClose,
449
- title: "Close chat",
450
- className: "w-7 h-7 rounded-lg flex items-center justify-center text-slate-400 hover:text-slate-600 dark:text-white/40 dark:hover:text-white/70 hover:bg-slate-100 dark:hover:bg-white/10 transition-all cursor-pointer",
451
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.X, { className: "w-4 h-4" })
452
- }
453
- )
454
- ] })
455
- ]
456
- }
457
- ),
458
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex-1 overflow-y-auto px-4 py-4 space-y-5 scrollbar-thin scrollbar-thumb-slate-200 dark:scrollbar-thumb-white/10 scrollbar-track-transparent min-h-0 bg-slate-50 dark:bg-transparent", children: [
459
- !mounted || isEmpty ? (
460
- /* Welcome state */
461
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "h-full flex flex-col items-center justify-center text-center gap-4 px-6 py-12", children: [
462
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
463
- "div",
464
- {
465
- className: `w-16 h-16 flex items-center justify-center shadow-lg ${ui.borderRadius === "full" ? "rounded-full" : "rounded-2xl"}`,
466
- style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
467
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.Sparkles, { className: "w-8 h-8 text-white" })
468
- }
469
- ),
470
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
471
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-slate-800 dark:text-white/80 font-medium leading-relaxed", children: ui.welcomeMessage }),
472
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-slate-500 dark:text-white/30 text-sm mt-2", children: "Ask a question to get started" })
473
- ] }),
474
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex flex-wrap gap-2 justify-center mt-2", children: CHAT_SUGGESTIONS.map(
475
- (suggestion) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
476
- "button",
477
- {
478
- onClick: () => {
479
- var _a;
480
- setInput(suggestion);
481
- (_a = inputRef.current) == null ? void 0 : _a.focus();
482
- },
483
- className: "px-3 py-1.5 rounded-full text-xs border border-slate-200 dark:border-white/10 text-slate-600 dark:text-white/50 hover:text-slate-900 dark:hover:text-white/80 hover:border-slate-300 dark:hover:border-white/20 hover:bg-slate-100 dark:hover:bg-white/5 transition-all",
484
- children: suggestion
485
- },
486
- suggestion
487
- )
488
- ) })
489
- ] })
490
- ) : messages.map((msg) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
491
- MessageBubble,
492
- {
493
- message: msg,
494
- sources: msg.sources,
495
- primaryColor: ui.primaryColor,
496
- accentColor: ui.accentColor
420
+ key: suggestion,
421
+ onClick: () => {
422
+ var _a;
423
+ setInput(suggestion);
424
+ (_a = inputRef.current) == null ? void 0 : _a.focus();
497
425
  },
498
- msg.id
499
- )),
500
- isLoading && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
501
- MessageBubble,
502
- {
503
- message: { role: "assistant", content: "" },
504
- isStreaming: true,
505
- primaryColor: ui.primaryColor,
506
- accentColor: ui.accentColor
507
- }
508
- ),
509
- error && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-2 text-rose-500 dark:text-rose-400 text-sm bg-rose-50 dark:bg-rose-400/10 border border-rose-200 dark:border-rose-400/20 rounded-xl px-4 py-3", children: [
510
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.TriangleAlert, { className: "w-4 h-4 flex-shrink-0" }),
511
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: error })
512
- ] }),
513
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: bottomRef })
514
- ] }),
515
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `px-4 pb-4 pt-2 border-t border-slate-200 dark:border-white/10 ${isGlass ? "bg-transparent" : "bg-white dark:bg-[#0f0f1a]"}`, children: [
516
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `flex items-end gap-2 bg-slate-50 dark:bg-white/5 border border-slate-200 dark:border-white/10 p-2 focus-within:border-slate-300 dark:focus-within:border-white/20 transition-all ${ui.borderRadius === "full" ? "rounded-3xl" : "rounded-2xl"}`, children: [
517
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
518
- "textarea",
519
- {
520
- ref: inputRef,
521
- value: input,
522
- onChange: (e) => setInput(e.target.value),
523
- onKeyDown: handleKeyDown,
524
- placeholder: ui.placeholder,
525
- rows: 1,
526
- disabled: isLoading,
527
- className: "flex-1 bg-transparent text-slate-900 dark:text-white/90 placeholder-slate-400 dark:placeholder-white/30 text-sm resize-none outline-none py-1.5 px-2 max-h-32 leading-relaxed disabled:opacity-50",
528
- style: { scrollbarWidth: "none" }
529
- }
530
- ),
531
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
532
- "button",
533
- {
534
- onClick: sendMessage,
535
- disabled: !input.trim() || isLoading,
536
- className: "flex-shrink-0 w-9 h-9 rounded-xl flex items-center justify-center transition-all disabled:opacity-30 disabled:cursor-not-allowed hover:scale-105 active:scale-95 shadow-md",
537
- style: {
538
- background: input.trim() && !isLoading ? `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` : "rgba(148, 163, 184, 0.2)"
539
- // slate-400/20 for light mode disabled
540
- },
541
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.ArrowUp, { className: "w-4 h-4 text-white" })
542
- }
543
- )
544
- ] }),
545
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-center text-[10px] text-slate-400 dark:text-white/20 mt-2", children: "Press Enter to send \xB7 Shift+Enter for new line" })
546
- ] })
547
- ]
548
- }
426
+ className: "px-3 py-1.5 rounded-full text-xs border border-slate-200 dark:border-white/10 text-slate-600 dark:text-white/50 hover:text-slate-900 dark:hover:text-white/80 hover:border-slate-300 dark:hover:border-white/20 hover:bg-slate-100 dark:hover:bg-white/5 transition-all"
427
+ },
428
+ suggestion
429
+ )
430
+ )))
431
+ ) : messages.map((msg) => /* @__PURE__ */ import_react6.default.createElement(
432
+ MessageBubble,
433
+ {
434
+ key: msg.id,
435
+ message: msg,
436
+ sources: msg.sources,
437
+ primaryColor: ui.primaryColor,
438
+ accentColor: ui.accentColor
439
+ }
440
+ )), isLoading && /* @__PURE__ */ import_react6.default.createElement(
441
+ MessageBubble,
442
+ {
443
+ message: { role: "assistant", content: "" },
444
+ isStreaming: true,
445
+ primaryColor: ui.primaryColor,
446
+ accentColor: ui.accentColor
447
+ }
448
+ ), error && /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex items-center gap-2 text-rose-500 dark:text-rose-400 text-sm bg-rose-50 dark:bg-rose-400/10 border border-rose-200 dark:border-rose-400/20 rounded-xl px-4 py-3" }, /* @__PURE__ */ import_react6.default.createElement(import_lucide_react4.TriangleAlert, { className: "w-4 h-4 flex-shrink-0" }), /* @__PURE__ */ import_react6.default.createElement("span", null, error)), /* @__PURE__ */ import_react6.default.createElement("div", { ref: bottomRef })),
449
+ /* @__PURE__ */ import_react6.default.createElement("div", { className: `px-4 pb-4 pt-2 border-t border-slate-200 dark:border-white/10 ${isGlass ? "bg-transparent" : "bg-white dark:bg-[#0f0f1a]"}` }, /* @__PURE__ */ import_react6.default.createElement("div", { className: `flex items-end gap-2 bg-slate-50 dark:bg-white/5 border border-slate-200 dark:border-white/10 p-2 focus-within:border-slate-300 dark:focus-within:border-white/20 transition-all ${ui.borderRadius === "full" ? "rounded-3xl" : "rounded-2xl"}` }, /* @__PURE__ */ import_react6.default.createElement(
450
+ "textarea",
451
+ {
452
+ ref: inputRef,
453
+ value: input,
454
+ onChange: (e) => setInput(e.target.value),
455
+ onKeyDown: handleKeyDown,
456
+ placeholder: ui.placeholder,
457
+ rows: 1,
458
+ disabled: isLoading,
459
+ className: "flex-1 bg-transparent text-slate-900 dark:text-white/90 placeholder-slate-400 dark:placeholder-white/30 text-sm resize-none outline-none py-1.5 px-2 max-h-32 leading-relaxed disabled:opacity-50",
460
+ style: { scrollbarWidth: "none" }
461
+ }
462
+ ), /* @__PURE__ */ import_react6.default.createElement(
463
+ "button",
464
+ {
465
+ onClick: sendMessage,
466
+ disabled: !input.trim() || isLoading,
467
+ className: "flex-shrink-0 w-9 h-9 rounded-xl flex items-center justify-center transition-all disabled:opacity-30 disabled:cursor-not-allowed hover:scale-105 active:scale-95 shadow-md",
468
+ style: {
469
+ background: input.trim() && !isLoading ? `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` : "rgba(148, 163, 184, 0.2)"
470
+ // slate-400/20 for light mode disabled
471
+ }
472
+ },
473
+ /* @__PURE__ */ import_react6.default.createElement(import_lucide_react4.ArrowUp, { className: "w-4 h-4 text-white" })
474
+ )), /* @__PURE__ */ import_react6.default.createElement("p", { className: "text-center text-[10px] text-slate-400 dark:text-white/20 mt-2" }, "Press Enter to send \xB7 Shift+Enter for new line"))
549
475
  );
550
476
  }
551
477
 
552
478
  // src/components/ChatWidget.tsx
553
- var import_jsx_runtime6 = require("react/jsx-runtime");
554
479
  function ChatWidget({ position = "bottom-right" }) {
555
480
  const { ui } = useConfig();
556
- const [isOpen, setIsOpen] = (0, import_react6.useState)(false);
557
- const [hasUnread, setHasUnread] = (0, import_react6.useState)(false);
481
+ const [isOpen, setIsOpen] = (0, import_react7.useState)(false);
482
+ const [hasUnread, setHasUnread] = (0, import_react7.useState)(false);
558
483
  if (ui.showWidget === false) return null;
559
484
  const positionClass = position === "bottom-left" ? "bottom-6 left-6" : "bottom-6 right-6";
560
485
  const windowPositionClass = position === "bottom-left" ? "bottom-20 left-6" : "bottom-20 right-6";
@@ -563,68 +488,60 @@ function ChatWidget({ position = "bottom-right" }) {
563
488
  setIsOpen(true);
564
489
  setHasUnread(false);
565
490
  };
566
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
567
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
568
- "div",
491
+ return /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, null, /* @__PURE__ */ import_react7.default.createElement(
492
+ "div",
493
+ {
494
+ className: `fixed z-[9998] w-[380px] max-w-[calc(100vw-3rem)] transition-all duration-300 ease-in-out ${windowPositionClass} ${isOpen ? "opacity-100 translate-y-0 pointer-events-auto" : "opacity-0 translate-y-4 pointer-events-none"}`,
495
+ style: { height: "600px", maxHeight: "calc(100vh - 6rem)" }
496
+ },
497
+ /* @__PURE__ */ import_react7.default.createElement(
498
+ ChatWindow,
569
499
  {
570
- className: `fixed z-[9998] w-[380px] max-w-[calc(100vw-3rem)] transition-all duration-300 ease-in-out ${windowPositionClass} ${isOpen ? "opacity-100 translate-y-0 pointer-events-auto" : "opacity-0 translate-y-4 pointer-events-none"}`,
571
- style: { height: "600px", maxHeight: "calc(100vh - 6rem)" },
572
- children: [
573
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
574
- ChatWindow,
575
- {
576
- className: "h-full relative z-10",
577
- showClose: true,
578
- onClose: () => setIsOpen(false)
579
- }
580
- ),
581
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
582
- "div",
583
- {
584
- className: `absolute -bottom-1.5 w-4 h-4 rotate-45 border-r border-b border-slate-200 dark:border-white/10 z-0 ${ui.visualStyle === "solid" ? "bg-white dark:bg-[#0f0f1a]" : "bg-white/90 dark:bg-[#0f0f1a]/90 backdrop-blur-xl"} ${position === "bottom-left" ? "left-5" : "right-5"}`
585
- }
586
- )
587
- ]
500
+ className: "h-full relative z-10",
501
+ showClose: true,
502
+ onClose: () => setIsOpen(false)
588
503
  }
589
504
  ),
590
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
591
- "button",
505
+ /* @__PURE__ */ import_react7.default.createElement(
506
+ "div",
592
507
  {
593
- onClick: isOpen ? () => setIsOpen(false) : handleOpen,
594
- className: `fixed z-[9999] w-14 h-14 shadow-2xl flex items-center justify-center transition-all duration-300 cursor-pointer hover:scale-110 active:scale-95 ${ui.borderRadius === "full" ? "rounded-full" : "rounded-2xl"} ${positionClass}`,
595
- style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
596
- "aria-label": "Open chat",
597
- children: [
598
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
599
- "span",
600
- {
601
- className: "absolute inset-0 rounded-full animate-ping opacity-20",
602
- style: { background: ui.primaryColor }
603
- }
604
- ),
605
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
606
- "span",
607
- {
608
- className: `transition-transform duration-300 ${isOpen ? "rotate-90 scale-90" : "rotate-0 scale-100"}`,
609
- children: isOpen ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.X, { className: "w-6 h-6 text-white" }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.MessageSquare, { className: "w-6 h-6 text-white" })
610
- }
611
- ),
612
- hasUnread && !isOpen && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "absolute top-0 right-0 w-4 h-4 bg-rose-500 rounded-full border-2 border-white flex items-center justify-center text-[9px] font-bold text-white", children: "1" })
613
- ]
508
+ className: `absolute -bottom-1.5 w-4 h-4 rotate-45 border-r border-b border-slate-200 dark:border-white/10 z-0 ${ui.visualStyle === "solid" ? "bg-white dark:bg-[#0f0f1a]" : "bg-white/90 dark:bg-[#0f0f1a]/90 backdrop-blur-xl"} ${position === "bottom-left" ? "left-5" : "right-5"}`
614
509
  }
615
510
  )
616
- ] });
511
+ ), /* @__PURE__ */ import_react7.default.createElement(
512
+ "button",
513
+ {
514
+ onClick: isOpen ? () => setIsOpen(false) : handleOpen,
515
+ className: `fixed z-[9999] w-14 h-14 shadow-2xl flex items-center justify-center transition-all duration-300 cursor-pointer hover:scale-110 active:scale-95 ${ui.borderRadius === "full" ? "rounded-full" : "rounded-2xl"} ${positionClass}`,
516
+ style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
517
+ "aria-label": "Open chat"
518
+ },
519
+ /* @__PURE__ */ import_react7.default.createElement(
520
+ "span",
521
+ {
522
+ className: "absolute inset-0 rounded-full animate-ping opacity-20",
523
+ style: { background: ui.primaryColor }
524
+ }
525
+ ),
526
+ /* @__PURE__ */ import_react7.default.createElement(
527
+ "span",
528
+ {
529
+ className: `transition-transform duration-300 ${isOpen ? "rotate-90 scale-90" : "rotate-0 scale-100"}`
530
+ },
531
+ isOpen ? /* @__PURE__ */ import_react7.default.createElement(import_lucide_react5.X, { className: "w-6 h-6 text-white" }) : /* @__PURE__ */ import_react7.default.createElement(import_lucide_react5.MessageSquare, { className: "w-6 h-6 text-white" })
532
+ ),
533
+ hasUnread && !isOpen && /* @__PURE__ */ import_react7.default.createElement("span", { className: "absolute top-0 right-0 w-4 h-4 bg-rose-500 rounded-full border-2 border-white flex items-center justify-center text-[9px] font-bold text-white" }, "1")
534
+ ));
617
535
  }
618
536
 
619
537
  // src/components/DocumentUpload.tsx
620
- var import_react7 = require("react");
538
+ var import_react8 = __toESM(require("react"));
621
539
  var import_lucide_react6 = require("lucide-react");
622
- var import_jsx_runtime7 = require("react/jsx-runtime");
623
540
  function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
624
541
  const { ui } = useConfig();
625
- const [fileStates, setFileStates] = (0, import_react7.useState)([]);
626
- const [isDragging, setIsDragging] = (0, import_react7.useState)(false);
627
- const fileInputRef = (0, import_react7.useRef)(null);
542
+ const [fileStates, setFileStates] = (0, import_react8.useState)([]);
543
+ const [isDragging, setIsDragging] = (0, import_react8.useState)(false);
544
+ const fileInputRef = (0, import_react8.useRef)(null);
628
545
  const addFiles = (files) => {
629
546
  const newStates = files.map((file) => ({ file, status: "idle" }));
630
547
  setFileStates((prev) => [...prev, ...newStates]);
@@ -674,99 +591,72 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
674
591
  };
675
592
  const isUploading = fileStates.some((s) => s.status === "uploading");
676
593
  const hasIdle = fileStates.some((s) => s.status === "idle");
677
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
594
+ return /* @__PURE__ */ import_react8.default.createElement(
678
595
  "div",
679
596
  {
680
597
  className: `p-6 border-2 border-dashed transition-all duration-300 rounded-2xl ${isDragging ? "border-emerald-500 bg-emerald-50/50 dark:bg-emerald-500/5" : "border-slate-200 dark:border-white/10 bg-white dark:bg-white/5"} ${className}`,
681
598
  onDragOver,
682
599
  onDragLeave,
683
- onDrop,
684
- children: [
685
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-col items-center justify-center text-center", children: [
686
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
687
- "div",
688
- {
689
- className: "w-12 h-12 rounded-full flex items-center justify-center mb-4 shadow-sm",
690
- style: { background: `linear-gradient(135deg, ${ui.primaryColor}20, ${ui.accentColor}20)` },
691
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react6.Upload, { className: "w-6 h-6", style: { color: ui.primaryColor } })
692
- }
693
- ),
694
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { className: "text-slate-900 dark:text-white font-semibold mb-1", children: "Upload Documents" }),
695
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-slate-500 dark:text-white/40 text-sm mb-6 max-w-xs", children: "Drag and drop PDF, DOCX, TXT, or JSON files to train your AI on your own data." }),
696
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
697
- "button",
698
- {
699
- onClick: () => {
700
- var _a;
701
- return (_a = fileInputRef.current) == null ? void 0 : _a.click();
702
- },
703
- disabled: isUploading,
704
- className: "px-4 py-2 rounded-lg text-sm font-medium transition-all hover:scale-105 active:scale-95 disabled:opacity-50",
705
- style: {
706
- backgroundColor: `${ui.primaryColor}15`,
707
- color: ui.primaryColor,
708
- border: `1px solid ${ui.primaryColor}30`
709
- },
710
- children: "Select Files"
711
- }
712
- ),
713
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
714
- "input",
715
- {
716
- ref: fileInputRef,
717
- type: "file",
718
- multiple: true,
719
- onChange: onFileSelect,
720
- className: "hidden",
721
- accept: ".pdf,.docx,.txt,.md,.json,.csv"
722
- }
723
- )
724
- ] }),
725
- fileStates.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mt-8 space-y-3", children: [
726
- fileStates.map((state, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
727
- "div",
728
- {
729
- className: "flex items-center justify-between p-3 rounded-xl bg-slate-50 dark:bg-white/5 border border-slate-100 dark:border-white/10",
730
- children: [
731
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-3 overflow-hidden", children: [
732
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "w-8 h-8 rounded-lg bg-white dark:bg-white/10 flex items-center justify-center shadow-sm", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react6.File, { className: "w-4 h-4 text-slate-400" }) }),
733
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "truncate", children: [
734
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-xs font-medium text-slate-700 dark:text-white/80 truncate", children: state.file.name }),
735
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "text-[10px] text-slate-400", children: [
736
- (state.file.size / 1024).toFixed(1),
737
- " KB"
738
- ] })
739
- ] })
740
- ] }),
741
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-2", children: [
742
- state.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react6.Loader2, { className: "w-4 h-4 text-slate-400 animate-spin" }),
743
- state.status === "success" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react6.CheckCircle, { className: "w-4 h-4 text-emerald-500" }),
744
- state.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { title: state.error, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react6.AlertCircle, { className: "w-4 h-4 text-rose-500" }) }),
745
- state.status !== "uploading" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
746
- "button",
747
- {
748
- onClick: () => removeFile(i),
749
- className: "p-1 rounded-md hover:bg-slate-200 dark:hover:bg-white/10 transition-colors",
750
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react6.X, { className: "w-3.5 h-3.5 text-slate-400" })
751
- }
752
- )
753
- ] })
754
- ]
755
- },
756
- i
757
- )),
758
- hasIdle && !isUploading && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
759
- "button",
760
- {
761
- onClick: uploadFiles,
762
- className: "w-full mt-4 py-2.5 rounded-xl text-sm font-semibold text-white shadow-lg transition-all hover:scale-[1.02] active:scale-[0.98]",
763
- style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
764
- children: "Start Upload"
765
- }
766
- )
767
- ] })
768
- ]
769
- }
600
+ onDrop
601
+ },
602
+ /* @__PURE__ */ import_react8.default.createElement("div", { className: "flex flex-col items-center justify-center text-center" }, /* @__PURE__ */ import_react8.default.createElement(
603
+ "div",
604
+ {
605
+ className: "w-12 h-12 rounded-full flex items-center justify-center mb-4 shadow-sm",
606
+ style: { background: `linear-gradient(135deg, ${ui.primaryColor}20, ${ui.accentColor}20)` }
607
+ },
608
+ /* @__PURE__ */ import_react8.default.createElement(import_lucide_react6.Upload, { className: "w-6 h-6", style: { color: ui.primaryColor } })
609
+ ), /* @__PURE__ */ import_react8.default.createElement("h3", { className: "text-slate-900 dark:text-white font-semibold mb-1" }, "Upload Documents"), /* @__PURE__ */ import_react8.default.createElement("p", { className: "text-slate-500 dark:text-white/40 text-sm mb-6 max-w-xs" }, "Drag and drop PDF, DOCX, TXT, or JSON files to train your AI on your own data."), /* @__PURE__ */ import_react8.default.createElement(
610
+ "button",
611
+ {
612
+ onClick: () => {
613
+ var _a;
614
+ return (_a = fileInputRef.current) == null ? void 0 : _a.click();
615
+ },
616
+ disabled: isUploading,
617
+ className: "px-4 py-2 rounded-lg text-sm font-medium transition-all hover:scale-105 active:scale-95 disabled:opacity-50",
618
+ style: {
619
+ backgroundColor: `${ui.primaryColor}15`,
620
+ color: ui.primaryColor,
621
+ border: `1px solid ${ui.primaryColor}30`
622
+ }
623
+ },
624
+ "Select Files"
625
+ ), /* @__PURE__ */ import_react8.default.createElement(
626
+ "input",
627
+ {
628
+ ref: fileInputRef,
629
+ type: "file",
630
+ multiple: true,
631
+ onChange: onFileSelect,
632
+ className: "hidden",
633
+ accept: ".pdf,.docx,.txt,.md,.json,.csv"
634
+ }
635
+ )),
636
+ fileStates.length > 0 && /* @__PURE__ */ import_react8.default.createElement("div", { className: "mt-8 space-y-3" }, fileStates.map((state, i) => /* @__PURE__ */ import_react8.default.createElement(
637
+ "div",
638
+ {
639
+ key: i,
640
+ className: "flex items-center justify-between p-3 rounded-xl bg-slate-50 dark:bg-white/5 border border-slate-100 dark:border-white/10"
641
+ },
642
+ /* @__PURE__ */ import_react8.default.createElement("div", { className: "flex items-center gap-3 overflow-hidden" }, /* @__PURE__ */ import_react8.default.createElement("div", { className: "w-8 h-8 rounded-lg bg-white dark:bg-white/10 flex items-center justify-center shadow-sm" }, /* @__PURE__ */ import_react8.default.createElement(import_lucide_react6.File, { className: "w-4 h-4 text-slate-400" })), /* @__PURE__ */ import_react8.default.createElement("div", { className: "truncate" }, /* @__PURE__ */ import_react8.default.createElement("p", { className: "text-xs font-medium text-slate-700 dark:text-white/80 truncate" }, state.file.name), /* @__PURE__ */ import_react8.default.createElement("p", { className: "text-[10px] text-slate-400" }, (state.file.size / 1024).toFixed(1), " KB"))),
643
+ /* @__PURE__ */ import_react8.default.createElement("div", { className: "flex items-center gap-2" }, state.status === "uploading" && /* @__PURE__ */ import_react8.default.createElement(import_lucide_react6.Loader2, { className: "w-4 h-4 text-slate-400 animate-spin" }), state.status === "success" && /* @__PURE__ */ import_react8.default.createElement(import_lucide_react6.CheckCircle, { className: "w-4 h-4 text-emerald-500" }), state.status === "error" && /* @__PURE__ */ import_react8.default.createElement("div", { title: state.error }, /* @__PURE__ */ import_react8.default.createElement(import_lucide_react6.AlertCircle, { className: "w-4 h-4 text-rose-500" })), state.status !== "uploading" && /* @__PURE__ */ import_react8.default.createElement(
644
+ "button",
645
+ {
646
+ onClick: () => removeFile(i),
647
+ className: "p-1 rounded-md hover:bg-slate-200 dark:hover:bg-white/10 transition-colors"
648
+ },
649
+ /* @__PURE__ */ import_react8.default.createElement(import_lucide_react6.X, { className: "w-3.5 h-3.5 text-slate-400" })
650
+ ))
651
+ )), hasIdle && !isUploading && /* @__PURE__ */ import_react8.default.createElement(
652
+ "button",
653
+ {
654
+ onClick: uploadFiles,
655
+ className: "w-full mt-4 py-2.5 rounded-xl text-sm font-semibold text-white shadow-lg transition-all hover:scale-[1.02] active:scale-[0.98]",
656
+ style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
657
+ },
658
+ "Start Upload"
659
+ ))
770
660
  );
771
661
  }
772
662
  // Annotate the CommonJS export names for ESM import in node: