@retrivora-ai/rag-engine 1.1.4 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -7,11 +7,11 @@ import {
7
7
  } from "./chunk-X4TOT24V.mjs";
8
8
 
9
9
  // src/components/ChatWidget.tsx
10
- import React6, { useState as useState4 } from "react";
10
+ import React8, { useState as useState4 } from "react";
11
11
  import { MessageSquare, X as X2 } from "lucide-react";
12
12
 
13
13
  // src/components/ChatWindow.tsx
14
- import React5, { useState as useState3, useRef as useRef2, useEffect as useEffect3, useCallback as useCallback2 } from "react";
14
+ import React7, { useState as useState3, useRef as useRef3, useEffect as useEffect3, useCallback as useCallback2 } from "react";
15
15
  import {
16
16
  Bot as Bot2,
17
17
  Trash2,
@@ -25,8 +25,8 @@ import {
25
25
  } from "lucide-react";
26
26
 
27
27
  // src/components/MessageBubble.tsx
28
- import React2 from "react";
29
- import { Bot, User, ChevronDown as ChevronDown2, ChevronRight } from "lucide-react";
28
+ import React4 from "react";
29
+ import { Bot, User, ChevronDown as ChevronDown2, ChevronRight as ChevronRight2 } from "lucide-react";
30
30
  import ReactMarkdown from "react-markdown";
31
31
  import remarkGfm from "remark-gfm";
32
32
 
@@ -53,6 +53,79 @@ function SourceCard({ source, index }) {
53
53
  );
54
54
  }
55
55
 
56
+ // src/components/ProductCarousel.tsx
57
+ import React3, { useRef } from "react";
58
+ import { ChevronLeft, ChevronRight } from "lucide-react";
59
+
60
+ // src/components/ProductCard.tsx
61
+ import React2 from "react";
62
+ import Image from "next/image";
63
+ import { ShoppingCart, ExternalLink } from "lucide-react";
64
+ function ProductCard({ product, primaryColor = "#6366f1" }) {
65
+ return /* @__PURE__ */ React2.createElement("div", { className: "flex-shrink-0 w-64 bg-white dark:bg-white/5 border border-slate-200 dark:border-white/10 rounded-xl overflow-hidden shadow-sm hover:shadow-md transition-all duration-300 group" }, /* @__PURE__ */ React2.createElement("div", { className: "relative h-40 w-full bg-slate-100 dark:bg-white/5 flex items-center justify-center overflow-hidden" }, product.image ? /* @__PURE__ */ React2.createElement(
66
+ Image,
67
+ {
68
+ src: product.image,
69
+ alt: product.name,
70
+ fill: true,
71
+ unoptimized: true,
72
+ className: "object-cover group-hover:scale-105 transition-transform duration-500"
73
+ }
74
+ ) : /* @__PURE__ */ React2.createElement("div", { className: "text-slate-400 dark:text-white/20" }, /* @__PURE__ */ React2.createElement(ShoppingCart, { className: "w-12 h-12" })), product.brand && /* @__PURE__ */ React2.createElement("div", { className: "absolute top-2 left-2 px-2 py-1 bg-white/90 dark:bg-black/60 backdrop-blur-md rounded-md text-[10px] font-bold uppercase tracking-wider text-slate-700 dark:text-white/90 shadow-sm" }, product.brand)), /* @__PURE__ */ React2.createElement("div", { className: "p-4 flex flex-col gap-2" }, /* @__PURE__ */ React2.createElement("div", { className: "flex justify-between items-start gap-2" }, /* @__PURE__ */ React2.createElement("h3", { className: "text-sm font-semibold text-slate-800 dark:text-white/90 line-clamp-1" }, product.name), product.price && /* @__PURE__ */ React2.createElement("span", { className: "text-sm font-bold", style: { color: primaryColor } }, typeof product.price === "number" ? `$${product.price}` : product.price)), product.description && /* @__PURE__ */ React2.createElement("p", { className: "text-[11px] text-slate-500 dark:text-white/50 line-clamp-2 leading-relaxed" }, product.description), /* @__PURE__ */ React2.createElement("div", { className: "mt-2 flex gap-2" }, /* @__PURE__ */ React2.createElement(
75
+ "button",
76
+ {
77
+ className: "flex-1 py-2 px-3 rounded-lg text-[11px] font-medium text-white shadow-sm hover:opacity-90 transition-opacity flex items-center justify-center gap-1.5",
78
+ style: { background: primaryColor }
79
+ },
80
+ /* @__PURE__ */ React2.createElement(ShoppingCart, { className: "w-3 h-3" }),
81
+ "Add to Cart"
82
+ ), product.link && /* @__PURE__ */ React2.createElement(
83
+ "a",
84
+ {
85
+ href: product.link,
86
+ target: "_blank",
87
+ rel: "noopener noreferrer",
88
+ className: "p-2 rounded-lg bg-slate-100 dark:bg-white/10 text-slate-600 dark:text-white/70 hover:bg-slate-200 dark:hover:bg-white/20 transition-colors"
89
+ },
90
+ /* @__PURE__ */ React2.createElement(ExternalLink, { className: "w-3.5 h-3.5" })
91
+ ))));
92
+ }
93
+
94
+ // src/components/ProductCarousel.tsx
95
+ function ProductCarousel({ products, primaryColor = "#6366f1" }) {
96
+ const scrollRef = useRef(null);
97
+ const scroll = (direction) => {
98
+ if (scrollRef.current) {
99
+ const scrollAmount = direction === "left" ? -280 : 280;
100
+ scrollRef.current.scrollBy({ left: scrollAmount, behavior: "smooth" });
101
+ }
102
+ };
103
+ if (!products || products.length === 0) return null;
104
+ return /* @__PURE__ */ React3.createElement("div", { className: "relative w-full my-4 group/carousel" }, /* @__PURE__ */ React3.createElement("div", { className: "absolute -left-3 top-1/2 -translate-y-1/2 z-10 opacity-0 group-hover/carousel:opacity-100 transition-opacity" }, /* @__PURE__ */ React3.createElement(
105
+ "button",
106
+ {
107
+ onClick: () => scroll("left"),
108
+ className: "p-1.5 rounded-full bg-white dark:bg-slate-800 shadow-lg border border-slate-200 dark:border-white/10 text-slate-600 dark:text-white/80 hover:text-indigo-500 dark:hover:text-indigo-400 transition-colors"
109
+ },
110
+ /* @__PURE__ */ React3.createElement(ChevronLeft, { className: "w-4 h-4" })
111
+ )), /* @__PURE__ */ React3.createElement("div", { className: "absolute -right-3 top-1/2 -translate-y-1/2 z-10 opacity-0 group-hover/carousel:opacity-100 transition-opacity" }, /* @__PURE__ */ React3.createElement(
112
+ "button",
113
+ {
114
+ onClick: () => scroll("right"),
115
+ className: "p-1.5 rounded-full bg-white dark:bg-slate-800 shadow-lg border border-slate-200 dark:border-white/10 text-slate-600 dark:text-white/80 hover:text-indigo-500 dark:hover:text-indigo-400 transition-colors"
116
+ },
117
+ /* @__PURE__ */ React3.createElement(ChevronRight, { className: "w-4 h-4" })
118
+ )), /* @__PURE__ */ React3.createElement(
119
+ "div",
120
+ {
121
+ ref: scrollRef,
122
+ className: "flex gap-4 overflow-x-auto pb-4 px-1 scrollbar-hide snap-x snap-mandatory",
123
+ style: { scrollbarWidth: "none", msOverflowStyle: "none" }
124
+ },
125
+ products.map((product) => /* @__PURE__ */ React3.createElement("div", { key: product.id, className: "snap-start" }, /* @__PURE__ */ React3.createElement(ProductCard, { product, primaryColor })))
126
+ ));
127
+ }
128
+
56
129
  // src/components/MessageBubble.tsx
57
130
  function MessageBubble({
58
131
  message,
@@ -62,37 +135,92 @@ function MessageBubble({
62
135
  accentColor = "#8b5cf6"
63
136
  }) {
64
137
  const isUser = message.role === "user";
65
- const [showSources, setShowSources] = React2.useState(false);
66
- return /* @__PURE__ */ React2.createElement("div", { className: `flex gap-3 ${isUser ? "flex-row-reverse" : "flex-row"} items-start` }, /* @__PURE__ */ React2.createElement(
138
+ const [showSources, setShowSources] = React4.useState(false);
139
+ const resolveImage = (data) => {
140
+ if (!data) return void 0;
141
+ const singleFields = ["image", "img", "thumbnail"];
142
+ for (const field of singleFields) {
143
+ const val = data[field];
144
+ if (typeof val === "string" && val) return val;
145
+ }
146
+ if (Array.isArray(data.images) && data.images.length > 0) {
147
+ if (typeof data.images[0] === "string") return data.images[0];
148
+ }
149
+ return void 0;
150
+ };
151
+ const productsFromSources = React4.useMemo(() => {
152
+ if (isUser || !sources) return [];
153
+ return sources.filter((s) => {
154
+ const m = s.metadata || {};
155
+ return m.price || m.image || m.img || m.thumbnail || m.images || m.brand || m.type === "product";
156
+ }).map((s) => {
157
+ const m = s.metadata || {};
158
+ return {
159
+ id: s.id,
160
+ name: m.name || m.title || s.content.split("\n")[0] || "Unknown Product",
161
+ brand: m.brand,
162
+ price: m.price,
163
+ image: resolveImage(m),
164
+ link: m.link,
165
+ description: s.content
166
+ };
167
+ });
168
+ }, [sources, isUser]);
169
+ const { productsFromContent, cleanContent } = React4.useMemo(() => {
170
+ if (isUser) return { productsFromContent: [], cleanContent: message.content };
171
+ const jsonRegex = /```json\s*([\s\S]*?)\s*```/g;
172
+ const products = [];
173
+ let content = message.content;
174
+ if (content.includes('"type": "products"') || content.includes('"type":"products"')) {
175
+ const matches = Array.from(content.matchAll(jsonRegex));
176
+ for (const m of matches) {
177
+ try {
178
+ const data = JSON.parse(m[1]);
179
+ if (data.type === "products" && Array.isArray(data.items)) {
180
+ const formattedItems = data.items.map((item) => __spreadProps(__spreadValues({}, item), {
181
+ image: item.image || resolveImage(item)
182
+ }));
183
+ products.push(...formattedItems);
184
+ content = content.replace(m[0], "");
185
+ }
186
+ } catch (e) {
187
+ }
188
+ }
189
+ }
190
+ return { productsFromContent: products, cleanContent: content.trim() };
191
+ }, [message.content, isUser]);
192
+ const allProducts = [...productsFromSources, ...productsFromContent];
193
+ const hasProducts = allProducts.length > 0;
194
+ return /* @__PURE__ */ React4.createElement("div", { className: `flex gap-3 ${isUser ? "flex-row-reverse" : "flex-row"} items-start` }, /* @__PURE__ */ React4.createElement(
67
195
  "div",
68
196
  {
69
197
  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"}`,
70
198
  style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
71
199
  },
72
- isUser ? /* @__PURE__ */ React2.createElement(User, { className: "w-4 h-4 text-white" }) : /* @__PURE__ */ React2.createElement(Bot, { className: "w-4 h-4" })
73
- ), /* @__PURE__ */ React2.createElement("div", { className: `flex flex-col gap-1 max-w-[75%] ${isUser ? "items-end" : "items-start"}` }, /* @__PURE__ */ React2.createElement(
200
+ isUser ? /* @__PURE__ */ React4.createElement(User, { className: "w-4 h-4 text-white" }) : /* @__PURE__ */ React4.createElement(Bot, { className: "w-4 h-4" })
201
+ ), /* @__PURE__ */ React4.createElement("div", { className: `flex flex-col gap-1 max-w-[75%] ${isUser ? "items-end" : "items-start"}` }, /* @__PURE__ */ React4.createElement(
74
202
  "div",
75
203
  {
76
204
  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"}`,
77
205
  style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
78
206
  },
79
- isStreaming && !message.content ? /* @__PURE__ */ React2.createElement("span", { className: "flex items-center gap-1 py-1" }, /* @__PURE__ */ React2.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:0ms]" }), /* @__PURE__ */ React2.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:150ms]" }), /* @__PURE__ */ React2.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:300ms]" })) : /* @__PURE__ */ React2.createElement("div", { className: `prose prose-sm max-w-none ${isUser ? "prose-invert" : "dark:prose-invert"}` }, /* @__PURE__ */ React2.createElement(ReactMarkdown, { remarkPlugins: [remarkGfm] }, message.content), isStreaming && message.content && /* @__PURE__ */ React2.createElement("span", { className: "inline-block w-1.5 h-3.5 ml-1 bg-emerald-500 animate-pulse align-middle" }))
80
- ), !isUser && sources && sources.length > 0 && /* @__PURE__ */ React2.createElement("div", { className: "w-full" }, /* @__PURE__ */ React2.createElement(
207
+ isStreaming && !message.content ? /* @__PURE__ */ React4.createElement("span", { className: "flex items-center gap-1 py-1" }, /* @__PURE__ */ React4.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:0ms]" }), /* @__PURE__ */ React4.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:150ms]" }), /* @__PURE__ */ React4.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:300ms]" })) : /* @__PURE__ */ React4.createElement("div", { className: `prose prose-sm max-w-none ${isUser ? "prose-invert" : "dark:prose-invert"}` }, /* @__PURE__ */ React4.createElement(ReactMarkdown, { remarkPlugins: [remarkGfm] }, cleanContent || message.content), hasProducts && /* @__PURE__ */ React4.createElement(ProductCarousel, { products: allProducts, primaryColor }), isStreaming && message.content && /* @__PURE__ */ React4.createElement("span", { className: "inline-block w-1.5 h-3.5 ml-1 bg-emerald-500 animate-pulse align-middle" }))
208
+ ), !isUser && sources && sources.length > 0 && /* @__PURE__ */ React4.createElement("div", { className: "w-full" }, /* @__PURE__ */ React4.createElement(
81
209
  "button",
82
210
  {
83
211
  onClick: () => setShowSources((s) => !s),
84
212
  className: "text-[11px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-1 mt-1"
85
213
  },
86
- showSources ? /* @__PURE__ */ React2.createElement(ChevronDown2, { className: "w-3 h-3" }) : /* @__PURE__ */ React2.createElement(ChevronRight, { className: "w-3 h-3" }),
214
+ showSources ? /* @__PURE__ */ React4.createElement(ChevronDown2, { className: "w-3 h-3" }) : /* @__PURE__ */ React4.createElement(ChevronRight2, { className: "w-3 h-3" }),
87
215
  sources.length,
88
216
  " source",
89
217
  sources.length !== 1 ? "s" : "",
90
218
  " used"
91
- ), showSources && /* @__PURE__ */ React2.createElement("div", { className: "mt-2 flex flex-col gap-2" }, sources.map((src, i) => /* @__PURE__ */ React2.createElement(SourceCard, { key: src.id, source: src, index: i }))))));
219
+ ), showSources && /* @__PURE__ */ React4.createElement("div", { className: "mt-2 flex flex-col gap-2" }, sources.map((src, i) => /* @__PURE__ */ React4.createElement(SourceCard, { key: src.id, source: src, index: i }))))));
92
220
  }
93
221
 
94
222
  // src/components/ConfigProvider.tsx
95
- import React3, { createContext, useContext } from "react";
223
+ import React5, { createContext, useContext } from "react";
96
224
  var defaultConfig = {
97
225
  projectId: "default",
98
226
  ui: {
@@ -121,17 +249,17 @@ function ConfigProvider({
121
249
  projectId: (config == null ? void 0 : config.projectId) || defaultConfig.projectId,
122
250
  ui: mergeDefined(defaultConfig.ui, config == null ? void 0 : config.ui)
123
251
  };
124
- return /* @__PURE__ */ React3.createElement(ConfigContext.Provider, { value: merged }, children);
252
+ return /* @__PURE__ */ React5.createElement(ConfigContext.Provider, { value: merged }, children);
125
253
  }
126
254
  function useConfig() {
127
255
  return useContext(ConfigContext);
128
256
  }
129
257
 
130
258
  // src/hooks/useRagChat.ts
131
- import { useState as useState2, useCallback, useRef, useEffect as useEffect2 } from "react";
259
+ import { useState as useState2, useCallback, useRef as useRef2, useEffect as useEffect2 } from "react";
132
260
 
133
261
  // src/hooks/useStoredMessages.ts
134
- import * as React4 from "react";
262
+ import * as React6 from "react";
135
263
  function readStoredMessages(storageKey) {
136
264
  if (typeof window === "undefined") {
137
265
  return [];
@@ -148,8 +276,8 @@ function readStoredMessages(storageKey) {
148
276
  }
149
277
  }
150
278
  function useStoredMessages(storageKey, persist) {
151
- const [messages, setMessages] = React4.useState(() => persist ? readStoredMessages(storageKey) : []);
152
- React4.useEffect(() => {
279
+ const [messages, setMessages] = React6.useState(() => persist ? readStoredMessages(storageKey) : []);
280
+ React6.useEffect(() => {
153
281
  if (!persist || typeof window === "undefined") {
154
282
  return;
155
283
  }
@@ -191,8 +319,8 @@ function useRagChat(projectId, options = {}) {
191
319
  const [messages, setMessages] = useStoredMessages(storageKey, persist);
192
320
  const [isLoading, setIsLoading] = useState2(false);
193
321
  const [error, setError] = useState2(null);
194
- const lastInputRef = useRef("");
195
- const messagesRef = useRef(messages);
322
+ const lastInputRef = useRef2("");
323
+ const messagesRef = useRef2(messages);
196
324
  useEffect2(() => {
197
325
  messagesRef.current = messages;
198
326
  }, [messages]);
@@ -348,8 +476,8 @@ function ChatWindow({
348
476
  const { ui, projectId } = useConfig();
349
477
  const [input, setInput] = useState3("");
350
478
  const [mounted, setMounted] = useState3(false);
351
- const bottomRef = useRef2(null);
352
- const inputRef = useRef2(null);
479
+ const bottomRef = useRef3(null);
480
+ const inputRef = useRef3(null);
353
481
  const { messages, send, clear, isLoading, error } = useRagChat(projectId, {
354
482
  namespace: projectId
355
483
  });
@@ -384,83 +512,83 @@ function ChatWindow({
384
512
  const isEmpty = messages.length === 0;
385
513
  const currentRadius = BORDER_RADIUS_MAP[ui.borderRadius || "xl"];
386
514
  const isGlass = ui.visualStyle !== "solid";
387
- return /* @__PURE__ */ React5.createElement(
515
+ return /* @__PURE__ */ React7.createElement(
388
516
  "div",
389
517
  {
390
518
  className: `relative 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}`,
391
519
  style: __spreadValues({ "--primary": ui.primaryColor, "--accent": ui.accentColor }, style)
392
520
  },
393
- onResizeStart && /* @__PURE__ */ React5.createElement(
521
+ onResizeStart && /* @__PURE__ */ React7.createElement(
394
522
  "div",
395
523
  {
396
524
  onMouseDown: onResizeStart,
397
525
  className: "absolute top-0 left-0 w-6 h-6 cursor-nw-resize z-[100] group flex items-start justify-start p-1",
398
526
  title: "Drag to resize"
399
527
  },
400
- /* @__PURE__ */ React5.createElement("div", { className: "w-2.5 h-2.5 border-t-2 border-l-2 border-slate-300 dark:border-white/20 group-hover:border-slate-500 dark:group-hover:border-white/50 transition-colors rounded-tl-[2px]" })
528
+ /* @__PURE__ */ React7.createElement("div", { className: "w-2.5 h-2.5 border-t-2 border-l-2 border-slate-300 dark:border-white/20 group-hover:border-slate-500 dark:group-hover:border-white/50 transition-colors rounded-tl-[2px]" })
401
529
  ),
402
- /* @__PURE__ */ React5.createElement(
530
+ /* @__PURE__ */ React7.createElement(
403
531
  "div",
404
532
  {
405
533
  className: "flex items-center justify-between px-5 py-4 border-b border-slate-200 dark:border-white/10",
406
534
  style: { background: `linear-gradient(135deg, ${ui.primaryColor}15, ${ui.accentColor}10)` }
407
535
  },
408
- /* @__PURE__ */ React5.createElement("div", { className: "flex items-center gap-3" }, ui.logoUrl ? (
536
+ /* @__PURE__ */ React7.createElement("div", { className: "flex items-center gap-3" }, ui.logoUrl ? (
409
537
  // eslint-disable-next-line @next/next/no-img-element
410
- /* @__PURE__ */ React5.createElement("img", { src: ui.logoUrl, alt: "logo", className: "w-8 h-8 rounded-lg object-cover" })
411
- ) : /* @__PURE__ */ React5.createElement(
538
+ /* @__PURE__ */ React7.createElement("img", { src: ui.logoUrl, alt: "logo", className: "w-8 h-8 rounded-lg object-cover" })
539
+ ) : /* @__PURE__ */ React7.createElement(
412
540
  "div",
413
541
  {
414
542
  className: `w-9 h-9 flex items-center justify-center shadow-md ${ui.borderRadius === "full" ? "rounded-full" : "rounded-xl"}`,
415
543
  style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
416
544
  },
417
- /* @__PURE__ */ React5.createElement(Bot2, { className: "w-5 h-5 text-white" })
418
- ), /* @__PURE__ */ React5.createElement("div", null, /* @__PURE__ */ React5.createElement("h2", { className: "text-slate-900 dark:text-white font-semibold text-sm leading-tight" }, ui.title), ui.poweredBy && /* @__PURE__ */ React5.createElement("p", { className: "text-slate-500 dark:text-white/40 text-[11px] leading-tight" }, `Powered by ${ui.poweredBy}`))),
419
- /* @__PURE__ */ React5.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ React5.createElement("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400 mr-2" }, /* @__PURE__ */ React5.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-emerald-500 dark:bg-emerald-400 animate-pulse" }), "Online"), /* @__PURE__ */ React5.createElement("div", { className: "flex items-center bg-slate-100/50 dark:bg-white/5 rounded-lg p-0.5 border border-slate-200/50 dark:border-white/5" }, mounted && messages.length > 0 && /* @__PURE__ */ React5.createElement(
545
+ /* @__PURE__ */ React7.createElement(Bot2, { className: "w-5 h-5 text-white" })
546
+ ), /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement("h2", { className: "text-slate-900 dark:text-white font-semibold text-sm leading-tight" }, ui.title), ui.poweredBy && /* @__PURE__ */ React7.createElement("p", { className: "text-slate-500 dark:text-white/40 text-[11px] leading-tight" }, `Powered by ${ui.poweredBy}`))),
547
+ /* @__PURE__ */ React7.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ React7.createElement("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400 mr-2" }, /* @__PURE__ */ React7.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-emerald-500 dark:bg-emerald-400 animate-pulse" }), "Online"), /* @__PURE__ */ React7.createElement("div", { className: "flex items-center bg-slate-100/50 dark:bg-white/5 rounded-lg p-0.5 border border-slate-200/50 dark:border-white/5" }, mounted && messages.length > 0 && /* @__PURE__ */ React7.createElement(
420
548
  "button",
421
549
  {
422
550
  onClick: clearHistory,
423
551
  title: "Clear conversation",
424
552
  className: "w-7 h-7 rounded-md flex items-center justify-center text-slate-400 hover:text-rose-500 dark:text-white/40 dark:hover:text-rose-400 hover:bg-white dark:hover:bg-white/10 transition-all cursor-pointer"
425
553
  },
426
- /* @__PURE__ */ React5.createElement(Trash2, { className: "w-3.5 h-3.5" })
427
- ), isResized && onResetResize && /* @__PURE__ */ React5.createElement(
554
+ /* @__PURE__ */ React7.createElement(Trash2, { className: "w-3.5 h-3.5" })
555
+ ), isResized && onResetResize && /* @__PURE__ */ React7.createElement(
428
556
  "button",
429
557
  {
430
558
  onClick: onResetResize,
431
559
  title: "Reset to default size",
432
560
  className: "w-7 h-7 rounded-md flex items-center justify-center text-slate-400 hover:text-blue-500 dark:text-white/40 dark:hover:text-blue-400 hover:bg-white dark:hover:bg-white/10 transition-all cursor-pointer"
433
561
  },
434
- /* @__PURE__ */ React5.createElement(RotateCcw, { className: "w-3.5 h-3.5" })
435
- ), onMaximize && /* @__PURE__ */ React5.createElement(
562
+ /* @__PURE__ */ React7.createElement(RotateCcw, { className: "w-3.5 h-3.5" })
563
+ ), onMaximize && /* @__PURE__ */ React7.createElement(
436
564
  "button",
437
565
  {
438
566
  onClick: onMaximize,
439
567
  title: isMaximized ? "Minimize" : "Maximize",
440
568
  className: "w-7 h-7 rounded-md flex items-center justify-center text-slate-400 hover:text-blue-500 dark:text-white/40 dark:hover:text-blue-400 hover:bg-white dark:hover:bg-white/10 transition-all cursor-pointer"
441
569
  },
442
- isMaximized ? /* @__PURE__ */ React5.createElement(Minimize2, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ React5.createElement(Maximize2, { className: "w-3.5 h-3.5" })
443
- ), showClose && onClose && /* @__PURE__ */ React5.createElement(
570
+ isMaximized ? /* @__PURE__ */ React7.createElement(Minimize2, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ React7.createElement(Maximize2, { className: "w-3.5 h-3.5" })
571
+ ), showClose && onClose && /* @__PURE__ */ React7.createElement(
444
572
  "button",
445
573
  {
446
574
  onClick: onClose,
447
575
  title: "Close chat",
448
576
  className: "w-7 h-7 rounded-md flex items-center justify-center text-slate-400 hover:text-slate-600 dark:text-white/40 dark:hover:text-white/70 hover:bg-white dark:hover:bg-white/10 transition-all cursor-pointer"
449
577
  },
450
- /* @__PURE__ */ React5.createElement(X, { className: "w-4 h-4" })
578
+ /* @__PURE__ */ React7.createElement(X, { className: "w-4 h-4" })
451
579
  )))
452
580
  ),
453
- /* @__PURE__ */ React5.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 ? (
581
+ /* @__PURE__ */ React7.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 ? (
454
582
  /* Welcome state */
455
- /* @__PURE__ */ React5.createElement("div", { className: "h-full flex flex-col items-center justify-center text-center gap-4 px-6 py-12" }, /* @__PURE__ */ React5.createElement(
583
+ /* @__PURE__ */ React7.createElement("div", { className: "h-full flex flex-col items-center justify-center text-center gap-4 px-6 py-12" }, /* @__PURE__ */ React7.createElement(
456
584
  "div",
457
585
  {
458
586
  className: `w-16 h-16 flex items-center justify-center shadow-lg ${ui.borderRadius === "full" ? "rounded-full" : "rounded-2xl"}`,
459
587
  style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
460
588
  },
461
- /* @__PURE__ */ React5.createElement(Sparkles, { className: "w-8 h-8 text-white" })
462
- ), /* @__PURE__ */ React5.createElement("div", null, /* @__PURE__ */ React5.createElement("p", { className: "text-slate-800 dark:text-white/80 font-medium leading-relaxed" }, ui.welcomeMessage), /* @__PURE__ */ React5.createElement("p", { className: "text-slate-500 dark:text-white/30 text-sm mt-2" }, "Ask a question to get started")), /* @__PURE__ */ React5.createElement("div", { className: "flex flex-wrap gap-2 justify-center mt-2" }, CHAT_SUGGESTIONS.map(
463
- (suggestion) => /* @__PURE__ */ React5.createElement(
589
+ /* @__PURE__ */ React7.createElement(Sparkles, { className: "w-8 h-8 text-white" })
590
+ ), /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement("p", { className: "text-slate-800 dark:text-white/80 font-medium leading-relaxed" }, ui.welcomeMessage), /* @__PURE__ */ React7.createElement("p", { className: "text-slate-500 dark:text-white/30 text-sm mt-2" }, "Ask a question to get started")), /* @__PURE__ */ React7.createElement("div", { className: "flex flex-wrap gap-2 justify-center mt-2" }, CHAT_SUGGESTIONS.map(
591
+ (suggestion) => /* @__PURE__ */ React7.createElement(
464
592
  "button",
465
593
  {
466
594
  key: suggestion,
@@ -474,7 +602,7 @@ function ChatWindow({
474
602
  suggestion
475
603
  )
476
604
  )))
477
- ) : messages.map((msg, index) => /* @__PURE__ */ React5.createElement(
605
+ ) : messages.map((msg, index) => /* @__PURE__ */ React7.createElement(
478
606
  MessageBubble,
479
607
  {
480
608
  key: msg.id,
@@ -484,7 +612,7 @@ function ChatWindow({
484
612
  primaryColor: ui.primaryColor,
485
613
  accentColor: ui.accentColor
486
614
  }
487
- )), isLoading && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) !== "assistant" && /* @__PURE__ */ React5.createElement(
615
+ )), isLoading && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) !== "assistant" && /* @__PURE__ */ React7.createElement(
488
616
  MessageBubble,
489
617
  {
490
618
  message: { role: "assistant", content: "" },
@@ -492,8 +620,8 @@ function ChatWindow({
492
620
  primaryColor: ui.primaryColor,
493
621
  accentColor: ui.accentColor
494
622
  }
495
- ), error && /* @__PURE__ */ React5.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__ */ React5.createElement(TriangleAlert, { className: "w-4 h-4 flex-shrink-0" }), /* @__PURE__ */ React5.createElement("span", null, error)), /* @__PURE__ */ React5.createElement("div", { ref: bottomRef })),
496
- /* @__PURE__ */ React5.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__ */ React5.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__ */ React5.createElement(
623
+ ), error && /* @__PURE__ */ React7.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__ */ React7.createElement(TriangleAlert, { className: "w-4 h-4 flex-shrink-0" }), /* @__PURE__ */ React7.createElement("span", null, error)), /* @__PURE__ */ React7.createElement("div", { ref: bottomRef })),
624
+ /* @__PURE__ */ React7.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__ */ React7.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__ */ React7.createElement(
497
625
  "textarea",
498
626
  {
499
627
  ref: inputRef,
@@ -506,7 +634,7 @@ function ChatWindow({
506
634
  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",
507
635
  style: { scrollbarWidth: "none" }
508
636
  }
509
- ), /* @__PURE__ */ React5.createElement(
637
+ ), /* @__PURE__ */ React7.createElement(
510
638
  "button",
511
639
  {
512
640
  onClick: sendMessage,
@@ -517,8 +645,8 @@ function ChatWindow({
517
645
  // slate-400/20 for light mode disabled
518
646
  }
519
647
  },
520
- /* @__PURE__ */ React5.createElement(ArrowUp, { className: "w-4 h-4 text-white" })
521
- )), /* @__PURE__ */ React5.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"))
648
+ /* @__PURE__ */ React7.createElement(ArrowUp, { className: "w-4 h-4 text-white" })
649
+ )), /* @__PURE__ */ React7.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"))
522
650
  );
523
651
  }
524
652
 
@@ -581,7 +709,7 @@ function ChatWidget({ position = "bottom-right" }) {
581
709
  }
582
710
  };
583
711
  const isResized = dimensions.width !== DEFAULT_DIMENSIONS.width || dimensions.height !== DEFAULT_DIMENSIONS.height;
584
- return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(
712
+ return /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(
585
713
  "div",
586
714
  {
587
715
  className: `fixed z-[9998] max-w-[calc(100vw-3rem)] ease-in-out ${windowPositionClass} ${isOpen ? "opacity-100 translate-y-0 pointer-events-auto" : "opacity-0 translate-y-4 pointer-events-none"} ${isResizing ? "" : "transition-all duration-300"}`,
@@ -591,7 +719,7 @@ function ChatWidget({ position = "bottom-right" }) {
591
719
  maxHeight: "calc(100vh - 6rem)"
592
720
  }
593
721
  },
594
- /* @__PURE__ */ React6.createElement(
722
+ /* @__PURE__ */ React8.createElement(
595
723
  ChatWindow,
596
724
  {
597
725
  className: "h-full relative z-10",
@@ -604,13 +732,13 @@ function ChatWidget({ position = "bottom-right" }) {
604
732
  isMaximized
605
733
  }
606
734
  ),
607
- /* @__PURE__ */ React6.createElement(
735
+ /* @__PURE__ */ React8.createElement(
608
736
  "div",
609
737
  {
610
738
  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"}`
611
739
  }
612
740
  )
613
- ), /* @__PURE__ */ React6.createElement(
741
+ ), /* @__PURE__ */ React8.createElement(
614
742
  "button",
615
743
  {
616
744
  onClick: isOpen ? () => setIsOpen(false) : handleOpen,
@@ -618,32 +746,32 @@ function ChatWidget({ position = "bottom-right" }) {
618
746
  style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
619
747
  "aria-label": "Open chat"
620
748
  },
621
- /* @__PURE__ */ React6.createElement(
749
+ /* @__PURE__ */ React8.createElement(
622
750
  "span",
623
751
  {
624
752
  className: "absolute inset-0 rounded-full animate-ping opacity-20",
625
753
  style: { background: ui.primaryColor }
626
754
  }
627
755
  ),
628
- /* @__PURE__ */ React6.createElement(
756
+ /* @__PURE__ */ React8.createElement(
629
757
  "span",
630
758
  {
631
759
  className: `transition-transform duration-300 ${isOpen ? "rotate-90 scale-90" : "rotate-0 scale-100"}`
632
760
  },
633
- isOpen ? /* @__PURE__ */ React6.createElement(X2, { className: "w-6 h-6 text-white" }) : /* @__PURE__ */ React6.createElement(MessageSquare, { className: "w-6 h-6 text-white" })
761
+ isOpen ? /* @__PURE__ */ React8.createElement(X2, { className: "w-6 h-6 text-white" }) : /* @__PURE__ */ React8.createElement(MessageSquare, { className: "w-6 h-6 text-white" })
634
762
  ),
635
- hasUnread && !isOpen && /* @__PURE__ */ React6.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")
763
+ hasUnread && !isOpen && /* @__PURE__ */ React8.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")
636
764
  ));
637
765
  }
638
766
 
639
767
  // src/components/DocumentUpload.tsx
640
- import React7, { useState as useState5, useRef as useRef3 } from "react";
768
+ import React9, { useState as useState5, useRef as useRef4 } from "react";
641
769
  import { Upload, File, X as X3, CheckCircle, AlertCircle, Loader2 } from "lucide-react";
642
770
  function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
643
771
  const { ui } = useConfig();
644
772
  const [fileStates, setFileStates] = useState5([]);
645
773
  const [isDragging, setIsDragging] = useState5(false);
646
- const fileInputRef = useRef3(null);
774
+ const fileInputRef = useRef4(null);
647
775
  const addFiles = (files) => {
648
776
  const newStates = files.map((file) => ({ file, status: "idle" }));
649
777
  setFileStates((prev) => [...prev, ...newStates]);
@@ -693,7 +821,7 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
693
821
  };
694
822
  const isUploading = fileStates.some((s) => s.status === "uploading");
695
823
  const hasIdle = fileStates.some((s) => s.status === "idle");
696
- return /* @__PURE__ */ React7.createElement(
824
+ return /* @__PURE__ */ React9.createElement(
697
825
  "div",
698
826
  {
699
827
  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}`,
@@ -701,14 +829,14 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
701
829
  onDragLeave,
702
830
  onDrop
703
831
  },
704
- /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col items-center justify-center text-center" }, /* @__PURE__ */ React7.createElement(
832
+ /* @__PURE__ */ React9.createElement("div", { className: "flex flex-col items-center justify-center text-center" }, /* @__PURE__ */ React9.createElement(
705
833
  "div",
706
834
  {
707
835
  className: "w-12 h-12 rounded-full flex items-center justify-center mb-4 shadow-sm",
708
836
  style: { background: `linear-gradient(135deg, ${ui.primaryColor}20, ${ui.accentColor}20)` }
709
837
  },
710
- /* @__PURE__ */ React7.createElement(Upload, { className: "w-6 h-6", style: { color: ui.primaryColor } })
711
- ), /* @__PURE__ */ React7.createElement("h3", { className: "text-slate-900 dark:text-white font-semibold mb-1" }, "Upload Documents"), /* @__PURE__ */ React7.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__ */ React7.createElement(
838
+ /* @__PURE__ */ React9.createElement(Upload, { className: "w-6 h-6", style: { color: ui.primaryColor } })
839
+ ), /* @__PURE__ */ React9.createElement("h3", { className: "text-slate-900 dark:text-white font-semibold mb-1" }, "Upload Documents"), /* @__PURE__ */ React9.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__ */ React9.createElement(
712
840
  "button",
713
841
  {
714
842
  onClick: () => {
@@ -724,7 +852,7 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
724
852
  }
725
853
  },
726
854
  "Select Files"
727
- ), /* @__PURE__ */ React7.createElement(
855
+ ), /* @__PURE__ */ React9.createElement(
728
856
  "input",
729
857
  {
730
858
  ref: fileInputRef,
@@ -735,22 +863,22 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
735
863
  accept: ".pdf,.docx,.txt,.md,.json,.csv"
736
864
  }
737
865
  )),
738
- fileStates.length > 0 && /* @__PURE__ */ React7.createElement("div", { className: "mt-8 space-y-3" }, fileStates.map((state, i) => /* @__PURE__ */ React7.createElement(
866
+ fileStates.length > 0 && /* @__PURE__ */ React9.createElement("div", { className: "mt-8 space-y-3" }, fileStates.map((state, i) => /* @__PURE__ */ React9.createElement(
739
867
  "div",
740
868
  {
741
869
  key: i,
742
870
  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"
743
871
  },
744
- /* @__PURE__ */ React7.createElement("div", { className: "flex items-center gap-3 overflow-hidden" }, /* @__PURE__ */ React7.createElement("div", { className: "w-8 h-8 rounded-lg bg-white dark:bg-white/10 flex items-center justify-center shadow-sm" }, /* @__PURE__ */ React7.createElement(File, { className: "w-4 h-4 text-slate-400" })), /* @__PURE__ */ React7.createElement("div", { className: "truncate" }, /* @__PURE__ */ React7.createElement("p", { className: "text-xs font-medium text-slate-700 dark:text-white/80 truncate" }, state.file.name), /* @__PURE__ */ React7.createElement("p", { className: "text-[10px] text-slate-400" }, (state.file.size / 1024).toFixed(1), " KB"))),
745
- /* @__PURE__ */ React7.createElement("div", { className: "flex items-center gap-2" }, state.status === "uploading" && /* @__PURE__ */ React7.createElement(Loader2, { className: "w-4 h-4 text-slate-400 animate-spin" }), state.status === "success" && /* @__PURE__ */ React7.createElement(CheckCircle, { className: "w-4 h-4 text-emerald-500" }), state.status === "error" && /* @__PURE__ */ React7.createElement("div", { title: state.error }, /* @__PURE__ */ React7.createElement(AlertCircle, { className: "w-4 h-4 text-rose-500" })), state.status !== "uploading" && /* @__PURE__ */ React7.createElement(
872
+ /* @__PURE__ */ React9.createElement("div", { className: "flex items-center gap-3 overflow-hidden" }, /* @__PURE__ */ React9.createElement("div", { className: "w-8 h-8 rounded-lg bg-white dark:bg-white/10 flex items-center justify-center shadow-sm" }, /* @__PURE__ */ React9.createElement(File, { className: "w-4 h-4 text-slate-400" })), /* @__PURE__ */ React9.createElement("div", { className: "truncate" }, /* @__PURE__ */ React9.createElement("p", { className: "text-xs font-medium text-slate-700 dark:text-white/80 truncate" }, state.file.name), /* @__PURE__ */ React9.createElement("p", { className: "text-[10px] text-slate-400" }, (state.file.size / 1024).toFixed(1), " KB"))),
873
+ /* @__PURE__ */ React9.createElement("div", { className: "flex items-center gap-2" }, state.status === "uploading" && /* @__PURE__ */ React9.createElement(Loader2, { className: "w-4 h-4 text-slate-400 animate-spin" }), state.status === "success" && /* @__PURE__ */ React9.createElement(CheckCircle, { className: "w-4 h-4 text-emerald-500" }), state.status === "error" && /* @__PURE__ */ React9.createElement("div", { title: state.error }, /* @__PURE__ */ React9.createElement(AlertCircle, { className: "w-4 h-4 text-rose-500" })), state.status !== "uploading" && /* @__PURE__ */ React9.createElement(
746
874
  "button",
747
875
  {
748
876
  onClick: () => removeFile(i),
749
877
  className: "p-1 rounded-md hover:bg-slate-200 dark:hover:bg-white/10 transition-colors"
750
878
  },
751
- /* @__PURE__ */ React7.createElement(X3, { className: "w-3.5 h-3.5 text-slate-400" })
879
+ /* @__PURE__ */ React9.createElement(X3, { className: "w-3.5 h-3.5 text-slate-400" })
752
880
  ))
753
- )), hasIdle && !isUploading && /* @__PURE__ */ React7.createElement(
881
+ )), hasIdle && !isUploading && /* @__PURE__ */ React9.createElement(
754
882
  "button",
755
883
  {
756
884
  onClick: uploadFiles,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retrivora-ai/rag-engine",
3
- "version": "1.1.4",
3
+ "version": "1.1.5",
4
4
  "description": "Retrivora AI is a plug-and-play AI engine for RAG chat experiences — generic vector DB + LLM provider, embeddable or standalone.",
5
5
  "author": "Abhinav Alkuchi",
6
6
  "license": "MIT",
@@ -65,6 +65,15 @@ body {
65
65
  background: rgba(255, 255, 255, 0.2);
66
66
  }
67
67
 
68
+ .scrollbar-hide::-webkit-scrollbar {
69
+ display: none;
70
+ }
71
+
72
+ .scrollbar-hide {
73
+ -ms-overflow-style: none;
74
+ scrollbar-width: none;
75
+ }
76
+
68
77
  /* ─── Prose Overrides (markdown in chat) ───────────────────── */
69
78
  .prose-invert {
70
79
  color: inherit;