@retrivora-ai/rag-engine 1.2.2 → 1.2.4
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/{chunk-GCPPRD2G.mjs → chunk-X4TMJV23.mjs} +39 -3
- package/dist/handlers/index.js +39 -3
- package/dist/handlers/index.mjs +1 -1
- package/dist/index.js +231 -106
- package/dist/index.mjs +201 -73
- package/dist/server.js +39 -3
- package/dist/server.mjs +1 -1
- package/package.json +2 -1
- package/src/components/ChatWindow.tsx +2 -1
- package/src/components/DynamicChart.tsx +113 -0
- package/src/components/MessageBubble.tsx +54 -1
- package/src/core/LangChainAgent.ts +21 -2
- package/src/core/Pipeline.ts +18 -0
package/dist/index.js
CHANGED
|
@@ -22,6 +22,18 @@ var __spreadValues = (a, b) => {
|
|
|
22
22
|
return a;
|
|
23
23
|
};
|
|
24
24
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
25
|
+
var __objRest = (source, exclude) => {
|
|
26
|
+
var target = {};
|
|
27
|
+
for (var prop in source)
|
|
28
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
29
|
+
target[prop] = source[prop];
|
|
30
|
+
if (source != null && __getOwnPropSymbols)
|
|
31
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
32
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
33
|
+
target[prop] = source[prop];
|
|
34
|
+
}
|
|
35
|
+
return target;
|
|
36
|
+
};
|
|
25
37
|
var __export = (target, all) => {
|
|
26
38
|
for (var name in all)
|
|
27
39
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -59,15 +71,15 @@ __export(index_exports, {
|
|
|
59
71
|
module.exports = __toCommonJS(index_exports);
|
|
60
72
|
|
|
61
73
|
// src/components/ChatWidget.tsx
|
|
62
|
-
var
|
|
74
|
+
var import_react9 = __toESM(require("react"));
|
|
63
75
|
var import_lucide_react6 = require("lucide-react");
|
|
64
76
|
|
|
65
77
|
// src/components/ChatWindow.tsx
|
|
66
|
-
var
|
|
78
|
+
var import_react8 = __toESM(require("react"));
|
|
67
79
|
var import_lucide_react5 = require("lucide-react");
|
|
68
80
|
|
|
69
81
|
// src/components/MessageBubble.tsx
|
|
70
|
-
var
|
|
82
|
+
var import_react5 = __toESM(require("react"));
|
|
71
83
|
var import_lucide_react4 = require("lucide-react");
|
|
72
84
|
var import_react_markdown = __toESM(require("react-markdown"));
|
|
73
85
|
var import_remark_gfm = __toESM(require("remark-gfm"));
|
|
@@ -204,6 +216,71 @@ function ProductCarousel({ products, primaryColor = "#6366f1", onAddToCart }) {
|
|
|
204
216
|
));
|
|
205
217
|
}
|
|
206
218
|
|
|
219
|
+
// src/components/DynamicChart.tsx
|
|
220
|
+
var import_react4 = __toESM(require("react"));
|
|
221
|
+
var import_recharts = require("recharts");
|
|
222
|
+
var DEFAULT_COLORS = ["#6366f1", "#10b981", "#f59e0b", "#ef4444", "#8b5cf6", "#ec4899"];
|
|
223
|
+
function DynamicChart({ config, primaryColor = "#6366f1", accentColor = "#8b5cf6" }) {
|
|
224
|
+
const { type, data, xAxisKey = "name", dataKeys = [] } = config;
|
|
225
|
+
const colors = config.colors || [primaryColor, accentColor, ...DEFAULT_COLORS];
|
|
226
|
+
if (!data || data.length === 0) {
|
|
227
|
+
return /* @__PURE__ */ import_react4.default.createElement("div", { className: "p-4 text-sm text-slate-500" }, "No data available for chart.");
|
|
228
|
+
}
|
|
229
|
+
if (type === "pie") {
|
|
230
|
+
const pieDataKey = dataKeys[0] || Object.keys(data[0]).find((k) => k !== xAxisKey) || "value";
|
|
231
|
+
return /* @__PURE__ */ import_react4.default.createElement("div", { className: "w-full h-64 mt-4 mb-2 select-none" }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.ResponsiveContainer, { width: "100%", height: "100%" }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.PieChart, null, /* @__PURE__ */ import_react4.default.createElement(
|
|
232
|
+
import_recharts.Pie,
|
|
233
|
+
{
|
|
234
|
+
data,
|
|
235
|
+
dataKey: pieDataKey,
|
|
236
|
+
nameKey: xAxisKey,
|
|
237
|
+
cx: "50%",
|
|
238
|
+
cy: "50%",
|
|
239
|
+
outerRadius: 80,
|
|
240
|
+
label: ({ name, percent }) => `${name} ${((percent != null ? percent : 0) * 100).toFixed(0)}%`
|
|
241
|
+
},
|
|
242
|
+
data.map((entry, index) => /* @__PURE__ */ import_react4.default.createElement(import_recharts.Cell, { key: `cell-${index}`, fill: colors[index % colors.length] }))
|
|
243
|
+
), /* @__PURE__ */ import_react4.default.createElement(
|
|
244
|
+
import_recharts.Tooltip,
|
|
245
|
+
{
|
|
246
|
+
contentStyle: { borderRadius: "8px", border: "none", boxShadow: "0 4px 6px -1px rgb(0 0 0 / 0.1)" }
|
|
247
|
+
}
|
|
248
|
+
), /* @__PURE__ */ import_react4.default.createElement(import_recharts.Legend, null))));
|
|
249
|
+
}
|
|
250
|
+
return /* @__PURE__ */ import_react4.default.createElement("div", { className: "w-full h-64 mt-4 mb-2 select-none" }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.ResponsiveContainer, { width: "100%", height: "100%" }, type === "bar" ? /* @__PURE__ */ import_react4.default.createElement(import_recharts.BarChart, { data, margin: { top: 10, right: 10, left: -20, bottom: 0 } }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ import_react4.default.createElement(import_recharts.XAxis, { dataKey: xAxisKey, tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: { stroke: "#cbd5e1" } }), /* @__PURE__ */ import_react4.default.createElement(import_recharts.YAxis, { tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: false }), /* @__PURE__ */ import_react4.default.createElement(
|
|
251
|
+
import_recharts.Tooltip,
|
|
252
|
+
{
|
|
253
|
+
contentStyle: { borderRadius: "8px", border: "none", boxShadow: "0 4px 6px -1px rgb(0 0 0 / 0.1)" },
|
|
254
|
+
cursor: { fill: "#f1f5f9" }
|
|
255
|
+
}
|
|
256
|
+
), /* @__PURE__ */ import_react4.default.createElement(import_recharts.Legend, { wrapperStyle: { fontSize: 12 } }), dataKeys.map((key, index) => /* @__PURE__ */ import_react4.default.createElement(
|
|
257
|
+
import_recharts.Bar,
|
|
258
|
+
{
|
|
259
|
+
key,
|
|
260
|
+
dataKey: key,
|
|
261
|
+
fill: colors[index % colors.length],
|
|
262
|
+
radius: [4, 4, 0, 0],
|
|
263
|
+
barSize: Math.max(20, 60 / data.length)
|
|
264
|
+
}
|
|
265
|
+
))) : /* @__PURE__ */ import_react4.default.createElement(import_recharts.LineChart, { data, margin: { top: 10, right: 10, left: -20, bottom: 0 } }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ import_react4.default.createElement(import_recharts.XAxis, { dataKey: xAxisKey, tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: { stroke: "#cbd5e1" } }), /* @__PURE__ */ import_react4.default.createElement(import_recharts.YAxis, { tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: false }), /* @__PURE__ */ import_react4.default.createElement(
|
|
266
|
+
import_recharts.Tooltip,
|
|
267
|
+
{
|
|
268
|
+
contentStyle: { borderRadius: "8px", border: "none", boxShadow: "0 4px 6px -1px rgb(0 0 0 / 0.1)" }
|
|
269
|
+
}
|
|
270
|
+
), /* @__PURE__ */ import_react4.default.createElement(import_recharts.Legend, { wrapperStyle: { fontSize: 12 } }), dataKeys.map((key, index) => /* @__PURE__ */ import_react4.default.createElement(
|
|
271
|
+
import_recharts.Line,
|
|
272
|
+
{
|
|
273
|
+
key,
|
|
274
|
+
type: "monotone",
|
|
275
|
+
dataKey: key,
|
|
276
|
+
stroke: colors[index % colors.length],
|
|
277
|
+
strokeWidth: 3,
|
|
278
|
+
dot: { r: 4, strokeWidth: 2 },
|
|
279
|
+
activeDot: { r: 6 }
|
|
280
|
+
}
|
|
281
|
+
)))));
|
|
282
|
+
}
|
|
283
|
+
|
|
207
284
|
// src/components/MessageBubble.tsx
|
|
208
285
|
function MessageBubble({
|
|
209
286
|
message,
|
|
@@ -214,7 +291,7 @@ function MessageBubble({
|
|
|
214
291
|
onAddToCart
|
|
215
292
|
}) {
|
|
216
293
|
const isUser = message.role === "user";
|
|
217
|
-
const [showSources, setShowSources] =
|
|
294
|
+
const [showSources, setShowSources] = import_react5.default.useState(false);
|
|
218
295
|
const resolveImage = (data) => {
|
|
219
296
|
if (!data) return void 0;
|
|
220
297
|
const singleFields = ["image", "img", "thumbnail"];
|
|
@@ -227,7 +304,7 @@ function MessageBubble({
|
|
|
227
304
|
}
|
|
228
305
|
return void 0;
|
|
229
306
|
};
|
|
230
|
-
const productsFromSources =
|
|
307
|
+
const productsFromSources = import_react5.default.useMemo(() => {
|
|
231
308
|
if (isUser || !sources) return [];
|
|
232
309
|
return sources.filter((s) => {
|
|
233
310
|
const m = s.metadata || {};
|
|
@@ -245,7 +322,7 @@ function MessageBubble({
|
|
|
245
322
|
};
|
|
246
323
|
});
|
|
247
324
|
}, [sources, isUser]);
|
|
248
|
-
const { productsFromContent, cleanContent } =
|
|
325
|
+
const { productsFromContent, cleanContent } = import_react5.default.useMemo(() => {
|
|
249
326
|
if (isUser) return { productsFromContent: [], cleanContent: message.content };
|
|
250
327
|
const jsonRegex = /```json\s*([\s\S]*?)\s*```/g;
|
|
251
328
|
const products = [];
|
|
@@ -268,7 +345,7 @@ function MessageBubble({
|
|
|
268
345
|
}
|
|
269
346
|
return { productsFromContent: products, cleanContent: content.trim() };
|
|
270
347
|
}, [message.content, isUser]);
|
|
271
|
-
const allProducts =
|
|
348
|
+
const allProducts = import_react5.default.useMemo(() => {
|
|
272
349
|
if (productsFromContent.length > 0) return productsFromContent;
|
|
273
350
|
const uniqueProducts = [];
|
|
274
351
|
const seenIds = /* @__PURE__ */ new Set();
|
|
@@ -286,43 +363,90 @@ function MessageBubble({
|
|
|
286
363
|
return uniqueProducts;
|
|
287
364
|
}, [productsFromSources, productsFromContent, message.content]);
|
|
288
365
|
const hasProducts = allProducts.length > 0;
|
|
289
|
-
return /* @__PURE__ */
|
|
366
|
+
return /* @__PURE__ */ import_react5.default.createElement("div", { className: `flex gap-3 ${isUser ? "flex-row-reverse" : "flex-row"} items-start` }, /* @__PURE__ */ import_react5.default.createElement(
|
|
290
367
|
"div",
|
|
291
368
|
{
|
|
292
369
|
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"}`,
|
|
293
370
|
style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
|
|
294
371
|
},
|
|
295
|
-
isUser ? /* @__PURE__ */
|
|
296
|
-
), /* @__PURE__ */
|
|
372
|
+
isUser ? /* @__PURE__ */ import_react5.default.createElement(import_lucide_react4.User, { className: "w-4 h-4 text-white" }) : /* @__PURE__ */ import_react5.default.createElement(import_lucide_react4.Bot, { className: "w-4 h-4" })
|
|
373
|
+
), /* @__PURE__ */ import_react5.default.createElement("div", { className: `flex flex-col gap-1 max-w-[90%] ${isUser ? "items-end" : "items-start"}` }, /* @__PURE__ */ import_react5.default.createElement(
|
|
297
374
|
"div",
|
|
298
375
|
{
|
|
299
376
|
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"}`,
|
|
300
377
|
style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
|
|
301
378
|
},
|
|
302
|
-
isStreaming && !message.content ? /* @__PURE__ */
|
|
303
|
-
|
|
379
|
+
isStreaming && !message.content ? /* @__PURE__ */ import_react5.default.createElement("span", { className: "flex items-center gap-1 py-1" }, /* @__PURE__ */ import_react5.default.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:0ms]" }), /* @__PURE__ */ import_react5.default.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:150ms]" }), /* @__PURE__ */ import_react5.default.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:300ms]" })) : /* @__PURE__ */ import_react5.default.createElement("div", { className: `prose prose-sm max-w-none ${isUser ? "prose-invert" : "dark:prose-invert"}` }, /* @__PURE__ */ import_react5.default.createElement(
|
|
380
|
+
import_react_markdown.default,
|
|
381
|
+
{
|
|
382
|
+
remarkPlugins: [import_remark_gfm.default],
|
|
383
|
+
components: {
|
|
384
|
+
table: (_a) => {
|
|
385
|
+
var props = __objRest(_a, []);
|
|
386
|
+
return /* @__PURE__ */ import_react5.default.createElement("div", { className: "overflow-x-auto my-4 rounded-xl border border-slate-200 dark:border-white/10 shadow-sm" }, /* @__PURE__ */ import_react5.default.createElement("table", __spreadValues({ className: "w-full text-left border-collapse min-w-[400px]" }, props)));
|
|
387
|
+
},
|
|
388
|
+
thead: (_b) => {
|
|
389
|
+
var props = __objRest(_b, []);
|
|
390
|
+
return /* @__PURE__ */ import_react5.default.createElement("thead", __spreadValues({ className: "bg-slate-50 dark:bg-white/5 border-b border-slate-200 dark:border-white/10" }, props));
|
|
391
|
+
},
|
|
392
|
+
th: (_c) => {
|
|
393
|
+
var props = __objRest(_c, []);
|
|
394
|
+
return /* @__PURE__ */ import_react5.default.createElement("th", __spreadValues({ className: "p-3 font-semibold text-slate-700 dark:text-white/90 first:rounded-tl-xl last:rounded-tr-xl" }, props));
|
|
395
|
+
},
|
|
396
|
+
td: (_d) => {
|
|
397
|
+
var props = __objRest(_d, []);
|
|
398
|
+
return /* @__PURE__ */ import_react5.default.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));
|
|
399
|
+
},
|
|
400
|
+
code(_e) {
|
|
401
|
+
var _f = _e, { inline, className, children } = _f, props = __objRest(_f, ["inline", "className", "children"]);
|
|
402
|
+
const match = /language-(\w+)/.exec(className || "");
|
|
403
|
+
const isChart = match && match[1] === "chart";
|
|
404
|
+
if (!inline && isChart) {
|
|
405
|
+
const rawContent = String(children).trim();
|
|
406
|
+
try {
|
|
407
|
+
const config = JSON.parse(rawContent);
|
|
408
|
+
return /* @__PURE__ */ import_react5.default.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__ */ import_react5.default.createElement(
|
|
409
|
+
DynamicChart,
|
|
410
|
+
{
|
|
411
|
+
config,
|
|
412
|
+
primaryColor,
|
|
413
|
+
accentColor
|
|
414
|
+
}
|
|
415
|
+
));
|
|
416
|
+
} catch (err) {
|
|
417
|
+
console.error("[MessageBubble] Chart parsing failed:", err, "\nRaw content:", rawContent);
|
|
418
|
+
return /* @__PURE__ */ import_react5.default.createElement("div", { className: "p-4 bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 rounded-lg text-sm border border-red-100 dark:border-red-900/30" }, /* @__PURE__ */ import_react5.default.createElement("p", { className: "font-medium mb-1" }, "Failed to render chart"), /* @__PURE__ */ import_react5.default.createElement("p", { className: "opacity-70 text-xs" }, "The generated configuration is invalid. Check console for details."));
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return /* @__PURE__ */ import_react5.default.createElement("code", __spreadValues({ className }, props), children);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
},
|
|
425
|
+
cleanContent || message.content
|
|
426
|
+
), isStreaming && message.content && /* @__PURE__ */ import_react5.default.createElement("span", { className: "inline-block w-1.5 h-3.5 ml-1 bg-emerald-500 animate-pulse align-middle" }))
|
|
427
|
+
), !isUser && hasProducts && /* @__PURE__ */ import_react5.default.createElement("div", { className: "w-full mt-1" }, /* @__PURE__ */ import_react5.default.createElement(
|
|
304
428
|
ProductCarousel,
|
|
305
429
|
{
|
|
306
430
|
products: allProducts,
|
|
307
431
|
primaryColor,
|
|
308
432
|
onAddToCart
|
|
309
433
|
}
|
|
310
|
-
)), !isUser && sources && sources.length > 0 && /* @__PURE__ */
|
|
434
|
+
)), !isUser && sources && sources.length > 0 && /* @__PURE__ */ import_react5.default.createElement("div", { className: "w-full" }, /* @__PURE__ */ import_react5.default.createElement(
|
|
311
435
|
"button",
|
|
312
436
|
{
|
|
313
437
|
onClick: () => setShowSources((s) => !s),
|
|
314
438
|
className: "text-[11px] text-indigo-400 hover:text-indigo-300 transition-colors flex items-center gap-1 mt-1"
|
|
315
439
|
},
|
|
316
|
-
showSources ? /* @__PURE__ */
|
|
440
|
+
showSources ? /* @__PURE__ */ import_react5.default.createElement(import_lucide_react4.ChevronDown, { className: "w-3 h-3" }) : /* @__PURE__ */ import_react5.default.createElement(import_lucide_react4.ChevronRight, { className: "w-3 h-3" }),
|
|
317
441
|
sources.length,
|
|
318
442
|
" source",
|
|
319
443
|
sources.length !== 1 ? "s" : "",
|
|
320
444
|
" used"
|
|
321
|
-
), showSources && /* @__PURE__ */
|
|
445
|
+
), showSources && /* @__PURE__ */ import_react5.default.createElement("div", { className: "mt-2 flex flex-col gap-2" }, sources.map((src, i) => /* @__PURE__ */ import_react5.default.createElement(SourceCard, { key: src.id, source: src, index: i }))))));
|
|
322
446
|
}
|
|
323
447
|
|
|
324
448
|
// src/components/ConfigProvider.tsx
|
|
325
|
-
var
|
|
449
|
+
var import_react6 = __toESM(require("react"));
|
|
326
450
|
|
|
327
451
|
// src/utils/templateUtils.ts
|
|
328
452
|
function mergeDefined(base, override) {
|
|
@@ -374,7 +498,7 @@ var CHAT_SUGGESTIONS = [
|
|
|
374
498
|
];
|
|
375
499
|
|
|
376
500
|
// src/components/ConfigProvider.tsx
|
|
377
|
-
var ConfigContext = (0,
|
|
501
|
+
var ConfigContext = (0, import_react6.createContext)(DEFAULT_CONFIG);
|
|
378
502
|
function ConfigProvider({
|
|
379
503
|
config,
|
|
380
504
|
children
|
|
@@ -383,17 +507,17 @@ function ConfigProvider({
|
|
|
383
507
|
projectId: (config == null ? void 0 : config.projectId) || DEFAULT_CONFIG.projectId,
|
|
384
508
|
ui: mergeDefined(DEFAULT_CONFIG.ui, config == null ? void 0 : config.ui)
|
|
385
509
|
};
|
|
386
|
-
return /* @__PURE__ */
|
|
510
|
+
return /* @__PURE__ */ import_react6.default.createElement(ConfigContext.Provider, { value: merged }, children);
|
|
387
511
|
}
|
|
388
512
|
function useConfig() {
|
|
389
|
-
return (0,
|
|
513
|
+
return (0, import_react6.useContext)(ConfigContext);
|
|
390
514
|
}
|
|
391
515
|
|
|
392
516
|
// src/hooks/useRagChat.ts
|
|
393
|
-
var
|
|
517
|
+
var import_react7 = require("react");
|
|
394
518
|
|
|
395
519
|
// src/hooks/useStoredMessages.ts
|
|
396
|
-
var
|
|
520
|
+
var React7 = __toESM(require("react"));
|
|
397
521
|
function readStoredMessages(storageKey) {
|
|
398
522
|
if (typeof window === "undefined") {
|
|
399
523
|
return [];
|
|
@@ -410,8 +534,8 @@ function readStoredMessages(storageKey) {
|
|
|
410
534
|
}
|
|
411
535
|
}
|
|
412
536
|
function useStoredMessages(storageKey, persist) {
|
|
413
|
-
const [messages, setMessages] =
|
|
414
|
-
|
|
537
|
+
const [messages, setMessages] = React7.useState(() => persist ? readStoredMessages(storageKey) : []);
|
|
538
|
+
React7.useEffect(() => {
|
|
415
539
|
if (!persist || typeof window === "undefined") {
|
|
416
540
|
return;
|
|
417
541
|
}
|
|
@@ -451,14 +575,14 @@ function useRagChat(projectId, options = {}) {
|
|
|
451
575
|
} = options;
|
|
452
576
|
const storageKey = `rag_chat_${projectId}`;
|
|
453
577
|
const [messages, setMessages] = useStoredMessages(storageKey, persist);
|
|
454
|
-
const [isLoading, setIsLoading] = (0,
|
|
455
|
-
const [error, setError] = (0,
|
|
456
|
-
const lastInputRef = (0,
|
|
457
|
-
const messagesRef = (0,
|
|
458
|
-
(0,
|
|
578
|
+
const [isLoading, setIsLoading] = (0, import_react7.useState)(false);
|
|
579
|
+
const [error, setError] = (0, import_react7.useState)(null);
|
|
580
|
+
const lastInputRef = (0, import_react7.useRef)("");
|
|
581
|
+
const messagesRef = (0, import_react7.useRef)(messages);
|
|
582
|
+
(0, import_react7.useEffect)(() => {
|
|
459
583
|
messagesRef.current = messages;
|
|
460
584
|
}, [messages]);
|
|
461
|
-
const sendMessage = (0,
|
|
585
|
+
const sendMessage = (0, import_react7.useCallback)(
|
|
462
586
|
async (text, opts) => {
|
|
463
587
|
var _a, _b;
|
|
464
588
|
const trimmed = text.trim();
|
|
@@ -555,12 +679,12 @@ function useRagChat(projectId, options = {}) {
|
|
|
555
679
|
},
|
|
556
680
|
[apiUrl, isLoading, namespace, onError, onReply, projectId, setMessages]
|
|
557
681
|
);
|
|
558
|
-
const clear = (0,
|
|
682
|
+
const clear = (0, import_react7.useCallback)(() => {
|
|
559
683
|
setMessages([]);
|
|
560
684
|
setError(null);
|
|
561
685
|
if (persist) localStorage.removeItem(storageKey);
|
|
562
686
|
}, [persist, setMessages, storageKey]);
|
|
563
|
-
const retry = (0,
|
|
687
|
+
const retry = (0, import_react7.useCallback)(async () => {
|
|
564
688
|
if (lastInputRef.current) {
|
|
565
689
|
const latestMessage = messagesRef.current[messagesRef.current.length - 1];
|
|
566
690
|
await sendMessage(lastInputRef.current, {
|
|
@@ -594,18 +718,18 @@ function ChatWindow({
|
|
|
594
718
|
}) {
|
|
595
719
|
var _a;
|
|
596
720
|
const { ui, projectId } = useConfig();
|
|
597
|
-
const [input, setInput] = (0,
|
|
598
|
-
const [mounted, setMounted] = (0,
|
|
599
|
-
const bottomRef = (0,
|
|
600
|
-
const inputRef = (0,
|
|
721
|
+
const [input, setInput] = (0, import_react8.useState)("");
|
|
722
|
+
const [mounted, setMounted] = (0, import_react8.useState)(false);
|
|
723
|
+
const bottomRef = (0, import_react8.useRef)(null);
|
|
724
|
+
const inputRef = (0, import_react8.useRef)(null);
|
|
601
725
|
const { messages, send, clear, isLoading, error } = useRagChat(projectId, {
|
|
602
726
|
namespace: projectId
|
|
603
727
|
});
|
|
604
|
-
const [suggestions, setSuggestions] = (0,
|
|
605
|
-
const [isSuggesting, setIsSuggesting] = (0,
|
|
606
|
-
const [isListening, setIsListening] = (0,
|
|
607
|
-
const recognitionRef = (0,
|
|
608
|
-
(0,
|
|
728
|
+
const [suggestions, setSuggestions] = (0, import_react8.useState)([]);
|
|
729
|
+
const [isSuggesting, setIsSuggesting] = (0, import_react8.useState)(false);
|
|
730
|
+
const [isListening, setIsListening] = (0, import_react8.useState)(false);
|
|
731
|
+
const recognitionRef = (0, import_react8.useRef)(null);
|
|
732
|
+
(0, import_react8.useEffect)(() => {
|
|
609
733
|
if (typeof window !== "undefined") {
|
|
610
734
|
const win = window;
|
|
611
735
|
const SpeechRecognition = win.SpeechRecognition || win.webkitSpeechRecognition;
|
|
@@ -651,16 +775,16 @@ function ChatWindow({
|
|
|
651
775
|
}
|
|
652
776
|
}
|
|
653
777
|
};
|
|
654
|
-
(0,
|
|
778
|
+
(0, import_react8.useEffect)(() => {
|
|
655
779
|
setMounted(true);
|
|
656
780
|
}, []);
|
|
657
|
-
(0,
|
|
781
|
+
(0, import_react8.useEffect)(() => {
|
|
658
782
|
var _a2;
|
|
659
783
|
if (messages.length > 0 || isLoading) {
|
|
660
784
|
(_a2 = bottomRef.current) == null ? void 0 : _a2.scrollIntoView({ behavior: "smooth" });
|
|
661
785
|
}
|
|
662
786
|
}, [messages, isLoading]);
|
|
663
|
-
const sendMessage = (0,
|
|
787
|
+
const sendMessage = (0, import_react8.useCallback)(async () => {
|
|
664
788
|
var _a2;
|
|
665
789
|
const text = input.trim();
|
|
666
790
|
if (!text || isLoading) return;
|
|
@@ -690,7 +814,7 @@ function ChatWindow({
|
|
|
690
814
|
const isEmpty = messages.length === 0;
|
|
691
815
|
const currentRadius = BORDER_RADIUS_MAP[ui.borderRadius || "xl"];
|
|
692
816
|
const isGlass = ui.visualStyle !== "solid";
|
|
693
|
-
(0,
|
|
817
|
+
(0, import_react8.useEffect)(() => {
|
|
694
818
|
if (input.trim().length < 3) {
|
|
695
819
|
return;
|
|
696
820
|
}
|
|
@@ -714,83 +838,83 @@ function ChatWindow({
|
|
|
714
838
|
}, 800);
|
|
715
839
|
return () => clearTimeout(timer);
|
|
716
840
|
}, [input, projectId]);
|
|
717
|
-
return /* @__PURE__ */
|
|
841
|
+
return /* @__PURE__ */ import_react8.default.createElement(
|
|
718
842
|
"div",
|
|
719
843
|
{
|
|
720
844
|
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}`,
|
|
721
845
|
style: __spreadValues({ "--primary": ui.primaryColor, "--accent": ui.accentColor }, style)
|
|
722
846
|
},
|
|
723
|
-
onResizeStart && /* @__PURE__ */
|
|
847
|
+
onResizeStart && /* @__PURE__ */ import_react8.default.createElement(
|
|
724
848
|
"div",
|
|
725
849
|
{
|
|
726
850
|
onMouseDown: onResizeStart,
|
|
727
851
|
className: "absolute top-0 left-0 w-6 h-6 cursor-nw-resize z-[100] group flex items-start justify-start p-1",
|
|
728
852
|
title: "Drag to resize"
|
|
729
853
|
},
|
|
730
|
-
/* @__PURE__ */
|
|
854
|
+
/* @__PURE__ */ import_react8.default.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]" })
|
|
731
855
|
),
|
|
732
|
-
/* @__PURE__ */
|
|
856
|
+
/* @__PURE__ */ import_react8.default.createElement(
|
|
733
857
|
"div",
|
|
734
858
|
{
|
|
735
859
|
className: "flex items-center justify-between px-5 py-4 border-b border-slate-200 dark:border-white/10",
|
|
736
860
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}15, ${ui.accentColor}10)` }
|
|
737
861
|
},
|
|
738
|
-
/* @__PURE__ */
|
|
862
|
+
/* @__PURE__ */ import_react8.default.createElement("div", { className: "flex items-center gap-3" }, ui.logoUrl ? (
|
|
739
863
|
// eslint-disable-next-line @next/next/no-img-element
|
|
740
|
-
/* @__PURE__ */
|
|
741
|
-
) : /* @__PURE__ */
|
|
864
|
+
/* @__PURE__ */ import_react8.default.createElement("img", { src: ui.logoUrl, alt: "logo", className: "w-8 h-8 rounded-lg object-cover" })
|
|
865
|
+
) : /* @__PURE__ */ import_react8.default.createElement(
|
|
742
866
|
"div",
|
|
743
867
|
{
|
|
744
868
|
className: `w-9 h-9 flex items-center justify-center shadow-md ${ui.borderRadius === "full" ? "rounded-full" : "rounded-xl"}`,
|
|
745
869
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
|
|
746
870
|
},
|
|
747
|
-
/* @__PURE__ */
|
|
748
|
-
), /* @__PURE__ */
|
|
749
|
-
/* @__PURE__ */
|
|
871
|
+
/* @__PURE__ */ import_react8.default.createElement(import_lucide_react5.Bot, { className: "w-5 h-5 text-white" })
|
|
872
|
+
), /* @__PURE__ */ import_react8.default.createElement("div", null, /* @__PURE__ */ import_react8.default.createElement("h2", { className: "text-slate-900 dark:text-white font-semibold text-sm leading-tight" }, ui.title), ui.poweredBy && /* @__PURE__ */ import_react8.default.createElement("p", { className: "text-slate-500 dark:text-white/40 text-[11px] leading-tight" }, `Powered by ${ui.poweredBy}`))),
|
|
873
|
+
/* @__PURE__ */ import_react8.default.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ import_react8.default.createElement("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400 mr-2" }, /* @__PURE__ */ import_react8.default.createElement("span", { className: "w-1.5 h-1.5 rounded-full bg-emerald-500 dark:bg-emerald-400 animate-pulse" }), "Online"), /* @__PURE__ */ import_react8.default.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__ */ import_react8.default.createElement(
|
|
750
874
|
"button",
|
|
751
875
|
{
|
|
752
876
|
onClick: clearHistory,
|
|
753
877
|
title: "Clear conversation",
|
|
754
878
|
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"
|
|
755
879
|
},
|
|
756
|
-
/* @__PURE__ */
|
|
757
|
-
), isResized && onResetResize && /* @__PURE__ */
|
|
880
|
+
/* @__PURE__ */ import_react8.default.createElement(import_lucide_react5.Trash2, { className: "w-3.5 h-3.5" })
|
|
881
|
+
), isResized && onResetResize && /* @__PURE__ */ import_react8.default.createElement(
|
|
758
882
|
"button",
|
|
759
883
|
{
|
|
760
884
|
onClick: onResetResize,
|
|
761
885
|
title: "Reset to default size",
|
|
762
886
|
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"
|
|
763
887
|
},
|
|
764
|
-
/* @__PURE__ */
|
|
765
|
-
), onMaximize && /* @__PURE__ */
|
|
888
|
+
/* @__PURE__ */ import_react8.default.createElement(import_lucide_react5.RotateCcw, { className: "w-3.5 h-3.5" })
|
|
889
|
+
), onMaximize && /* @__PURE__ */ import_react8.default.createElement(
|
|
766
890
|
"button",
|
|
767
891
|
{
|
|
768
892
|
onClick: onMaximize,
|
|
769
893
|
title: isMaximized ? "Minimize" : "Maximize",
|
|
770
894
|
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"
|
|
771
895
|
},
|
|
772
|
-
isMaximized ? /* @__PURE__ */
|
|
773
|
-
), showClose && onClose && /* @__PURE__ */
|
|
896
|
+
isMaximized ? /* @__PURE__ */ import_react8.default.createElement(import_lucide_react5.Minimize2, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ import_react8.default.createElement(import_lucide_react5.Maximize2, { className: "w-3.5 h-3.5" })
|
|
897
|
+
), showClose && onClose && /* @__PURE__ */ import_react8.default.createElement(
|
|
774
898
|
"button",
|
|
775
899
|
{
|
|
776
900
|
onClick: onClose,
|
|
777
901
|
title: "Close chat",
|
|
778
902
|
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"
|
|
779
903
|
},
|
|
780
|
-
/* @__PURE__ */
|
|
904
|
+
/* @__PURE__ */ import_react8.default.createElement(import_lucide_react5.X, { className: "w-4 h-4" })
|
|
781
905
|
)))
|
|
782
906
|
),
|
|
783
|
-
/* @__PURE__ */
|
|
907
|
+
/* @__PURE__ */ import_react8.default.createElement("div", { className: "flex-1 overflow-y-auto px-4 py-4 space-y-5 scrollbar-thin scrollbar-thumb-slate-200 dark:scrollbar-thumb-white/10 scrollbar-track-transparent min-h-0 bg-slate-50 dark:bg-transparent" }, !mounted || isEmpty ? (
|
|
784
908
|
/* Welcome state */
|
|
785
|
-
/* @__PURE__ */
|
|
909
|
+
/* @__PURE__ */ import_react8.default.createElement("div", { className: "h-full flex flex-col items-center justify-center text-center gap-4 px-6 py-12" }, /* @__PURE__ */ import_react8.default.createElement(
|
|
786
910
|
"div",
|
|
787
911
|
{
|
|
788
912
|
className: `w-16 h-16 flex items-center justify-center shadow-lg ${ui.borderRadius === "full" ? "rounded-full" : "rounded-2xl"}`,
|
|
789
913
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` }
|
|
790
914
|
},
|
|
791
|
-
/* @__PURE__ */
|
|
792
|
-
), /* @__PURE__ */
|
|
793
|
-
(suggestion) => /* @__PURE__ */
|
|
915
|
+
/* @__PURE__ */ import_react8.default.createElement(import_lucide_react5.Sparkles, { className: "w-8 h-8 text-white" })
|
|
916
|
+
), /* @__PURE__ */ import_react8.default.createElement("div", null, /* @__PURE__ */ import_react8.default.createElement("p", { className: "text-slate-800 dark:text-white/80 font-medium leading-relaxed" }, ui.welcomeMessage), /* @__PURE__ */ import_react8.default.createElement("p", { className: "text-slate-500 dark:text-white/30 text-sm mt-2" }, "Ask a question to get started")), /* @__PURE__ */ import_react8.default.createElement("div", { className: "flex flex-wrap gap-2 justify-center mt-2" }, CHAT_SUGGESTIONS.map(
|
|
917
|
+
(suggestion) => /* @__PURE__ */ import_react8.default.createElement(
|
|
794
918
|
"button",
|
|
795
919
|
{
|
|
796
920
|
key: suggestion,
|
|
@@ -804,7 +928,7 @@ function ChatWindow({
|
|
|
804
928
|
suggestion
|
|
805
929
|
)
|
|
806
930
|
)))
|
|
807
|
-
) : messages.map((msg, index) => /* @__PURE__ */
|
|
931
|
+
) : messages.map((msg, index) => /* @__PURE__ */ import_react8.default.createElement(
|
|
808
932
|
MessageBubble,
|
|
809
933
|
{
|
|
810
934
|
key: msg.id,
|
|
@@ -815,7 +939,7 @@ function ChatWindow({
|
|
|
815
939
|
accentColor: ui.accentColor,
|
|
816
940
|
onAddToCart
|
|
817
941
|
}
|
|
818
|
-
)), isLoading && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) !== "assistant" && /* @__PURE__ */
|
|
942
|
+
)), isLoading && ((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) !== "assistant" && /* @__PURE__ */ import_react8.default.createElement(
|
|
819
943
|
MessageBubble,
|
|
820
944
|
{
|
|
821
945
|
message: { id: "loading", role: "assistant", content: "", createdAt: (/* @__PURE__ */ new Date()).toISOString() },
|
|
@@ -824,8 +948,8 @@ function ChatWindow({
|
|
|
824
948
|
accentColor: ui.accentColor,
|
|
825
949
|
onAddToCart
|
|
826
950
|
}
|
|
827
|
-
), error && /* @__PURE__ */
|
|
828
|
-
/* @__PURE__ */
|
|
951
|
+
), error && /* @__PURE__ */ import_react8.default.createElement("div", { className: "flex items-center gap-2 text-rose-500 dark:text-rose-400 text-sm bg-rose-50 dark:bg-rose-400/10 border border-rose-200 dark:border-rose-400/20 rounded-xl px-4 py-3" }, /* @__PURE__ */ import_react8.default.createElement(import_lucide_react5.TriangleAlert, { className: "w-4 h-4 flex-shrink-0" }), /* @__PURE__ */ import_react8.default.createElement("span", null, error)), /* @__PURE__ */ import_react8.default.createElement("div", { ref: bottomRef })),
|
|
952
|
+
/* @__PURE__ */ import_react8.default.createElement("div", { className: `px-4 pb-4 pt-2 border-t border-slate-200 dark:border-white/10 ${isGlass ? "bg-transparent" : "bg-white dark:bg-[#0f0f1a]"}` }, (suggestions.length > 0 || isSuggesting) && !isLoading && /* @__PURE__ */ import_react8.default.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__ */ import_react8.default.createElement(
|
|
829
953
|
"button",
|
|
830
954
|
{
|
|
831
955
|
key: suggestion,
|
|
@@ -837,9 +961,9 @@ function ChatWindow({
|
|
|
837
961
|
},
|
|
838
962
|
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"
|
|
839
963
|
},
|
|
840
|
-
/* @__PURE__ */
|
|
964
|
+
/* @__PURE__ */ import_react8.default.createElement(import_lucide_react5.Sparkles, { className: "w-3 h-3 text-amber-400" }),
|
|
841
965
|
suggestion
|
|
842
|
-
)), isSuggesting && suggestions.length === 0 && /* @__PURE__ */
|
|
966
|
+
)), isSuggesting && suggestions.length === 0 && /* @__PURE__ */ import_react8.default.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__ */ import_react8.default.createElement(import_lucide_react5.Sparkles, { className: "w-3 h-3" }), "Thinking...")), /* @__PURE__ */ import_react8.default.createElement("div", { className: `flex items-end gap-2 bg-slate-50 dark:bg-white/5 border border-slate-200 dark:border-white/10 p-2 focus-within:border-slate-300 dark:focus-within:border-white/20 transition-all ${ui.borderRadius === "full" ? "rounded-3xl" : "rounded-2xl"}` }, /* @__PURE__ */ import_react8.default.createElement(
|
|
843
967
|
"textarea",
|
|
844
968
|
{
|
|
845
969
|
ref: inputRef,
|
|
@@ -858,16 +982,17 @@ function ChatWindow({
|
|
|
858
982
|
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",
|
|
859
983
|
style: { scrollbarWidth: "none" }
|
|
860
984
|
}
|
|
861
|
-
), ui.enableVoiceInput !== false && /* @__PURE__ */
|
|
985
|
+
), ui.enableVoiceInput !== false && /* @__PURE__ */ import_react8.default.createElement(
|
|
862
986
|
"button",
|
|
863
987
|
{
|
|
864
988
|
type: "button",
|
|
865
989
|
onClick: toggleListening,
|
|
866
|
-
|
|
990
|
+
disabled: isLoading,
|
|
991
|
+
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"}`,
|
|
867
992
|
title: isListening ? "Stop listening" : "Start voice input"
|
|
868
993
|
},
|
|
869
|
-
isListening ? /* @__PURE__ */
|
|
870
|
-
), /* @__PURE__ */
|
|
994
|
+
isListening ? /* @__PURE__ */ import_react8.default.createElement(import_lucide_react5.MicOff, { className: "w-4 h-4" }) : /* @__PURE__ */ import_react8.default.createElement(import_lucide_react5.Mic, { className: "w-4 h-4" })
|
|
995
|
+
), /* @__PURE__ */ import_react8.default.createElement(
|
|
871
996
|
"button",
|
|
872
997
|
{
|
|
873
998
|
onClick: sendMessage,
|
|
@@ -878,8 +1003,8 @@ function ChatWindow({
|
|
|
878
1003
|
// slate-400/20 for light mode disabled
|
|
879
1004
|
}
|
|
880
1005
|
},
|
|
881
|
-
/* @__PURE__ */
|
|
882
|
-
)), /* @__PURE__ */
|
|
1006
|
+
/* @__PURE__ */ import_react8.default.createElement(import_lucide_react5.ArrowUp, { className: "w-4 h-4 text-white" })
|
|
1007
|
+
)), /* @__PURE__ */ import_react8.default.createElement("p", { className: "text-center text-[10px] text-slate-400 dark:text-white/20 mt-2" }, "Press Enter to send \xB7 Shift+Enter for new line"))
|
|
883
1008
|
);
|
|
884
1009
|
}
|
|
885
1010
|
|
|
@@ -887,12 +1012,12 @@ function ChatWindow({
|
|
|
887
1012
|
var DEFAULT_DIMENSIONS = { width: 380, height: 600 };
|
|
888
1013
|
function ChatWidget({ position = "bottom-right", onAddToCart }) {
|
|
889
1014
|
const { ui } = useConfig();
|
|
890
|
-
const [isOpen, setIsOpen] = (0,
|
|
891
|
-
const [hasUnread, setHasUnread] = (0,
|
|
892
|
-
const [dimensions, setDimensions] = (0,
|
|
893
|
-
const [isResizing, setIsResizing] = (0,
|
|
894
|
-
const [isMaximized, setIsMaximized] = (0,
|
|
895
|
-
const [prevDimensions, setPrevDimensions] = (0,
|
|
1015
|
+
const [isOpen, setIsOpen] = (0, import_react9.useState)(false);
|
|
1016
|
+
const [hasUnread, setHasUnread] = (0, import_react9.useState)(false);
|
|
1017
|
+
const [dimensions, setDimensions] = (0, import_react9.useState)(DEFAULT_DIMENSIONS);
|
|
1018
|
+
const [isResizing, setIsResizing] = (0, import_react9.useState)(false);
|
|
1019
|
+
const [isMaximized, setIsMaximized] = (0, import_react9.useState)(false);
|
|
1020
|
+
const [prevDimensions, setPrevDimensions] = (0, import_react9.useState)(DEFAULT_DIMENSIONS);
|
|
896
1021
|
if (ui.showWidget === false) return null;
|
|
897
1022
|
const positionClass = position === "bottom-left" ? "bottom-6 left-6" : "bottom-6 right-6";
|
|
898
1023
|
const windowPositionClass = position === "bottom-left" ? "bottom-20 left-6" : "bottom-20 right-6";
|
|
@@ -942,7 +1067,7 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
|
|
|
942
1067
|
}
|
|
943
1068
|
};
|
|
944
1069
|
const isResized = dimensions.width !== DEFAULT_DIMENSIONS.width || dimensions.height !== DEFAULT_DIMENSIONS.height;
|
|
945
|
-
return /* @__PURE__ */
|
|
1070
|
+
return /* @__PURE__ */ import_react9.default.createElement(import_react9.default.Fragment, null, /* @__PURE__ */ import_react9.default.createElement(
|
|
946
1071
|
"div",
|
|
947
1072
|
{
|
|
948
1073
|
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"}`,
|
|
@@ -952,7 +1077,7 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
|
|
|
952
1077
|
maxHeight: "calc(100vh - 6rem)"
|
|
953
1078
|
}
|
|
954
1079
|
},
|
|
955
|
-
/* @__PURE__ */
|
|
1080
|
+
/* @__PURE__ */ import_react9.default.createElement(
|
|
956
1081
|
ChatWindow,
|
|
957
1082
|
{
|
|
958
1083
|
className: "h-full relative z-10",
|
|
@@ -966,13 +1091,13 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
|
|
|
966
1091
|
onAddToCart
|
|
967
1092
|
}
|
|
968
1093
|
),
|
|
969
|
-
/* @__PURE__ */
|
|
1094
|
+
/* @__PURE__ */ import_react9.default.createElement(
|
|
970
1095
|
"div",
|
|
971
1096
|
{
|
|
972
1097
|
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"}`
|
|
973
1098
|
}
|
|
974
1099
|
)
|
|
975
|
-
), /* @__PURE__ */
|
|
1100
|
+
), /* @__PURE__ */ import_react9.default.createElement(
|
|
976
1101
|
"button",
|
|
977
1102
|
{
|
|
978
1103
|
onClick: isOpen ? () => setIsOpen(false) : handleOpen,
|
|
@@ -980,32 +1105,32 @@ function ChatWidget({ position = "bottom-right", onAddToCart }) {
|
|
|
980
1105
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` },
|
|
981
1106
|
"aria-label": "Open chat"
|
|
982
1107
|
},
|
|
983
|
-
/* @__PURE__ */
|
|
1108
|
+
/* @__PURE__ */ import_react9.default.createElement(
|
|
984
1109
|
"span",
|
|
985
1110
|
{
|
|
986
1111
|
className: "absolute inset-0 rounded-full animate-ping opacity-20",
|
|
987
1112
|
style: { background: ui.primaryColor }
|
|
988
1113
|
}
|
|
989
1114
|
),
|
|
990
|
-
/* @__PURE__ */
|
|
1115
|
+
/* @__PURE__ */ import_react9.default.createElement(
|
|
991
1116
|
"span",
|
|
992
1117
|
{
|
|
993
1118
|
className: `transition-transform duration-300 ${isOpen ? "rotate-90 scale-90" : "rotate-0 scale-100"}`
|
|
994
1119
|
},
|
|
995
|
-
isOpen ? /* @__PURE__ */
|
|
1120
|
+
isOpen ? /* @__PURE__ */ import_react9.default.createElement(import_lucide_react6.X, { className: "w-6 h-6 text-white" }) : /* @__PURE__ */ import_react9.default.createElement(import_lucide_react6.MessageSquare, { className: "w-6 h-6 text-white" })
|
|
996
1121
|
),
|
|
997
|
-
hasUnread && !isOpen && /* @__PURE__ */
|
|
1122
|
+
hasUnread && !isOpen && /* @__PURE__ */ import_react9.default.createElement("span", { className: "absolute top-0 right-0 w-4 h-4 bg-rose-500 rounded-full border-2 border-white flex items-center justify-center text-[9px] font-bold text-white" }, "1")
|
|
998
1123
|
));
|
|
999
1124
|
}
|
|
1000
1125
|
|
|
1001
1126
|
// src/components/DocumentUpload.tsx
|
|
1002
|
-
var
|
|
1127
|
+
var import_react10 = __toESM(require("react"));
|
|
1003
1128
|
var import_lucide_react7 = require("lucide-react");
|
|
1004
1129
|
function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
1005
1130
|
const { ui } = useConfig();
|
|
1006
|
-
const [fileStates, setFileStates] = (0,
|
|
1007
|
-
const [isDragging, setIsDragging] = (0,
|
|
1008
|
-
const fileInputRef = (0,
|
|
1131
|
+
const [fileStates, setFileStates] = (0, import_react10.useState)([]);
|
|
1132
|
+
const [isDragging, setIsDragging] = (0, import_react10.useState)(false);
|
|
1133
|
+
const fileInputRef = (0, import_react10.useRef)(null);
|
|
1009
1134
|
const addFiles = (files) => {
|
|
1010
1135
|
const newStates = files.map((file) => ({ file, status: "idle" }));
|
|
1011
1136
|
setFileStates((prev) => [...prev, ...newStates]);
|
|
@@ -1055,7 +1180,7 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
1055
1180
|
};
|
|
1056
1181
|
const isUploading = fileStates.some((s) => s.status === "uploading");
|
|
1057
1182
|
const hasIdle = fileStates.some((s) => s.status === "idle");
|
|
1058
|
-
return /* @__PURE__ */
|
|
1183
|
+
return /* @__PURE__ */ import_react10.default.createElement(
|
|
1059
1184
|
"div",
|
|
1060
1185
|
{
|
|
1061
1186
|
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}`,
|
|
@@ -1063,14 +1188,14 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
1063
1188
|
onDragLeave,
|
|
1064
1189
|
onDrop
|
|
1065
1190
|
},
|
|
1066
|
-
/* @__PURE__ */
|
|
1191
|
+
/* @__PURE__ */ import_react10.default.createElement("div", { className: "flex flex-col items-center justify-center text-center" }, /* @__PURE__ */ import_react10.default.createElement(
|
|
1067
1192
|
"div",
|
|
1068
1193
|
{
|
|
1069
1194
|
className: "w-12 h-12 rounded-full flex items-center justify-center mb-4 shadow-sm",
|
|
1070
1195
|
style: { background: `linear-gradient(135deg, ${ui.primaryColor}20, ${ui.accentColor}20)` }
|
|
1071
1196
|
},
|
|
1072
|
-
/* @__PURE__ */
|
|
1073
|
-
), /* @__PURE__ */
|
|
1197
|
+
/* @__PURE__ */ import_react10.default.createElement(import_lucide_react7.Upload, { className: "w-6 h-6", style: { color: ui.primaryColor } })
|
|
1198
|
+
), /* @__PURE__ */ import_react10.default.createElement("h3", { className: "text-slate-900 dark:text-white font-semibold mb-1" }, "Upload Documents"), /* @__PURE__ */ import_react10.default.createElement("p", { className: "text-slate-500 dark:text-white/40 text-sm mb-6 max-w-xs" }, "Drag and drop PDF, DOCX, TXT, or JSON files to train your AI on your own data."), /* @__PURE__ */ import_react10.default.createElement(
|
|
1074
1199
|
"button",
|
|
1075
1200
|
{
|
|
1076
1201
|
onClick: () => {
|
|
@@ -1086,7 +1211,7 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
1086
1211
|
}
|
|
1087
1212
|
},
|
|
1088
1213
|
"Select Files"
|
|
1089
|
-
), /* @__PURE__ */
|
|
1214
|
+
), /* @__PURE__ */ import_react10.default.createElement(
|
|
1090
1215
|
"input",
|
|
1091
1216
|
{
|
|
1092
1217
|
ref: fileInputRef,
|
|
@@ -1097,22 +1222,22 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
1097
1222
|
accept: ".pdf,.docx,.txt,.md,.json,.csv"
|
|
1098
1223
|
}
|
|
1099
1224
|
)),
|
|
1100
|
-
fileStates.length > 0 && /* @__PURE__ */
|
|
1225
|
+
fileStates.length > 0 && /* @__PURE__ */ import_react10.default.createElement("div", { className: "mt-8 space-y-3" }, fileStates.map((state, i) => /* @__PURE__ */ import_react10.default.createElement(
|
|
1101
1226
|
"div",
|
|
1102
1227
|
{
|
|
1103
1228
|
key: i,
|
|
1104
1229
|
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"
|
|
1105
1230
|
},
|
|
1106
|
-
/* @__PURE__ */
|
|
1107
|
-
/* @__PURE__ */
|
|
1231
|
+
/* @__PURE__ */ import_react10.default.createElement("div", { className: "flex items-center gap-3 overflow-hidden" }, /* @__PURE__ */ import_react10.default.createElement("div", { className: "w-8 h-8 rounded-lg bg-white dark:bg-white/10 flex items-center justify-center shadow-sm" }, /* @__PURE__ */ import_react10.default.createElement(import_lucide_react7.File, { className: "w-4 h-4 text-slate-400" })), /* @__PURE__ */ import_react10.default.createElement("div", { className: "truncate" }, /* @__PURE__ */ import_react10.default.createElement("p", { className: "text-xs font-medium text-slate-700 dark:text-white/80 truncate" }, state.file.name), /* @__PURE__ */ import_react10.default.createElement("p", { className: "text-[10px] text-slate-400" }, (state.file.size / 1024).toFixed(1), " KB"))),
|
|
1232
|
+
/* @__PURE__ */ import_react10.default.createElement("div", { className: "flex items-center gap-2" }, state.status === "uploading" && /* @__PURE__ */ import_react10.default.createElement(import_lucide_react7.Loader2, { className: "w-4 h-4 text-slate-400 animate-spin" }), state.status === "success" && /* @__PURE__ */ import_react10.default.createElement(import_lucide_react7.CheckCircle, { className: "w-4 h-4 text-emerald-500" }), state.status === "error" && /* @__PURE__ */ import_react10.default.createElement("div", { title: state.error }, /* @__PURE__ */ import_react10.default.createElement(import_lucide_react7.AlertCircle, { className: "w-4 h-4 text-rose-500" })), state.status !== "uploading" && /* @__PURE__ */ import_react10.default.createElement(
|
|
1108
1233
|
"button",
|
|
1109
1234
|
{
|
|
1110
1235
|
onClick: () => removeFile(i),
|
|
1111
1236
|
className: "p-1 rounded-md hover:bg-slate-200 dark:hover:bg-white/10 transition-colors"
|
|
1112
1237
|
},
|
|
1113
|
-
/* @__PURE__ */
|
|
1238
|
+
/* @__PURE__ */ import_react10.default.createElement(import_lucide_react7.X, { className: "w-3.5 h-3.5 text-slate-400" })
|
|
1114
1239
|
))
|
|
1115
|
-
)), hasIdle && !isUploading && /* @__PURE__ */
|
|
1240
|
+
)), hasIdle && !isUploading && /* @__PURE__ */ import_react10.default.createElement(
|
|
1116
1241
|
"button",
|
|
1117
1242
|
{
|
|
1118
1243
|
onClick: uploadFiles,
|