@retrivora-ai/rag-engine 1.9.2 → 1.9.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +27 -0
  2. package/dist/{ILLMProvider-Bw2A28nU.d.mts → ILLMProvider-DNhyOYoK.d.mts} +41 -1
  3. package/dist/{ILLMProvider-Bw2A28nU.d.ts → ILLMProvider-DNhyOYoK.d.ts} +41 -1
  4. package/dist/handlers/index.d.mts +2 -2
  5. package/dist/handlers/index.d.ts +2 -2
  6. package/dist/handlers/index.js +563 -205
  7. package/dist/handlers/index.mjs +563 -205
  8. package/dist/index-C9v7-tWd.d.mts +183 -0
  9. package/dist/{index-B70ZLkfG.d.mts → index-CHL1jdYm.d.mts} +1 -1
  10. package/dist/index-CjQdL0cX.d.ts +183 -0
  11. package/dist/{index-DVu-mkAM.d.ts → index-Hgbwl9X4.d.ts} +1 -1
  12. package/dist/index.css +40 -0
  13. package/dist/index.d.mts +3 -3
  14. package/dist/index.d.ts +3 -3
  15. package/dist/index.js +326 -158
  16. package/dist/index.mjs +312 -151
  17. package/dist/server.d.mts +15 -94
  18. package/dist/server.d.ts +15 -94
  19. package/dist/server.js +623 -205
  20. package/dist/server.mjs +615 -205
  21. package/package.json +1 -1
  22. package/src/app/api/chat/route.ts +2 -2
  23. package/src/app/api/health/route.ts +3 -2
  24. package/src/app/api/ingest/route.ts +3 -2
  25. package/src/app/api/suggestions/route.ts +3 -2
  26. package/src/app/api/upload/route.ts +3 -2
  27. package/src/app/constants.tsx +85 -30
  28. package/src/app/layout.tsx +18 -7
  29. package/src/components/MessageBubble.tsx +39 -2
  30. package/src/components/ThinkingBlock.tsx +75 -0
  31. package/src/components/VisualizationRenderer.tsx +27 -1
  32. package/src/config/RagConfig.ts +47 -0
  33. package/src/config/serverConfig.ts +25 -0
  34. package/src/core/ConfigResolver.ts +56 -4
  35. package/src/core/ConfigValidator.ts +2 -1
  36. package/src/core/Pipeline.ts +226 -68
  37. package/src/core/ProviderRegistry.ts +11 -2
  38. package/src/core/QueryProcessor.ts +38 -4
  39. package/src/core/Retrivora.ts +51 -0
  40. package/src/exceptions/index.ts +59 -0
  41. package/src/handlers/index.ts +2 -0
  42. package/src/hooks/useRagChat.ts +26 -4
  43. package/src/index.ts +25 -1
  44. package/src/lib/plugin.ts +24 -0
  45. package/src/llm/LLMFactory.ts +4 -1
  46. package/src/llm/providers/AnthropicProvider.ts +70 -20
  47. package/src/llm/providers/GeminiProvider.ts +14 -15
  48. package/src/llm/providers/OllamaProvider.ts +13 -16
  49. package/src/llm/providers/OpenAIProvider.ts +9 -14
  50. package/src/llm/providers/UniversalLLMAdapter.ts +5 -5
  51. package/src/llm/utils.ts +46 -0
  52. package/src/providers/vectordb/MongoDBProvider.ts +19 -7
  53. package/src/providers/vectordb/MultiTablePostgresProvider.ts +45 -13
  54. package/src/rag/EntityExtractor.ts +2 -2
  55. package/src/rag/Reranker.ts +9 -16
  56. package/src/server.ts +27 -1
  57. package/src/types/chat.ts +7 -0
  58. package/src/utils/UITransformer.ts +73 -4
  59. package/dist/DocumentChunker-Dh9TvmGG.d.mts +0 -45
  60. package/dist/DocumentChunker-Dh9TvmGG.d.ts +0 -45
package/dist/index.js CHANGED
@@ -59,12 +59,19 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
59
59
  // src/index.ts
60
60
  var index_exports = {};
61
61
  __export(index_exports, {
62
+ AuthenticationException: () => AuthenticationException,
62
63
  ChatWidget: () => ChatWidget,
63
64
  ChatWindow: () => ChatWindow,
64
65
  ConfigProvider: () => ConfigProvider,
66
+ ConfigurationException: () => ConfigurationException,
65
67
  DocumentUpload: () => DocumentUpload,
68
+ EmbeddingFailedException: () => EmbeddingFailedException,
66
69
  MessageBubble: () => MessageBubble,
67
70
  ObservabilityPanel: () => ObservabilityPanel,
71
+ ProviderNotFoundException: () => ProviderNotFoundException,
72
+ RateLimitException: () => RateLimitException,
73
+ RetrievalException: () => RetrievalException,
74
+ RetrivoraError: () => RetrivoraError,
68
75
  SourceCard: () => SourceCard,
69
76
  addSynonyms: () => addSynonyms,
70
77
  useConfig: () => useConfig,
@@ -74,12 +81,12 @@ module.exports = __toCommonJS(index_exports);
74
81
  var import_index = require("./index.css");
75
82
 
76
83
  // src/components/ChatWidget.tsx
77
- var import_react12 = require("react");
78
- var import_lucide_react8 = require("lucide-react");
84
+ var import_react13 = require("react");
85
+ var import_lucide_react9 = require("lucide-react");
79
86
 
80
87
  // src/components/ChatWindow.tsx
81
- var import_react11 = require("react");
82
- var import_lucide_react7 = require("lucide-react");
88
+ var import_react12 = require("react");
89
+ var import_lucide_react8 = require("lucide-react");
83
90
 
84
91
  // src/components/DocumentUpload.tsx
85
92
  var import_react2 = require("react");
@@ -342,8 +349,8 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
342
349
  }
343
350
 
344
351
  // src/components/MessageBubble.tsx
345
- var import_react9 = __toESM(require("react"));
346
- var import_lucide_react6 = require("lucide-react");
352
+ var import_react10 = __toESM(require("react"));
353
+ var import_lucide_react7 = require("lucide-react");
347
354
  var import_react_markdown = __toESM(require("react-markdown"));
348
355
 
349
356
  // src/components/SourceCard.tsx
@@ -803,6 +810,7 @@ function renderVisualization(type, data, onAddToCart, primaryColor, isStreaming)
803
810
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TableView, { data, isStreaming });
804
811
  case "product_carousel":
805
812
  case "carousel":
813
+ if (isStreaming) return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CarouselSkeleton, {});
806
814
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CarouselView, { data, onAddToCart, primaryColor });
807
815
  case "text":
808
816
  default:
@@ -813,6 +821,26 @@ function renderVisualization(type, data, onAddToCart, primaryColor, isStreaming)
813
821
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TextView, { data: { content: "Unable to render the requested visualization." } });
814
822
  }
815
823
  }
824
+ function CarouselSkeleton() {
825
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "w-full py-2", children: [
826
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mb-3 h-4 w-36 rounded-full bg-slate-200 animate-pulse" }),
827
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex gap-3 overflow-hidden", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
828
+ "div",
829
+ {
830
+ className: "flex-shrink-0 w-44 rounded-2xl border border-slate-200 bg-white shadow-sm overflow-hidden animate-pulse",
831
+ children: [
832
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "h-28 bg-slate-100" }),
833
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "p-3 space-y-2", children: [
834
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "h-3 w-28 rounded-full bg-slate-200" }),
835
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "h-3 w-16 rounded-full bg-slate-100" }),
836
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "h-3 w-20 rounded-full bg-emerald-100" })
837
+ ] })
838
+ ]
839
+ },
840
+ i
841
+ )) })
842
+ ] });
843
+ }
816
844
  function ChartSkeleton({ type }) {
817
845
  if (type === "pie") {
818
846
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "w-full mt-4 mb-2 animate-pulse", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mx-auto w-40 h-40 rounded-full bg-slate-100 dark:bg-white/10" }) });
@@ -2203,8 +2231,54 @@ function normaliseChild(children) {
2203
2231
  return children;
2204
2232
  }
2205
2233
 
2206
- // src/components/MessageBubble.tsx
2234
+ // src/components/ThinkingBlock.tsx
2235
+ var import_react9 = require("react");
2236
+ var import_lucide_react6 = require("lucide-react");
2207
2237
  var import_jsx_runtime12 = require("react/jsx-runtime");
2238
+ function ThinkingBlock({ thinking, thinkingMs, isStreaming = false }) {
2239
+ const [isExpanded, setIsExpanded] = (0, import_react9.useState)(true);
2240
+ const containerRef = (0, import_react9.useRef)(null);
2241
+ (0, import_react9.useEffect)(() => {
2242
+ if (!isStreaming) {
2243
+ setIsExpanded(false);
2244
+ } else {
2245
+ setIsExpanded(true);
2246
+ }
2247
+ }, [isStreaming]);
2248
+ (0, import_react9.useEffect)(() => {
2249
+ if (isStreaming && isExpanded && containerRef.current) {
2250
+ containerRef.current.scrollTop = containerRef.current.scrollHeight;
2251
+ }
2252
+ }, [thinking, isStreaming, isExpanded]);
2253
+ const durationSec = thinkingMs ? (thinkingMs / 1e3).toFixed(1) : null;
2254
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "w-full max-w-2xl my-1.5 border border-slate-200 dark:border-white/10 rounded-xl bg-slate-50/50 dark:bg-white/5 overflow-hidden transition-all duration-200", children: [
2255
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2256
+ "button",
2257
+ {
2258
+ onClick: () => setIsExpanded(!isExpanded),
2259
+ className: "w-full px-4 py-2.5 flex items-center justify-between text-xs font-medium text-slate-500 dark:text-white/40 hover:bg-slate-100 dark:hover:bg-white/10 transition-colors cursor-pointer select-none",
2260
+ children: [
2261
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-2", children: [
2262
+ isStreaming ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.Loader2, { className: "w-3.5 h-3.5 animate-spin text-slate-400 dark:text-white/30" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.Brain, { className: "w-3.5 h-3.5 text-slate-400 dark:text-white/40" }),
2263
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: isStreaming ? "Thinking..." : durationSec ? `Thought for ${durationSec}s` : "Thinking process" })
2264
+ ] }),
2265
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { children: isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.ChevronDown, { className: "w-3.5 h-3.5 text-slate-400 dark:text-white/30" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.ChevronRight, { className: "w-3.5 h-3.5 text-slate-400 dark:text-white/30" }) })
2266
+ ]
2267
+ }
2268
+ ),
2269
+ isExpanded && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2270
+ "div",
2271
+ {
2272
+ ref: containerRef,
2273
+ className: "px-4 pb-3 pt-1 border-t border-slate-200 dark:border-white/10 text-xs font-mono leading-relaxed text-slate-600 dark:text-white/60 bg-slate-50/20 dark:bg-transparent max-h-60 overflow-y-auto whitespace-pre-wrap select-text break-words",
2274
+ children: thinking
2275
+ }
2276
+ )
2277
+ ] });
2278
+ }
2279
+
2280
+ // src/components/MessageBubble.tsx
2281
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2208
2282
  function normalizePlusSeparatedLists(raw) {
2209
2283
  return raw.split("\n").map((line) => {
2210
2284
  const productListLine = /[—:]\s*\d+\s+\+\s+[A-Za-z]/.test(line) || /\b(products?|categories?|in stock|out of stock)\b/i.test(line);
@@ -2228,10 +2302,10 @@ function MessageBubble({
2228
2302
  const isUser = message.role === "user";
2229
2303
  const isCompact = viewportSize === "compact";
2230
2304
  const isMedium = viewportSize === "medium";
2231
- const [showSources, setShowSources] = import_react9.default.useState(false);
2232
- const [showTrace, setShowTrace] = import_react9.default.useState(false);
2233
- const [copied, setCopied] = import_react9.default.useState(false);
2234
- const handleCopy = import_react9.default.useCallback(async () => {
2305
+ const [showSources, setShowSources] = import_react10.default.useState(false);
2306
+ const [showTrace, setShowTrace] = import_react10.default.useState(false);
2307
+ const [copied, setCopied] = import_react10.default.useState(false);
2308
+ const handleCopy = import_react10.default.useCallback(async () => {
2235
2309
  try {
2236
2310
  await navigator.clipboard.writeText(message.content);
2237
2311
  setCopied(true);
@@ -2240,11 +2314,11 @@ function MessageBubble({
2240
2314
  console.error("Failed to copy text:", err);
2241
2315
  }
2242
2316
  }, [message.content]);
2243
- const structuredContent = import_react9.default.useMemo(
2317
+ const structuredContent = import_react10.default.useMemo(
2244
2318
  () => isUser ? { payload: null, text: message.content } : extractStructuredPayload(message.content),
2245
2319
  [isUser, message.content]
2246
2320
  );
2247
- const hasRichUI = import_react9.default.useMemo(() => {
2321
+ const hasRichUI = import_react10.default.useMemo(() => {
2248
2322
  if (message.uiTransformation) {
2249
2323
  const type = message.uiTransformation.type;
2250
2324
  if (type && !["text", "table"].includes(type)) return true;
@@ -2259,10 +2333,10 @@ function MessageBubble({
2259
2333
  uiTransformationType && !["text", "product_carousel", "carousel"].includes(uiTransformationType)
2260
2334
  );
2261
2335
  const shouldRenderStructuredOnly = !isUser && hasRichUI && isLikelyUiOnlyMessage(structuredContent.text);
2262
- const productsFromSources = import_react9.default.useMemo(() => {
2336
+ const productsFromSources = import_react10.default.useMemo(() => {
2263
2337
  return extractProductsFromSources(sources, isUser);
2264
2338
  }, [sources, isUser]);
2265
- const { productsFromContent, cleanContent } = import_react9.default.useMemo(() => {
2339
+ const { productsFromContent, cleanContent } = import_react10.default.useMemo(() => {
2266
2340
  if (isUser) {
2267
2341
  return { productsFromContent: [], cleanContent: message.content };
2268
2342
  }
@@ -2278,10 +2352,10 @@ function MessageBubble({
2278
2352
  isStreaming
2279
2353
  );
2280
2354
  }, [message.content, isUser, structuredContent, productsFromSources, isStreaming]);
2281
- const allProducts = import_react9.default.useMemo(() => {
2355
+ const allProducts = import_react10.default.useMemo(() => {
2282
2356
  return deduplicateProducts(productsFromSources, productsFromContent, message.content);
2283
2357
  }, [productsFromSources, productsFromContent, message.content]);
2284
- const processedMarkdown = import_react9.default.useMemo(() => {
2358
+ const processedMarkdown = import_react10.default.useMemo(() => {
2285
2359
  let raw = structuredContent.payload ? structuredContent.text : cleanContent || message.content;
2286
2360
  raw = raw.replace(/\$\s*(\d+)(?!\.\d)/g, "$1");
2287
2361
  raw = normalizePlusSeparatedLists(raw);
@@ -2312,41 +2386,49 @@ ${match.trim()}
2312
2386
  }
2313
2387
  return raw;
2314
2388
  }, [cleanContent, message.content, isStreaming, structuredContent]);
2315
- const markdownComponents = import_react9.default.useMemo(
2389
+ const markdownComponents = import_react10.default.useMemo(
2316
2390
  () => createMarkdownComponents({ primaryColor, accentColor, isStreaming, onAddToCart, viewportSize }),
2317
2391
  [primaryColor, accentColor, isStreaming, onAddToCart, viewportSize]
2318
2392
  );
2319
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `flex ${isCompact ? "gap-2" : "gap-3"} ${isUser ? "flex-row-reverse" : "flex-row"} items-start`, children: [
2320
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2393
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `flex ${isCompact ? "gap-2" : "gap-3"} ${isUser ? "flex-row-reverse" : "flex-row"} items-start`, children: [
2394
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2321
2395
  "div",
2322
2396
  {
2323
2397
  className: `flex-shrink-0 ${isCompact ? "w-7 h-7" : "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"}`,
2324
2398
  style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {},
2325
- children: isUser ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.User, { className: `${isCompact ? "w-3.5 h-3.5" : "w-4 h-4"} text-white` }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.Bot, { className: `${isCompact ? "w-3.5 h-3.5" : "w-4 h-4"}` })
2399
+ children: isUser ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.User, { className: `${isCompact ? "w-3.5 h-3.5" : "w-4 h-4"} text-white` }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Bot, { className: `${isCompact ? "w-3.5 h-3.5" : "w-4 h-4"}` })
2326
2400
  }
2327
2401
  ),
2328
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `flex flex-col gap-1 min-w-0 ${isCompact ? "max-w-[94%]" : isMedium ? "max-w-[92%]" : "max-w-[90%]"} ${isUser ? "items-end" : "items-start"}`, children: [
2329
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2402
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `flex flex-col gap-1 min-w-0 ${isCompact ? "max-w-[94%]" : isMedium ? "max-w-[92%]" : "max-w-[90%]"} ${isUser ? "items-end" : "items-start"}`, children: [
2403
+ !isUser && message.thinking && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2404
+ ThinkingBlock,
2405
+ {
2406
+ thinking: message.thinking,
2407
+ thinkingMs: message.thinkingMs,
2408
+ isStreaming: isStreaming && !message.content
2409
+ }
2410
+ ),
2411
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2330
2412
  "div",
2331
2413
  {
2332
2414
  className: `relative group ${isCompact ? "px-3 py-2.5 text-[13px]" : "px-4 py-3 text-sm"} rounded-2xl 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"}`,
2333
2415
  style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {},
2334
2416
  children: [
2335
- !isUser && !isStreaming && message.content && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2417
+ !isUser && !isStreaming && message.content && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2336
2418
  "button",
2337
2419
  {
2338
2420
  onClick: handleCopy,
2339
2421
  className: `absolute top-2 right-2 p-1.5 rounded-lg border transition-all duration-200 cursor-pointer ${copied ? "bg-emerald-500/10 border-emerald-500/20 text-emerald-500 dark:text-emerald-400" : "bg-slate-500/5 hover:bg-slate-500/10 border-slate-200 dark:border-white/10 text-slate-400 dark:text-white/30 hover:text-slate-600 dark:hover:text-white/60"} opacity-0 group-hover:opacity-100 backdrop-blur-sm shadow-sm scale-95 group-hover:scale-100`,
2340
2422
  title: copied ? "Copied!" : "Copy response",
2341
- children: copied ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.Check, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.Copy, { className: "w-3.5 h-3.5" })
2423
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Check, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Copy, { className: "w-3.5 h-3.5" })
2342
2424
  }
2343
2425
  ),
2344
- isStreaming && !message.content ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "flex items-center gap-1 py-1", children: [
2345
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:0ms]" }),
2346
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:150ms]" }),
2347
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:300ms]" })
2348
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `prose ${isCompact ? "prose-xs" : "prose-sm"} max-w-none break-words ${isUser ? "prose-invert" : "dark:prose-invert"}`, children: [
2349
- !isUser && structuredContent.payload && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2426
+ isStreaming && !message.content ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "flex items-center gap-1 py-1", children: [
2427
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:0ms]" }),
2428
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:150ms]" }),
2429
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:300ms]" })
2430
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `prose ${isCompact ? "prose-xs" : "prose-sm"} max-w-none break-words ${isUser ? "prose-invert" : "dark:prose-invert"}`, children: [
2431
+ !isUser && structuredContent.payload && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2350
2432
  UIDispatcher,
2351
2433
  {
2352
2434
  rawContent: structuredContent.payload,
@@ -2357,9 +2439,9 @@ ${match.trim()}
2357
2439
  viewportSize
2358
2440
  }
2359
2441
  ),
2360
- !shouldRenderStructuredOnly && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_markdown.default, { components: markdownComponents, children: processedMarkdown }),
2361
- isStreaming && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "inline-flex items-center gap-1.5 ml-2 text-emerald-500 animate-pulse align-middle text-xs font-medium", children: [
2362
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2442
+ !shouldRenderStructuredOnly && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_markdown.default, { components: markdownComponents, children: processedMarkdown }),
2443
+ isStreaming && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "inline-flex items-center gap-1.5 ml-2 text-emerald-500 animate-pulse align-middle text-xs font-medium", children: [
2444
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2363
2445
  HourglassLoader_default,
2364
2446
  {
2365
2447
  size: 18,
@@ -2376,13 +2458,33 @@ ${match.trim()}
2376
2458
  ),
2377
2459
  (() => {
2378
2460
  var _a2, _b;
2379
- if (isUser || structuredContent.payload || !message.uiTransformation) return null;
2461
+ if (isUser || structuredContent.payload) return null;
2462
+ if (isStreaming && !message.uiTransformation && sources && sources.length > 0) {
2463
+ const hasProductSource = sources.some(
2464
+ (s) => s.metadata && Object.keys(s.metadata).some(
2465
+ (k) => ["name", "title", "price", "brand", "image", "product", "sku", "category"].includes(k.toLowerCase())
2466
+ )
2467
+ );
2468
+ if (hasProductSource) {
2469
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "w-full mt-3", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2470
+ VisualizationRenderer,
2471
+ {
2472
+ data: { type: "product_carousel", title: "Recommended Products", description: "Loading...", data: [] },
2473
+ primaryColor,
2474
+ onAddToCart,
2475
+ className: "rounded-3xl border border-slate-200/60 dark:border-white/10 bg-white/90 dark:bg-slate-900/80 p-4",
2476
+ isStreaming: true
2477
+ }
2478
+ ) });
2479
+ }
2480
+ }
2481
+ if (!message.uiTransformation) return null;
2380
2482
  const ui = message.uiTransformation;
2381
2483
  const textContent = (_b = (_a2 = ui.data) == null ? void 0 : _a2.content) != null ? _b : "";
2382
2484
  const isNegativeOrFallbackText = textContent.toLowerCase().includes("cannot answer") || textContent.toLowerCase().includes("no relevant data") || textContent.toLowerCase().includes("no data available") || typeof ui.title === "string" && ui.title.toLowerCase().includes("no data") || typeof ui.description === "string" && ui.description.toLowerCase().includes("no relevant data");
2383
2485
  const shouldShow = !isNegativeOrFallbackText && (ui.type === "table" || !["text", "table"].includes(ui.type) || ui.type === "text" && !hasRichUI && allProducts.length === 0 && textContent && !processedMarkdown.toLowerCase().includes(textContent.trim().toLowerCase()));
2384
2486
  if (!shouldShow) return null;
2385
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "w-full mt-3", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2487
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "w-full mt-3", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2386
2488
  VisualizationRenderer,
2387
2489
  {
2388
2490
  data: ui,
@@ -2393,7 +2495,7 @@ ${match.trim()}
2393
2495
  }
2394
2496
  ) });
2395
2497
  })(),
2396
- !isUser && !hasRichUI && !shouldSuppressProductCarousel && allProducts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "w-full mt-1", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2498
+ !isUser && !hasRichUI && !shouldSuppressProductCarousel && allProducts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "w-full mt-1", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2397
2499
  ProductCarousel,
2398
2500
  {
2399
2501
  products: allProducts,
@@ -2401,14 +2503,14 @@ ${match.trim()}
2401
2503
  onAddToCart
2402
2504
  }
2403
2505
  ) }),
2404
- !isUser && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-4 mt-1 w-full flex-wrap", children: [
2405
- sources && sources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2506
+ !isUser && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-4 mt-1 w-full flex-wrap", children: [
2507
+ sources && sources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2406
2508
  "button",
2407
2509
  {
2408
2510
  onClick: () => setShowSources((s) => !s),
2409
2511
  className: "text-[11px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-1",
2410
2512
  children: [
2411
- showSources ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.ChevronDown, { className: "w-3 h-3" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.ChevronRight, { className: "w-3 h-3" }),
2513
+ showSources ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.ChevronDown, { className: "w-3 h-3" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.ChevronRight, { className: "w-3 h-3" }),
2412
2514
  sources.length,
2413
2515
  " source",
2414
2516
  sources.length !== 1 ? "s" : "",
@@ -2416,31 +2518,31 @@ ${match.trim()}
2416
2518
  ]
2417
2519
  }
2418
2520
  ),
2419
- message.trace && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2521
+ message.trace && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2420
2522
  "button",
2421
2523
  {
2422
2524
  onClick: () => setShowTrace((t) => !t),
2423
2525
  className: "text-[11px] text-emerald-500 hover:text-emerald-400 transition-colors flex items-center gap-1",
2424
2526
  children: [
2425
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.Activity, { className: "w-3 h-3" }),
2527
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Activity, { className: "w-3 h-3" }),
2426
2528
  showTrace ? "Hide Trace" : "Trace"
2427
2529
  ]
2428
2530
  }
2429
2531
  )
2430
2532
  ] }),
2431
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "w-full flex flex-col gap-2 min-w-0", children: [
2432
- showSources && sources && sources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mt-1 flex flex-col gap-2", children: sources.map((src, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SourceCard, { source: src, index: i }, src.id)) }),
2433
- showTrace && message.trace && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ObservabilityPanel, { trace: message.trace, primaryColor })
2533
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "w-full flex flex-col gap-2 min-w-0", children: [
2534
+ showSources && sources && sources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "mt-1 flex flex-col gap-2", children: sources.map((src, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SourceCard, { source: src, index: i }, src.id)) }),
2535
+ showTrace && message.trace && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ObservabilityPanel, { trace: message.trace, primaryColor })
2434
2536
  ] })
2435
2537
  ] })
2436
2538
  ] });
2437
2539
  }
2438
2540
 
2439
2541
  // src/hooks/useRagChat.ts
2440
- var import_react10 = require("react");
2542
+ var import_react11 = require("react");
2441
2543
 
2442
2544
  // src/hooks/useStoredMessages.ts
2443
- var React10 = __toESM(require("react"));
2545
+ var React11 = __toESM(require("react"));
2444
2546
  function readStoredMessages(storageKey) {
2445
2547
  if (typeof window === "undefined") {
2446
2548
  return [];
@@ -2457,8 +2559,8 @@ function readStoredMessages(storageKey) {
2457
2559
  }
2458
2560
  }
2459
2561
  function useStoredMessages(storageKey, persist) {
2460
- const [messages, setMessages] = React10.useState(() => persist ? readStoredMessages(storageKey) : []);
2461
- React10.useEffect(() => {
2562
+ const [messages, setMessages] = React11.useState(() => persist ? readStoredMessages(storageKey) : []);
2563
+ React11.useEffect(() => {
2462
2564
  if (!persist || typeof window === "undefined") {
2463
2565
  return;
2464
2566
  }
@@ -2498,15 +2600,15 @@ function useRagChat(projectId, options = {}) {
2498
2600
  } = options;
2499
2601
  const storageKey = `rag_chat_${projectId}`;
2500
2602
  const [messages, setMessages] = useStoredMessages(storageKey, persist);
2501
- const [isLoading, setIsLoading] = (0, import_react10.useState)(false);
2502
- const [error, setError] = (0, import_react10.useState)(null);
2503
- const lastInputRef = (0, import_react10.useRef)("");
2504
- const messagesRef = (0, import_react10.useRef)(messages);
2505
- const abortControllerRef = (0, import_react10.useRef)(null);
2506
- (0, import_react10.useEffect)(() => {
2603
+ const [isLoading, setIsLoading] = (0, import_react11.useState)(false);
2604
+ const [error, setError] = (0, import_react11.useState)(null);
2605
+ const lastInputRef = (0, import_react11.useRef)("");
2606
+ const messagesRef = (0, import_react11.useRef)(messages);
2607
+ const abortControllerRef = (0, import_react11.useRef)(null);
2608
+ (0, import_react11.useEffect)(() => {
2507
2609
  messagesRef.current = messages;
2508
2610
  }, [messages]);
2509
- const sendMessage = (0, import_react10.useCallback)(
2611
+ const sendMessage = (0, import_react11.useCallback)(
2510
2612
  async (text, opts) => {
2511
2613
  var _a, _b;
2512
2614
  const trimmed = text.trim();
@@ -2550,18 +2652,25 @@ function useRagChat(projectId, options = {}) {
2550
2652
  const reader = response.body.getReader();
2551
2653
  const decoder = new TextDecoder();
2552
2654
  let assistantContent = "";
2655
+ let thinkingContent = "";
2656
+ let thinkingMs;
2553
2657
  let sources = [];
2554
2658
  let uiTransformation = null;
2555
2659
  let trace;
2556
2660
  let buffer = "";
2557
2661
  let pendingFlush = false;
2558
2662
  const pendingContentRef = { current: "" };
2663
+ const pendingThinkingRef = { current: "" };
2559
2664
  const flushTextUpdate = (msgId) => {
2560
2665
  pendingFlush = false;
2561
2666
  const snapshot = pendingContentRef.current;
2667
+ const thinkingSnapshot = pendingThinkingRef.current;
2562
2668
  setMessages(
2563
2669
  (prev) => prev.map(
2564
- (msg) => msg.id === msgId ? __spreadProps(__spreadValues({}, msg), { content: snapshot }) : msg
2670
+ (msg) => msg.id === msgId ? __spreadProps(__spreadValues({}, msg), {
2671
+ content: snapshot,
2672
+ thinking: thinkingSnapshot || void 0
2673
+ }) : msg
2565
2674
  )
2566
2675
  );
2567
2676
  };
@@ -2595,8 +2704,13 @@ function useRagChat(projectId, options = {}) {
2595
2704
  assistantContent += frame.text;
2596
2705
  pendingContentRef.current = assistantContent;
2597
2706
  scheduleFlush(assistantMessageId);
2707
+ } else if (frame.type === "thinking" && frame.text) {
2708
+ thinkingContent += frame.text;
2709
+ pendingThinkingRef.current = thinkingContent;
2710
+ scheduleFlush(assistantMessageId);
2598
2711
  } else if (frame.type === "metadata") {
2599
2712
  sources = (_a = frame.sources) != null ? _a : [];
2713
+ thinkingMs = frame.thinkingMs;
2600
2714
  hasNonTextFrame = true;
2601
2715
  } else if (frame.type === "ui_transformation") {
2602
2716
  uiTransformation = frame.data;
@@ -2614,6 +2728,8 @@ function useRagChat(projectId, options = {}) {
2614
2728
  (prev) => prev.map(
2615
2729
  (msg) => msg.id === assistantMessageId ? __spreadProps(__spreadValues({}, msg), {
2616
2730
  content: assistantContent,
2731
+ thinking: thinkingContent || void 0,
2732
+ thinkingMs,
2617
2733
  sources: sources.length > 0 ? sources : msg.sources,
2618
2734
  uiTransformation: uiTransformation || msg.uiTransformation
2619
2735
  }) : msg
@@ -2624,8 +2740,11 @@ function useRagChat(projectId, options = {}) {
2624
2740
  if (buffer.trim()) {
2625
2741
  for (const frame of parseSseChunk(buffer)) {
2626
2742
  if (frame.type === "text" && frame.text) assistantContent += frame.text;
2627
- else if (frame.type === "metadata") sources = (_b = frame.sources) != null ? _b : [];
2628
- else if (frame.type === "observability") trace = frame.data;
2743
+ else if (frame.type === "thinking" && frame.text) thinkingContent += frame.text;
2744
+ else if (frame.type === "metadata") {
2745
+ sources = (_b = frame.sources) != null ? _b : [];
2746
+ thinkingMs = frame.thinkingMs;
2747
+ } else if (frame.type === "observability") trace = frame.data;
2629
2748
  }
2630
2749
  }
2631
2750
  const finalMsg = {
@@ -2635,6 +2754,8 @@ function useRagChat(projectId, options = {}) {
2635
2754
  sources: sources.length > 0 ? sources : void 0,
2636
2755
  uiTransformation: uiTransformation != null ? uiTransformation : void 0,
2637
2756
  trace,
2757
+ thinking: thinkingContent || void 0,
2758
+ thinkingMs,
2638
2759
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
2639
2760
  };
2640
2761
  setMessages(
@@ -2656,12 +2777,12 @@ function useRagChat(projectId, options = {}) {
2656
2777
  },
2657
2778
  [apiUrl, isLoading, namespace, onError, onReply, projectId, setMessages]
2658
2779
  );
2659
- const clear = (0, import_react10.useCallback)(() => {
2780
+ const clear = (0, import_react11.useCallback)(() => {
2660
2781
  setMessages([]);
2661
2782
  setError(null);
2662
2783
  if (persist) localStorage.removeItem(storageKey);
2663
2784
  }, [persist, setMessages, storageKey]);
2664
- const retry = (0, import_react10.useCallback)(async () => {
2785
+ const retry = (0, import_react11.useCallback)(async () => {
2665
2786
  if (lastInputRef.current) {
2666
2787
  const latestMessage = messagesRef.current[messagesRef.current.length - 1];
2667
2788
  await sendMessage(lastInputRef.current, {
@@ -2669,7 +2790,7 @@ function useRagChat(projectId, options = {}) {
2669
2790
  });
2670
2791
  }
2671
2792
  }, [sendMessage]);
2672
- const stop = (0, import_react10.useCallback)(() => {
2793
+ const stop = (0, import_react11.useCallback)(() => {
2673
2794
  if (abortControllerRef.current) {
2674
2795
  abortControllerRef.current.abort();
2675
2796
  abortControllerRef.current = null;
@@ -2689,7 +2810,7 @@ function useRagChat(projectId, options = {}) {
2689
2810
  }
2690
2811
 
2691
2812
  // src/components/ChatWindow.tsx
2692
- var import_jsx_runtime13 = require("react/jsx-runtime");
2813
+ var import_jsx_runtime14 = require("react/jsx-runtime");
2693
2814
  function ChatWindow({
2694
2815
  className = "",
2695
2816
  style,
@@ -2704,21 +2825,21 @@ function ChatWindow({
2704
2825
  }) {
2705
2826
  var _a;
2706
2827
  const { ui, projectId } = useConfig();
2707
- const [input, setInput] = (0, import_react11.useState)("");
2708
- const [mounted, setMounted] = (0, import_react11.useState)(false);
2709
- const [viewportSize, setViewportSize] = (0, import_react11.useState)("large");
2710
- const windowRef = (0, import_react11.useRef)(null);
2711
- const bottomRef = (0, import_react11.useRef)(null);
2712
- const inputRef = (0, import_react11.useRef)(null);
2828
+ const [input, setInput] = (0, import_react12.useState)("");
2829
+ const [mounted, setMounted] = (0, import_react12.useState)(false);
2830
+ const [viewportSize, setViewportSize] = (0, import_react12.useState)("large");
2831
+ const windowRef = (0, import_react12.useRef)(null);
2832
+ const bottomRef = (0, import_react12.useRef)(null);
2833
+ const inputRef = (0, import_react12.useRef)(null);
2713
2834
  const { messages, send, clear, isLoading, error, stop } = useRagChat(projectId, {
2714
2835
  namespace: projectId
2715
2836
  });
2716
- const [suggestions, setSuggestions] = (0, import_react11.useState)([]);
2717
- const [isSuggesting, setIsSuggesting] = (0, import_react11.useState)(false);
2718
- const [isListening, setIsListening] = (0, import_react11.useState)(false);
2719
- const [isUploadModalOpen, setIsUploadModalOpen] = (0, import_react11.useState)(false);
2720
- const recognitionRef = (0, import_react11.useRef)(null);
2721
- (0, import_react11.useEffect)(() => {
2837
+ const [suggestions, setSuggestions] = (0, import_react12.useState)([]);
2838
+ const [isSuggesting, setIsSuggesting] = (0, import_react12.useState)(false);
2839
+ const [isListening, setIsListening] = (0, import_react12.useState)(false);
2840
+ const [isUploadModalOpen, setIsUploadModalOpen] = (0, import_react12.useState)(false);
2841
+ const recognitionRef = (0, import_react12.useRef)(null);
2842
+ (0, import_react12.useEffect)(() => {
2722
2843
  if (typeof window !== "undefined") {
2723
2844
  const win = window;
2724
2845
  const SpeechRecognition = win.SpeechRecognition || win.webkitSpeechRecognition;
@@ -2764,10 +2885,10 @@ function ChatWindow({
2764
2885
  }
2765
2886
  }
2766
2887
  };
2767
- (0, import_react11.useEffect)(() => {
2888
+ (0, import_react12.useEffect)(() => {
2768
2889
  setMounted(true);
2769
2890
  }, []);
2770
- (0, import_react11.useEffect)(() => {
2891
+ (0, import_react12.useEffect)(() => {
2771
2892
  const element = windowRef.current;
2772
2893
  if (!element || typeof ResizeObserver === "undefined") return;
2773
2894
  const resolveViewportSize = (width) => {
@@ -2783,13 +2904,13 @@ function ChatWindow({
2783
2904
  observer.observe(element);
2784
2905
  return () => observer.disconnect();
2785
2906
  }, []);
2786
- (0, import_react11.useEffect)(() => {
2907
+ (0, import_react12.useEffect)(() => {
2787
2908
  var _a2;
2788
2909
  if (messages.length > 0 || isLoading) {
2789
2910
  (_a2 = bottomRef.current) == null ? void 0 : _a2.scrollIntoView({ behavior: "smooth" });
2790
2911
  }
2791
2912
  }, [messages, isLoading]);
2792
- const sendMessage = (0, import_react11.useCallback)(async () => {
2913
+ const sendMessage = (0, import_react12.useCallback)(async () => {
2793
2914
  var _a2;
2794
2915
  const text = input.trim();
2795
2916
  if (!text || isLoading) return;
@@ -2819,7 +2940,7 @@ function ChatWindow({
2819
2940
  const isEmpty = messages.length === 0;
2820
2941
  const currentRadius = BORDER_RADIUS_MAP[ui.borderRadius || "xl"];
2821
2942
  const isGlass = ui.visualStyle !== "solid";
2822
- (0, import_react11.useEffect)(() => {
2943
+ (0, import_react12.useEffect)(() => {
2823
2944
  if (input.trim().length < 3) {
2824
2945
  return;
2825
2946
  }
@@ -2843,85 +2964,85 @@ function ChatWindow({
2843
2964
  }, 800);
2844
2965
  return () => clearTimeout(timer);
2845
2966
  }, [input, projectId]);
2846
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2967
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2847
2968
  "div",
2848
2969
  {
2849
2970
  ref: windowRef,
2850
2971
  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}`,
2851
2972
  style: __spreadValues({ "--primary": ui.primaryColor, "--accent": ui.accentColor }, style),
2852
2973
  children: [
2853
- onResizeStart && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2974
+ onResizeStart && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2854
2975
  "div",
2855
2976
  {
2856
2977
  onMouseDown: onResizeStart,
2857
2978
  className: "absolute top-0 left-0 w-6 h-6 cursor-nw-resize z-[100] group flex items-start justify-start p-1",
2858
2979
  title: "Drag to resize",
2859
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("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]" })
2980
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("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]" })
2860
2981
  }
2861
2982
  ),
2862
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2983
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2863
2984
  "div",
2864
2985
  {
2865
2986
  className: "flex items-center justify-between px-5 py-4 border-b border-slate-200 dark:border-white/10",
2866
2987
  style: { background: `linear-gradient(135deg, ${ui.primaryColor}15, ${ui.accentColor}10)` },
2867
2988
  children: [
2868
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-3", children: [
2989
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-3", children: [
2869
2990
  ui.logoUrl ? (
2870
2991
  // eslint-disable-next-line @next/next/no-img-element
2871
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("img", { src: ui.logoUrl, alt: "logo", className: "w-8 h-8 rounded-lg object-cover" })
2872
- ) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2992
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("img", { src: ui.logoUrl, alt: "logo", className: "w-8 h-8 rounded-lg object-cover" })
2993
+ ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2873
2994
  "div",
2874
2995
  {
2875
2996
  className: `w-9 h-9 flex items-center justify-center shadow-md ${ui.borderRadius === "full" ? "rounded-full" : "rounded-xl"}`,
2876
2997
  style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
2877
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Bot, { className: "w-5 h-5 text-white" })
2998
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.Bot, { className: "w-5 h-5 text-white" })
2878
2999
  }
2879
3000
  ),
2880
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
2881
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h2", { className: "text-slate-900 dark:text-white font-semibold text-sm leading-tight", children: ui.title }),
2882
- ui.poweredBy && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-slate-500 dark:text-white/40 text-[11px] leading-tight", children: `Powered by ${ui.poweredBy}` })
3001
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
3002
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h2", { className: "text-slate-900 dark:text-white font-semibold text-sm leading-tight", children: ui.title }),
3003
+ ui.poweredBy && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-slate-500 dark:text-white/40 text-[11px] leading-tight", children: `Powered by ${ui.poweredBy}` })
2883
3004
  ] })
2884
3005
  ] }),
2885
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-1.5", children: [
2886
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400 mr-2", children: [
2887
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-emerald-500 dark:bg-emerald-400 animate-pulse" }),
3006
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-1.5", children: [
3007
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400 mr-2", children: [
3008
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-emerald-500 dark:bg-emerald-400 animate-pulse" }),
2888
3009
  "Online"
2889
3010
  ] }),
2890
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("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", children: [
2891
- mounted && messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3011
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("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", children: [
3012
+ mounted && messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2892
3013
  "button",
2893
3014
  {
2894
3015
  onClick: clearHistory,
2895
3016
  title: "Clear conversation",
2896
3017
  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",
2897
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Trash2, { className: "w-3.5 h-3.5" })
3018
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.Trash2, { className: "w-3.5 h-3.5" })
2898
3019
  }
2899
3020
  ),
2900
- isResized && onResetResize && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3021
+ isResized && onResetResize && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2901
3022
  "button",
2902
3023
  {
2903
3024
  onClick: onResetResize,
2904
3025
  title: "Reset to default size",
2905
3026
  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",
2906
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.RotateCcw, { className: "w-3.5 h-3.5" })
3027
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.RotateCcw, { className: "w-3.5 h-3.5" })
2907
3028
  }
2908
3029
  ),
2909
- onMaximize && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3030
+ onMaximize && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2910
3031
  "button",
2911
3032
  {
2912
3033
  onClick: onMaximize,
2913
3034
  title: isMaximized ? "Minimize" : "Maximize",
2914
3035
  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",
2915
- children: isMaximized ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Minimize2, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Maximize2, { className: "w-3.5 h-3.5" })
3036
+ children: isMaximized ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.Minimize2, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.Maximize2, { className: "w-3.5 h-3.5" })
2916
3037
  }
2917
3038
  ),
2918
- showClose && onClose && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3039
+ showClose && onClose && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2919
3040
  "button",
2920
3041
  {
2921
3042
  onClick: onClose,
2922
3043
  title: "Close chat",
2923
3044
  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",
2924
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.X, { className: "w-4 h-4" })
3045
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.X, { className: "w-4 h-4" })
2925
3046
  }
2926
3047
  )
2927
3048
  ] })
@@ -2929,24 +3050,24 @@ function ChatWindow({
2929
3050
  ]
2930
3051
  }
2931
3052
  ),
2932
- /* @__PURE__ */ (0, import_jsx_runtime13.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: [
3053
+ /* @__PURE__ */ (0, import_jsx_runtime14.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: [
2933
3054
  !mounted || isEmpty ? (
2934
3055
  /* Welcome state */
2935
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "h-full flex flex-col items-center justify-center text-center gap-4 px-6 py-12", children: [
2936
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3056
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "h-full flex flex-col items-center justify-center text-center gap-4 px-6 py-12", children: [
3057
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2937
3058
  "div",
2938
3059
  {
2939
3060
  className: `w-16 h-16 flex items-center justify-center shadow-lg ${ui.borderRadius === "full" ? "rounded-full" : "rounded-2xl"}`,
2940
3061
  style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
2941
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Sparkles, { className: "w-8 h-8 text-white" })
3062
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.Sparkles, { className: "w-8 h-8 text-white" })
2942
3063
  }
2943
3064
  ),
2944
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
2945
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-slate-800 dark:text-white/80 font-medium leading-relaxed", children: ui.welcomeMessage }),
2946
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-slate-500 dark:text-white/30 text-sm mt-2", children: "Ask a question to get started" })
3065
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
3066
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-slate-800 dark:text-white/80 font-medium leading-relaxed", children: ui.welcomeMessage }),
3067
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-slate-500 dark:text-white/30 text-sm mt-2", children: "Ask a question to get started" })
2947
3068
  ] }),
2948
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex flex-wrap gap-2 justify-center mt-2", children: CHAT_SUGGESTIONS.map(
2949
- (suggestion) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3069
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex flex-wrap gap-2 justify-center mt-2", children: CHAT_SUGGESTIONS.map(
3070
+ (suggestion) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2950
3071
  "button",
2951
3072
  {
2952
3073
  onClick: () => {
@@ -2961,7 +3082,7 @@ function ChatWindow({
2961
3082
  )
2962
3083
  ) })
2963
3084
  ] })
2964
- ) : messages.map((msg, index) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3085
+ ) : messages.map((msg, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2965
3086
  MessageBubble,
2966
3087
  {
2967
3088
  message: msg,
@@ -2974,7 +3095,7 @@ function ChatWindow({
2974
3095
  },
2975
3096
  msg.id
2976
3097
  )),
2977
- isLoading && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) !== "assistant" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3098
+ isLoading && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) !== "assistant" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2978
3099
  MessageBubble,
2979
3100
  {
2980
3101
  message: { id: "loading", role: "assistant", content: "", createdAt: (/* @__PURE__ */ new Date()).toISOString() },
@@ -2985,22 +3106,22 @@ function ChatWindow({
2985
3106
  viewportSize
2986
3107
  }
2987
3108
  ),
2988
- error && /* @__PURE__ */ (0, import_jsx_runtime13.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: [
2989
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.TriangleAlert, { className: "w-4 h-4 flex-shrink-0" }),
2990
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: error })
3109
+ error && /* @__PURE__ */ (0, import_jsx_runtime14.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: [
3110
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.TriangleAlert, { className: "w-4 h-4 flex-shrink-0" }),
3111
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: error })
2991
3112
  ] }),
2992
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { ref: bottomRef })
3113
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { ref: bottomRef })
2993
3114
  ] }),
2994
- isUploadModalOpen && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "absolute inset-0 z-50 flex items-center justify-center p-4 bg-slate-900/50 backdrop-blur-sm rounded-inherit", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "relative w-full max-w-md bg-white dark:bg-[#0f0f1a] rounded-2xl shadow-2xl overflow-hidden animate-in zoom-in-95 duration-200", children: [
2995
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3115
+ isUploadModalOpen && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "absolute inset-0 z-50 flex items-center justify-center p-4 bg-slate-900/50 backdrop-blur-sm rounded-inherit", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "relative w-full max-w-md bg-white dark:bg-[#0f0f1a] rounded-2xl shadow-2xl overflow-hidden animate-in zoom-in-95 duration-200", children: [
3116
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2996
3117
  "button",
2997
3118
  {
2998
3119
  onClick: () => setIsUploadModalOpen(false),
2999
3120
  className: "absolute top-4 right-4 p-1.5 rounded-lg text-slate-400 hover:text-slate-600 hover:bg-slate-100 dark:hover:text-white/80 dark:hover:bg-white/10 transition-colors z-10",
3000
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.X, { className: "w-5 h-5" })
3121
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.X, { className: "w-5 h-5" })
3001
3122
  }
3002
3123
  ),
3003
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3124
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3004
3125
  DocumentUpload,
3005
3126
  {
3006
3127
  namespace: projectId,
@@ -3008,9 +3129,9 @@ function ChatWindow({
3008
3129
  }
3009
3130
  )
3010
3131
  ] }) }),
3011
- /* @__PURE__ */ (0, import_jsx_runtime13.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: [
3012
- (suggestions.length > 0 || isSuggesting) && !isLoading && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "mb-3 flex flex-wrap gap-2 animate-in fade-in slide-in-from-bottom-2 duration-300", children: [
3013
- suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
3132
+ /* @__PURE__ */ (0, import_jsx_runtime14.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: [
3133
+ (suggestions.length > 0 || isSuggesting) && !isLoading && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "mb-3 flex flex-wrap gap-2 animate-in fade-in slide-in-from-bottom-2 duration-300", children: [
3134
+ suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3014
3135
  "button",
3015
3136
  {
3016
3137
  onClick: () => {
@@ -3021,19 +3142,19 @@ function ChatWindow({
3021
3142
  },
3022
3143
  className: "flex items-center gap-1.5 px-3 py-1.5 rounded-xl text-[11px] font-medium bg-white dark:bg-white/5 border border-slate-200 dark:border-white/10 text-slate-600 dark:text-white/60 hover:text-slate-900 dark:hover:text-white/90 hover:border-slate-300 dark:hover:border-white/20 transition-all shadow-sm cursor-pointer group",
3023
3144
  children: [
3024
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Sparkles, { className: "w-3 h-3 text-amber-400" }),
3145
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.Sparkles, { className: "w-3 h-3 text-amber-400" }),
3025
3146
  suggestion
3026
3147
  ]
3027
3148
  },
3028
3149
  suggestion
3029
3150
  )),
3030
- isSuggesting && suggestions.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-1.5 px-3 py-1.5 rounded-xl text-[11px] font-medium text-slate-400 dark:text-white/30 animate-pulse", children: [
3031
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Sparkles, { className: "w-3 h-3" }),
3151
+ isSuggesting && suggestions.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-1.5 px-3 py-1.5 rounded-xl text-[11px] font-medium text-slate-400 dark:text-white/30 animate-pulse", children: [
3152
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.Sparkles, { className: "w-3 h-3" }),
3032
3153
  "Thinking..."
3033
3154
  ] })
3034
3155
  ] }),
3035
- /* @__PURE__ */ (0, import_jsx_runtime13.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: [
3036
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3156
+ /* @__PURE__ */ (0, import_jsx_runtime14.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: [
3157
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3037
3158
  "textarea",
3038
3159
  {
3039
3160
  ref: inputRef,
@@ -3053,7 +3174,7 @@ function ChatWindow({
3053
3174
  style: { scrollbarWidth: "none" }
3054
3175
  }
3055
3176
  ),
3056
- ui.enableVoiceInput !== false && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3177
+ ui.enableVoiceInput !== false && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3057
3178
  "button",
3058
3179
  {
3059
3180
  type: "button",
@@ -3061,28 +3182,28 @@ function ChatWindow({
3061
3182
  disabled: isLoading,
3062
3183
  className: `flex-shrink-0 w-9 h-9 rounded-xl flex items-center justify-center transition-all hover:scale-105 active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100 disabled:active:scale-100 ${isListening ? "bg-rose-500 text-white animate-pulse shadow-md shadow-rose-500/20" : "text-slate-400 dark:text-white/40 hover:bg-slate-200 dark:hover:bg-white/10"}`,
3063
3184
  title: isListening ? "Stop listening" : "Start voice input",
3064
- children: isListening ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.MicOff, { className: "w-4 h-4" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Mic, { className: "w-4 h-4" })
3185
+ children: isListening ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.MicOff, { className: "w-4 h-4" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.Mic, { className: "w-4 h-4" })
3065
3186
  }
3066
3187
  ),
3067
- ui.allowUpload !== false && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3188
+ ui.allowUpload !== false && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3068
3189
  "button",
3069
3190
  {
3070
3191
  type: "button",
3071
3192
  onClick: () => setIsUploadModalOpen(true),
3072
3193
  className: "flex-shrink-0 w-9 h-9 rounded-xl flex items-center justify-center transition-all hover:scale-105 active:scale-95 text-slate-400 dark:text-white/40 hover:bg-slate-200 dark:hover:bg-white/10",
3073
3194
  title: "Upload Document",
3074
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Paperclip, { className: "w-4 h-4" })
3195
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.Paperclip, { className: "w-4 h-4" })
3075
3196
  }
3076
3197
  ),
3077
- isLoading ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3198
+ isLoading ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3078
3199
  "button",
3079
3200
  {
3080
3201
  onClick: stop,
3081
3202
  className: "flex-shrink-0 w-9 h-9 rounded-xl flex items-center justify-center transition-all hover:scale-105 active:scale-95 shadow-md bg-rose-500 hover:bg-rose-600 text-white cursor-pointer",
3082
3203
  title: "Stop generating",
3083
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "w-3.5 h-3.5 bg-white rounded-[2px]" })
3204
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "w-3.5 h-3.5 bg-white rounded-[2px]" })
3084
3205
  }
3085
- ) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3206
+ ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3086
3207
  "button",
3087
3208
  {
3088
3209
  onClick: sendMessage,
@@ -3092,11 +3213,11 @@ function ChatWindow({
3092
3213
  background: input.trim() ? `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` : "rgba(148, 163, 184, 0.2)"
3093
3214
  // slate-400/20 for light mode disabled
3094
3215
  },
3095
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.ArrowUp, { className: "w-4 h-4 text-white" })
3216
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.ArrowUp, { className: "w-4 h-4 text-white" })
3096
3217
  }
3097
3218
  )
3098
3219
  ] }),
3099
- /* @__PURE__ */ (0, import_jsx_runtime13.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" })
3220
+ /* @__PURE__ */ (0, import_jsx_runtime14.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" })
3100
3221
  ] })
3101
3222
  ]
3102
3223
  }
@@ -3104,7 +3225,7 @@ function ChatWindow({
3104
3225
  }
3105
3226
 
3106
3227
  // src/components/ChatWidget.tsx
3107
- var import_jsx_runtime14 = require("react/jsx-runtime");
3228
+ var import_jsx_runtime15 = require("react/jsx-runtime");
3108
3229
  var DEFAULT_DIMENSIONS = { width: 380, height: 600 };
3109
3230
  var GEMINI_STYLES = `
3110
3231
  @keyframes shapeshift {
@@ -3145,12 +3266,12 @@ var GEMINI_STYLES = `
3145
3266
  `;
3146
3267
  function ChatWidget({ position = "bottom-right", onAddToCart }) {
3147
3268
  const { ui } = useConfig();
3148
- const [isOpen, setIsOpen] = (0, import_react12.useState)(false);
3149
- const [hasUnread, setHasUnread] = (0, import_react12.useState)(false);
3150
- const [dimensions, setDimensions] = (0, import_react12.useState)(DEFAULT_DIMENSIONS);
3151
- const [isResizing, setIsResizing] = (0, import_react12.useState)(false);
3152
- const [isMaximized, setIsMaximized] = (0, import_react12.useState)(false);
3153
- const [prevDimensions, setPrevDimensions] = (0, import_react12.useState)(DEFAULT_DIMENSIONS);
3269
+ const [isOpen, setIsOpen] = (0, import_react13.useState)(false);
3270
+ const [hasUnread, setHasUnread] = (0, import_react13.useState)(false);
3271
+ const [dimensions, setDimensions] = (0, import_react13.useState)(DEFAULT_DIMENSIONS);
3272
+ const [isResizing, setIsResizing] = (0, import_react13.useState)(false);
3273
+ const [isMaximized, setIsMaximized] = (0, import_react13.useState)(false);
3274
+ const [prevDimensions, setPrevDimensions] = (0, import_react13.useState)(DEFAULT_DIMENSIONS);
3154
3275
  if (ui.showWidget === false) return null;
3155
3276
  const positionClass = position === "bottom-left" ? "bottom-6 left-6" : "bottom-6 right-6";
3156
3277
  const windowPositionClass = position === "bottom-left" ? "bottom-20 left-6" : "bottom-20 right-6";
@@ -3199,9 +3320,9 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
3199
3320
  }
3200
3321
  };
3201
3322
  const isResized = dimensions.width !== DEFAULT_DIMENSIONS.width || dimensions.height !== DEFAULT_DIMENSIONS.height;
3202
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
3203
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("style", { dangerouslySetInnerHTML: { __html: GEMINI_STYLES } }),
3204
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3323
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
3324
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("style", { dangerouslySetInnerHTML: { __html: GEMINI_STYLES } }),
3325
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3205
3326
  "div",
3206
3327
  {
3207
3328
  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"}`,
@@ -3211,7 +3332,7 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
3211
3332
  maxHeight: "calc(100vh - 6rem)"
3212
3333
  },
3213
3334
  children: [
3214
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3335
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3215
3336
  ChatWindow,
3216
3337
  {
3217
3338
  className: "h-full relative z-10",
@@ -3225,7 +3346,7 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
3225
3346
  onAddToCart
3226
3347
  }
3227
3348
  ),
3228
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3349
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3229
3350
  "div",
3230
3351
  {
3231
3352
  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"}`
@@ -3234,18 +3355,18 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
3234
3355
  ]
3235
3356
  }
3236
3357
  ),
3237
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3358
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3238
3359
  "button",
3239
3360
  {
3240
3361
  onClick: isOpen ? () => setIsOpen(false) : handleOpen,
3241
3362
  className: `group fixed z-[9999] w-14 h-14 drop-shadow-2xl flex items-center justify-center transition-all duration-300 cursor-pointer hover:scale-110 active:scale-95 ${positionClass}`,
3242
3363
  "aria-label": "Open chat",
3243
3364
  children: [
3244
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3365
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3245
3366
  "div",
3246
3367
  {
3247
3368
  className: "absolute inset-0 transition-all duration-300 overflow-hidden rounded-full group-hover:rounded-none group-hover:animate-[shapeshift_5s_ease-in-out_infinite_forwards]",
3248
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3369
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3249
3370
  "div",
3250
3371
  {
3251
3372
  className: "absolute top-0 left-0 w-[400%] h-[400%] transition-transform duration-300 group-hover:animate-[gradientMove_3.5s_ease-in-out_infinite_alternate]",
@@ -3256,34 +3377,81 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
3256
3377
  )
3257
3378
  }
3258
3379
  ),
3259
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3380
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3260
3381
  "span",
3261
3382
  {
3262
3383
  className: "absolute inset-0 rounded-full animate-ping opacity-20 pointer-events-none",
3263
3384
  style: { background: ui.primaryColor }
3264
3385
  }
3265
3386
  ),
3266
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3387
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3267
3388
  "span",
3268
3389
  {
3269
3390
  className: `relative z-10 transition-transform duration-300 ${isOpen ? "rotate-90 scale-90" : "rotate-0 scale-100"}`,
3270
- children: isOpen ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.X, { className: "w-6 h-6 text-white" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.MessageSquare, { className: "w-6 h-6 text-white" })
3391
+ children: isOpen ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react9.X, { className: "w-6 h-6 text-white" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react9.MessageSquare, { className: "w-6 h-6 text-white" })
3271
3392
  }
3272
3393
  ),
3273
- hasUnread && !isOpen && /* @__PURE__ */ (0, import_jsx_runtime14.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" })
3394
+ hasUnread && !isOpen && /* @__PURE__ */ (0, import_jsx_runtime15.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" })
3274
3395
  ]
3275
3396
  }
3276
3397
  )
3277
3398
  ] });
3278
3399
  }
3400
+
3401
+ // src/exceptions/index.ts
3402
+ var RetrivoraError = class extends Error {
3403
+ constructor(message, code, details) {
3404
+ super(message);
3405
+ this.name = new.target.name;
3406
+ this.code = code;
3407
+ this.details = details;
3408
+ }
3409
+ };
3410
+ var ProviderNotFoundException = class extends RetrivoraError {
3411
+ constructor(providerType, provider, details) {
3412
+ super(`Unsupported ${providerType} provider: ${provider}`, "PROVIDER_NOT_FOUND", details);
3413
+ }
3414
+ };
3415
+ var EmbeddingFailedException = class extends RetrivoraError {
3416
+ constructor(message = "Embedding generation failed", details) {
3417
+ super(message, "EMBEDDING_FAILED", details);
3418
+ }
3419
+ };
3420
+ var RetrievalException = class extends RetrivoraError {
3421
+ constructor(message = "Retrieval failed", details) {
3422
+ super(message, "RETRIEVAL_FAILED", details);
3423
+ }
3424
+ };
3425
+ var RateLimitException = class extends RetrivoraError {
3426
+ constructor(message = "Provider rate limit exceeded", details) {
3427
+ super(message, "RATE_LIMITED", details);
3428
+ }
3429
+ };
3430
+ var ConfigurationException = class extends RetrivoraError {
3431
+ constructor(message, details) {
3432
+ super(message, "CONFIGURATION_ERROR", details);
3433
+ }
3434
+ };
3435
+ var AuthenticationException = class extends RetrivoraError {
3436
+ constructor(message = "Provider authentication failed", details) {
3437
+ super(message, "AUTHENTICATION_ERROR", details);
3438
+ }
3439
+ };
3279
3440
  // Annotate the CommonJS export names for ESM import in node:
3280
3441
  0 && (module.exports = {
3442
+ AuthenticationException,
3281
3443
  ChatWidget,
3282
3444
  ChatWindow,
3283
3445
  ConfigProvider,
3446
+ ConfigurationException,
3284
3447
  DocumentUpload,
3448
+ EmbeddingFailedException,
3285
3449
  MessageBubble,
3286
3450
  ObservabilityPanel,
3451
+ ProviderNotFoundException,
3452
+ RateLimitException,
3453
+ RetrievalException,
3454
+ RetrivoraError,
3287
3455
  SourceCard,
3288
3456
  addSynonyms,
3289
3457
  useConfig,