@retrivora-ai/rag-engine 1.2.1 → 1.2.3
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/DocumentChunker-BXOUMKoP.d.ts +93 -0
- package/dist/DocumentChunker-D1dg5iCi.d.mts +93 -0
- package/dist/{chunk-GCPPRD2G.mjs → chunk-WGPNEAK3.mjs} +37 -3
- package/dist/handlers/index.d.mts +2 -2
- package/dist/handlers/index.d.ts +2 -2
- package/dist/handlers/index.js +37 -3
- package/dist/handlers/index.mjs +1 -1
- package/dist/{index-DbtE8wLM.d.ts → index-B67KQ9NN.d.ts} +1 -1
- package/dist/{RagConfig-BOLOz0_O.d.mts → index-Cti1u0y1.d.mts} +86 -94
- package/dist/{RagConfig-BOLOz0_O.d.ts → index-Cti1u0y1.d.ts} +86 -94
- package/dist/{index-64BDupW3.d.mts → index-kUXnRvuI.d.mts} +1 -1
- package/dist/index.d.mts +52 -78
- package/dist/index.d.ts +52 -78
- package/dist/index.js +313 -124
- package/dist/index.mjs +293 -97
- package/dist/server.d.mts +5 -4
- package/dist/server.d.ts +5 -4
- package/dist/server.js +37 -3
- package/dist/server.mjs +1 -1
- package/package.json +2 -1
- package/src/components/ChatWidget.tsx +1 -8
- package/src/components/ChatWindow.tsx +120 -29
- package/src/components/ConfigProvider.tsx +7 -33
- package/src/components/DocumentUpload.tsx +1 -8
- package/src/components/DynamicChart.tsx +113 -0
- package/src/components/MessageBubble.tsx +51 -13
- package/src/components/ProductCard.tsx +1 -7
- package/src/components/ProductCarousel.tsx +1 -7
- package/src/components/SourceCard.tsx +1 -6
- package/src/config/RagConfig.ts +2 -0
- package/src/config/uiConstants.ts +23 -0
- package/src/core/LangChainAgent.ts +20 -2
- package/src/core/Pipeline.ts +19 -1
- package/src/core/VectorPlugin.ts +1 -1
- package/src/handlers/index.ts +1 -1
- package/src/hooks/useRagChat.ts +1 -45
- package/src/hooks/useStoredMessages.ts +1 -1
- package/src/index.ts +20 -5
- package/src/llm/ILLMProvider.ts +1 -13
- package/src/llm/providers/AnthropicProvider.ts +2 -1
- package/src/llm/providers/GeminiProvider.ts +2 -1
- package/src/llm/providers/OllamaProvider.ts +2 -1
- package/src/llm/providers/OpenAIProvider.ts +2 -1
- package/src/llm/providers/UniversalLLMAdapter.ts +2 -1
- package/src/server.ts +2 -2
- package/src/types/chat.ts +53 -0
- package/src/types/index.ts +3 -0
- package/src/types/props.ts +79 -0
- package/dist/DocumentChunker-Dh9TvmGG.d.mts +0 -45
- package/dist/DocumentChunker-Dh9TvmGG.d.ts +0 -45
package/dist/index.mjs
CHANGED
|
@@ -2,16 +2,17 @@ import {
|
|
|
2
2
|
mergeDefined
|
|
3
3
|
} from "./chunk-YLTMFW4M.mjs";
|
|
4
4
|
import {
|
|
5
|
+
__objRest,
|
|
5
6
|
__spreadProps,
|
|
6
7
|
__spreadValues
|
|
7
8
|
} from "./chunk-X4TOT24V.mjs";
|
|
8
9
|
|
|
9
10
|
// src/components/ChatWidget.tsx
|
|
10
|
-
import
|
|
11
|
+
import React9, { useState as useState5 } from "react";
|
|
11
12
|
import { MessageSquare, X as X2 } from "lucide-react";
|
|
12
13
|
|
|
13
14
|
// src/components/ChatWindow.tsx
|
|
14
|
-
import
|
|
15
|
+
import React8, { useState as useState4, useRef as useRef3, useEffect as useEffect4, useCallback as useCallback2 } from "react";
|
|
15
16
|
import {
|
|
16
17
|
Bot as Bot2,
|
|
17
18
|
Trash2,
|
|
@@ -21,11 +22,13 @@ import {
|
|
|
21
22
|
TriangleAlert,
|
|
22
23
|
RotateCcw,
|
|
23
24
|
Maximize2,
|
|
24
|
-
Minimize2
|
|
25
|
+
Minimize2,
|
|
26
|
+
Mic,
|
|
27
|
+
MicOff
|
|
25
28
|
} from "lucide-react";
|
|
26
29
|
|
|
27
30
|
// src/components/MessageBubble.tsx
|
|
28
|
-
import
|
|
31
|
+
import React5 from "react";
|
|
29
32
|
import { Bot, User, ChevronDown as ChevronDown2, ChevronRight as ChevronRight2 } from "lucide-react";
|
|
30
33
|
import ReactMarkdown from "react-markdown";
|
|
31
34
|
import remarkGfm from "remark-gfm";
|
|
@@ -162,6 +165,85 @@ function ProductCarousel({ products, primaryColor = "#6366f1", onAddToCart }) {
|
|
|
162
165
|
));
|
|
163
166
|
}
|
|
164
167
|
|
|
168
|
+
// src/components/DynamicChart.tsx
|
|
169
|
+
import React4 from "react";
|
|
170
|
+
import {
|
|
171
|
+
BarChart,
|
|
172
|
+
Bar,
|
|
173
|
+
LineChart,
|
|
174
|
+
Line,
|
|
175
|
+
PieChart,
|
|
176
|
+
Pie,
|
|
177
|
+
Cell,
|
|
178
|
+
XAxis,
|
|
179
|
+
YAxis,
|
|
180
|
+
CartesianGrid,
|
|
181
|
+
Tooltip,
|
|
182
|
+
Legend,
|
|
183
|
+
ResponsiveContainer
|
|
184
|
+
} from "recharts";
|
|
185
|
+
var DEFAULT_COLORS = ["#6366f1", "#10b981", "#f59e0b", "#ef4444", "#8b5cf6", "#ec4899"];
|
|
186
|
+
function DynamicChart({ config, primaryColor = "#6366f1", accentColor = "#8b5cf6" }) {
|
|
187
|
+
const { type, data, xAxisKey = "name", dataKeys = [] } = config;
|
|
188
|
+
const colors = config.colors || [primaryColor, accentColor, ...DEFAULT_COLORS];
|
|
189
|
+
if (!data || data.length === 0) {
|
|
190
|
+
return /* @__PURE__ */ React4.createElement("div", { className: "p-4 text-sm text-slate-500" }, "No data available for chart.");
|
|
191
|
+
}
|
|
192
|
+
if (type === "pie") {
|
|
193
|
+
const pieDataKey = dataKeys[0] || Object.keys(data[0]).find((k) => k !== xAxisKey) || "value";
|
|
194
|
+
return /* @__PURE__ */ React4.createElement("div", { className: "w-full h-64 mt-4 mb-2 select-none" }, /* @__PURE__ */ React4.createElement(ResponsiveContainer, { width: "100%", height: "100%" }, /* @__PURE__ */ React4.createElement(PieChart, null, /* @__PURE__ */ React4.createElement(
|
|
195
|
+
Pie,
|
|
196
|
+
{
|
|
197
|
+
data,
|
|
198
|
+
dataKey: pieDataKey,
|
|
199
|
+
nameKey: xAxisKey,
|
|
200
|
+
cx: "50%",
|
|
201
|
+
cy: "50%",
|
|
202
|
+
outerRadius: 80,
|
|
203
|
+
label: ({ name, percent }) => `${name} ${((percent != null ? percent : 0) * 100).toFixed(0)}%`
|
|
204
|
+
},
|
|
205
|
+
data.map((entry, index) => /* @__PURE__ */ React4.createElement(Cell, { key: `cell-${index}`, fill: colors[index % colors.length] }))
|
|
206
|
+
), /* @__PURE__ */ React4.createElement(
|
|
207
|
+
Tooltip,
|
|
208
|
+
{
|
|
209
|
+
contentStyle: { borderRadius: "8px", border: "none", boxShadow: "0 4px 6px -1px rgb(0 0 0 / 0.1)" }
|
|
210
|
+
}
|
|
211
|
+
), /* @__PURE__ */ React4.createElement(Legend, null))));
|
|
212
|
+
}
|
|
213
|
+
return /* @__PURE__ */ React4.createElement("div", { className: "w-full h-64 mt-4 mb-2 select-none" }, /* @__PURE__ */ React4.createElement(ResponsiveContainer, { width: "100%", height: "100%" }, type === "bar" ? /* @__PURE__ */ React4.createElement(BarChart, { data, margin: { top: 10, right: 10, left: -20, bottom: 0 } }, /* @__PURE__ */ React4.createElement(CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ React4.createElement(XAxis, { dataKey: xAxisKey, tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: { stroke: "#cbd5e1" } }), /* @__PURE__ */ React4.createElement(YAxis, { tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: false }), /* @__PURE__ */ React4.createElement(
|
|
214
|
+
Tooltip,
|
|
215
|
+
{
|
|
216
|
+
contentStyle: { borderRadius: "8px", border: "none", boxShadow: "0 4px 6px -1px rgb(0 0 0 / 0.1)" },
|
|
217
|
+
cursor: { fill: "#f1f5f9" }
|
|
218
|
+
}
|
|
219
|
+
), /* @__PURE__ */ React4.createElement(Legend, { wrapperStyle: { fontSize: 12 } }), dataKeys.map((key, index) => /* @__PURE__ */ React4.createElement(
|
|
220
|
+
Bar,
|
|
221
|
+
{
|
|
222
|
+
key,
|
|
223
|
+
dataKey: key,
|
|
224
|
+
fill: colors[index % colors.length],
|
|
225
|
+
radius: [4, 4, 0, 0],
|
|
226
|
+
barSize: Math.max(20, 60 / data.length)
|
|
227
|
+
}
|
|
228
|
+
))) : /* @__PURE__ */ React4.createElement(LineChart, { data, margin: { top: 10, right: 10, left: -20, bottom: 0 } }, /* @__PURE__ */ React4.createElement(CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ React4.createElement(XAxis, { dataKey: xAxisKey, tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: { stroke: "#cbd5e1" } }), /* @__PURE__ */ React4.createElement(YAxis, { tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: false }), /* @__PURE__ */ React4.createElement(
|
|
229
|
+
Tooltip,
|
|
230
|
+
{
|
|
231
|
+
contentStyle: { borderRadius: "8px", border: "none", boxShadow: "0 4px 6px -1px rgb(0 0 0 / 0.1)" }
|
|
232
|
+
}
|
|
233
|
+
), /* @__PURE__ */ React4.createElement(Legend, { wrapperStyle: { fontSize: 12 } }), dataKeys.map((key, index) => /* @__PURE__ */ React4.createElement(
|
|
234
|
+
Line,
|
|
235
|
+
{
|
|
236
|
+
key,
|
|
237
|
+
type: "monotone",
|
|
238
|
+
dataKey: key,
|
|
239
|
+
stroke: colors[index % colors.length],
|
|
240
|
+
strokeWidth: 3,
|
|
241
|
+
dot: { r: 4, strokeWidth: 2 },
|
|
242
|
+
activeDot: { r: 6 }
|
|
243
|
+
}
|
|
244
|
+
)))));
|
|
245
|
+
}
|
|
246
|
+
|
|
165
247
|
// src/components/MessageBubble.tsx
|
|
166
248
|
function MessageBubble({
|
|
167
249
|
message,
|
|
@@ -172,7 +254,7 @@ function MessageBubble({
|
|
|
172
254
|
onAddToCart
|
|
173
255
|
}) {
|
|
174
256
|
const isUser = message.role === "user";
|
|
175
|
-
const [showSources, setShowSources] =
|
|
257
|
+
const [showSources, setShowSources] = React5.useState(false);
|
|
176
258
|
const resolveImage = (data) => {
|
|
177
259
|
if (!data) return void 0;
|
|
178
260
|
const singleFields = ["image", "img", "thumbnail"];
|
|
@@ -185,7 +267,7 @@ function MessageBubble({
|
|
|
185
267
|
}
|
|
186
268
|
return void 0;
|
|
187
269
|
};
|
|
188
|
-
const productsFromSources =
|
|
270
|
+
const productsFromSources = React5.useMemo(() => {
|
|
189
271
|
if (isUser || !sources) return [];
|
|
190
272
|
return sources.filter((s) => {
|
|
191
273
|
const m = s.metadata || {};
|
|
@@ -203,7 +285,7 @@ function MessageBubble({
|
|
|
203
285
|
};
|
|
204
286
|
});
|
|
205
287
|
}, [sources, isUser]);
|
|
206
|
-
const { productsFromContent, cleanContent } =
|
|
288
|
+
const { productsFromContent, cleanContent } = React5.useMemo(() => {
|
|
207
289
|
if (isUser) return { productsFromContent: [], cleanContent: message.content };
|
|
208
290
|
const jsonRegex = /```json\s*([\s\S]*?)\s*```/g;
|
|
209
291
|
const products = [];
|
|
@@ -226,7 +308,7 @@ function MessageBubble({
|
|
|
226
308
|
}
|
|
227
309
|
return { productsFromContent: products, cleanContent: content.trim() };
|
|
228
310
|
}, [message.content, isUser]);
|
|
229
|
-
const allProducts =
|
|
311
|
+
const allProducts = React5.useMemo(() => {
|
|
230
312
|
if (productsFromContent.length > 0) return productsFromContent;
|
|
231
313
|
const uniqueProducts = [];
|
|
232
314
|
const seenIds = /* @__PURE__ */ new Set();
|
|
@@ -244,44 +326,91 @@ function MessageBubble({
|
|
|
244
326
|
return uniqueProducts;
|
|
245
327
|
}, [productsFromSources, productsFromContent, message.content]);
|
|
246
328
|
const hasProducts = allProducts.length > 0;
|
|
247
|
-
return /* @__PURE__ */
|
|
329
|
+
return /* @__PURE__ */ React5.createElement("div", { className: `flex gap-3 ${isUser ? "flex-row-reverse" : "flex-row"} items-start` }, /* @__PURE__ */ React5.createElement(
|
|
248
330
|
"div",
|
|
249
331
|
{
|
|
250
332
|
className: `flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center shadow-lg ${isUser ? "text-white" : "bg-slate-100 dark:bg-white/10 text-slate-700 dark:text-white/80"}`,
|
|
251
333
|
style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
|
|
252
334
|
},
|
|
253
|
-
isUser ? /* @__PURE__ */
|
|
254
|
-
), /* @__PURE__ */
|
|
335
|
+
isUser ? /* @__PURE__ */ React5.createElement(User, { className: "w-4 h-4 text-white" }) : /* @__PURE__ */ React5.createElement(Bot, { className: "w-4 h-4" })
|
|
336
|
+
), /* @__PURE__ */ React5.createElement("div", { className: `flex flex-col gap-1 max-w-[90%] ${isUser ? "items-end" : "items-start"}` }, /* @__PURE__ */ React5.createElement(
|
|
255
337
|
"div",
|
|
256
338
|
{
|
|
257
339
|
className: `relative px-4 py-3 rounded-2xl text-sm leading-relaxed shadow-sm dark:shadow-lg ${isUser ? "text-white rounded-tr-sm" : "bg-white dark:bg-white/5 border border-slate-200 dark:border-white/10 text-slate-800 dark:text-white/90 rounded-tl-sm"}`,
|
|
258
340
|
style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
|
|
259
341
|
},
|
|
260
|
-
isStreaming && !message.content ? /* @__PURE__ */
|
|
261
|
-
|
|
342
|
+
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 prose-sm max-w-none ${isUser ? "prose-invert" : "dark:prose-invert"}` }, /* @__PURE__ */ React5.createElement(
|
|
343
|
+
ReactMarkdown,
|
|
344
|
+
{
|
|
345
|
+
remarkPlugins: [remarkGfm],
|
|
346
|
+
components: {
|
|
347
|
+
table: (_a) => {
|
|
348
|
+
var props = __objRest(_a, []);
|
|
349
|
+
return /* @__PURE__ */ React5.createElement("div", { className: "overflow-x-auto my-4 rounded-xl border border-slate-200 dark:border-white/10 shadow-sm" }, /* @__PURE__ */ React5.createElement("table", __spreadValues({ className: "w-full text-left border-collapse min-w-[400px]" }, props)));
|
|
350
|
+
},
|
|
351
|
+
thead: (_b) => {
|
|
352
|
+
var props = __objRest(_b, []);
|
|
353
|
+
return /* @__PURE__ */ React5.createElement("thead", __spreadValues({ className: "bg-slate-50 dark:bg-white/5 border-b border-slate-200 dark:border-white/10" }, props));
|
|
354
|
+
},
|
|
355
|
+
th: (_c) => {
|
|
356
|
+
var props = __objRest(_c, []);
|
|
357
|
+
return /* @__PURE__ */ React5.createElement("th", __spreadValues({ className: "p-3 font-semibold text-slate-700 dark:text-white/90 first:rounded-tl-xl last:rounded-tr-xl" }, props));
|
|
358
|
+
},
|
|
359
|
+
td: (_d) => {
|
|
360
|
+
var props = __objRest(_d, []);
|
|
361
|
+
return /* @__PURE__ */ React5.createElement("td", __spreadValues({ className: "p-3 border-b border-slate-100 dark:border-white/5 last:border-0 text-slate-600 dark:text-white/70" }, props));
|
|
362
|
+
},
|
|
363
|
+
code(_e) {
|
|
364
|
+
var _f = _e, { inline, className, children } = _f, props = __objRest(_f, ["inline", "className", "children"]);
|
|
365
|
+
const match = /language-(\w+)/.exec(className || "");
|
|
366
|
+
const isChart = match && match[1] === "chart";
|
|
367
|
+
if (!inline && isChart) {
|
|
368
|
+
try {
|
|
369
|
+
const config = JSON.parse(String(children).replace(/\n$/, ""));
|
|
370
|
+
return /* @__PURE__ */ React5.createElement("div", { className: "my-4 p-4 bg-white dark:bg-slate-900 rounded-xl border border-slate-200 dark:border-white/10 shadow-sm" }, /* @__PURE__ */ React5.createElement(
|
|
371
|
+
DynamicChart,
|
|
372
|
+
{
|
|
373
|
+
config,
|
|
374
|
+
primaryColor,
|
|
375
|
+
accentColor
|
|
376
|
+
}
|
|
377
|
+
));
|
|
378
|
+
} catch (e) {
|
|
379
|
+
return /* @__PURE__ */ React5.createElement("div", { className: "p-4 bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 rounded-lg text-sm" }, "Failed to render chart: Invalid configuration.");
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return /* @__PURE__ */ React5.createElement("code", __spreadValues({ className }, props), children);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
},
|
|
386
|
+
cleanContent || message.content
|
|
387
|
+
), 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" }))
|
|
388
|
+
), !isUser && hasProducts && /* @__PURE__ */ React5.createElement("div", { className: "w-full mt-1" }, /* @__PURE__ */ React5.createElement(
|
|
262
389
|
ProductCarousel,
|
|
263
390
|
{
|
|
264
391
|
products: allProducts,
|
|
265
392
|
primaryColor,
|
|
266
393
|
onAddToCart
|
|
267
394
|
}
|
|
268
|
-
)), !isUser && sources && sources.length > 0 && /* @__PURE__ */
|
|
395
|
+
)), !isUser && sources && sources.length > 0 && /* @__PURE__ */ React5.createElement("div", { className: "w-full" }, /* @__PURE__ */ React5.createElement(
|
|
269
396
|
"button",
|
|
270
397
|
{
|
|
271
398
|
onClick: () => setShowSources((s) => !s),
|
|
272
399
|
className: "text-[11px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-1 mt-1"
|
|
273
400
|
},
|
|
274
|
-
showSources ? /* @__PURE__ */
|
|
401
|
+
showSources ? /* @__PURE__ */ React5.createElement(ChevronDown2, { className: "w-3 h-3" }) : /* @__PURE__ */ React5.createElement(ChevronRight2, { className: "w-3 h-3" }),
|
|
275
402
|
sources.length,
|
|
276
403
|
" source",
|
|
277
404
|
sources.length !== 1 ? "s" : "",
|
|
278
405
|
" used"
|
|
279
|
-
), showSources && /* @__PURE__ */
|
|
406
|
+
), 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 }))))));
|
|
280
407
|
}
|
|
281
408
|
|
|
282
409
|
// src/components/ConfigProvider.tsx
|
|
283
|
-
import
|
|
284
|
-
|
|
410
|
+
import React6, { createContext, useContext } from "react";
|
|
411
|
+
|
|
412
|
+
// src/config/uiConstants.ts
|
|
413
|
+
var DEFAULT_CONFIG = {
|
|
285
414
|
projectId: "default",
|
|
286
415
|
ui: {
|
|
287
416
|
title: "AI Assistant",
|
|
@@ -297,19 +426,35 @@ var defaultConfig = {
|
|
|
297
426
|
visualStyle: "glass",
|
|
298
427
|
borderRadius: "xl",
|
|
299
428
|
allowUpload: true,
|
|
300
|
-
allowResize: true
|
|
429
|
+
allowResize: true,
|
|
430
|
+
enableVoiceInput: true
|
|
301
431
|
}
|
|
302
432
|
};
|
|
303
|
-
var
|
|
433
|
+
var BORDER_RADIUS_MAP = {
|
|
434
|
+
none: "rounded-none",
|
|
435
|
+
sm: "rounded-sm",
|
|
436
|
+
md: "rounded-md",
|
|
437
|
+
lg: "rounded-lg",
|
|
438
|
+
xl: "rounded-xl",
|
|
439
|
+
full: "rounded-3xl"
|
|
440
|
+
};
|
|
441
|
+
var CHAT_SUGGESTIONS = [
|
|
442
|
+
"What can you help me with?",
|
|
443
|
+
"Summarise the key topics",
|
|
444
|
+
"Show me an example"
|
|
445
|
+
];
|
|
446
|
+
|
|
447
|
+
// src/components/ConfigProvider.tsx
|
|
448
|
+
var ConfigContext = createContext(DEFAULT_CONFIG);
|
|
304
449
|
function ConfigProvider({
|
|
305
450
|
config,
|
|
306
451
|
children
|
|
307
452
|
}) {
|
|
308
453
|
const merged = {
|
|
309
|
-
projectId: (config == null ? void 0 : config.projectId) ||
|
|
310
|
-
ui: mergeDefined(
|
|
454
|
+
projectId: (config == null ? void 0 : config.projectId) || DEFAULT_CONFIG.projectId,
|
|
455
|
+
ui: mergeDefined(DEFAULT_CONFIG.ui, config == null ? void 0 : config.ui)
|
|
311
456
|
};
|
|
312
|
-
return /* @__PURE__ */
|
|
457
|
+
return /* @__PURE__ */ React6.createElement(ConfigContext.Provider, { value: merged }, children);
|
|
313
458
|
}
|
|
314
459
|
function useConfig() {
|
|
315
460
|
return useContext(ConfigContext);
|
|
@@ -319,7 +464,7 @@ function useConfig() {
|
|
|
319
464
|
import { useState as useState3, useCallback, useRef as useRef2, useEffect as useEffect3 } from "react";
|
|
320
465
|
|
|
321
466
|
// src/hooks/useStoredMessages.ts
|
|
322
|
-
import * as
|
|
467
|
+
import * as React7 from "react";
|
|
323
468
|
function readStoredMessages(storageKey) {
|
|
324
469
|
if (typeof window === "undefined") {
|
|
325
470
|
return [];
|
|
@@ -336,8 +481,8 @@ function readStoredMessages(storageKey) {
|
|
|
336
481
|
}
|
|
337
482
|
}
|
|
338
483
|
function useStoredMessages(storageKey, persist) {
|
|
339
|
-
const [messages, setMessages] =
|
|
340
|
-
|
|
484
|
+
const [messages, setMessages] = React7.useState(() => persist ? readStoredMessages(storageKey) : []);
|
|
485
|
+
React7.useEffect(() => {
|
|
341
486
|
if (!persist || typeof window === "undefined") {
|
|
342
487
|
return;
|
|
343
488
|
}
|
|
@@ -505,21 +650,6 @@ function useRagChat(projectId, options = {}) {
|
|
|
505
650
|
};
|
|
506
651
|
}
|
|
507
652
|
|
|
508
|
-
// src/config/uiConstants.ts
|
|
509
|
-
var BORDER_RADIUS_MAP = {
|
|
510
|
-
none: "rounded-none",
|
|
511
|
-
sm: "rounded-sm",
|
|
512
|
-
md: "rounded-md",
|
|
513
|
-
lg: "rounded-lg",
|
|
514
|
-
xl: "rounded-xl",
|
|
515
|
-
full: "rounded-3xl"
|
|
516
|
-
};
|
|
517
|
-
var CHAT_SUGGESTIONS = [
|
|
518
|
-
"What can you help me with?",
|
|
519
|
-
"Summarise the key topics",
|
|
520
|
-
"Show me an example"
|
|
521
|
-
];
|
|
522
|
-
|
|
523
653
|
// src/components/ChatWindow.tsx
|
|
524
654
|
function ChatWindow({
|
|
525
655
|
className = "",
|
|
@@ -542,6 +672,56 @@ function ChatWindow({
|
|
|
542
672
|
const { messages, send, clear, isLoading, error } = useRagChat(projectId, {
|
|
543
673
|
namespace: projectId
|
|
544
674
|
});
|
|
675
|
+
const [suggestions, setSuggestions] = useState4([]);
|
|
676
|
+
const [isSuggesting, setIsSuggesting] = useState4(false);
|
|
677
|
+
const [isListening, setIsListening] = useState4(false);
|
|
678
|
+
const recognitionRef = useRef3(null);
|
|
679
|
+
useEffect4(() => {
|
|
680
|
+
if (typeof window !== "undefined") {
|
|
681
|
+
const win = window;
|
|
682
|
+
const SpeechRecognition = win.SpeechRecognition || win.webkitSpeechRecognition;
|
|
683
|
+
if (SpeechRecognition) {
|
|
684
|
+
const recognition = new SpeechRecognition();
|
|
685
|
+
recognition.continuous = true;
|
|
686
|
+
recognition.interimResults = true;
|
|
687
|
+
recognition.onresult = (event) => {
|
|
688
|
+
let finalTranscript = "";
|
|
689
|
+
for (let i = event.resultIndex; i < event.results.length; ++i) {
|
|
690
|
+
if (event.results[i].isFinal) {
|
|
691
|
+
finalTranscript += event.results[i][0].transcript;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
if (finalTranscript) {
|
|
695
|
+
setInput((prev) => (prev ? prev + " " : "") + finalTranscript.trim());
|
|
696
|
+
}
|
|
697
|
+
};
|
|
698
|
+
recognition.onerror = (event) => {
|
|
699
|
+
console.error("Speech recognition error:", event.error);
|
|
700
|
+
setIsListening(false);
|
|
701
|
+
};
|
|
702
|
+
recognition.onend = () => {
|
|
703
|
+
setIsListening(false);
|
|
704
|
+
};
|
|
705
|
+
recognitionRef.current = recognition;
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
}, []);
|
|
709
|
+
const toggleListening = () => {
|
|
710
|
+
if (!recognitionRef.current) {
|
|
711
|
+
alert("Speech recognition is not supported in your browser.");
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
if (isListening) {
|
|
715
|
+
recognitionRef.current.stop();
|
|
716
|
+
} else {
|
|
717
|
+
try {
|
|
718
|
+
recognitionRef.current.start();
|
|
719
|
+
setIsListening(true);
|
|
720
|
+
} catch (err) {
|
|
721
|
+
console.error("Failed to start recognition:", err);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
};
|
|
545
725
|
useEffect4(() => {
|
|
546
726
|
setMounted(true);
|
|
547
727
|
}, []);
|
|
@@ -552,15 +732,21 @@ function ChatWindow({
|
|
|
552
732
|
}
|
|
553
733
|
}, [messages, isLoading]);
|
|
554
734
|
const sendMessage = useCallback2(async () => {
|
|
735
|
+
var _a2;
|
|
555
736
|
const text = input.trim();
|
|
556
737
|
if (!text || isLoading) return;
|
|
738
|
+
if (isListening) {
|
|
739
|
+
(_a2 = recognitionRef.current) == null ? void 0 : _a2.stop();
|
|
740
|
+
}
|
|
557
741
|
setInput("");
|
|
742
|
+
setSuggestions([]);
|
|
743
|
+
setIsSuggesting(false);
|
|
558
744
|
await send(text);
|
|
559
745
|
window.setTimeout(() => {
|
|
560
|
-
var
|
|
561
|
-
return (
|
|
746
|
+
var _a3;
|
|
747
|
+
return (_a3 = inputRef.current) == null ? void 0 : _a3.focus();
|
|
562
748
|
}, 50);
|
|
563
|
-
}, [input, isLoading, send]);
|
|
749
|
+
}, [input, isLoading, send, isListening]);
|
|
564
750
|
const handleKeyDown = (e) => {
|
|
565
751
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
566
752
|
e.preventDefault();
|
|
@@ -569,12 +755,12 @@ function ChatWindow({
|
|
|
569
755
|
};
|
|
570
756
|
const clearHistory = () => {
|
|
571
757
|
clear();
|
|
758
|
+
setSuggestions([]);
|
|
759
|
+
setIsSuggesting(false);
|
|
572
760
|
};
|
|
573
761
|
const isEmpty = messages.length === 0;
|
|
574
762
|
const currentRadius = BORDER_RADIUS_MAP[ui.borderRadius || "xl"];
|
|
575
763
|
const isGlass = ui.visualStyle !== "solid";
|
|
576
|
-
const [suggestions, setSuggestions] = useState4([]);
|
|
577
|
-
const [isSuggesting, setIsSuggesting] = useState4(false);
|
|
578
764
|
useEffect4(() => {
|
|
579
765
|
if (input.trim().length < 3) {
|
|
580
766
|
return;
|
|
@@ -599,83 +785,83 @@ function ChatWindow({
|
|
|
599
785
|
}, 800);
|
|
600
786
|
return () => clearTimeout(timer);
|
|
601
787
|
}, [input, projectId]);
|
|
602
|
-
return /* @__PURE__ */
|
|
788
|
+
return /* @__PURE__ */ React8.createElement(
|
|
603
789
|
"div",
|
|
604
790
|
{
|
|
605
791
|
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}`,
|
|
606
792
|
style: __spreadValues({ "--primary": ui.primaryColor, "--accent": ui.accentColor }, style)
|
|
607
793
|
},
|
|
608
|
-
onResizeStart && /* @__PURE__ */
|
|
794
|
+
onResizeStart && /* @__PURE__ */ React8.createElement(
|
|
609
795
|
"div",
|
|
610
796
|
{
|
|
611
797
|
onMouseDown: onResizeStart,
|
|
612
798
|
className: "absolute top-0 left-0 w-6 h-6 cursor-nw-resize z-[100] group flex items-start justify-start p-1",
|
|
613
799
|
title: "Drag to resize"
|
|
614
800
|
},
|
|
615
|
-
/* @__PURE__ */
|
|
801
|
+
/* @__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]" })
|
|
616
802
|
),
|
|
617
|
-
/* @__PURE__ */
|
|
803
|
+
/* @__PURE__ */ React8.createElement(
|
|
618
804
|
"div",
|
|
619
805
|
{
|
|
620
806
|
className: "flex items-center justify-between px-5 py-4 border-b border-slate-200 dark:border-white/10",
|
|
621
807
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}15, ${ui.accentColor}10)` }
|
|
622
808
|
},
|
|
623
|
-
/* @__PURE__ */
|
|
809
|
+
/* @__PURE__ */ React8.createElement("div", { className: "flex items-center gap-3" }, ui.logoUrl ? (
|
|
624
810
|
// eslint-disable-next-line @next/next/no-img-element
|
|
625
|
-
/* @__PURE__ */
|
|
626
|
-
) : /* @__PURE__ */
|
|
811
|
+
/* @__PURE__ */ React8.createElement("img", { src: ui.logoUrl, alt: "logo", className: "w-8 h-8 rounded-lg object-cover" })
|
|
812
|
+
) : /* @__PURE__ */ React8.createElement(
|
|
627
813
|
"div",
|
|
628
814
|
{
|
|
629
815
|
className: `w-9 h-9 flex items-center justify-center shadow-md ${ui.borderRadius === "full" ? "rounded-full" : "rounded-xl"}`,
|
|
630
816
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
|
|
631
817
|
},
|
|
632
|
-
/* @__PURE__ */
|
|
633
|
-
), /* @__PURE__ */
|
|
634
|
-
/* @__PURE__ */
|
|
818
|
+
/* @__PURE__ */ React8.createElement(Bot2, { className: "w-5 h-5 text-white" })
|
|
819
|
+
), /* @__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}`))),
|
|
820
|
+
/* @__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(
|
|
635
821
|
"button",
|
|
636
822
|
{
|
|
637
823
|
onClick: clearHistory,
|
|
638
824
|
title: "Clear conversation",
|
|
639
825
|
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"
|
|
640
826
|
},
|
|
641
|
-
/* @__PURE__ */
|
|
642
|
-
), isResized && onResetResize && /* @__PURE__ */
|
|
827
|
+
/* @__PURE__ */ React8.createElement(Trash2, { className: "w-3.5 h-3.5" })
|
|
828
|
+
), isResized && onResetResize && /* @__PURE__ */ React8.createElement(
|
|
643
829
|
"button",
|
|
644
830
|
{
|
|
645
831
|
onClick: onResetResize,
|
|
646
832
|
title: "Reset to default size",
|
|
647
833
|
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"
|
|
648
834
|
},
|
|
649
|
-
/* @__PURE__ */
|
|
650
|
-
), onMaximize && /* @__PURE__ */
|
|
835
|
+
/* @__PURE__ */ React8.createElement(RotateCcw, { className: "w-3.5 h-3.5" })
|
|
836
|
+
), onMaximize && /* @__PURE__ */ React8.createElement(
|
|
651
837
|
"button",
|
|
652
838
|
{
|
|
653
839
|
onClick: onMaximize,
|
|
654
840
|
title: isMaximized ? "Minimize" : "Maximize",
|
|
655
841
|
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"
|
|
656
842
|
},
|
|
657
|
-
isMaximized ? /* @__PURE__ */
|
|
658
|
-
), showClose && onClose && /* @__PURE__ */
|
|
843
|
+
isMaximized ? /* @__PURE__ */ React8.createElement(Minimize2, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ React8.createElement(Maximize2, { className: "w-3.5 h-3.5" })
|
|
844
|
+
), showClose && onClose && /* @__PURE__ */ React8.createElement(
|
|
659
845
|
"button",
|
|
660
846
|
{
|
|
661
847
|
onClick: onClose,
|
|
662
848
|
title: "Close chat",
|
|
663
849
|
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"
|
|
664
850
|
},
|
|
665
|
-
/* @__PURE__ */
|
|
851
|
+
/* @__PURE__ */ React8.createElement(X, { className: "w-4 h-4" })
|
|
666
852
|
)))
|
|
667
853
|
),
|
|
668
|
-
/* @__PURE__ */
|
|
854
|
+
/* @__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 ? (
|
|
669
855
|
/* Welcome state */
|
|
670
|
-
/* @__PURE__ */
|
|
856
|
+
/* @__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(
|
|
671
857
|
"div",
|
|
672
858
|
{
|
|
673
859
|
className: `w-16 h-16 flex items-center justify-center shadow-lg ${ui.borderRadius === "full" ? "rounded-full" : "rounded-2xl"}`,
|
|
674
860
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
|
|
675
861
|
},
|
|
676
|
-
/* @__PURE__ */
|
|
677
|
-
), /* @__PURE__ */
|
|
678
|
-
(suggestion) => /* @__PURE__ */
|
|
862
|
+
/* @__PURE__ */ React8.createElement(Sparkles, { className: "w-8 h-8 text-white" })
|
|
863
|
+
), /* @__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(
|
|
864
|
+
(suggestion) => /* @__PURE__ */ React8.createElement(
|
|
679
865
|
"button",
|
|
680
866
|
{
|
|
681
867
|
key: suggestion,
|
|
@@ -689,7 +875,7 @@ function ChatWindow({
|
|
|
689
875
|
suggestion
|
|
690
876
|
)
|
|
691
877
|
)))
|
|
692
|
-
) : messages.map((msg, index) => /* @__PURE__ */
|
|
878
|
+
) : messages.map((msg, index) => /* @__PURE__ */ React8.createElement(
|
|
693
879
|
MessageBubble,
|
|
694
880
|
{
|
|
695
881
|
key: msg.id,
|
|
@@ -700,17 +886,17 @@ function ChatWindow({
|
|
|
700
886
|
accentColor: ui.accentColor,
|
|
701
887
|
onAddToCart
|
|
702
888
|
}
|
|
703
|
-
)), isLoading && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) !== "assistant" && /* @__PURE__ */
|
|
889
|
+
)), isLoading && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) !== "assistant" && /* @__PURE__ */ React8.createElement(
|
|
704
890
|
MessageBubble,
|
|
705
891
|
{
|
|
706
|
-
message: { role: "assistant", content: "" },
|
|
892
|
+
message: { id: "loading", role: "assistant", content: "", createdAt: (/* @__PURE__ */ new Date()).toISOString() },
|
|
707
893
|
isStreaming: true,
|
|
708
894
|
primaryColor: ui.primaryColor,
|
|
709
895
|
accentColor: ui.accentColor,
|
|
710
896
|
onAddToCart
|
|
711
897
|
}
|
|
712
|
-
), error && /* @__PURE__ */
|
|
713
|
-
/* @__PURE__ */
|
|
898
|
+
), 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 })),
|
|
899
|
+
/* @__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(
|
|
714
900
|
"button",
|
|
715
901
|
{
|
|
716
902
|
key: suggestion,
|
|
@@ -722,9 +908,9 @@ function ChatWindow({
|
|
|
722
908
|
},
|
|
723
909
|
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"
|
|
724
910
|
},
|
|
725
|
-
/* @__PURE__ */
|
|
911
|
+
/* @__PURE__ */ React8.createElement(Sparkles, { className: "w-3 h-3 text-amber-400" }),
|
|
726
912
|
suggestion
|
|
727
|
-
)), isSuggesting && suggestions.length === 0 && /* @__PURE__ */
|
|
913
|
+
)), 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(
|
|
728
914
|
"textarea",
|
|
729
915
|
{
|
|
730
916
|
ref: inputRef,
|
|
@@ -743,7 +929,17 @@ function ChatWindow({
|
|
|
743
929
|
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",
|
|
744
930
|
style: { scrollbarWidth: "none" }
|
|
745
931
|
}
|
|
746
|
-
), /* @__PURE__ */
|
|
932
|
+
), ui.enableVoiceInput !== false && /* @__PURE__ */ React8.createElement(
|
|
933
|
+
"button",
|
|
934
|
+
{
|
|
935
|
+
type: "button",
|
|
936
|
+
onClick: toggleListening,
|
|
937
|
+
disabled: isLoading,
|
|
938
|
+
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"}`,
|
|
939
|
+
title: isListening ? "Stop listening" : "Start voice input"
|
|
940
|
+
},
|
|
941
|
+
isListening ? /* @__PURE__ */ React8.createElement(MicOff, { className: "w-4 h-4" }) : /* @__PURE__ */ React8.createElement(Mic, { className: "w-4 h-4" })
|
|
942
|
+
), /* @__PURE__ */ React8.createElement(
|
|
747
943
|
"button",
|
|
748
944
|
{
|
|
749
945
|
onClick: sendMessage,
|
|
@@ -754,8 +950,8 @@ function ChatWindow({
|
|
|
754
950
|
// slate-400/20 for light mode disabled
|
|
755
951
|
}
|
|
756
952
|
},
|
|
757
|
-
/* @__PURE__ */
|
|
758
|
-
)), /* @__PURE__ */
|
|
953
|
+
/* @__PURE__ */ React8.createElement(ArrowUp, { className: "w-4 h-4 text-white" })
|
|
954
|
+
)), /* @__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"))
|
|
759
955
|
);
|
|
760
956
|
}
|
|
761
957
|
|
|
@@ -818,7 +1014,7 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
|
|
|
818
1014
|
}
|
|
819
1015
|
};
|
|
820
1016
|
const isResized = dimensions.width !== DEFAULT_DIMENSIONS.width || dimensions.height !== DEFAULT_DIMENSIONS.height;
|
|
821
|
-
return /* @__PURE__ */
|
|
1017
|
+
return /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(
|
|
822
1018
|
"div",
|
|
823
1019
|
{
|
|
824
1020
|
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"}`,
|
|
@@ -828,7 +1024,7 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
|
|
|
828
1024
|
maxHeight: "calc(100vh - 6rem)"
|
|
829
1025
|
}
|
|
830
1026
|
},
|
|
831
|
-
/* @__PURE__ */
|
|
1027
|
+
/* @__PURE__ */ React9.createElement(
|
|
832
1028
|
ChatWindow,
|
|
833
1029
|
{
|
|
834
1030
|
className: "h-full relative z-10",
|
|
@@ -842,13 +1038,13 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
|
|
|
842
1038
|
onAddToCart
|
|
843
1039
|
}
|
|
844
1040
|
),
|
|
845
|
-
/* @__PURE__ */
|
|
1041
|
+
/* @__PURE__ */ React9.createElement(
|
|
846
1042
|
"div",
|
|
847
1043
|
{
|
|
848
1044
|
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"}`
|
|
849
1045
|
}
|
|
850
1046
|
)
|
|
851
|
-
), /* @__PURE__ */
|
|
1047
|
+
), /* @__PURE__ */ React9.createElement(
|
|
852
1048
|
"button",
|
|
853
1049
|
{
|
|
854
1050
|
onClick: isOpen ? () => setIsOpen(false) : handleOpen,
|
|
@@ -856,26 +1052,26 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
|
|
|
856
1052
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
|
|
857
1053
|
"aria-label": "Open chat"
|
|
858
1054
|
},
|
|
859
|
-
/* @__PURE__ */
|
|
1055
|
+
/* @__PURE__ */ React9.createElement(
|
|
860
1056
|
"span",
|
|
861
1057
|
{
|
|
862
1058
|
className: "absolute inset-0 rounded-full animate-ping opacity-20",
|
|
863
1059
|
style: { background: ui.primaryColor }
|
|
864
1060
|
}
|
|
865
1061
|
),
|
|
866
|
-
/* @__PURE__ */
|
|
1062
|
+
/* @__PURE__ */ React9.createElement(
|
|
867
1063
|
"span",
|
|
868
1064
|
{
|
|
869
1065
|
className: `transition-transform duration-300 ${isOpen ? "rotate-90 scale-90" : "rotate-0 scale-100"}`
|
|
870
1066
|
},
|
|
871
|
-
isOpen ? /* @__PURE__ */
|
|
1067
|
+
isOpen ? /* @__PURE__ */ React9.createElement(X2, { className: "w-6 h-6 text-white" }) : /* @__PURE__ */ React9.createElement(MessageSquare, { className: "w-6 h-6 text-white" })
|
|
872
1068
|
),
|
|
873
|
-
hasUnread && !isOpen && /* @__PURE__ */
|
|
1069
|
+
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")
|
|
874
1070
|
));
|
|
875
1071
|
}
|
|
876
1072
|
|
|
877
1073
|
// src/components/DocumentUpload.tsx
|
|
878
|
-
import
|
|
1074
|
+
import React10, { useState as useState6, useRef as useRef4 } from "react";
|
|
879
1075
|
import { Upload, File, X as X3, CheckCircle, AlertCircle, Loader2 } from "lucide-react";
|
|
880
1076
|
function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
881
1077
|
const { ui } = useConfig();
|
|
@@ -931,7 +1127,7 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
931
1127
|
};
|
|
932
1128
|
const isUploading = fileStates.some((s) => s.status === "uploading");
|
|
933
1129
|
const hasIdle = fileStates.some((s) => s.status === "idle");
|
|
934
|
-
return /* @__PURE__ */
|
|
1130
|
+
return /* @__PURE__ */ React10.createElement(
|
|
935
1131
|
"div",
|
|
936
1132
|
{
|
|
937
1133
|
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}`,
|
|
@@ -939,14 +1135,14 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
939
1135
|
onDragLeave,
|
|
940
1136
|
onDrop
|
|
941
1137
|
},
|
|
942
|
-
/* @__PURE__ */
|
|
1138
|
+
/* @__PURE__ */ React10.createElement("div", { className: "flex flex-col items-center justify-center text-center" }, /* @__PURE__ */ React10.createElement(
|
|
943
1139
|
"div",
|
|
944
1140
|
{
|
|
945
1141
|
className: "w-12 h-12 rounded-full flex items-center justify-center mb-4 shadow-sm",
|
|
946
1142
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}20, ${ui.accentColor}20)` }
|
|
947
1143
|
},
|
|
948
|
-
/* @__PURE__ */
|
|
949
|
-
), /* @__PURE__ */
|
|
1144
|
+
/* @__PURE__ */ React10.createElement(Upload, { className: "w-6 h-6", style: { color: ui.primaryColor } })
|
|
1145
|
+
), /* @__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(
|
|
950
1146
|
"button",
|
|
951
1147
|
{
|
|
952
1148
|
onClick: () => {
|
|
@@ -962,7 +1158,7 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
962
1158
|
}
|
|
963
1159
|
},
|
|
964
1160
|
"Select Files"
|
|
965
|
-
), /* @__PURE__ */
|
|
1161
|
+
), /* @__PURE__ */ React10.createElement(
|
|
966
1162
|
"input",
|
|
967
1163
|
{
|
|
968
1164
|
ref: fileInputRef,
|
|
@@ -973,22 +1169,22 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
973
1169
|
accept: ".pdf,.docx,.txt,.md,.json,.csv"
|
|
974
1170
|
}
|
|
975
1171
|
)),
|
|
976
|
-
fileStates.length > 0 && /* @__PURE__ */
|
|
1172
|
+
fileStates.length > 0 && /* @__PURE__ */ React10.createElement("div", { className: "mt-8 space-y-3" }, fileStates.map((state, i) => /* @__PURE__ */ React10.createElement(
|
|
977
1173
|
"div",
|
|
978
1174
|
{
|
|
979
1175
|
key: i,
|
|
980
1176
|
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"
|
|
981
1177
|
},
|
|
982
|
-
/* @__PURE__ */
|
|
983
|
-
/* @__PURE__ */
|
|
1178
|
+
/* @__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"))),
|
|
1179
|
+
/* @__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(
|
|
984
1180
|
"button",
|
|
985
1181
|
{
|
|
986
1182
|
onClick: () => removeFile(i),
|
|
987
1183
|
className: "p-1 rounded-md hover:bg-slate-200 dark:hover:bg-white/10 transition-colors"
|
|
988
1184
|
},
|
|
989
|
-
/* @__PURE__ */
|
|
1185
|
+
/* @__PURE__ */ React10.createElement(X3, { className: "w-3.5 h-3.5 text-slate-400" })
|
|
990
1186
|
))
|
|
991
|
-
)), hasIdle && !isUploading && /* @__PURE__ */
|
|
1187
|
+
)), hasIdle && !isUploading && /* @__PURE__ */ React10.createElement(
|
|
992
1188
|
"button",
|
|
993
1189
|
{
|
|
994
1190
|
onClick: uploadFiles,
|