@retrivora-ai/rag-engine 1.7.6 → 1.7.8

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
@@ -8,11 +8,11 @@ import {
8
8
  } from "./chunk-X4TOT24V.mjs";
9
9
 
10
10
  // src/components/ChatWidget.tsx
11
- import React9, { useState as useState5 } from "react";
11
+ import React10, { useState as useState5 } from "react";
12
12
  import { MessageSquare, X as X2 } from "lucide-react";
13
13
 
14
14
  // src/components/ChatWindow.tsx
15
- import React8, { useState as useState4, useRef as useRef3, useEffect as useEffect4, useCallback as useCallback2 } from "react";
15
+ import React9, { useState as useState4, useRef as useRef3, useEffect as useEffect4, useCallback as useCallback2 } from "react";
16
16
  import {
17
17
  Bot as Bot2,
18
18
  Trash2,
@@ -28,44 +28,44 @@ import {
28
28
  } from "lucide-react";
29
29
 
30
30
  // src/components/MessageBubble.tsx
31
- import React5 from "react";
31
+ import React6 from "react";
32
32
  import { Bot, User, ChevronDown as ChevronDown2, ChevronRight as ChevronRight2 } from "lucide-react";
33
33
  import ReactMarkdown from "react-markdown";
34
34
  import remarkGfm from "remark-gfm";
35
35
 
36
36
  // src/components/SourceCard.tsx
37
- import React from "react";
37
+ import React2 from "react";
38
38
  import { ChevronDown, ChevronUp } from "lucide-react";
39
39
  function SourceCard({ source, index }) {
40
40
  var _a, _b;
41
- const [expanded, setExpanded] = React.useState(false);
41
+ const [expanded, setExpanded] = React2.useState(false);
42
42
  const scorePercent = Math.round(source.score * 100);
43
43
  const scoreColor = source.score >= 0.8 ? "text-emerald-400" : source.score >= 0.6 ? "text-amber-400" : "text-rose-400";
44
44
  const scoreBg = source.score >= 0.8 ? "bg-emerald-50 border-emerald-100 dark:bg-emerald-400/10 dark:border-emerald-400/20" : source.score >= 0.6 ? "bg-amber-50 border-amber-100 dark:bg-amber-400/10 dark:border-amber-400/20" : "bg-rose-50 border-rose-100 dark:bg-rose-400/10 dark:border-rose-400/20";
45
45
  const preview = source.content.slice(0, 120);
46
46
  const hasMore = source.content.length > 120;
47
- return /* @__PURE__ */ React.createElement(
47
+ return /* @__PURE__ */ React2.createElement(
48
48
  "div",
49
49
  {
50
50
  className: `rounded-xl border backdrop-blur-sm p-3 transition-all duration-200 hover:scale-[1.01] cursor-pointer ${scoreBg}`,
51
51
  onClick: () => setExpanded((e) => !e)
52
52
  },
53
- /* @__PURE__ */ React.createElement("div", { className: "flex items-start justify-between gap-2" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 min-w-0" }, /* @__PURE__ */ React.createElement("span", { className: "flex-shrink-0 w-5 h-5 rounded-full bg-slate-200 dark:bg-white/10 flex items-center justify-center text-[10px] font-bold text-slate-500 dark:text-white/60" }, index + 1), /* @__PURE__ */ React.createElement("span", { className: "text-xs text-slate-500 dark:text-white/50 truncate font-mono" }, (_b = (_a = source.metadata) == null ? void 0 : _a.docId) != null ? _b : source.id)), /* @__PURE__ */ React.createElement("span", { className: `flex-shrink-0 text-xs font-semibold ${scoreColor} tabular-nums` }, scorePercent, "%")),
54
- /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-xs text-slate-600 dark:text-white/70 leading-relaxed" }, expanded ? source.content : `${preview}${hasMore && !expanded ? "\u2026" : ""}`),
55
- hasMore && /* @__PURE__ */ React.createElement("button", { className: "mt-1 text-[10px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-0.5" }, expanded ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ChevronUp, { className: "w-3 h-3" }), " Show less") : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ChevronDown, { className: "w-3 h-3" }), " Show more"))
53
+ /* @__PURE__ */ React2.createElement("div", { className: "flex items-start justify-between gap-2" }, /* @__PURE__ */ React2.createElement("div", { className: "flex items-center gap-2 min-w-0" }, /* @__PURE__ */ React2.createElement("span", { className: "flex-shrink-0 w-5 h-5 rounded-full bg-slate-200 dark:bg-white/10 flex items-center justify-center text-[10px] font-bold text-slate-500 dark:text-white/60" }, index + 1), /* @__PURE__ */ React2.createElement("span", { className: "text-xs text-slate-500 dark:text-white/50 truncate font-mono" }, (_b = (_a = source.metadata) == null ? void 0 : _a.docId) != null ? _b : source.id)), /* @__PURE__ */ React2.createElement("span", { className: `flex-shrink-0 text-xs font-semibold ${scoreColor} tabular-nums` }, scorePercent, "%")),
54
+ /* @__PURE__ */ React2.createElement("p", { className: "mt-2 text-xs text-slate-600 dark:text-white/70 leading-relaxed" }, expanded ? source.content : `${preview}${hasMore && !expanded ? "\u2026" : ""}`),
55
+ hasMore && /* @__PURE__ */ React2.createElement("button", { className: "mt-1 text-[10px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-0.5" }, expanded ? /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(ChevronUp, { className: "w-3 h-3" }), " Show less") : /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(ChevronDown, { className: "w-3 h-3" }), " Show more"))
56
56
  );
57
57
  }
58
58
 
59
59
  // src/components/ProductCarousel.tsx
60
- import React3, { useRef, useState, useEffect } from "react";
60
+ import React4, { useRef, useState, useEffect } from "react";
61
61
  import { ChevronLeft, ChevronRight } from "lucide-react";
62
62
 
63
63
  // src/components/ProductCard.tsx
64
- import React2 from "react";
64
+ import React3 from "react";
65
65
  import Image from "next/image";
66
66
  import { ShoppingCart, ExternalLink } from "lucide-react";
67
67
  function ProductCard({ product, primaryColor = "#6366f1", onAddToCart }) {
68
- return /* @__PURE__ */ React2.createElement("div", { className: "flex-shrink-0 w-full 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(
68
+ return /* @__PURE__ */ React3.createElement("div", { className: "flex-shrink-0 w-full 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__ */ React3.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__ */ React3.createElement(
69
69
  Image,
70
70
  {
71
71
  src: product.image,
@@ -74,16 +74,16 @@ function ProductCard({ product, primaryColor = "#6366f1", onAddToCart }) {
74
74
  unoptimized: true,
75
75
  className: "object-cover group-hover:scale-105 transition-transform duration-500"
76
76
  }
77
- ) : /* @__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(
77
+ ) : /* @__PURE__ */ React3.createElement("div", { className: "text-slate-400 dark:text-white/20" }, /* @__PURE__ */ React3.createElement(ShoppingCart, { className: "w-12 h-12" })), product.brand && /* @__PURE__ */ React3.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__ */ React3.createElement("div", { className: "p-4 flex flex-col gap-2" }, /* @__PURE__ */ React3.createElement("div", { className: "flex justify-between items-start gap-2" }, /* @__PURE__ */ React3.createElement("h3", { className: "text-sm font-semibold text-slate-800 dark:text-white/90 line-clamp-1" }, product.name), product.price && /* @__PURE__ */ React3.createElement("span", { className: "text-sm font-bold", style: { color: primaryColor } }, typeof product.price === "number" ? `$${product.price}` : product.price)), product.description && /* @__PURE__ */ React3.createElement("p", { className: "text-[11px] text-slate-500 dark:text-white/50 line-clamp-2 leading-relaxed" }, product.description), /* @__PURE__ */ React3.createElement("div", { className: "mt-2 flex gap-2" }, /* @__PURE__ */ React3.createElement(
78
78
  "button",
79
79
  {
80
80
  onClick: () => onAddToCart == null ? void 0 : onAddToCart(product),
81
81
  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",
82
82
  style: { background: primaryColor }
83
83
  },
84
- /* @__PURE__ */ React2.createElement(ShoppingCart, { className: "w-3 h-3" }),
84
+ /* @__PURE__ */ React3.createElement(ShoppingCart, { className: "w-3 h-3" }),
85
85
  "Add to Cart"
86
- ), product.link && /* @__PURE__ */ React2.createElement(
86
+ ), product.link && /* @__PURE__ */ React3.createElement(
87
87
  "a",
88
88
  {
89
89
  href: product.link,
@@ -91,7 +91,7 @@ function ProductCard({ product, primaryColor = "#6366f1", onAddToCart }) {
91
91
  rel: "noopener noreferrer",
92
92
  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"
93
93
  },
94
- /* @__PURE__ */ React2.createElement(ExternalLink, { className: "w-3.5 h-3.5" })
94
+ /* @__PURE__ */ React3.createElement(ExternalLink, { className: "w-3.5 h-3.5" })
95
95
  ))));
96
96
  }
97
97
 
@@ -123,9 +123,9 @@ function ProductCarousel({ products, primaryColor = "#6366f1", onAddToCart }) {
123
123
  };
124
124
  if (!products || products.length === 0) return null;
125
125
  if (products.length === 1) {
126
- return /* @__PURE__ */ React3.createElement("div", { className: "my-4 w-[min(88%,18rem)] min-w-0 max-w-full animate-fade-in-up" }, /* @__PURE__ */ React3.createElement(ProductCard, { product: products[0], primaryColor, onAddToCart }));
126
+ return /* @__PURE__ */ React4.createElement("div", { className: "my-4 w-[min(88%,18rem)] min-w-0 max-w-full animate-fade-in-up" }, /* @__PURE__ */ React4.createElement(ProductCard, { product: products[0], primaryColor, onAddToCart }));
127
127
  }
128
- return /* @__PURE__ */ React3.createElement("div", { className: "relative w-full my-4 group/carousel animate-fade-in-up" }, canScroll && /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("div", { className: "absolute -left-4 top-1/2 -translate-y-1/2 z-20 opacity-100 md:opacity-0 md:group-hover/carousel:opacity-100 transition-opacity" }, /* @__PURE__ */ React3.createElement(
128
+ return /* @__PURE__ */ React4.createElement("div", { className: "relative w-full my-4 group/carousel animate-fade-in-up" }, canScroll && /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement("div", { className: "absolute -left-4 top-1/2 -translate-y-1/2 z-20 opacity-100 md:opacity-0 md:group-hover/carousel:opacity-100 transition-opacity" }, /* @__PURE__ */ React4.createElement(
129
129
  "button",
130
130
  {
131
131
  onClick: (e) => {
@@ -135,8 +135,8 @@ function ProductCarousel({ products, primaryColor = "#6366f1", onAddToCart }) {
135
135
  className: "p-2 rounded-full bg-white dark:bg-slate-800 shadow-xl 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-all hover:scale-110 active:scale-95",
136
136
  "aria-label": "Scroll left"
137
137
  },
138
- /* @__PURE__ */ React3.createElement(ChevronLeft, { className: "w-5 h-5" })
139
- )), /* @__PURE__ */ React3.createElement("div", { className: "absolute -right-4 top-1/2 -translate-y-1/2 z-20 opacity-100 md:opacity-0 md:group-hover/carousel:opacity-100 transition-opacity" }, /* @__PURE__ */ React3.createElement(
138
+ /* @__PURE__ */ React4.createElement(ChevronLeft, { className: "w-5 h-5" })
139
+ )), /* @__PURE__ */ React4.createElement("div", { className: "absolute -right-4 top-1/2 -translate-y-1/2 z-20 opacity-100 md:opacity-0 md:group-hover/carousel:opacity-100 transition-opacity" }, /* @__PURE__ */ React4.createElement(
140
140
  "button",
141
141
  {
142
142
  onClick: (e) => {
@@ -146,27 +146,27 @@ function ProductCarousel({ products, primaryColor = "#6366f1", onAddToCart }) {
146
146
  className: "p-2 rounded-full bg-white dark:bg-slate-800 shadow-xl 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-all hover:scale-110 active:scale-95",
147
147
  "aria-label": "Scroll right"
148
148
  },
149
- /* @__PURE__ */ React3.createElement(ChevronRight, { className: "w-5 h-5" })
150
- ))), /* @__PURE__ */ React3.createElement(
149
+ /* @__PURE__ */ React4.createElement(ChevronRight, { className: "w-5 h-5" })
150
+ ))), /* @__PURE__ */ React4.createElement(
151
151
  "div",
152
152
  {
153
153
  ref: scrollRef,
154
154
  className: "flex gap-4 overflow-x-auto pb-4 px-1 scrollbar-hide snap-x snap-mandatory",
155
155
  style: { scrollbarWidth: "none", msOverflowStyle: "none" }
156
156
  },
157
- products.map((product) => /* @__PURE__ */ React3.createElement(
157
+ products.map((product) => /* @__PURE__ */ React4.createElement(
158
158
  "div",
159
159
  {
160
160
  key: product.id,
161
161
  className: "snap-start flex-shrink-0 w-[min(88%,18rem)] min-w-[11rem] max-w-full"
162
162
  },
163
- /* @__PURE__ */ React3.createElement(ProductCard, { product, primaryColor, onAddToCart })
163
+ /* @__PURE__ */ React4.createElement(ProductCard, { product, primaryColor, onAddToCart })
164
164
  ))
165
165
  ));
166
166
  }
167
167
 
168
168
  // src/components/DynamicChart.tsx
169
- import React4 from "react";
169
+ import React5 from "react";
170
170
  import {
171
171
  BarChart,
172
172
  Bar,
@@ -191,9 +191,9 @@ function DynamicChart({
191
191
  }) {
192
192
  const { type, data } = config;
193
193
  const colors = config.colors || [primaryColor, accentColor, ...DEFAULT_COLORS];
194
- const containerRef = React4.useRef(null);
195
- const [containerWidth, setContainerWidth] = React4.useState(0);
196
- React4.useEffect(() => {
194
+ const containerRef = React5.useRef(null);
195
+ const [containerWidth, setContainerWidth] = React5.useState(0);
196
+ React5.useEffect(() => {
197
197
  const element = containerRef.current;
198
198
  if (!element || typeof ResizeObserver === "undefined") return;
199
199
  const updateWidth = (width) => {
@@ -219,7 +219,7 @@ function DynamicChart({
219
219
  return text.length > maxLength ? `${text.slice(0, maxLength)}\u2026` : text;
220
220
  };
221
221
  const chartMargin = isTiny ? { top: 8, right: 4, left: -28, bottom: 0 } : isCompact ? { top: 10, right: 6, left: -24, bottom: 0 } : { top: 10, right: 10, left: -20, bottom: 0 };
222
- const sanitizedData = React4.useMemo(() => {
222
+ const sanitizedData = React5.useMemo(() => {
223
223
  if (!data) return [];
224
224
  return data.map((item) => {
225
225
  const newItem = {};
@@ -252,7 +252,7 @@ function DynamicChart({
252
252
  });
253
253
  }, [data]);
254
254
  if (!data || data.length === 0) {
255
- return /* @__PURE__ */ React4.createElement("div", { className: "p-4 text-sm text-slate-500" }, "No data available for chart.");
255
+ return /* @__PURE__ */ React5.createElement("div", { className: "p-4 text-sm text-slate-500" }, "No data available for chart.");
256
256
  }
257
257
  const firstItem = sanitizedData[0];
258
258
  const allKeys = Object.keys(firstItem);
@@ -302,11 +302,11 @@ function DynamicChart({
302
302
  const renderTooltip = (row, label) => {
303
303
  var _a, _b;
304
304
  if (!row) return null;
305
- return /* @__PURE__ */ React4.createElement("div", { className: "rounded-xl border border-slate-200 bg-white px-3 py-2 text-xs shadow-xl dark:border-white/10 dark:bg-slate-950" }, /* @__PURE__ */ React4.createElement("p", { className: "mb-2 font-semibold text-slate-800 dark:text-white/90" }, String((_b = (_a = row[finalXKey]) != null ? _a : label) != null ? _b : "Details")), Object.entries(row).map(([key, value]) => {
305
+ return /* @__PURE__ */ React5.createElement("div", { className: "rounded-xl border border-slate-200 bg-white px-3 py-2 text-xs shadow-xl dark:border-white/10 dark:bg-slate-950" }, /* @__PURE__ */ React5.createElement("p", { className: "mb-2 font-semibold text-slate-800 dark:text-white/90" }, String((_b = (_a = row[finalXKey]) != null ? _a : label) != null ? _b : "Details")), Object.entries(row).map(([key, value]) => {
306
306
  var _a2;
307
307
  if (value === null || value === void 0 || key === finalXKey) return null;
308
308
  if (typeof value === "object") return null;
309
- return /* @__PURE__ */ React4.createElement("div", { key, className: "flex items-center justify-between gap-3 text-slate-600 dark:text-white/70" }, /* @__PURE__ */ React4.createElement("span", null, (_a2 = tooltipLabelMap[key]) != null ? _a2 : key), /* @__PURE__ */ React4.createElement("span", { className: "font-medium text-slate-900 dark:text-white/90" }, String(value)));
309
+ return /* @__PURE__ */ React5.createElement("div", { key, className: "flex items-center justify-between gap-3 text-slate-600 dark:text-white/70" }, /* @__PURE__ */ React5.createElement("span", null, (_a2 = tooltipLabelMap[key]) != null ? _a2 : key), /* @__PURE__ */ React5.createElement("span", { className: "font-medium text-slate-900 dark:text-white/90" }, String(value)));
310
310
  }));
311
311
  };
312
312
  const getTooltipRow = (payload) => {
@@ -318,7 +318,7 @@ function DynamicChart({
318
318
  return row;
319
319
  };
320
320
  if (type === "pie") {
321
- return /* @__PURE__ */ React4.createElement("div", { ref: containerRef, className: "w-full min-w-0 mt-4 mb-2 select-none overflow-hidden" }, /* @__PURE__ */ React4.createElement("div", { className: "mx-auto w-full max-w-full aspect-square" }, /* @__PURE__ */ React4.createElement(ResponsiveContainer, { width: "100%", height: "100%" }, /* @__PURE__ */ React4.createElement(PieChart, null, /* @__PURE__ */ React4.createElement(
321
+ return /* @__PURE__ */ React5.createElement("div", { ref: containerRef, className: "w-full min-w-0 mt-4 mb-2 select-none overflow-hidden" }, /* @__PURE__ */ React5.createElement("div", { className: "mx-auto w-full max-w-full aspect-square" }, /* @__PURE__ */ React5.createElement(ResponsiveContainer, { width: "100%", height: "100%" }, /* @__PURE__ */ React5.createElement(PieChart, null, /* @__PURE__ */ React5.createElement(
322
322
  Pie,
323
323
  {
324
324
  data: sanitizedData,
@@ -330,10 +330,10 @@ function DynamicChart({
330
330
  label: false,
331
331
  labelLine: false
332
332
  },
333
- sanitizedData.map((entry, index) => /* @__PURE__ */ React4.createElement(Cell, { key: `cell-${index}`, fill: stockAwareColor(entry, index) }))
334
- ), /* @__PURE__ */ React4.createElement(Tooltip, { content: (props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === "string" ? props.label : void 0) }), showLegend && !isCompact && /* @__PURE__ */ React4.createElement(Legend, { wrapperStyle: { fontSize: 12 }, verticalAlign: "bottom" })))));
333
+ sanitizedData.map((entry, index) => /* @__PURE__ */ React5.createElement(Cell, { key: `cell-${index}`, fill: stockAwareColor(entry, index) }))
334
+ ), /* @__PURE__ */ React5.createElement(Tooltip, { content: (props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === "string" ? props.label : void 0) }), showLegend && !isCompact && /* @__PURE__ */ React5.createElement(Legend, { wrapperStyle: { fontSize: 12 }, verticalAlign: "bottom" })))));
335
335
  }
336
- return /* @__PURE__ */ React4.createElement("div", { ref: containerRef, className: "w-full min-w-0 mt-4 mb-2 select-none overflow-hidden" }, /* @__PURE__ */ React4.createElement("div", { className: "w-full aspect-[4/3]" }, /* @__PURE__ */ React4.createElement(ResponsiveContainer, { width: "100%", height: "100%" }, type === "bar" ? /* @__PURE__ */ React4.createElement(BarChart, { data: sanitizedData, margin: chartMargin }, /* @__PURE__ */ React4.createElement(CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ React4.createElement(XAxis, { dataKey: finalXKey, tick: axisTick, tickFormatter: truncateAxisLabel, tickLine: false, axisLine: { stroke: "#cbd5e1" }, interval: 0, minTickGap: isTiny ? 2 : isCompact ? 6 : 12 }), /* @__PURE__ */ React4.createElement(YAxis, { tick: axisTick, tickLine: false, axisLine: false }), /* @__PURE__ */ React4.createElement(Tooltip, { content: (props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === "string" ? props.label : void 0), cursor: { fill: "#f1f5f9" } }), showLegend && /* @__PURE__ */ React4.createElement(Legend, { wrapperStyle: { fontSize: isCompact ? 10 : 12 } }), finalDataKeys.map((key, index) => /* @__PURE__ */ React4.createElement(
336
+ return /* @__PURE__ */ React5.createElement("div", { ref: containerRef, className: "w-full min-w-0 mt-4 mb-2 select-none overflow-hidden" }, /* @__PURE__ */ React5.createElement("div", { className: "w-full aspect-[4/3]" }, /* @__PURE__ */ React5.createElement(ResponsiveContainer, { width: "100%", height: "100%" }, type === "bar" ? /* @__PURE__ */ React5.createElement(BarChart, { data: sanitizedData, margin: chartMargin }, /* @__PURE__ */ React5.createElement(CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ React5.createElement(XAxis, { dataKey: finalXKey, tick: axisTick, tickFormatter: truncateAxisLabel, tickLine: false, axisLine: { stroke: "#cbd5e1" }, interval: 0, minTickGap: isTiny ? 2 : isCompact ? 6 : 12 }), /* @__PURE__ */ React5.createElement(YAxis, { tick: axisTick, tickLine: false, axisLine: false }), /* @__PURE__ */ React5.createElement(Tooltip, { content: (props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === "string" ? props.label : void 0), cursor: { fill: "#f1f5f9" } }), showLegend && /* @__PURE__ */ React5.createElement(Legend, { wrapperStyle: { fontSize: isCompact ? 10 : 12 } }), finalDataKeys.map((key, index) => /* @__PURE__ */ React5.createElement(
337
337
  Bar,
338
338
  {
339
339
  key,
@@ -342,7 +342,7 @@ function DynamicChart({
342
342
  radius: [4, 4, 0, 0],
343
343
  barSize: isTiny ? Math.max(10, 28 / data.length) : isCompact ? Math.max(14, 42 / data.length) : Math.max(20, 60 / data.length)
344
344
  }
345
- ))) : /* @__PURE__ */ React4.createElement(LineChart, { data: sanitizedData, margin: chartMargin }, /* @__PURE__ */ React4.createElement(CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ React4.createElement(XAxis, { dataKey: finalXKey, tick: axisTick, tickFormatter: truncateAxisLabel, tickLine: false, axisLine: { stroke: "#cbd5e1" }, interval: 0, minTickGap: isTiny ? 2 : isCompact ? 6 : 12 }), /* @__PURE__ */ React4.createElement(YAxis, { tick: axisTick, tickLine: false, axisLine: false }), /* @__PURE__ */ React4.createElement(Tooltip, { content: (props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === "string" ? props.label : void 0) }), showLegend && /* @__PURE__ */ React4.createElement(Legend, { wrapperStyle: { fontSize: isCompact ? 10 : 12 } }), finalDataKeys.map((key, index) => /* @__PURE__ */ React4.createElement(
345
+ ))) : /* @__PURE__ */ React5.createElement(LineChart, { data: sanitizedData, margin: chartMargin }, /* @__PURE__ */ React5.createElement(CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ React5.createElement(XAxis, { dataKey: finalXKey, tick: axisTick, tickFormatter: truncateAxisLabel, tickLine: false, axisLine: { stroke: "#cbd5e1" }, interval: 0, minTickGap: isTiny ? 2 : isCompact ? 6 : 12 }), /* @__PURE__ */ React5.createElement(YAxis, { tick: axisTick, tickLine: false, axisLine: false }), /* @__PURE__ */ React5.createElement(Tooltip, { content: (props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === "string" ? props.label : void 0) }), showLegend && /* @__PURE__ */ React5.createElement(Legend, { wrapperStyle: { fontSize: isCompact ? 10 : 12 } }), finalDataKeys.map((key, index) => /* @__PURE__ */ React5.createElement(
346
346
  Line,
347
347
  {
348
348
  key,
@@ -356,6 +356,178 @@ function DynamicChart({
356
356
  ))))));
357
357
  }
358
358
 
359
+ // src/components/VisualizationRenderer.tsx
360
+ import Image2 from "next/image";
361
+ function VisualizationRenderer({
362
+ data,
363
+ className = ""
364
+ }) {
365
+ if (!data) {
366
+ return /* @__PURE__ */ React.createElement("div", { className: `p-4 text-gray-500 ${className}` }, "No data available for visualization");
367
+ }
368
+ return /* @__PURE__ */ React.createElement("div", { className: `space-y-4 ${className}` }, /* @__PURE__ */ React.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React.createElement("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white" }, data.title), data.description && /* @__PURE__ */ React.createElement("p", { className: "text-sm text-gray-600 dark:text-gray-400" }, data.description)), renderVisualization(data.type, data.data));
369
+ }
370
+ function renderVisualization(type, data) {
371
+ switch (type) {
372
+ case "pie_chart":
373
+ return renderPieChart(data);
374
+ case "bar_chart":
375
+ return renderBarChart(data);
376
+ case "line_chart":
377
+ return renderLineChart(data);
378
+ case "table":
379
+ return renderTable(data);
380
+ case "product_carousel":
381
+ return renderProductCarousel(data);
382
+ case "text":
383
+ default:
384
+ return renderText(data);
385
+ }
386
+ }
387
+ function renderPieChart(data) {
388
+ if (!Array.isArray(data)) {
389
+ return /* @__PURE__ */ React.createElement("div", { className: "text-red-500" }, "Invalid pie chart data");
390
+ }
391
+ return /* @__PURE__ */ React.createElement("div", { className: "bg-white dark:bg-gray-800 p-4 rounded-lg shadow" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, data.map((item, idx) => /* @__PURE__ */ React.createElement(
392
+ "div",
393
+ {
394
+ key: idx,
395
+ className: "flex items-center gap-2 p-2 bg-gray-50 dark:bg-gray-700 rounded"
396
+ },
397
+ /* @__PURE__ */ React.createElement(
398
+ "div",
399
+ {
400
+ className: "w-3 h-3 rounded-full",
401
+ style: { backgroundColor: generateColor(idx) }
402
+ }
403
+ ),
404
+ /* @__PURE__ */ React.createElement("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300" }, item.label, ": ", item.value),
405
+ item.inStock !== void 0 && /* @__PURE__ */ React.createElement(
406
+ "span",
407
+ {
408
+ className: `text-xs px-2 py-1 rounded ${item.inStock ? "bg-green-100 text-green-800" : "bg-red-100 text-red-800"}`
409
+ },
410
+ item.inStock ? "In Stock" : "Out of Stock"
411
+ )
412
+ ))));
413
+ }
414
+ function renderBarChart(data) {
415
+ if (!Array.isArray(data)) {
416
+ return /* @__PURE__ */ React.createElement("div", { className: "text-red-500" }, "Invalid bar chart data");
417
+ }
418
+ return /* @__PURE__ */ React.createElement("div", { className: "bg-white dark:bg-gray-800 p-4 rounded-lg shadow overflow-x-auto" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-3" }, data.map((item, idx) => /* @__PURE__ */ React.createElement("div", { key: idx, className: "space-y-1" }, /* @__PURE__ */ React.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React.createElement("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300" }, item.category), /* @__PURE__ */ React.createElement("span", { className: "text-sm text-gray-600 dark:text-gray-400" }, item.value)), /* @__PURE__ */ React.createElement("div", { className: "w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2" }, /* @__PURE__ */ React.createElement(
419
+ "div",
420
+ {
421
+ className: "h-full rounded-full transition-all",
422
+ style: {
423
+ width: `${item.value / Math.max(...data.map((d) => d.value)) * 100}%`,
424
+ backgroundColor: generateColor(idx)
425
+ }
426
+ }
427
+ )), item.inStock !== void 0 && /* @__PURE__ */ React.createElement(
428
+ "span",
429
+ {
430
+ className: `text-xs px-2 py-1 rounded inline-block ${item.inStock ? "bg-green-100 text-green-800" : "bg-red-100 text-red-800"}`
431
+ },
432
+ item.inStock ? "In Stock" : "Out of Stock"
433
+ )))));
434
+ }
435
+ function renderLineChart(data) {
436
+ if (!Array.isArray(data)) {
437
+ return /* @__PURE__ */ React.createElement("div", { className: "text-red-500" }, "Invalid line chart data");
438
+ }
439
+ return /* @__PURE__ */ React.createElement("div", { className: "bg-white dark:bg-gray-800 p-4 rounded-lg shadow overflow-x-auto" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-2" }, data.map((point, idx) => /* @__PURE__ */ React.createElement(
440
+ "div",
441
+ {
442
+ key: idx,
443
+ className: "flex justify-between items-center p-2 bg-gray-50 dark:bg-gray-700 rounded"
444
+ },
445
+ /* @__PURE__ */ React.createElement("span", { className: "text-sm text-gray-600 dark:text-gray-400" }, point.label || point.timestamp),
446
+ /* @__PURE__ */ React.createElement("span", { className: "text-sm font-semibold text-gray-900 dark:text-white" }, typeof point.value === "number" ? point.value.toFixed(2) : point.value)
447
+ ))));
448
+ }
449
+ function renderTable(data) {
450
+ if (!data.columns || !data.rows) {
451
+ return /* @__PURE__ */ React.createElement("div", { className: "text-red-500" }, "Invalid table data");
452
+ }
453
+ return /* @__PURE__ */ React.createElement("div", { className: "bg-white dark:bg-gray-800 rounded-lg shadow overflow-x-auto" }, /* @__PURE__ */ React.createElement("table", { className: "w-full text-sm" }, /* @__PURE__ */ React.createElement("thead", { className: "bg-gray-100 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600" }, /* @__PURE__ */ React.createElement("tr", null, data.columns.map((col, idx) => /* @__PURE__ */ React.createElement(
454
+ "th",
455
+ {
456
+ key: idx,
457
+ className: "px-4 py-2 text-left font-semibold text-gray-900 dark:text-white"
458
+ },
459
+ col
460
+ )))), /* @__PURE__ */ React.createElement("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600" }, data.rows.map((row, rowIdx) => /* @__PURE__ */ React.createElement(
461
+ "tr",
462
+ {
463
+ key: rowIdx,
464
+ className: "hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
465
+ },
466
+ row.map((cell, cellIdx) => /* @__PURE__ */ React.createElement(
467
+ "td",
468
+ {
469
+ key: cellIdx,
470
+ className: "px-4 py-2 text-gray-700 dark:text-gray-300"
471
+ },
472
+ String(cell)
473
+ ))
474
+ )))));
475
+ }
476
+ function renderProductCarousel(data) {
477
+ if (!Array.isArray(data)) {
478
+ return /* @__PURE__ */ React.createElement("div", { className: "text-red-500" }, "Invalid carousel data");
479
+ }
480
+ return /* @__PURE__ */ React.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React.createElement("div", { className: "flex gap-4 pb-4" }, data.map((product) => /* @__PURE__ */ React.createElement(
481
+ "div",
482
+ {
483
+ key: product.id,
484
+ className: "flex-shrink-0 w-64 bg-white dark:bg-gray-800 rounded-lg shadow-md overflow-hidden hover:shadow-lg transition-shadow"
485
+ },
486
+ product.image && /* @__PURE__ */ React.createElement("div", { className: "relative w-full h-40 bg-gray-200" }, /* @__PURE__ */ React.createElement(
487
+ Image2,
488
+ {
489
+ src: product.image,
490
+ alt: product.name,
491
+ fill: true,
492
+ className: "object-cover",
493
+ sizes: "(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
494
+ }
495
+ )),
496
+ /* @__PURE__ */ React.createElement("div", { className: "p-4 space-y-2" }, /* @__PURE__ */ React.createElement("h4", { className: "font-semibold text-gray-900 dark:text-white line-clamp-2" }, product.name), product.brand && /* @__PURE__ */ React.createElement("p", { className: "text-xs text-gray-500 dark:text-gray-400" }, "Brand: ", product.brand), product.price && /* @__PURE__ */ React.createElement("p", { className: "text-lg font-bold text-gray-900 dark:text-white" }, "$", typeof product.price === "number" ? product.price.toFixed(2) : product.price), product.description && /* @__PURE__ */ React.createElement("p", { className: "text-sm text-gray-600 dark:text-gray-400 line-clamp-2" }, product.description), /* @__PURE__ */ React.createElement("div", { className: "flex gap-2 pt-2" }, /* @__PURE__ */ React.createElement(
497
+ "span",
498
+ {
499
+ className: `text-xs px-2 py-1 rounded flex-1 text-center ${product.inStock ? "bg-green-100 text-green-800" : "bg-red-100 text-red-800"}`
500
+ },
501
+ product.inStock ? "In Stock" : "Out of Stock"
502
+ )))
503
+ ))));
504
+ }
505
+ function renderText(data) {
506
+ const content = (data == null ? void 0 : data.content) || String(data);
507
+ return /* @__PURE__ */ React.createElement("div", { className: "bg-white dark:bg-gray-800 p-4 rounded-lg shadow prose dark:prose-invert max-w-none" }, /* @__PURE__ */ React.createElement("p", { className: "text-gray-700 dark:text-gray-300 whitespace-pre-wrap" }, content));
508
+ }
509
+ function generateColor(index) {
510
+ const colors = [
511
+ "#3B82F6",
512
+ // blue
513
+ "#10B981",
514
+ // green
515
+ "#F59E0B",
516
+ // amber
517
+ "#EF4444",
518
+ // red
519
+ "#8B5CF6",
520
+ // purple
521
+ "#EC4899",
522
+ // pink
523
+ "#06B6D4",
524
+ // cyan
525
+ "#F97316"
526
+ // orange
527
+ ];
528
+ return colors[index % colors.length];
529
+ }
530
+
359
531
  // src/components/MessageBubble.tsx
360
532
  function sanitizeJson(raw) {
361
533
  let s = raw.trim();
@@ -509,7 +681,7 @@ function resolveImage(data) {
509
681
  return void 0;
510
682
  }
511
683
  function normaliseChild(children) {
512
- if (typeof children === "object" && children !== null && !Array.isArray(children) && !React5.isValidElement(children)) {
684
+ if (typeof children === "object" && children !== null && !Array.isArray(children) && !React6.isValidElement(children)) {
513
685
  return JSON.stringify(children);
514
686
  }
515
687
  return children;
@@ -523,7 +695,7 @@ function formatColumnLabel(value) {
523
695
  function DataTable({ config, viewportSize = "large" }) {
524
696
  const isCompact = viewportSize === "compact";
525
697
  const isMedium = viewportSize === "medium";
526
- const columns = React5.useMemo(() => {
698
+ const columns = React6.useMemo(() => {
527
699
  const rowKeys = Array.from(
528
700
  new Set(
529
701
  config.data.flatMap((row) => Object.keys(row))
@@ -553,27 +725,27 @@ function DataTable({ config, viewportSize = "large" }) {
553
725
  return rowKeys.map((key) => ({ label: formatColumnLabel(key), accessor: key }));
554
726
  }, [config]);
555
727
  if (!config.data.length || !columns.length) {
556
- return /* @__PURE__ */ React5.createElement("p", { className: "text-xs text-slate-400 italic my-2" }, "No data to display.");
728
+ return /* @__PURE__ */ React6.createElement("p", { className: "text-xs text-slate-400 italic my-2" }, "No data to display.");
557
729
  }
558
730
  const formatCell = (val) => {
559
731
  if (val === null || val === void 0) return "\u2014";
560
732
  if (typeof val === "boolean") return val ? "\u2713" : "\u2717";
561
733
  return String(val);
562
734
  };
563
- return /* @__PURE__ */ React5.createElement("div", { className: "my-4 rounded-xl border border-slate-200 dark:border-white/10 shadow-sm overflow-hidden" }, config.title && /* @__PURE__ */ React5.createElement("div", { className: "px-4 py-2.5 bg-slate-50 dark:bg-white/5 border-b border-slate-200 dark:border-white/10" }, /* @__PURE__ */ React5.createElement("p", { className: "text-xs font-semibold text-slate-600 dark:text-white/70 uppercase tracking-wide" }, config.title)), /* @__PURE__ */ React5.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React5.createElement("table", { className: `w-full text-left border-collapse ${isCompact ? "min-w-[240px] text-xs" : isMedium ? "min-w-[280px] text-[13px]" : "min-w-[320px] text-sm"}` }, /* @__PURE__ */ React5.createElement("thead", { className: "bg-slate-50 dark:bg-white/5 border-b border-slate-200 dark:border-white/10" }, /* @__PURE__ */ React5.createElement("tr", null, columns.map((column) => /* @__PURE__ */ React5.createElement(
735
+ return /* @__PURE__ */ React6.createElement("div", { className: "my-4 rounded-xl border border-slate-200 dark:border-white/10 shadow-sm overflow-hidden" }, config.title && /* @__PURE__ */ React6.createElement("div", { className: "px-4 py-2.5 bg-slate-50 dark:bg-white/5 border-b border-slate-200 dark:border-white/10" }, /* @__PURE__ */ React6.createElement("p", { className: "text-xs font-semibold text-slate-600 dark:text-white/70 uppercase tracking-wide" }, config.title)), /* @__PURE__ */ React6.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React6.createElement("table", { className: `w-full text-left border-collapse ${isCompact ? "min-w-[240px] text-xs" : isMedium ? "min-w-[280px] text-[13px]" : "min-w-[320px] text-sm"}` }, /* @__PURE__ */ React6.createElement("thead", { className: "bg-slate-50 dark:bg-white/5 border-b border-slate-200 dark:border-white/10" }, /* @__PURE__ */ React6.createElement("tr", null, columns.map((column) => /* @__PURE__ */ React6.createElement(
564
736
  "th",
565
737
  {
566
738
  key: column.label,
567
739
  className: `${isCompact ? "px-2.5 py-2" : "px-4 py-3"} font-semibold text-slate-700 dark:text-white/90 whitespace-nowrap`
568
740
  },
569
741
  column.label
570
- )))), /* @__PURE__ */ React5.createElement("tbody", null, config.data.map((row, ri) => /* @__PURE__ */ React5.createElement(
742
+ )))), /* @__PURE__ */ React6.createElement("tbody", null, config.data.map((row, ri) => /* @__PURE__ */ React6.createElement(
571
743
  "tr",
572
744
  {
573
745
  key: ri,
574
746
  className: "border-b border-slate-100 dark:border-white/5 last:border-0 hover:bg-slate-50/60 dark:hover:bg-white/5 transition-colors"
575
747
  },
576
- columns.map((column) => /* @__PURE__ */ React5.createElement(
748
+ columns.map((column) => /* @__PURE__ */ React6.createElement(
577
749
  "td",
578
750
  {
579
751
  key: column.label,
@@ -581,7 +753,7 @@ function DataTable({ config, viewportSize = "large" }) {
581
753
  },
582
754
  formatCell(row[column.accessor])
583
755
  ))
584
- ))))), /* @__PURE__ */ React5.createElement("div", { className: "px-4 py-2 bg-slate-50 dark:bg-white/5 border-t border-slate-100 dark:border-white/5" }, /* @__PURE__ */ React5.createElement("p", { className: "text-[11px] text-slate-400 dark:text-white/30" }, config.data.length, " row", config.data.length !== 1 ? "s" : "")));
756
+ ))))), /* @__PURE__ */ React6.createElement("div", { className: "px-4 py-2 bg-slate-50 dark:bg-white/5 border-t border-slate-100 dark:border-white/5" }, /* @__PURE__ */ React6.createElement("p", { className: "text-[11px] text-slate-400 dark:text-white/30" }, config.data.length, " row", config.data.length !== 1 ? "s" : "")));
585
757
  }
586
758
  function normalizeTabularRows(rows, columns) {
587
759
  if (!Array.isArray(rows)) return [];
@@ -614,7 +786,7 @@ function resolveStructuredRows(config) {
614
786
  }
615
787
  function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAddToCart, viewportSize = "large" }) {
616
788
  var _a;
617
- const result = React5.useMemo(() => {
789
+ const result = React6.useMemo(() => {
618
790
  if (isStreaming) return { loading: true };
619
791
  try {
620
792
  const clean = rawContent.replace(/^```[a-z]*\s*/i, "").replace(/```\s*$/, "").trim();
@@ -656,10 +828,10 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAd
656
828
  }
657
829
  }, [rawContent, isStreaming]);
658
830
  if ("loading" in result) {
659
- return /* @__PURE__ */ React5.createElement("div", { className: "my-4 p-8 bg-slate-50 dark:bg-white/5 rounded-xl border border-dashed border-slate-300 dark:border-white/10 flex flex-col items-center justify-center gap-3 animate-pulse" }, /* @__PURE__ */ React5.createElement("div", { className: "w-5 h-5 border-2 border-indigo-500 border-t-transparent rounded-full animate-spin" }), /* @__PURE__ */ React5.createElement("p", { className: "text-xs text-slate-500 font-medium italic" }, "Preparing view..."));
831
+ return /* @__PURE__ */ React6.createElement("div", { className: "my-4 p-8 bg-slate-50 dark:bg-white/5 rounded-xl border border-dashed border-slate-300 dark:border-white/10 flex flex-col items-center justify-center gap-3 animate-pulse" }, /* @__PURE__ */ React6.createElement("div", { className: "w-5 h-5 border-2 border-indigo-500 border-t-transparent rounded-full animate-spin" }), /* @__PURE__ */ React6.createElement("p", { className: "text-xs text-slate-500 font-medium italic" }, "Preparing view..."));
660
832
  }
661
833
  if ("error" in result) {
662
- return /* @__PURE__ */ React5.createElement("pre", { className: "p-4 my-2 bg-slate-900 text-slate-100 rounded-lg text-[10px] overflow-auto max-h-40" }, /* @__PURE__ */ React5.createElement("code", null, rawContent));
834
+ return /* @__PURE__ */ React6.createElement("pre", { className: "p-4 my-2 bg-slate-900 text-slate-100 rounded-lg text-[10px] overflow-auto max-h-40" }, /* @__PURE__ */ React6.createElement("code", null, rawContent));
663
835
  }
664
836
  const { config } = result;
665
837
  const isCompact = viewportSize === "compact";
@@ -667,7 +839,7 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAd
667
839
  const hasDescription = typeof config.description === "string" && config.description.trim().length > 0;
668
840
  switch (config.view) {
669
841
  case "chart":
670
- return /* @__PURE__ */ React5.createElement("div", { className: `${isCompact ? "my-4 p-3" : "my-6 p-4"} bg-white dark:bg-slate-900 rounded-2xl border border-slate-200 dark:border-white/10 shadow-sm overflow-hidden` }, config.title && /* @__PURE__ */ React5.createElement("h4", { className: `${isCompact ? "text-[11px] mb-3" : "text-xs mb-4"} font-semibold text-slate-500 px-2` }, config.title), hasDescription && /* @__PURE__ */ React5.createElement("p", { className: `px-2 ${isCompact ? "text-xs" : "text-sm"} text-slate-500 dark:text-white/60` }, config.description), /* @__PURE__ */ React5.createElement(
842
+ return /* @__PURE__ */ React6.createElement("div", { className: `${isCompact ? "my-4 p-3" : "my-6 p-4"} bg-white dark:bg-slate-900 rounded-2xl border border-slate-200 dark:border-white/10 shadow-sm overflow-hidden` }, config.title && /* @__PURE__ */ React6.createElement("h4", { className: `${isCompact ? "text-[11px] mb-3" : "text-xs mb-4"} font-semibold text-slate-500 px-2` }, config.title), hasDescription && /* @__PURE__ */ React6.createElement("p", { className: `px-2 ${isCompact ? "text-xs" : "text-sm"} text-slate-500 dark:text-white/60` }, config.description), /* @__PURE__ */ React6.createElement(
671
843
  DynamicChart,
672
844
  {
673
845
  config: {
@@ -681,7 +853,7 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAd
681
853
  accentColor,
682
854
  viewportSize
683
855
  }
684
- ), hasInsights && /* @__PURE__ */ React5.createElement("div", { className: "mt-4 flex flex-wrap gap-2 px-2" }, (_a = config.insights) == null ? void 0 : _a.map((insight) => /* @__PURE__ */ React5.createElement(
856
+ ), hasInsights && /* @__PURE__ */ React6.createElement("div", { className: "mt-4 flex flex-wrap gap-2 px-2" }, (_a = config.insights) == null ? void 0 : _a.map((insight) => /* @__PURE__ */ React6.createElement(
685
857
  "span",
686
858
  {
687
859
  key: insight,
@@ -690,14 +862,14 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAd
690
862
  insight
691
863
  ))));
692
864
  case "carousel":
693
- return /* @__PURE__ */ React5.createElement("div", { className: "my-4" }, config.title && /* @__PURE__ */ React5.createElement("h4", { className: `${isCompact ? "mb-1.5 text-[11px]" : "mb-2 text-xs"} font-semibold text-slate-500` }, config.title), hasDescription && /* @__PURE__ */ React5.createElement("p", { className: `mb-3 ${isCompact ? "text-xs" : "text-sm"} text-slate-500 dark:text-white/60` }, config.description), /* @__PURE__ */ React5.createElement(ProductCarousel, { products: config.data.map((item) => {
865
+ return /* @__PURE__ */ React6.createElement("div", { className: "my-4" }, config.title && /* @__PURE__ */ React6.createElement("h4", { className: `${isCompact ? "mb-1.5 text-[11px]" : "mb-2 text-xs"} font-semibold text-slate-500` }, config.title), hasDescription && /* @__PURE__ */ React6.createElement("p", { className: `mb-3 ${isCompact ? "text-xs" : "text-sm"} text-slate-500 dark:text-white/60` }, config.description), /* @__PURE__ */ React6.createElement(ProductCarousel, { products: config.data.map((item) => {
694
866
  var _a2;
695
867
  return __spreadProps(__spreadValues({}, item), {
696
868
  image: (_a2 = item.image) != null ? _a2 : typeof resolveImage === "function" ? resolveImage(item) : void 0
697
869
  });
698
870
  }), primaryColor, onAddToCart }));
699
871
  case "table":
700
- return /* @__PURE__ */ React5.createElement("div", { className: `${isCompact ? "my-3 p-3 max-h-[320px]" : "my-4 p-4 max-h-[400px]"} bg-white dark:bg-slate-900 rounded-xl border border-slate-200 dark:border-white/10 shadow-sm overflow-auto` }, config.title && /* @__PURE__ */ React5.createElement("h4", { className: `${isCompact ? "text-[11px]" : "text-xs"} font-semibold text-slate-500 mb-2` }, config.title), hasDescription && /* @__PURE__ */ React5.createElement("p", { className: `mb-3 ${isCompact ? "text-xs" : "text-sm"} text-slate-500 dark:text-white/60` }, config.description), /* @__PURE__ */ React5.createElement(DataTable, { config: {
872
+ return /* @__PURE__ */ React6.createElement("div", { className: `${isCompact ? "my-3 p-3 max-h-[320px]" : "my-4 p-4 max-h-[400px]"} bg-white dark:bg-slate-900 rounded-xl border border-slate-200 dark:border-white/10 shadow-sm overflow-auto` }, config.title && /* @__PURE__ */ React6.createElement("h4", { className: `${isCompact ? "text-[11px]" : "text-xs"} font-semibold text-slate-500 mb-2` }, config.title), hasDescription && /* @__PURE__ */ React6.createElement("p", { className: `mb-3 ${isCompact ? "text-xs" : "text-sm"} text-slate-500 dark:text-white/60` }, config.description), /* @__PURE__ */ React6.createElement(DataTable, { config: {
701
873
  type: "table",
702
874
  title: config.title,
703
875
  description: config.description,
@@ -722,17 +894,17 @@ function MessageBubble({
722
894
  const isUser = message.role === "user";
723
895
  const isCompact = viewportSize === "compact";
724
896
  const isMedium = viewportSize === "medium";
725
- const [showSources, setShowSources] = React5.useState(false);
726
- const hasStructuredProductBlock = React5.useMemo(
897
+ const [showSources, setShowSources] = React6.useState(false);
898
+ const hasStructuredProductBlock = React6.useMemo(
727
899
  () => /```(?:ui|json|chart)\s*[\s\S]*?"?(?:view|type|data|products)"?\s*:\s*"?(?:carousel|products|table)"?/i.test(message.content) || /\{[\s\S]*?"?(?:view|type|data|products)"?\s*:\s*"?(?:carousel|products)"?[\s\S]*\}/i.test(message.content) && looksLikeStructuredPayload(message.content),
728
900
  [message.content]
729
901
  );
730
- const structuredContent = React5.useMemo(
902
+ const structuredContent = React6.useMemo(
731
903
  () => isUser ? { payload: null, text: message.content } : extractStructuredPayload(message.content),
732
904
  [isUser, message.content]
733
905
  );
734
906
  const shouldRenderStructuredOnly = !isUser && Boolean(structuredContent.payload) && isLikelyUiOnlyMessage(structuredContent.text);
735
- const productsFromSources = React5.useMemo(() => {
907
+ const productsFromSources = React6.useMemo(() => {
736
908
  if (isUser || !sources) return [];
737
909
  return sources.filter((s) => {
738
910
  var _a;
@@ -752,7 +924,7 @@ function MessageBubble({
752
924
  };
753
925
  });
754
926
  }, [sources, isUser]);
755
- const { productsFromContent, cleanContent } = React5.useMemo(() => {
927
+ const { productsFromContent, cleanContent } = React6.useMemo(() => {
756
928
  if (isUser) {
757
929
  return { productsFromContent: [], cleanContent: message.content };
758
930
  }
@@ -798,7 +970,7 @@ function MessageBubble({
798
970
  }
799
971
  return { productsFromContent: products, cleanContent: content.trim() };
800
972
  }, [message.content, isUser, structuredContent]);
801
- const allProducts = React5.useMemo(() => {
973
+ const allProducts = React6.useMemo(() => {
802
974
  if (productsFromContent.length > 0) return productsFromContent;
803
975
  const seen = /* @__PURE__ */ new Set();
804
976
  const contentLower = message.content.toLowerCase();
@@ -814,7 +986,7 @@ function MessageBubble({
814
986
  return false;
815
987
  });
816
988
  }, [productsFromSources, productsFromContent, message.content]);
817
- const processedMarkdown = React5.useMemo(() => {
989
+ const processedMarkdown = React6.useMemo(() => {
818
990
  let raw = structuredContent.payload ? structuredContent.text : cleanContent || message.content;
819
991
  const hasStructuredUiBlock = Boolean(structuredContent.payload) || /```(?:ui|json|chart)\s*[\s\S]*?"(?:view|chartType|type|data|items|rows|products|results)"\s*:/i.test(raw);
820
992
  raw = raw.replace(/([^\n])\n\|/g, "$1\n\n|").replace(/(\|[^\n]*\|)\n\n+(?=\|)/g, "$1\n");
@@ -848,16 +1020,16 @@ ${match.trim()}
848
1020
  }
849
1021
  return raw;
850
1022
  }, [cleanContent, message.content, isStreaming, structuredContent]);
851
- const markdownComponents = React5.useMemo(
1023
+ const markdownComponents = React6.useMemo(
852
1024
  () => ({
853
1025
  // Wrap in not-prose so Tailwind Typography resets don't clobber our styles.
854
1026
  // prose applies display:block and padding:0 to table/th/td — not-prose opts out.
855
1027
  table: (_a) => {
856
1028
  var props = __objRest(_a, []);
857
1029
  if (isStreaming) {
858
- return /* @__PURE__ */ React5.createElement("div", { className: "my-5 p-6 bg-slate-50 dark:bg-white/5 rounded-xl border border-dashed border-slate-300 dark:border-white/10 flex items-center justify-center gap-3 select-none" }, /* @__PURE__ */ React5.createElement("div", { className: "w-4 h-4 border-2 border-indigo-500 border-t-transparent rounded-full animate-spin" }), /* @__PURE__ */ React5.createElement("p", { className: "text-xs text-slate-500 font-medium italic animate-pulse" }, "Generating data table..."));
1030
+ return /* @__PURE__ */ React6.createElement("div", { className: "my-5 p-6 bg-slate-50 dark:bg-white/5 rounded-xl border border-dashed border-slate-300 dark:border-white/10 flex items-center justify-center gap-3 select-none" }, /* @__PURE__ */ React6.createElement("div", { className: "w-4 h-4 border-2 border-indigo-500 border-t-transparent rounded-full animate-spin" }), /* @__PURE__ */ React6.createElement("p", { className: "text-xs text-slate-500 font-medium italic animate-pulse" }, "Generating data table..."));
859
1031
  }
860
- return /* @__PURE__ */ React5.createElement("div", { className: "not-prose overflow-hidden my-5 rounded-xl border border-slate-200 dark:border-white/10 shadow-sm bg-white dark:bg-slate-900/50" }, /* @__PURE__ */ React5.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React5.createElement(
1032
+ return /* @__PURE__ */ React6.createElement("div", { className: "not-prose overflow-hidden my-5 rounded-xl border border-slate-200 dark:border-white/10 shadow-sm bg-white dark:bg-slate-900/50" }, /* @__PURE__ */ React6.createElement("div", { className: "overflow-x-auto" }, /* @__PURE__ */ React6.createElement(
861
1033
  "table",
862
1034
  __spreadValues({
863
1035
  className: "!table w-full text-left border-collapse min-w-[400px] text-sm"
@@ -866,7 +1038,7 @@ ${match.trim()}
866
1038
  },
867
1039
  thead: (_b) => {
868
1040
  var props = __objRest(_b, []);
869
- return /* @__PURE__ */ React5.createElement(
1041
+ return /* @__PURE__ */ React6.createElement(
870
1042
  "thead",
871
1043
  __spreadValues({
872
1044
  className: "!table-header-group bg-slate-50 dark:bg-white/5 border-b border-slate-200 dark:border-white/10"
@@ -875,11 +1047,11 @@ ${match.trim()}
875
1047
  },
876
1048
  tbody: (_c) => {
877
1049
  var props = __objRest(_c, []);
878
- return /* @__PURE__ */ React5.createElement("tbody", __spreadValues({ className: "!table-row-group divide-y divide-slate-100 dark:divide-white/5" }, props));
1050
+ return /* @__PURE__ */ React6.createElement("tbody", __spreadValues({ className: "!table-row-group divide-y divide-slate-100 dark:divide-white/5" }, props));
879
1051
  },
880
1052
  tr: (_d) => {
881
1053
  var props = __objRest(_d, []);
882
- return /* @__PURE__ */ React5.createElement(
1054
+ return /* @__PURE__ */ React6.createElement(
883
1055
  "tr",
884
1056
  __spreadValues({
885
1057
  className: "!table-row hover:bg-slate-50/70 dark:hover:bg-white/5 transition-colors"
@@ -888,7 +1060,7 @@ ${match.trim()}
888
1060
  },
889
1061
  th: (_e) => {
890
1062
  var _f = _e, { children } = _f, props = __objRest(_f, ["children"]);
891
- return /* @__PURE__ */ React5.createElement(
1063
+ return /* @__PURE__ */ React6.createElement(
892
1064
  "th",
893
1065
  __spreadValues({
894
1066
  className: "!table-cell px-4 py-3 font-bold text-slate-700 dark:text-white/90 whitespace-nowrap text-[11px] uppercase tracking-wider text-left"
@@ -898,7 +1070,7 @@ ${match.trim()}
898
1070
  },
899
1071
  td: (_g) => {
900
1072
  var _h = _g, { children } = _h, props = __objRest(_h, ["children"]);
901
- return /* @__PURE__ */ React5.createElement(
1073
+ return /* @__PURE__ */ React6.createElement(
902
1074
  "td",
903
1075
  __spreadValues({
904
1076
  className: "!table-cell px-4 py-3 text-slate-600 dark:text-white/70 whitespace-nowrap text-sm"
@@ -919,7 +1091,7 @@ ${match.trim()}
919
1091
  var _a;
920
1092
  const lang = (_a = /language-(\w+)/.exec(className != null ? className : "")) == null ? void 0 : _a[1];
921
1093
  if (!inline && (lang === "ui" || lang === "chart")) {
922
- return /* @__PURE__ */ React5.createElement(
1094
+ return /* @__PURE__ */ React6.createElement(
923
1095
  UIDispatcher,
924
1096
  {
925
1097
  rawContent: String(children != null ? children : "").trim(),
@@ -934,7 +1106,7 @@ ${match.trim()}
934
1106
  if (!inline && lang === "json") {
935
1107
  const content = String(children != null ? children : "").trim();
936
1108
  if (looksLikeStructuredPayload(content)) {
937
- return /* @__PURE__ */ React5.createElement(
1109
+ return /* @__PURE__ */ React6.createElement(
938
1110
  UIDispatcher,
939
1111
  {
940
1112
  rawContent: content,
@@ -950,7 +1122,7 @@ ${match.trim()}
950
1122
  if (!inline) {
951
1123
  const content = String(children != null ? children : "").trim();
952
1124
  if (looksLikeStructuredPayload(content)) {
953
- return /* @__PURE__ */ React5.createElement(
1125
+ return /* @__PURE__ */ React6.createElement(
954
1126
  UIDispatcher,
955
1127
  {
956
1128
  rawContent: content,
@@ -964,27 +1136,27 @@ ${match.trim()}
964
1136
  }
965
1137
  }
966
1138
  if (!inline && lang === "table-loading") {
967
- return /* @__PURE__ */ React5.createElement("div", { className: "my-5 p-6 bg-slate-50 dark:bg-white/5 rounded-xl border border-dashed border-slate-300 dark:border-white/10 flex items-center justify-center gap-3 select-none" }, /* @__PURE__ */ React5.createElement("div", { className: "w-4 h-4 border-2 border-indigo-500 border-t-transparent rounded-full animate-spin" }), /* @__PURE__ */ React5.createElement("p", { className: "text-xs text-slate-500 font-medium italic animate-pulse" }, "Generating data table..."));
1139
+ return /* @__PURE__ */ React6.createElement("div", { className: "my-5 p-6 bg-slate-50 dark:bg-white/5 rounded-xl border border-dashed border-slate-300 dark:border-white/10 flex items-center justify-center gap-3 select-none" }, /* @__PURE__ */ React6.createElement("div", { className: "w-4 h-4 border-2 border-indigo-500 border-t-transparent rounded-full animate-spin" }), /* @__PURE__ */ React6.createElement("p", { className: "text-xs text-slate-500 font-medium italic animate-pulse" }, "Generating data table..."));
968
1140
  }
969
- return /* @__PURE__ */ React5.createElement("code", __spreadValues({ className }, props), typeof children === "string" || typeof children === "number" ? children : JSON.stringify(children));
1141
+ return /* @__PURE__ */ React6.createElement("code", __spreadValues({ className }, props), typeof children === "string" || typeof children === "number" ? children : JSON.stringify(children));
970
1142
  }
971
1143
  }),
972
1144
  [primaryColor, accentColor, isStreaming, onAddToCart, viewportSize]
973
1145
  );
974
- return /* @__PURE__ */ React5.createElement("div", { className: `flex ${isCompact ? "gap-2" : "gap-3"} ${isUser ? "flex-row-reverse" : "flex-row"} items-start` }, /* @__PURE__ */ React5.createElement(
1146
+ return /* @__PURE__ */ React6.createElement("div", { className: `flex ${isCompact ? "gap-2" : "gap-3"} ${isUser ? "flex-row-reverse" : "flex-row"} items-start` }, /* @__PURE__ */ React6.createElement(
975
1147
  "div",
976
1148
  {
977
1149
  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"}`,
978
1150
  style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
979
1151
  },
980
- isUser ? /* @__PURE__ */ React5.createElement(User, { className: `${isCompact ? "w-3.5 h-3.5" : "w-4 h-4"} text-white` }) : /* @__PURE__ */ React5.createElement(Bot, { className: `${isCompact ? "w-3.5 h-3.5" : "w-4 h-4"}` })
981
- ), /* @__PURE__ */ React5.createElement("div", { className: `flex flex-col gap-1 ${isCompact ? "max-w-[94%]" : isMedium ? "max-w-[92%]" : "max-w-[90%]"} ${isUser ? "items-end" : "items-start"}` }, /* @__PURE__ */ React5.createElement(
1152
+ isUser ? /* @__PURE__ */ React6.createElement(User, { className: `${isCompact ? "w-3.5 h-3.5" : "w-4 h-4"} text-white` }) : /* @__PURE__ */ React6.createElement(Bot, { className: `${isCompact ? "w-3.5 h-3.5" : "w-4 h-4"}` })
1153
+ ), /* @__PURE__ */ React6.createElement("div", { className: `flex flex-col gap-1 ${isCompact ? "max-w-[94%]" : isMedium ? "max-w-[92%]" : "max-w-[90%]"} ${isUser ? "items-end" : "items-start"}` }, /* @__PURE__ */ React6.createElement(
982
1154
  "div",
983
1155
  {
984
1156
  className: `relative ${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"}`,
985
1157
  style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
986
1158
  },
987
- isStreaming && !message.content ? /* @__PURE__ */ React5.createElement("span", { className: "flex items-center gap-1 py-1" }, /* @__PURE__ */ React5.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:0ms]" }), /* @__PURE__ */ React5.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:150ms]" }), /* @__PURE__ */ React5.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:300ms]" })) : /* @__PURE__ */ React5.createElement("div", { className: `prose ${isCompact ? "prose-xs" : "prose-sm"} max-w-none break-words ${isUser ? "prose-invert" : "dark:prose-invert"}` }, !isUser && structuredContent.payload && /* @__PURE__ */ React5.createElement(
1159
+ isStreaming && !message.content ? /* @__PURE__ */ React6.createElement("span", { className: "flex items-center gap-1 py-1" }, /* @__PURE__ */ React6.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:0ms]" }), /* @__PURE__ */ React6.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:150ms]" }), /* @__PURE__ */ React6.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:300ms]" })) : /* @__PURE__ */ React6.createElement("div", { className: `prose ${isCompact ? "prose-xs" : "prose-sm"} max-w-none break-words ${isUser ? "prose-invert" : "dark:prose-invert"}` }, !isUser && structuredContent.payload && /* @__PURE__ */ React6.createElement(
988
1160
  UIDispatcher,
989
1161
  {
990
1162
  rawContent: structuredContent.payload,
@@ -994,30 +1166,30 @@ ${match.trim()}
994
1166
  onAddToCart,
995
1167
  viewportSize
996
1168
  }
997
- ), !shouldRenderStructuredOnly && /* @__PURE__ */ React5.createElement(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents }, processedMarkdown), isStreaming && message.content && /* @__PURE__ */ React5.createElement("span", { className: "inline-block w-1.5 h-3.5 ml-1 bg-emerald-500 animate-pulse align-middle" }))
998
- ), !isUser && !hasStructuredProductBlock && allProducts.length > 0 && /* @__PURE__ */ React5.createElement("div", { className: "w-full mt-1" }, /* @__PURE__ */ React5.createElement(
1169
+ ), !shouldRenderStructuredOnly && /* @__PURE__ */ React6.createElement(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents }, processedMarkdown), !isUser && !structuredContent.payload && message.uiTransformation && /* @__PURE__ */ React6.createElement("div", { className: "mt-4 border-t border-slate-100 dark:border-white/5 pt-4" }, /* @__PURE__ */ React6.createElement(VisualizationRenderer, { data: message.uiTransformation })), isStreaming && message.content && /* @__PURE__ */ React6.createElement("span", { className: "inline-block w-1.5 h-3.5 ml-1 bg-emerald-500 animate-pulse align-middle" }))
1170
+ ), !isUser && !hasStructuredProductBlock && allProducts.length > 0 && /* @__PURE__ */ React6.createElement("div", { className: "w-full mt-1" }, /* @__PURE__ */ React6.createElement(
999
1171
  ProductCarousel,
1000
1172
  {
1001
1173
  products: allProducts,
1002
1174
  primaryColor,
1003
1175
  onAddToCart
1004
1176
  }
1005
- )), !isUser && sources && sources.length > 0 && /* @__PURE__ */ React5.createElement("div", { className: "w-full" }, /* @__PURE__ */ React5.createElement(
1177
+ )), !isUser && sources && sources.length > 0 && /* @__PURE__ */ React6.createElement("div", { className: "w-full" }, /* @__PURE__ */ React6.createElement(
1006
1178
  "button",
1007
1179
  {
1008
1180
  onClick: () => setShowSources((s) => !s),
1009
1181
  className: "text-[11px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-1 mt-1"
1010
1182
  },
1011
- showSources ? /* @__PURE__ */ React5.createElement(ChevronDown2, { className: "w-3 h-3" }) : /* @__PURE__ */ React5.createElement(ChevronRight2, { className: "w-3 h-3" }),
1183
+ showSources ? /* @__PURE__ */ React6.createElement(ChevronDown2, { className: "w-3 h-3" }) : /* @__PURE__ */ React6.createElement(ChevronRight2, { className: "w-3 h-3" }),
1012
1184
  sources.length,
1013
1185
  " source",
1014
1186
  sources.length !== 1 ? "s" : "",
1015
1187
  " used"
1016
- ), showSources && /* @__PURE__ */ React5.createElement("div", { className: "mt-2 flex flex-col gap-2" }, sources.map((src, i) => /* @__PURE__ */ React5.createElement(SourceCard, { key: src.id, source: src, index: i }))))));
1188
+ ), showSources && /* @__PURE__ */ React6.createElement("div", { className: "mt-2 flex flex-col gap-2" }, sources.map((src, i) => /* @__PURE__ */ React6.createElement(SourceCard, { key: src.id, source: src, index: i }))))));
1017
1189
  }
1018
1190
 
1019
1191
  // src/components/ConfigProvider.tsx
1020
- import React6, { createContext, useContext } from "react";
1192
+ import React7, { createContext, useContext } from "react";
1021
1193
 
1022
1194
  // src/config/uiConstants.ts
1023
1195
  var DEFAULT_CONFIG = {
@@ -1064,7 +1236,7 @@ function ConfigProvider({
1064
1236
  projectId: (config == null ? void 0 : config.projectId) || DEFAULT_CONFIG.projectId,
1065
1237
  ui: mergeDefined(DEFAULT_CONFIG.ui, config == null ? void 0 : config.ui)
1066
1238
  };
1067
- return /* @__PURE__ */ React6.createElement(ConfigContext.Provider, { value: merged }, children);
1239
+ return /* @__PURE__ */ React7.createElement(ConfigContext.Provider, { value: merged }, children);
1068
1240
  }
1069
1241
  function useConfig() {
1070
1242
  return useContext(ConfigContext);
@@ -1074,7 +1246,7 @@ function useConfig() {
1074
1246
  import { useState as useState3, useCallback, useRef as useRef2, useEffect as useEffect3 } from "react";
1075
1247
 
1076
1248
  // src/hooks/useStoredMessages.ts
1077
- import * as React7 from "react";
1249
+ import * as React8 from "react";
1078
1250
  function readStoredMessages(storageKey) {
1079
1251
  if (typeof window === "undefined") {
1080
1252
  return [];
@@ -1091,8 +1263,8 @@ function readStoredMessages(storageKey) {
1091
1263
  }
1092
1264
  }
1093
1265
  function useStoredMessages(storageKey, persist) {
1094
- const [messages, setMessages] = React7.useState(() => persist ? readStoredMessages(storageKey) : []);
1095
- React7.useEffect(() => {
1266
+ const [messages, setMessages] = React8.useState(() => persist ? readStoredMessages(storageKey) : []);
1267
+ React8.useEffect(() => {
1096
1268
  if (!persist || typeof window === "undefined") {
1097
1269
  return;
1098
1270
  }
@@ -1178,6 +1350,7 @@ function useRagChat(projectId, options = {}) {
1178
1350
  const decoder = new TextDecoder();
1179
1351
  let assistantContent = "";
1180
1352
  let sources = [];
1353
+ let uiTransformation = null;
1181
1354
  let buffer = "";
1182
1355
  const assistantMessageId = `assistant_${Date.now()}`;
1183
1356
  setMessages((prev) => [
@@ -1202,13 +1375,19 @@ function useRagChat(projectId, options = {}) {
1202
1375
  assistantContent += frame.text;
1203
1376
  } else if (frame.type === "metadata") {
1204
1377
  sources = (_a = frame.sources) != null ? _a : [];
1378
+ } else if (frame.type === "ui_transformation") {
1379
+ uiTransformation = frame.data;
1205
1380
  } else if (frame.type === "error") {
1206
1381
  setError(frame.error || "Stream error");
1207
1382
  }
1208
1383
  }
1209
1384
  setMessages(
1210
1385
  (prev) => prev.map(
1211
- (msg) => msg.id === assistantMessageId ? __spreadProps(__spreadValues({}, msg), { content: assistantContent, sources: sources.length > 0 ? sources : msg.sources }) : msg
1386
+ (msg) => msg.id === assistantMessageId ? __spreadProps(__spreadValues({}, msg), {
1387
+ content: assistantContent,
1388
+ sources: sources.length > 0 ? sources : msg.sources,
1389
+ uiTransformation: uiTransformation || msg.uiTransformation
1390
+ }) : msg
1212
1391
  )
1213
1392
  );
1214
1393
  }
@@ -1223,6 +1402,7 @@ function useRagChat(projectId, options = {}) {
1223
1402
  role: "assistant",
1224
1403
  content: assistantContent,
1225
1404
  sources: sources.length > 0 ? sources : void 0,
1405
+ uiTransformation: uiTransformation || void 0,
1226
1406
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
1227
1407
  };
1228
1408
  onReply == null ? void 0 : onReply(finalAssistantMessage);
@@ -1413,84 +1593,84 @@ function ChatWindow({
1413
1593
  }, 800);
1414
1594
  return () => clearTimeout(timer);
1415
1595
  }, [input, projectId]);
1416
- return /* @__PURE__ */ React8.createElement(
1596
+ return /* @__PURE__ */ React9.createElement(
1417
1597
  "div",
1418
1598
  {
1419
1599
  ref: windowRef,
1420
1600
  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}`,
1421
1601
  style: __spreadValues({ "--primary": ui.primaryColor, "--accent": ui.accentColor }, style)
1422
1602
  },
1423
- onResizeStart && /* @__PURE__ */ React8.createElement(
1603
+ onResizeStart && /* @__PURE__ */ React9.createElement(
1424
1604
  "div",
1425
1605
  {
1426
1606
  onMouseDown: onResizeStart,
1427
1607
  className: "absolute top-0 left-0 w-6 h-6 cursor-nw-resize z-[100] group flex items-start justify-start p-1",
1428
1608
  title: "Drag to resize"
1429
1609
  },
1430
- /* @__PURE__ */ React8.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]" })
1610
+ /* @__PURE__ */ React9.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]" })
1431
1611
  ),
1432
- /* @__PURE__ */ React8.createElement(
1612
+ /* @__PURE__ */ React9.createElement(
1433
1613
  "div",
1434
1614
  {
1435
1615
  className: "flex items-center justify-between px-5 py-4 border-b border-slate-200 dark:border-white/10",
1436
1616
  style: { background: `linear-gradient(135deg, ${ui.primaryColor}15, ${ui.accentColor}10)` }
1437
1617
  },
1438
- /* @__PURE__ */ React8.createElement("div", { className: "flex items-center gap-3" }, ui.logoUrl ? (
1618
+ /* @__PURE__ */ React9.createElement("div", { className: "flex items-center gap-3" }, ui.logoUrl ? (
1439
1619
  // eslint-disable-next-line @next/next/no-img-element
1440
- /* @__PURE__ */ React8.createElement("img", { src: ui.logoUrl, alt: "logo", className: "w-8 h-8 rounded-lg object-cover" })
1441
- ) : /* @__PURE__ */ React8.createElement(
1620
+ /* @__PURE__ */ React9.createElement("img", { src: ui.logoUrl, alt: "logo", className: "w-8 h-8 rounded-lg object-cover" })
1621
+ ) : /* @__PURE__ */ React9.createElement(
1442
1622
  "div",
1443
1623
  {
1444
1624
  className: `w-9 h-9 flex items-center justify-center shadow-md ${ui.borderRadius === "full" ? "rounded-full" : "rounded-xl"}`,
1445
1625
  style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
1446
1626
  },
1447
- /* @__PURE__ */ React8.createElement(Bot2, { className: "w-5 h-5 text-white" })
1448
- ), /* @__PURE__ */ React8.createElement("div", null, /* @__PURE__ */ React8.createElement("h2", { className: "text-slate-900 dark:text-white font-semibold text-sm leading-tight" }, ui.title), ui.poweredBy && /* @__PURE__ */ React8.createElement("p", { className: "text-slate-500 dark:text-white/40 text-[11px] leading-tight" }, `Powered by ${ui.poweredBy}`))),
1449
- /* @__PURE__ */ React8.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ React8.createElement("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400 mr-2" }, /* @__PURE__ */ React8.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-emerald-500 dark:bg-emerald-400 animate-pulse" }), "Online"), /* @__PURE__ */ React8.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__ */ React8.createElement(
1627
+ /* @__PURE__ */ React9.createElement(Bot2, { className: "w-5 h-5 text-white" })
1628
+ ), /* @__PURE__ */ React9.createElement("div", null, /* @__PURE__ */ React9.createElement("h2", { className: "text-slate-900 dark:text-white font-semibold text-sm leading-tight" }, ui.title), ui.poweredBy && /* @__PURE__ */ React9.createElement("p", { className: "text-slate-500 dark:text-white/40 text-[11px] leading-tight" }, `Powered by ${ui.poweredBy}`))),
1629
+ /* @__PURE__ */ React9.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ React9.createElement("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400 mr-2" }, /* @__PURE__ */ React9.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-emerald-500 dark:bg-emerald-400 animate-pulse" }), "Online"), /* @__PURE__ */ React9.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__ */ React9.createElement(
1450
1630
  "button",
1451
1631
  {
1452
1632
  onClick: clearHistory,
1453
1633
  title: "Clear conversation",
1454
1634
  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"
1455
1635
  },
1456
- /* @__PURE__ */ React8.createElement(Trash2, { className: "w-3.5 h-3.5" })
1457
- ), isResized && onResetResize && /* @__PURE__ */ React8.createElement(
1636
+ /* @__PURE__ */ React9.createElement(Trash2, { className: "w-3.5 h-3.5" })
1637
+ ), isResized && onResetResize && /* @__PURE__ */ React9.createElement(
1458
1638
  "button",
1459
1639
  {
1460
1640
  onClick: onResetResize,
1461
1641
  title: "Reset to default size",
1462
1642
  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"
1463
1643
  },
1464
- /* @__PURE__ */ React8.createElement(RotateCcw, { className: "w-3.5 h-3.5" })
1465
- ), onMaximize && /* @__PURE__ */ React8.createElement(
1644
+ /* @__PURE__ */ React9.createElement(RotateCcw, { className: "w-3.5 h-3.5" })
1645
+ ), onMaximize && /* @__PURE__ */ React9.createElement(
1466
1646
  "button",
1467
1647
  {
1468
1648
  onClick: onMaximize,
1469
1649
  title: isMaximized ? "Minimize" : "Maximize",
1470
1650
  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"
1471
1651
  },
1472
- isMaximized ? /* @__PURE__ */ React8.createElement(Minimize2, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ React8.createElement(Maximize2, { className: "w-3.5 h-3.5" })
1473
- ), showClose && onClose && /* @__PURE__ */ React8.createElement(
1652
+ isMaximized ? /* @__PURE__ */ React9.createElement(Minimize2, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ React9.createElement(Maximize2, { className: "w-3.5 h-3.5" })
1653
+ ), showClose && onClose && /* @__PURE__ */ React9.createElement(
1474
1654
  "button",
1475
1655
  {
1476
1656
  onClick: onClose,
1477
1657
  title: "Close chat",
1478
1658
  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"
1479
1659
  },
1480
- /* @__PURE__ */ React8.createElement(X, { className: "w-4 h-4" })
1660
+ /* @__PURE__ */ React9.createElement(X, { className: "w-4 h-4" })
1481
1661
  )))
1482
1662
  ),
1483
- /* @__PURE__ */ React8.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 ? (
1663
+ /* @__PURE__ */ React9.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 ? (
1484
1664
  /* Welcome state */
1485
- /* @__PURE__ */ React8.createElement("div", { className: "h-full flex flex-col items-center justify-center text-center gap-4 px-6 py-12" }, /* @__PURE__ */ React8.createElement(
1665
+ /* @__PURE__ */ React9.createElement("div", { className: "h-full flex flex-col items-center justify-center text-center gap-4 px-6 py-12" }, /* @__PURE__ */ React9.createElement(
1486
1666
  "div",
1487
1667
  {
1488
1668
  className: `w-16 h-16 flex items-center justify-center shadow-lg ${ui.borderRadius === "full" ? "rounded-full" : "rounded-2xl"}`,
1489
1669
  style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
1490
1670
  },
1491
- /* @__PURE__ */ React8.createElement(Sparkles, { className: "w-8 h-8 text-white" })
1492
- ), /* @__PURE__ */ React8.createElement("div", null, /* @__PURE__ */ React8.createElement("p", { className: "text-slate-800 dark:text-white/80 font-medium leading-relaxed" }, ui.welcomeMessage), /* @__PURE__ */ React8.createElement("p", { className: "text-slate-500 dark:text-white/30 text-sm mt-2" }, "Ask a question to get started")), /* @__PURE__ */ React8.createElement("div", { className: "flex flex-wrap gap-2 justify-center mt-2" }, CHAT_SUGGESTIONS.map(
1493
- (suggestion) => /* @__PURE__ */ React8.createElement(
1671
+ /* @__PURE__ */ React9.createElement(Sparkles, { className: "w-8 h-8 text-white" })
1672
+ ), /* @__PURE__ */ React9.createElement("div", null, /* @__PURE__ */ React9.createElement("p", { className: "text-slate-800 dark:text-white/80 font-medium leading-relaxed" }, ui.welcomeMessage), /* @__PURE__ */ React9.createElement("p", { className: "text-slate-500 dark:text-white/30 text-sm mt-2" }, "Ask a question to get started")), /* @__PURE__ */ React9.createElement("div", { className: "flex flex-wrap gap-2 justify-center mt-2" }, CHAT_SUGGESTIONS.map(
1673
+ (suggestion) => /* @__PURE__ */ React9.createElement(
1494
1674
  "button",
1495
1675
  {
1496
1676
  key: suggestion,
@@ -1504,7 +1684,7 @@ function ChatWindow({
1504
1684
  suggestion
1505
1685
  )
1506
1686
  )))
1507
- ) : messages.map((msg, index) => /* @__PURE__ */ React8.createElement(
1687
+ ) : messages.map((msg, index) => /* @__PURE__ */ React9.createElement(
1508
1688
  MessageBubble,
1509
1689
  {
1510
1690
  key: msg.id,
@@ -1516,7 +1696,7 @@ function ChatWindow({
1516
1696
  onAddToCart,
1517
1697
  viewportSize
1518
1698
  }
1519
- )), isLoading && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) !== "assistant" && /* @__PURE__ */ React8.createElement(
1699
+ )), isLoading && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) !== "assistant" && /* @__PURE__ */ React9.createElement(
1520
1700
  MessageBubble,
1521
1701
  {
1522
1702
  message: { id: "loading", role: "assistant", content: "", createdAt: (/* @__PURE__ */ new Date()).toISOString() },
@@ -1526,8 +1706,8 @@ function ChatWindow({
1526
1706
  onAddToCart,
1527
1707
  viewportSize
1528
1708
  }
1529
- ), error && /* @__PURE__ */ React8.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__ */ React8.createElement(TriangleAlert, { className: "w-4 h-4 flex-shrink-0" }), /* @__PURE__ */ React8.createElement("span", null, error)), /* @__PURE__ */ React8.createElement("div", { ref: bottomRef })),
1530
- /* @__PURE__ */ React8.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]"}` }, (suggestions.length > 0 || isSuggesting) && !isLoading && /* @__PURE__ */ React8.createElement("div", { className: "mb-3 flex flex-wrap gap-2 animate-in fade-in slide-in-from-bottom-2 duration-300" }, suggestions.map((suggestion) => /* @__PURE__ */ React8.createElement(
1709
+ ), error && /* @__PURE__ */ React9.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__ */ React9.createElement(TriangleAlert, { className: "w-4 h-4 flex-shrink-0" }), /* @__PURE__ */ React9.createElement("span", null, error)), /* @__PURE__ */ React9.createElement("div", { ref: bottomRef })),
1710
+ /* @__PURE__ */ React9.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]"}` }, (suggestions.length > 0 || isSuggesting) && !isLoading && /* @__PURE__ */ React9.createElement("div", { className: "mb-3 flex flex-wrap gap-2 animate-in fade-in slide-in-from-bottom-2 duration-300" }, suggestions.map((suggestion) => /* @__PURE__ */ React9.createElement(
1531
1711
  "button",
1532
1712
  {
1533
1713
  key: suggestion,
@@ -1539,9 +1719,9 @@ function ChatWindow({
1539
1719
  },
1540
1720
  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"
1541
1721
  },
1542
- /* @__PURE__ */ React8.createElement(Sparkles, { className: "w-3 h-3 text-amber-400" }),
1722
+ /* @__PURE__ */ React9.createElement(Sparkles, { className: "w-3 h-3 text-amber-400" }),
1543
1723
  suggestion
1544
- )), isSuggesting && suggestions.length === 0 && /* @__PURE__ */ React8.createElement("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" }, /* @__PURE__ */ React8.createElement(Sparkles, { className: "w-3 h-3" }), "Thinking...")), /* @__PURE__ */ React8.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__ */ React8.createElement(
1724
+ )), isSuggesting && suggestions.length === 0 && /* @__PURE__ */ React9.createElement("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" }, /* @__PURE__ */ React9.createElement(Sparkles, { className: "w-3 h-3" }), "Thinking...")), /* @__PURE__ */ React9.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__ */ React9.createElement(
1545
1725
  "textarea",
1546
1726
  {
1547
1727
  ref: inputRef,
@@ -1560,7 +1740,7 @@ function ChatWindow({
1560
1740
  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",
1561
1741
  style: { scrollbarWidth: "none" }
1562
1742
  }
1563
- ), ui.enableVoiceInput !== false && /* @__PURE__ */ React8.createElement(
1743
+ ), ui.enableVoiceInput !== false && /* @__PURE__ */ React9.createElement(
1564
1744
  "button",
1565
1745
  {
1566
1746
  type: "button",
@@ -1569,8 +1749,8 @@ function ChatWindow({
1569
1749
  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"}`,
1570
1750
  title: isListening ? "Stop listening" : "Start voice input"
1571
1751
  },
1572
- isListening ? /* @__PURE__ */ React8.createElement(MicOff, { className: "w-4 h-4" }) : /* @__PURE__ */ React8.createElement(Mic, { className: "w-4 h-4" })
1573
- ), /* @__PURE__ */ React8.createElement(
1752
+ isListening ? /* @__PURE__ */ React9.createElement(MicOff, { className: "w-4 h-4" }) : /* @__PURE__ */ React9.createElement(Mic, { className: "w-4 h-4" })
1753
+ ), /* @__PURE__ */ React9.createElement(
1574
1754
  "button",
1575
1755
  {
1576
1756
  onClick: sendMessage,
@@ -1581,8 +1761,8 @@ function ChatWindow({
1581
1761
  // slate-400/20 for light mode disabled
1582
1762
  }
1583
1763
  },
1584
- /* @__PURE__ */ React8.createElement(ArrowUp, { className: "w-4 h-4 text-white" })
1585
- )), /* @__PURE__ */ React8.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"))
1764
+ /* @__PURE__ */ React9.createElement(ArrowUp, { className: "w-4 h-4 text-white" })
1765
+ )), /* @__PURE__ */ React9.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"))
1586
1766
  );
1587
1767
  }
1588
1768
 
@@ -1645,7 +1825,7 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
1645
1825
  }
1646
1826
  };
1647
1827
  const isResized = dimensions.width !== DEFAULT_DIMENSIONS.width || dimensions.height !== DEFAULT_DIMENSIONS.height;
1648
- return /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(
1828
+ return /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(
1649
1829
  "div",
1650
1830
  {
1651
1831
  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"}`,
@@ -1655,7 +1835,7 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
1655
1835
  maxHeight: "calc(100vh - 6rem)"
1656
1836
  }
1657
1837
  },
1658
- /* @__PURE__ */ React9.createElement(
1838
+ /* @__PURE__ */ React10.createElement(
1659
1839
  ChatWindow,
1660
1840
  {
1661
1841
  className: "h-full relative z-10",
@@ -1669,13 +1849,13 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
1669
1849
  onAddToCart
1670
1850
  }
1671
1851
  ),
1672
- /* @__PURE__ */ React9.createElement(
1852
+ /* @__PURE__ */ React10.createElement(
1673
1853
  "div",
1674
1854
  {
1675
1855
  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"}`
1676
1856
  }
1677
1857
  )
1678
- ), /* @__PURE__ */ React9.createElement(
1858
+ ), /* @__PURE__ */ React10.createElement(
1679
1859
  "button",
1680
1860
  {
1681
1861
  onClick: isOpen ? () => setIsOpen(false) : handleOpen,
@@ -1683,26 +1863,26 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
1683
1863
  style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
1684
1864
  "aria-label": "Open chat"
1685
1865
  },
1686
- /* @__PURE__ */ React9.createElement(
1866
+ /* @__PURE__ */ React10.createElement(
1687
1867
  "span",
1688
1868
  {
1689
1869
  className: "absolute inset-0 rounded-full animate-ping opacity-20",
1690
1870
  style: { background: ui.primaryColor }
1691
1871
  }
1692
1872
  ),
1693
- /* @__PURE__ */ React9.createElement(
1873
+ /* @__PURE__ */ React10.createElement(
1694
1874
  "span",
1695
1875
  {
1696
1876
  className: `transition-transform duration-300 ${isOpen ? "rotate-90 scale-90" : "rotate-0 scale-100"}`
1697
1877
  },
1698
- isOpen ? /* @__PURE__ */ React9.createElement(X2, { className: "w-6 h-6 text-white" }) : /* @__PURE__ */ React9.createElement(MessageSquare, { className: "w-6 h-6 text-white" })
1878
+ isOpen ? /* @__PURE__ */ React10.createElement(X2, { className: "w-6 h-6 text-white" }) : /* @__PURE__ */ React10.createElement(MessageSquare, { className: "w-6 h-6 text-white" })
1699
1879
  ),
1700
- hasUnread && !isOpen && /* @__PURE__ */ React9.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")
1880
+ hasUnread && !isOpen && /* @__PURE__ */ React10.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")
1701
1881
  ));
1702
1882
  }
1703
1883
 
1704
1884
  // src/components/DocumentUpload.tsx
1705
- import React10, { useState as useState6, useRef as useRef4 } from "react";
1885
+ import React11, { useState as useState6, useRef as useRef4 } from "react";
1706
1886
  import { Upload, File, X as X3, CheckCircle, AlertCircle, Loader2 } from "lucide-react";
1707
1887
  function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
1708
1888
  const { ui } = useConfig();
@@ -1758,7 +1938,7 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
1758
1938
  };
1759
1939
  const isUploading = fileStates.some((s) => s.status === "uploading");
1760
1940
  const hasIdle = fileStates.some((s) => s.status === "idle");
1761
- return /* @__PURE__ */ React10.createElement(
1941
+ return /* @__PURE__ */ React11.createElement(
1762
1942
  "div",
1763
1943
  {
1764
1944
  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}`,
@@ -1766,14 +1946,14 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
1766
1946
  onDragLeave,
1767
1947
  onDrop
1768
1948
  },
1769
- /* @__PURE__ */ React10.createElement("div", { className: "flex flex-col items-center justify-center text-center" }, /* @__PURE__ */ React10.createElement(
1949
+ /* @__PURE__ */ React11.createElement("div", { className: "flex flex-col items-center justify-center text-center" }, /* @__PURE__ */ React11.createElement(
1770
1950
  "div",
1771
1951
  {
1772
1952
  className: "w-12 h-12 rounded-full flex items-center justify-center mb-4 shadow-sm",
1773
1953
  style: { background: `linear-gradient(135deg, ${ui.primaryColor}20, ${ui.accentColor}20)` }
1774
1954
  },
1775
- /* @__PURE__ */ React10.createElement(Upload, { className: "w-6 h-6", style: { color: ui.primaryColor } })
1776
- ), /* @__PURE__ */ React10.createElement("h3", { className: "text-slate-900 dark:text-white font-semibold mb-1" }, "Upload Documents"), /* @__PURE__ */ React10.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__ */ React10.createElement(
1955
+ /* @__PURE__ */ React11.createElement(Upload, { className: "w-6 h-6", style: { color: ui.primaryColor } })
1956
+ ), /* @__PURE__ */ React11.createElement("h3", { className: "text-slate-900 dark:text-white font-semibold mb-1" }, "Upload Documents"), /* @__PURE__ */ React11.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__ */ React11.createElement(
1777
1957
  "button",
1778
1958
  {
1779
1959
  onClick: () => {
@@ -1789,7 +1969,7 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
1789
1969
  }
1790
1970
  },
1791
1971
  "Select Files"
1792
- ), /* @__PURE__ */ React10.createElement(
1972
+ ), /* @__PURE__ */ React11.createElement(
1793
1973
  "input",
1794
1974
  {
1795
1975
  ref: fileInputRef,
@@ -1800,22 +1980,22 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
1800
1980
  accept: ".pdf,.docx,.txt,.md,.json,.csv"
1801
1981
  }
1802
1982
  )),
1803
- fileStates.length > 0 && /* @__PURE__ */ React10.createElement("div", { className: "mt-8 space-y-3" }, fileStates.map((state, i) => /* @__PURE__ */ React10.createElement(
1983
+ fileStates.length > 0 && /* @__PURE__ */ React11.createElement("div", { className: "mt-8 space-y-3" }, fileStates.map((state, i) => /* @__PURE__ */ React11.createElement(
1804
1984
  "div",
1805
1985
  {
1806
1986
  key: i,
1807
1987
  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"
1808
1988
  },
1809
- /* @__PURE__ */ React10.createElement("div", { className: "flex items-center gap-3 overflow-hidden" }, /* @__PURE__ */ React10.createElement("div", { className: "w-8 h-8 rounded-lg bg-white dark:bg-white/10 flex items-center justify-center shadow-sm" }, /* @__PURE__ */ React10.createElement(File, { className: "w-4 h-4 text-slate-400" })), /* @__PURE__ */ React10.createElement("div", { className: "truncate" }, /* @__PURE__ */ React10.createElement("p", { className: "text-xs font-medium text-slate-700 dark:text-white/80 truncate" }, state.file.name), /* @__PURE__ */ React10.createElement("p", { className: "text-[10px] text-slate-400" }, (state.file.size / 1024).toFixed(1), " KB"))),
1810
- /* @__PURE__ */ React10.createElement("div", { className: "flex items-center gap-2" }, state.status === "uploading" && /* @__PURE__ */ React10.createElement(Loader2, { className: "w-4 h-4 text-slate-400 animate-spin" }), state.status === "success" && /* @__PURE__ */ React10.createElement(CheckCircle, { className: "w-4 h-4 text-emerald-500" }), state.status === "error" && /* @__PURE__ */ React10.createElement("div", { title: state.error }, /* @__PURE__ */ React10.createElement(AlertCircle, { className: "w-4 h-4 text-rose-500" })), state.status !== "uploading" && /* @__PURE__ */ React10.createElement(
1989
+ /* @__PURE__ */ React11.createElement("div", { className: "flex items-center gap-3 overflow-hidden" }, /* @__PURE__ */ React11.createElement("div", { className: "w-8 h-8 rounded-lg bg-white dark:bg-white/10 flex items-center justify-center shadow-sm" }, /* @__PURE__ */ React11.createElement(File, { className: "w-4 h-4 text-slate-400" })), /* @__PURE__ */ React11.createElement("div", { className: "truncate" }, /* @__PURE__ */ React11.createElement("p", { className: "text-xs font-medium text-slate-700 dark:text-white/80 truncate" }, state.file.name), /* @__PURE__ */ React11.createElement("p", { className: "text-[10px] text-slate-400" }, (state.file.size / 1024).toFixed(1), " KB"))),
1990
+ /* @__PURE__ */ React11.createElement("div", { className: "flex items-center gap-2" }, state.status === "uploading" && /* @__PURE__ */ React11.createElement(Loader2, { className: "w-4 h-4 text-slate-400 animate-spin" }), state.status === "success" && /* @__PURE__ */ React11.createElement(CheckCircle, { className: "w-4 h-4 text-emerald-500" }), state.status === "error" && /* @__PURE__ */ React11.createElement("div", { title: state.error }, /* @__PURE__ */ React11.createElement(AlertCircle, { className: "w-4 h-4 text-rose-500" })), state.status !== "uploading" && /* @__PURE__ */ React11.createElement(
1811
1991
  "button",
1812
1992
  {
1813
1993
  onClick: () => removeFile(i),
1814
1994
  className: "p-1 rounded-md hover:bg-slate-200 dark:hover:bg-white/10 transition-colors"
1815
1995
  },
1816
- /* @__PURE__ */ React10.createElement(X3, { className: "w-3.5 h-3.5 text-slate-400" })
1996
+ /* @__PURE__ */ React11.createElement(X3, { className: "w-3.5 h-3.5 text-slate-400" })
1817
1997
  ))
1818
- )), hasIdle && !isUploading && /* @__PURE__ */ React10.createElement(
1998
+ )), hasIdle && !isUploading && /* @__PURE__ */ React11.createElement(
1819
1999
  "button",
1820
2000
  {
1821
2001
  onClick: uploadFiles,