@retrivora-ai/rag-engine 1.9.1 → 1.9.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/{ILLMProvider-BQyKZLnd.d.mts → ILLMProvider-Bw2A28nU.d.mts} +2 -0
- package/dist/{ILLMProvider-BQyKZLnd.d.ts → ILLMProvider-Bw2A28nU.d.ts} +2 -0
- package/dist/handlers/index.d.mts +2 -2
- package/dist/handlers/index.d.ts +2 -2
- package/dist/handlers/index.js +193 -109
- package/dist/handlers/index.mjs +193 -109
- package/dist/{index-CDftK3qs.d.mts → index-B70ZLkfG.d.mts} +1 -1
- package/dist/{index-A0GqPsaG.d.ts → index-DVu-mkAM.d.ts} +1 -1
- package/dist/index.css +57 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +90 -36
- package/dist/index.mjs +91 -37
- package/dist/server.d.mts +3 -3
- package/dist/server.d.ts +3 -3
- package/dist/server.js +193 -109
- package/dist/server.mjs +193 -109
- package/package.json +1 -1
- package/src/components/ChatWindow.tsx +24 -14
- package/src/components/MessageBubble.tsx +41 -6
- package/src/components/ProductCard.tsx +4 -4
- package/src/core/Pipeline.ts +53 -25
- package/src/core/QueryProcessor.ts +10 -9
- package/src/handlers/index.ts +31 -8
- package/src/hooks/useRagChat.ts +24 -0
- package/src/providers/vectordb/MongoDBProvider.ts +13 -6
- package/src/providers/vectordb/MultiTablePostgresProvider.ts +36 -4
- package/src/types/chat.ts +2 -0
- package/src/utils/SchemaMapper.ts +6 -4
- package/src/utils/UITransformer.ts +2 -1
- package/src/utils/synonyms.ts +5 -5
package/dist/index.js
CHANGED
|
@@ -420,7 +420,7 @@ function ProductCard({ product, primaryColor = "#6366f1", onAddToCart }) {
|
|
|
420
420
|
unoptimized: true,
|
|
421
421
|
className: "object-cover group-hover:scale-105 transition-transform duration-500"
|
|
422
422
|
}
|
|
423
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "text-slate-400 dark:text-white/20
|
|
423
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "text-slate-400 dark:text-white/20", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react3.ShoppingCart, { className: "w-12 h-12" }) }),
|
|
424
424
|
product.brand && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "absolute top-2 left-2 px-2 py-1 bg-white/90 dark:bg-black/60 backdrop-blur-md rounded-md text-[10px] font-bold uppercase tracking-wider text-slate-700 dark:text-white/90 shadow-sm", children: product.brand })
|
|
425
425
|
] }),
|
|
426
426
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "p-4 flex flex-col gap-2", children: [
|
|
@@ -434,7 +434,7 @@ function ProductCard({ product, primaryColor = "#6366f1", onAddToCart }) {
|
|
|
434
434
|
"button",
|
|
435
435
|
{
|
|
436
436
|
onClick: () => onAddToCart == null ? void 0 : onAddToCart(product),
|
|
437
|
-
className: "flex-1 py-2 px-3 rounded-lg text-[11px] font-medium text-white shadow-sm hover:opacity-90 transition-opacity flex items-center justify-center gap-1.5
|
|
437
|
+
className: "flex-1 py-2 px-3 rounded-lg text-[11px] font-medium text-white shadow-sm hover:opacity-90 transition-opacity flex items-center justify-center gap-1.5",
|
|
438
438
|
style: { background: primaryColor },
|
|
439
439
|
children: [
|
|
440
440
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react3.ShoppingCart, { className: "w-3 h-3" }),
|
|
@@ -1516,7 +1516,7 @@ var HourglassLoader_default = HourglassLoader;
|
|
|
1516
1516
|
// src/utils/synonyms.ts
|
|
1517
1517
|
var FIELD_SYNONYMS = {
|
|
1518
1518
|
name: ["product", "item", "title", "label", "heading", "subject", "product name", "item name"],
|
|
1519
|
-
price: ["cost", "amount", "msrp", "price", "rate", "value", "price_usd"],
|
|
1519
|
+
price: ["cost", "amount", "msrp", "price", "rate", "value", "price_usd", "variant price"],
|
|
1520
1520
|
brand: ["manufacturer", "vendor", "make", "company", "brand_name", "supplier"],
|
|
1521
1521
|
image: [
|
|
1522
1522
|
"imageUrl",
|
|
@@ -1529,7 +1529,9 @@ var FIELD_SYNONYMS = {
|
|
|
1529
1529
|
"image_url",
|
|
1530
1530
|
"main_image",
|
|
1531
1531
|
"product_image",
|
|
1532
|
-
"thumb"
|
|
1532
|
+
"thumb",
|
|
1533
|
+
"image src",
|
|
1534
|
+
"variant image"
|
|
1533
1535
|
],
|
|
1534
1536
|
stock: [
|
|
1535
1537
|
"inventory",
|
|
@@ -1540,7 +1542,8 @@ var FIELD_SYNONYMS = {
|
|
|
1540
1542
|
"inStock",
|
|
1541
1543
|
"is_available",
|
|
1542
1544
|
"in stock",
|
|
1543
|
-
"status"
|
|
1545
|
+
"status",
|
|
1546
|
+
"variant inventory qty"
|
|
1544
1547
|
],
|
|
1545
1548
|
category: [
|
|
1546
1549
|
"product_category",
|
|
@@ -1548,9 +1551,10 @@ var FIELD_SYNONYMS = {
|
|
|
1548
1551
|
"category_name",
|
|
1549
1552
|
"category name",
|
|
1550
1553
|
"department",
|
|
1551
|
-
"collection"
|
|
1554
|
+
"collection",
|
|
1555
|
+
"type"
|
|
1552
1556
|
],
|
|
1553
|
-
description: ["summary", "content", "body", "text", "info", "details"],
|
|
1557
|
+
description: ["summary", "content", "body", "text", "info", "details", "body (html)", "seo description"],
|
|
1554
1558
|
link: ["url", "href", "product_url", "page_url", "link"]
|
|
1555
1559
|
};
|
|
1556
1560
|
function addSynonyms(customSynonyms) {
|
|
@@ -2226,6 +2230,16 @@ function MessageBubble({
|
|
|
2226
2230
|
const isMedium = viewportSize === "medium";
|
|
2227
2231
|
const [showSources, setShowSources] = import_react9.default.useState(false);
|
|
2228
2232
|
const [showTrace, setShowTrace] = import_react9.default.useState(false);
|
|
2233
|
+
const [copied, setCopied] = import_react9.default.useState(false);
|
|
2234
|
+
const handleCopy = import_react9.default.useCallback(async () => {
|
|
2235
|
+
try {
|
|
2236
|
+
await navigator.clipboard.writeText(message.content);
|
|
2237
|
+
setCopied(true);
|
|
2238
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
2239
|
+
} catch (err) {
|
|
2240
|
+
console.error("Failed to copy text:", err);
|
|
2241
|
+
}
|
|
2242
|
+
}, [message.content]);
|
|
2229
2243
|
const structuredContent = import_react9.default.useMemo(
|
|
2230
2244
|
() => isUser ? { payload: null, text: message.content } : extractStructuredPayload(message.content),
|
|
2231
2245
|
[isUser, message.content]
|
|
@@ -2312,41 +2326,52 @@ ${match.trim()}
|
|
|
2312
2326
|
}
|
|
2313
2327
|
),
|
|
2314
2328
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `flex flex-col gap-1 min-w-0 ${isCompact ? "max-w-[94%]" : isMedium ? "max-w-[92%]" : "max-w-[90%]"} ${isUser ? "items-end" : "items-start"}`, children: [
|
|
2315
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.
|
|
2329
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2316
2330
|
"div",
|
|
2317
2331
|
{
|
|
2318
|
-
className: `relative ${isCompact ? "px-3 py-2.5 text-[13px]" : "px-4 py-3 text-sm"} rounded-2xl leading-relaxed shadow-sm dark:shadow-lg ${isUser ? "text-white rounded-tr-sm" : "bg-white dark:bg-white/5 border border-slate-200 dark:border-white/10 text-slate-800 dark:text-white/90 rounded-tl-sm"}`,
|
|
2332
|
+
className: `relative group ${isCompact ? "px-3 py-2.5 text-[13px]" : "px-4 py-3 text-sm"} rounded-2xl leading-relaxed shadow-sm dark:shadow-lg ${isUser ? "text-white rounded-tr-sm" : "bg-white dark:bg-white/5 border border-slate-200 dark:border-white/10 text-slate-800 dark:text-white/90 rounded-tl-sm"}`,
|
|
2319
2333
|
style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {},
|
|
2320
|
-
children:
|
|
2321
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2322
|
-
|
|
2323
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:300ms]" })
|
|
2324
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `prose ${isCompact ? "prose-xs" : "prose-sm"} max-w-none break-words ${isUser ? "prose-invert" : "dark:prose-invert"}`, children: [
|
|
2325
|
-
!isUser && structuredContent.payload && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2326
|
-
UIDispatcher,
|
|
2334
|
+
children: [
|
|
2335
|
+
!isUser && !isStreaming && message.content && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2336
|
+
"button",
|
|
2327
2337
|
{
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
onAddToCart,
|
|
2333
|
-
viewportSize
|
|
2338
|
+
onClick: handleCopy,
|
|
2339
|
+
className: `absolute top-2 right-2 p-1.5 rounded-lg border transition-all duration-200 cursor-pointer ${copied ? "bg-emerald-500/10 border-emerald-500/20 text-emerald-500 dark:text-emerald-400" : "bg-slate-500/5 hover:bg-slate-500/10 border-slate-200 dark:border-white/10 text-slate-400 dark:text-white/30 hover:text-slate-600 dark:hover:text-white/60"} opacity-0 group-hover:opacity-100 backdrop-blur-sm shadow-sm scale-95 group-hover:scale-100`,
|
|
2340
|
+
title: copied ? "Copied!" : "Copy response",
|
|
2341
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.Check, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.Copy, { className: "w-3.5 h-3.5" })
|
|
2334
2342
|
}
|
|
2335
2343
|
),
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2339
|
-
|
|
2344
|
+
isStreaming && !message.content ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "flex items-center gap-1 py-1", children: [
|
|
2345
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:0ms]" }),
|
|
2346
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:150ms]" }),
|
|
2347
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:300ms]" })
|
|
2348
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `prose ${isCompact ? "prose-xs" : "prose-sm"} max-w-none break-words ${isUser ? "prose-invert" : "dark:prose-invert"}`, children: [
|
|
2349
|
+
!isUser && structuredContent.payload && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2350
|
+
UIDispatcher,
|
|
2340
2351
|
{
|
|
2341
|
-
|
|
2352
|
+
rawContent: structuredContent.payload,
|
|
2342
2353
|
primaryColor,
|
|
2343
2354
|
accentColor,
|
|
2344
|
-
|
|
2355
|
+
isStreaming,
|
|
2356
|
+
onAddToCart,
|
|
2357
|
+
viewportSize
|
|
2345
2358
|
}
|
|
2346
2359
|
),
|
|
2347
|
-
|
|
2360
|
+
!shouldRenderStructuredOnly && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_markdown.default, { components: markdownComponents, children: processedMarkdown }),
|
|
2361
|
+
isStreaming && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "inline-flex items-center gap-1.5 ml-2 text-emerald-500 animate-pulse align-middle text-xs font-medium", children: [
|
|
2362
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2363
|
+
HourglassLoader_default,
|
|
2364
|
+
{
|
|
2365
|
+
size: 18,
|
|
2366
|
+
primaryColor,
|
|
2367
|
+
accentColor,
|
|
2368
|
+
glow: false
|
|
2369
|
+
}
|
|
2370
|
+
),
|
|
2371
|
+
"Thinking..."
|
|
2372
|
+
] })
|
|
2348
2373
|
] })
|
|
2349
|
-
]
|
|
2374
|
+
]
|
|
2350
2375
|
}
|
|
2351
2376
|
),
|
|
2352
2377
|
(() => {
|
|
@@ -2354,7 +2379,8 @@ ${match.trim()}
|
|
|
2354
2379
|
if (isUser || structuredContent.payload || !message.uiTransformation) return null;
|
|
2355
2380
|
const ui = message.uiTransformation;
|
|
2356
2381
|
const textContent = (_b = (_a2 = ui.data) == null ? void 0 : _a2.content) != null ? _b : "";
|
|
2357
|
-
const
|
|
2382
|
+
const isNegativeOrFallbackText = textContent.toLowerCase().includes("cannot answer") || textContent.toLowerCase().includes("no relevant data") || textContent.toLowerCase().includes("no data available") || typeof ui.title === "string" && ui.title.toLowerCase().includes("no data") || typeof ui.description === "string" && ui.description.toLowerCase().includes("no relevant data");
|
|
2383
|
+
const shouldShow = !isNegativeOrFallbackText && (ui.type === "table" || !["text", "table"].includes(ui.type) || ui.type === "text" && !hasRichUI && allProducts.length === 0 && textContent && !processedMarkdown.toLowerCase().includes(textContent.trim().toLowerCase()));
|
|
2358
2384
|
if (!shouldShow) return null;
|
|
2359
2385
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "w-full mt-3", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2360
2386
|
VisualizationRenderer,
|
|
@@ -2476,6 +2502,7 @@ function useRagChat(projectId, options = {}) {
|
|
|
2476
2502
|
const [error, setError] = (0, import_react10.useState)(null);
|
|
2477
2503
|
const lastInputRef = (0, import_react10.useRef)("");
|
|
2478
2504
|
const messagesRef = (0, import_react10.useRef)(messages);
|
|
2505
|
+
const abortControllerRef = (0, import_react10.useRef)(null);
|
|
2479
2506
|
(0, import_react10.useEffect)(() => {
|
|
2480
2507
|
messagesRef.current = messages;
|
|
2481
2508
|
}, [messages]);
|
|
@@ -2496,11 +2523,17 @@ function useRagChat(projectId, options = {}) {
|
|
|
2496
2523
|
}
|
|
2497
2524
|
setError(null);
|
|
2498
2525
|
setIsLoading(true);
|
|
2526
|
+
if (abortControllerRef.current) {
|
|
2527
|
+
abortControllerRef.current.abort();
|
|
2528
|
+
}
|
|
2529
|
+
const controller = new AbortController();
|
|
2530
|
+
abortControllerRef.current = controller;
|
|
2499
2531
|
try {
|
|
2500
2532
|
const history = messagesRef.current.map(({ role, content }) => ({ role, content }));
|
|
2501
2533
|
const response = await fetch(apiUrl, {
|
|
2502
2534
|
method: "POST",
|
|
2503
2535
|
headers: { "Content-Type": "application/json" },
|
|
2536
|
+
signal: controller.signal,
|
|
2504
2537
|
body: JSON.stringify({
|
|
2505
2538
|
message: trimmed,
|
|
2506
2539
|
history,
|
|
@@ -2609,11 +2642,16 @@ function useRagChat(projectId, options = {}) {
|
|
|
2609
2642
|
);
|
|
2610
2643
|
onReply == null ? void 0 : onReply(finalMsg);
|
|
2611
2644
|
} catch (err) {
|
|
2645
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
2646
|
+
console.log("[useRagChat] Streaming stopped by user.");
|
|
2647
|
+
return;
|
|
2648
|
+
}
|
|
2612
2649
|
const msg = err instanceof Error ? err.message : "Something went wrong. Please try again.";
|
|
2613
2650
|
setError(msg);
|
|
2614
2651
|
onError == null ? void 0 : onError(msg);
|
|
2615
2652
|
} finally {
|
|
2616
2653
|
setIsLoading(false);
|
|
2654
|
+
abortControllerRef.current = null;
|
|
2617
2655
|
}
|
|
2618
2656
|
},
|
|
2619
2657
|
[apiUrl, isLoading, namespace, onError, onReply, projectId, setMessages]
|
|
@@ -2631,6 +2669,13 @@ function useRagChat(projectId, options = {}) {
|
|
|
2631
2669
|
});
|
|
2632
2670
|
}
|
|
2633
2671
|
}, [sendMessage]);
|
|
2672
|
+
const stop = (0, import_react10.useCallback)(() => {
|
|
2673
|
+
if (abortControllerRef.current) {
|
|
2674
|
+
abortControllerRef.current.abort();
|
|
2675
|
+
abortControllerRef.current = null;
|
|
2676
|
+
}
|
|
2677
|
+
setIsLoading(false);
|
|
2678
|
+
}, []);
|
|
2634
2679
|
return {
|
|
2635
2680
|
messages,
|
|
2636
2681
|
isLoading,
|
|
@@ -2638,7 +2683,8 @@ function useRagChat(projectId, options = {}) {
|
|
|
2638
2683
|
send: sendMessage,
|
|
2639
2684
|
clear,
|
|
2640
2685
|
retry,
|
|
2641
|
-
setMessages
|
|
2686
|
+
setMessages,
|
|
2687
|
+
stop
|
|
2642
2688
|
};
|
|
2643
2689
|
}
|
|
2644
2690
|
|
|
@@ -2664,7 +2710,7 @@ function ChatWindow({
|
|
|
2664
2710
|
const windowRef = (0, import_react11.useRef)(null);
|
|
2665
2711
|
const bottomRef = (0, import_react11.useRef)(null);
|
|
2666
2712
|
const inputRef = (0, import_react11.useRef)(null);
|
|
2667
|
-
const { messages, send, clear, isLoading, error } = useRagChat(projectId, {
|
|
2713
|
+
const { messages, send, clear, isLoading, error, stop } = useRagChat(projectId, {
|
|
2668
2714
|
namespace: projectId
|
|
2669
2715
|
});
|
|
2670
2716
|
const [suggestions, setSuggestions] = (0, import_react11.useState)([]);
|
|
@@ -3028,14 +3074,22 @@ function ChatWindow({
|
|
|
3028
3074
|
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.Paperclip, { className: "w-4 h-4" })
|
|
3029
3075
|
}
|
|
3030
3076
|
),
|
|
3031
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3077
|
+
isLoading ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3078
|
+
"button",
|
|
3079
|
+
{
|
|
3080
|
+
onClick: stop,
|
|
3081
|
+
className: "flex-shrink-0 w-9 h-9 rounded-xl flex items-center justify-center transition-all hover:scale-105 active:scale-95 shadow-md bg-rose-500 hover:bg-rose-600 text-white cursor-pointer",
|
|
3082
|
+
title: "Stop generating",
|
|
3083
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "w-3.5 h-3.5 bg-white rounded-[2px]" })
|
|
3084
|
+
}
|
|
3085
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3032
3086
|
"button",
|
|
3033
3087
|
{
|
|
3034
3088
|
onClick: sendMessage,
|
|
3035
|
-
disabled: !input.trim()
|
|
3089
|
+
disabled: !input.trim(),
|
|
3036
3090
|
className: "flex-shrink-0 w-9 h-9 rounded-xl flex items-center justify-center transition-all disabled:opacity-30 disabled:cursor-not-allowed hover:scale-105 active:scale-95 shadow-md",
|
|
3037
3091
|
style: {
|
|
3038
|
-
background: input.trim()
|
|
3092
|
+
background: input.trim() ? `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` : "rgba(148, 163, 184, 0.2)"
|
|
3039
3093
|
// slate-400/20 for light mode disabled
|
|
3040
3094
|
},
|
|
3041
3095
|
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.ArrowUp, { className: "w-4 h-4 text-white" })
|
package/dist/index.mjs
CHANGED
|
@@ -316,7 +316,7 @@ function DocumentUpload({ namespace, onUploadComplete, className = "" }) {
|
|
|
316
316
|
|
|
317
317
|
// src/components/MessageBubble.tsx
|
|
318
318
|
import React9 from "react";
|
|
319
|
-
import { Bot, User, ChevronDown as ChevronDown3, ChevronRight as ChevronRight3, Activity } from "lucide-react";
|
|
319
|
+
import { Bot, User, ChevronDown as ChevronDown3, ChevronRight as ChevronRight3, Activity, Copy, Check } from "lucide-react";
|
|
320
320
|
import ReactMarkdown from "react-markdown";
|
|
321
321
|
|
|
322
322
|
// src/components/SourceCard.tsx
|
|
@@ -393,7 +393,7 @@ function ProductCard({ product, primaryColor = "#6366f1", onAddToCart }) {
|
|
|
393
393
|
unoptimized: true,
|
|
394
394
|
className: "object-cover group-hover:scale-105 transition-transform duration-500"
|
|
395
395
|
}
|
|
396
|
-
) : /* @__PURE__ */ jsx4("div", { className: "text-slate-400 dark:text-white/20
|
|
396
|
+
) : /* @__PURE__ */ jsx4("div", { className: "text-slate-400 dark:text-white/20", children: /* @__PURE__ */ jsx4(ShoppingCart, { className: "w-12 h-12" }) }),
|
|
397
397
|
product.brand && /* @__PURE__ */ jsx4("div", { className: "absolute top-2 left-2 px-2 py-1 bg-white/90 dark:bg-black/60 backdrop-blur-md rounded-md text-[10px] font-bold uppercase tracking-wider text-slate-700 dark:text-white/90 shadow-sm", children: product.brand })
|
|
398
398
|
] }),
|
|
399
399
|
/* @__PURE__ */ jsxs3("div", { className: "p-4 flex flex-col gap-2", children: [
|
|
@@ -407,7 +407,7 @@ function ProductCard({ product, primaryColor = "#6366f1", onAddToCart }) {
|
|
|
407
407
|
"button",
|
|
408
408
|
{
|
|
409
409
|
onClick: () => onAddToCart == null ? void 0 : onAddToCart(product),
|
|
410
|
-
className: "flex-1 py-2 px-3 rounded-lg text-[11px] font-medium text-white shadow-sm hover:opacity-90 transition-opacity flex items-center justify-center gap-1.5
|
|
410
|
+
className: "flex-1 py-2 px-3 rounded-lg text-[11px] font-medium text-white shadow-sm hover:opacity-90 transition-opacity flex items-center justify-center gap-1.5",
|
|
411
411
|
style: { background: primaryColor },
|
|
412
412
|
children: [
|
|
413
413
|
/* @__PURE__ */ jsx4(ShoppingCart, { className: "w-3 h-3" }),
|
|
@@ -1535,7 +1535,7 @@ var HourglassLoader_default = HourglassLoader;
|
|
|
1535
1535
|
// src/utils/synonyms.ts
|
|
1536
1536
|
var FIELD_SYNONYMS = {
|
|
1537
1537
|
name: ["product", "item", "title", "label", "heading", "subject", "product name", "item name"],
|
|
1538
|
-
price: ["cost", "amount", "msrp", "price", "rate", "value", "price_usd"],
|
|
1538
|
+
price: ["cost", "amount", "msrp", "price", "rate", "value", "price_usd", "variant price"],
|
|
1539
1539
|
brand: ["manufacturer", "vendor", "make", "company", "brand_name", "supplier"],
|
|
1540
1540
|
image: [
|
|
1541
1541
|
"imageUrl",
|
|
@@ -1548,7 +1548,9 @@ var FIELD_SYNONYMS = {
|
|
|
1548
1548
|
"image_url",
|
|
1549
1549
|
"main_image",
|
|
1550
1550
|
"product_image",
|
|
1551
|
-
"thumb"
|
|
1551
|
+
"thumb",
|
|
1552
|
+
"image src",
|
|
1553
|
+
"variant image"
|
|
1552
1554
|
],
|
|
1553
1555
|
stock: [
|
|
1554
1556
|
"inventory",
|
|
@@ -1559,7 +1561,8 @@ var FIELD_SYNONYMS = {
|
|
|
1559
1561
|
"inStock",
|
|
1560
1562
|
"is_available",
|
|
1561
1563
|
"in stock",
|
|
1562
|
-
"status"
|
|
1564
|
+
"status",
|
|
1565
|
+
"variant inventory qty"
|
|
1563
1566
|
],
|
|
1564
1567
|
category: [
|
|
1565
1568
|
"product_category",
|
|
@@ -1567,9 +1570,10 @@ var FIELD_SYNONYMS = {
|
|
|
1567
1570
|
"category_name",
|
|
1568
1571
|
"category name",
|
|
1569
1572
|
"department",
|
|
1570
|
-
"collection"
|
|
1573
|
+
"collection",
|
|
1574
|
+
"type"
|
|
1571
1575
|
],
|
|
1572
|
-
description: ["summary", "content", "body", "text", "info", "details"],
|
|
1576
|
+
description: ["summary", "content", "body", "text", "info", "details", "body (html)", "seo description"],
|
|
1573
1577
|
link: ["url", "href", "product_url", "page_url", "link"]
|
|
1574
1578
|
};
|
|
1575
1579
|
function addSynonyms(customSynonyms) {
|
|
@@ -2245,6 +2249,16 @@ function MessageBubble({
|
|
|
2245
2249
|
const isMedium = viewportSize === "medium";
|
|
2246
2250
|
const [showSources, setShowSources] = React9.useState(false);
|
|
2247
2251
|
const [showTrace, setShowTrace] = React9.useState(false);
|
|
2252
|
+
const [copied, setCopied] = React9.useState(false);
|
|
2253
|
+
const handleCopy = React9.useCallback(async () => {
|
|
2254
|
+
try {
|
|
2255
|
+
await navigator.clipboard.writeText(message.content);
|
|
2256
|
+
setCopied(true);
|
|
2257
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
2258
|
+
} catch (err) {
|
|
2259
|
+
console.error("Failed to copy text:", err);
|
|
2260
|
+
}
|
|
2261
|
+
}, [message.content]);
|
|
2248
2262
|
const structuredContent = React9.useMemo(
|
|
2249
2263
|
() => isUser ? { payload: null, text: message.content } : extractStructuredPayload(message.content),
|
|
2250
2264
|
[isUser, message.content]
|
|
@@ -2331,41 +2345,52 @@ ${match.trim()}
|
|
|
2331
2345
|
}
|
|
2332
2346
|
),
|
|
2333
2347
|
/* @__PURE__ */ jsxs11("div", { className: `flex flex-col gap-1 min-w-0 ${isCompact ? "max-w-[94%]" : isMedium ? "max-w-[92%]" : "max-w-[90%]"} ${isUser ? "items-end" : "items-start"}`, children: [
|
|
2334
|
-
/* @__PURE__ */
|
|
2348
|
+
/* @__PURE__ */ jsxs11(
|
|
2335
2349
|
"div",
|
|
2336
2350
|
{
|
|
2337
|
-
className: `relative ${isCompact ? "px-3 py-2.5 text-[13px]" : "px-4 py-3 text-sm"} rounded-2xl leading-relaxed shadow-sm dark:shadow-lg ${isUser ? "text-white rounded-tr-sm" : "bg-white dark:bg-white/5 border border-slate-200 dark:border-white/10 text-slate-800 dark:text-white/90 rounded-tl-sm"}`,
|
|
2351
|
+
className: `relative group ${isCompact ? "px-3 py-2.5 text-[13px]" : "px-4 py-3 text-sm"} rounded-2xl leading-relaxed shadow-sm dark:shadow-lg ${isUser ? "text-white rounded-tr-sm" : "bg-white dark:bg-white/5 border border-slate-200 dark:border-white/10 text-slate-800 dark:text-white/90 rounded-tl-sm"}`,
|
|
2338
2352
|
style: isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {},
|
|
2339
|
-
children:
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
/* @__PURE__ */ jsx12("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:300ms]" })
|
|
2343
|
-
] }) : /* @__PURE__ */ jsxs11("div", { className: `prose ${isCompact ? "prose-xs" : "prose-sm"} max-w-none break-words ${isUser ? "prose-invert" : "dark:prose-invert"}`, children: [
|
|
2344
|
-
!isUser && structuredContent.payload && /* @__PURE__ */ jsx12(
|
|
2345
|
-
UIDispatcher,
|
|
2353
|
+
children: [
|
|
2354
|
+
!isUser && !isStreaming && message.content && /* @__PURE__ */ jsx12(
|
|
2355
|
+
"button",
|
|
2346
2356
|
{
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
onAddToCart,
|
|
2352
|
-
viewportSize
|
|
2357
|
+
onClick: handleCopy,
|
|
2358
|
+
className: `absolute top-2 right-2 p-1.5 rounded-lg border transition-all duration-200 cursor-pointer ${copied ? "bg-emerald-500/10 border-emerald-500/20 text-emerald-500 dark:text-emerald-400" : "bg-slate-500/5 hover:bg-slate-500/10 border-slate-200 dark:border-white/10 text-slate-400 dark:text-white/30 hover:text-slate-600 dark:hover:text-white/60"} opacity-0 group-hover:opacity-100 backdrop-blur-sm shadow-sm scale-95 group-hover:scale-100`,
|
|
2359
|
+
title: copied ? "Copied!" : "Copy response",
|
|
2360
|
+
children: copied ? /* @__PURE__ */ jsx12(Check, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ jsx12(Copy, { className: "w-3.5 h-3.5" })
|
|
2353
2361
|
}
|
|
2354
2362
|
),
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
/* @__PURE__ */ jsx12(
|
|
2358
|
-
|
|
2363
|
+
isStreaming && !message.content ? /* @__PURE__ */ jsxs11("span", { className: "flex items-center gap-1 py-1", children: [
|
|
2364
|
+
/* @__PURE__ */ jsx12("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:0ms]" }),
|
|
2365
|
+
/* @__PURE__ */ jsx12("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:150ms]" }),
|
|
2366
|
+
/* @__PURE__ */ jsx12("span", { className: "w-1.5 h-1.5 rounded-full bg-slate-400 dark:bg-white/60 animate-bounce [animation-delay:300ms]" })
|
|
2367
|
+
] }) : /* @__PURE__ */ jsxs11("div", { className: `prose ${isCompact ? "prose-xs" : "prose-sm"} max-w-none break-words ${isUser ? "prose-invert" : "dark:prose-invert"}`, children: [
|
|
2368
|
+
!isUser && structuredContent.payload && /* @__PURE__ */ jsx12(
|
|
2369
|
+
UIDispatcher,
|
|
2359
2370
|
{
|
|
2360
|
-
|
|
2371
|
+
rawContent: structuredContent.payload,
|
|
2361
2372
|
primaryColor,
|
|
2362
2373
|
accentColor,
|
|
2363
|
-
|
|
2374
|
+
isStreaming,
|
|
2375
|
+
onAddToCart,
|
|
2376
|
+
viewportSize
|
|
2364
2377
|
}
|
|
2365
2378
|
),
|
|
2366
|
-
|
|
2379
|
+
!shouldRenderStructuredOnly && /* @__PURE__ */ jsx12(ReactMarkdown, { components: markdownComponents, children: processedMarkdown }),
|
|
2380
|
+
isStreaming && /* @__PURE__ */ jsxs11("span", { className: "inline-flex items-center gap-1.5 ml-2 text-emerald-500 animate-pulse align-middle text-xs font-medium", children: [
|
|
2381
|
+
/* @__PURE__ */ jsx12(
|
|
2382
|
+
HourglassLoader_default,
|
|
2383
|
+
{
|
|
2384
|
+
size: 18,
|
|
2385
|
+
primaryColor,
|
|
2386
|
+
accentColor,
|
|
2387
|
+
glow: false
|
|
2388
|
+
}
|
|
2389
|
+
),
|
|
2390
|
+
"Thinking..."
|
|
2391
|
+
] })
|
|
2367
2392
|
] })
|
|
2368
|
-
]
|
|
2393
|
+
]
|
|
2369
2394
|
}
|
|
2370
2395
|
),
|
|
2371
2396
|
(() => {
|
|
@@ -2373,7 +2398,8 @@ ${match.trim()}
|
|
|
2373
2398
|
if (isUser || structuredContent.payload || !message.uiTransformation) return null;
|
|
2374
2399
|
const ui = message.uiTransformation;
|
|
2375
2400
|
const textContent = (_b = (_a2 = ui.data) == null ? void 0 : _a2.content) != null ? _b : "";
|
|
2376
|
-
const
|
|
2401
|
+
const isNegativeOrFallbackText = textContent.toLowerCase().includes("cannot answer") || textContent.toLowerCase().includes("no relevant data") || textContent.toLowerCase().includes("no data available") || typeof ui.title === "string" && ui.title.toLowerCase().includes("no data") || typeof ui.description === "string" && ui.description.toLowerCase().includes("no relevant data");
|
|
2402
|
+
const shouldShow = !isNegativeOrFallbackText && (ui.type === "table" || !["text", "table"].includes(ui.type) || ui.type === "text" && !hasRichUI && allProducts.length === 0 && textContent && !processedMarkdown.toLowerCase().includes(textContent.trim().toLowerCase()));
|
|
2377
2403
|
if (!shouldShow) return null;
|
|
2378
2404
|
return /* @__PURE__ */ jsx12("div", { className: "w-full mt-3", children: /* @__PURE__ */ jsx12(
|
|
2379
2405
|
VisualizationRenderer,
|
|
@@ -2495,6 +2521,7 @@ function useRagChat(projectId, options = {}) {
|
|
|
2495
2521
|
const [error, setError] = useState4(null);
|
|
2496
2522
|
const lastInputRef = useRef3("");
|
|
2497
2523
|
const messagesRef = useRef3(messages);
|
|
2524
|
+
const abortControllerRef = useRef3(null);
|
|
2498
2525
|
useEffect3(() => {
|
|
2499
2526
|
messagesRef.current = messages;
|
|
2500
2527
|
}, [messages]);
|
|
@@ -2515,11 +2542,17 @@ function useRagChat(projectId, options = {}) {
|
|
|
2515
2542
|
}
|
|
2516
2543
|
setError(null);
|
|
2517
2544
|
setIsLoading(true);
|
|
2545
|
+
if (abortControllerRef.current) {
|
|
2546
|
+
abortControllerRef.current.abort();
|
|
2547
|
+
}
|
|
2548
|
+
const controller = new AbortController();
|
|
2549
|
+
abortControllerRef.current = controller;
|
|
2518
2550
|
try {
|
|
2519
2551
|
const history = messagesRef.current.map(({ role, content }) => ({ role, content }));
|
|
2520
2552
|
const response = await fetch(apiUrl, {
|
|
2521
2553
|
method: "POST",
|
|
2522
2554
|
headers: { "Content-Type": "application/json" },
|
|
2555
|
+
signal: controller.signal,
|
|
2523
2556
|
body: JSON.stringify({
|
|
2524
2557
|
message: trimmed,
|
|
2525
2558
|
history,
|
|
@@ -2628,11 +2661,16 @@ function useRagChat(projectId, options = {}) {
|
|
|
2628
2661
|
);
|
|
2629
2662
|
onReply == null ? void 0 : onReply(finalMsg);
|
|
2630
2663
|
} catch (err) {
|
|
2664
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
2665
|
+
console.log("[useRagChat] Streaming stopped by user.");
|
|
2666
|
+
return;
|
|
2667
|
+
}
|
|
2631
2668
|
const msg = err instanceof Error ? err.message : "Something went wrong. Please try again.";
|
|
2632
2669
|
setError(msg);
|
|
2633
2670
|
onError == null ? void 0 : onError(msg);
|
|
2634
2671
|
} finally {
|
|
2635
2672
|
setIsLoading(false);
|
|
2673
|
+
abortControllerRef.current = null;
|
|
2636
2674
|
}
|
|
2637
2675
|
},
|
|
2638
2676
|
[apiUrl, isLoading, namespace, onError, onReply, projectId, setMessages]
|
|
@@ -2650,6 +2688,13 @@ function useRagChat(projectId, options = {}) {
|
|
|
2650
2688
|
});
|
|
2651
2689
|
}
|
|
2652
2690
|
}, [sendMessage]);
|
|
2691
|
+
const stop = useCallback(() => {
|
|
2692
|
+
if (abortControllerRef.current) {
|
|
2693
|
+
abortControllerRef.current.abort();
|
|
2694
|
+
abortControllerRef.current = null;
|
|
2695
|
+
}
|
|
2696
|
+
setIsLoading(false);
|
|
2697
|
+
}, []);
|
|
2653
2698
|
return {
|
|
2654
2699
|
messages,
|
|
2655
2700
|
isLoading,
|
|
@@ -2657,7 +2702,8 @@ function useRagChat(projectId, options = {}) {
|
|
|
2657
2702
|
send: sendMessage,
|
|
2658
2703
|
clear,
|
|
2659
2704
|
retry,
|
|
2660
|
-
setMessages
|
|
2705
|
+
setMessages,
|
|
2706
|
+
stop
|
|
2661
2707
|
};
|
|
2662
2708
|
}
|
|
2663
2709
|
|
|
@@ -2683,7 +2729,7 @@ function ChatWindow({
|
|
|
2683
2729
|
const windowRef = useRef4(null);
|
|
2684
2730
|
const bottomRef = useRef4(null);
|
|
2685
2731
|
const inputRef = useRef4(null);
|
|
2686
|
-
const { messages, send, clear, isLoading, error } = useRagChat(projectId, {
|
|
2732
|
+
const { messages, send, clear, isLoading, error, stop } = useRagChat(projectId, {
|
|
2687
2733
|
namespace: projectId
|
|
2688
2734
|
});
|
|
2689
2735
|
const [suggestions, setSuggestions] = useState5([]);
|
|
@@ -3047,14 +3093,22 @@ function ChatWindow({
|
|
|
3047
3093
|
children: /* @__PURE__ */ jsx13(Paperclip, { className: "w-4 h-4" })
|
|
3048
3094
|
}
|
|
3049
3095
|
),
|
|
3050
|
-
/* @__PURE__ */ jsx13(
|
|
3096
|
+
isLoading ? /* @__PURE__ */ jsx13(
|
|
3097
|
+
"button",
|
|
3098
|
+
{
|
|
3099
|
+
onClick: stop,
|
|
3100
|
+
className: "flex-shrink-0 w-9 h-9 rounded-xl flex items-center justify-center transition-all hover:scale-105 active:scale-95 shadow-md bg-rose-500 hover:bg-rose-600 text-white cursor-pointer",
|
|
3101
|
+
title: "Stop generating",
|
|
3102
|
+
children: /* @__PURE__ */ jsx13("div", { className: "w-3.5 h-3.5 bg-white rounded-[2px]" })
|
|
3103
|
+
}
|
|
3104
|
+
) : /* @__PURE__ */ jsx13(
|
|
3051
3105
|
"button",
|
|
3052
3106
|
{
|
|
3053
3107
|
onClick: sendMessage,
|
|
3054
|
-
disabled: !input.trim()
|
|
3108
|
+
disabled: !input.trim(),
|
|
3055
3109
|
className: "flex-shrink-0 w-9 h-9 rounded-xl flex items-center justify-center transition-all disabled:opacity-30 disabled:cursor-not-allowed hover:scale-105 active:scale-95 shadow-md",
|
|
3056
3110
|
style: {
|
|
3057
|
-
background: input.trim()
|
|
3111
|
+
background: input.trim() ? `linear-gradient(135deg, ${ui.primaryColor}, ${ui.accentColor})` : "rgba(148, 163, 184, 0.2)"
|
|
3058
3112
|
// slate-400/20 for light mode disabled
|
|
3059
3113
|
},
|
|
3060
3114
|
children: /* @__PURE__ */ jsx13(ArrowUp, { className: "w-4 h-4 text-white" })
|
package/dist/server.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { n as VectorDBConfig, L as LLMConfig, e as EmbeddingConfig, k as RagConfig, I as ILLMProvider, g as IngestDocument, C as ChatMessage, d as ChatResponse, p as RetrievalResult, m as UpsertDocument, V as VectorMatch, G as GraphDBConfig, q as GraphNode, r as Edge, s as GraphSearchResult, o as VectorDBProvider, h as LLMProvider, f as EmbeddingProvider, j as RAGConfig, U as UIConfig, c as ChatOptions, E as EmbedOptions } from './ILLMProvider-
|
|
1
|
+
import { n as VectorDBConfig, L as LLMConfig, e as EmbeddingConfig, k as RagConfig, I as ILLMProvider, g as IngestDocument, C as ChatMessage, d as ChatResponse, p as RetrievalResult, m as UpsertDocument, V as VectorMatch, G as GraphDBConfig, q as GraphNode, r as Edge, s as GraphSearchResult, o as VectorDBProvider, h as LLMProvider, f as EmbeddingProvider, j as RAGConfig, U as UIConfig, c as ChatOptions, E as EmbedOptions } from './ILLMProvider-Bw2A28nU.mjs';
|
|
2
2
|
export { C as Chunk, a as ChunkOptions, D as DocumentChunker } from './DocumentChunker-Dh9TvmGG.mjs';
|
|
3
|
-
import { H as HealthCheckResult, I as IProviderValidator, a as IProviderHealthChecker } from './index-
|
|
4
|
-
export { C as ConfigValidator, V as ValidationError, b as VectorPlugin, c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, j as sseTextFrame } from './index-
|
|
3
|
+
import { H as HealthCheckResult, I as IProviderValidator, a as IProviderHealthChecker } from './index-B70ZLkfG.mjs';
|
|
4
|
+
export { C as ConfigValidator, V as ValidationError, b as VectorPlugin, c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, j as sseTextFrame } from './index-B70ZLkfG.mjs';
|
|
5
5
|
import 'next/server';
|
|
6
6
|
|
|
7
7
|
/**
|
package/dist/server.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { n as VectorDBConfig, L as LLMConfig, e as EmbeddingConfig, k as RagConfig, I as ILLMProvider, g as IngestDocument, C as ChatMessage, d as ChatResponse, p as RetrievalResult, m as UpsertDocument, V as VectorMatch, G as GraphDBConfig, q as GraphNode, r as Edge, s as GraphSearchResult, o as VectorDBProvider, h as LLMProvider, f as EmbeddingProvider, j as RAGConfig, U as UIConfig, c as ChatOptions, E as EmbedOptions } from './ILLMProvider-
|
|
1
|
+
import { n as VectorDBConfig, L as LLMConfig, e as EmbeddingConfig, k as RagConfig, I as ILLMProvider, g as IngestDocument, C as ChatMessage, d as ChatResponse, p as RetrievalResult, m as UpsertDocument, V as VectorMatch, G as GraphDBConfig, q as GraphNode, r as Edge, s as GraphSearchResult, o as VectorDBProvider, h as LLMProvider, f as EmbeddingProvider, j as RAGConfig, U as UIConfig, c as ChatOptions, E as EmbedOptions } from './ILLMProvider-Bw2A28nU.js';
|
|
2
2
|
export { C as Chunk, a as ChunkOptions, D as DocumentChunker } from './DocumentChunker-Dh9TvmGG.js';
|
|
3
|
-
import { H as HealthCheckResult, I as IProviderValidator, a as IProviderHealthChecker } from './index-
|
|
4
|
-
export { C as ConfigValidator, V as ValidationError, b as VectorPlugin, c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, j as sseTextFrame } from './index-
|
|
3
|
+
import { H as HealthCheckResult, I as IProviderValidator, a as IProviderHealthChecker } from './index-DVu-mkAM.js';
|
|
4
|
+
export { C as ConfigValidator, V as ValidationError, b as VectorPlugin, c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, j as sseTextFrame } from './index-DVu-mkAM.js';
|
|
5
5
|
import 'next/server';
|
|
6
6
|
|
|
7
7
|
/**
|