@retrivora-ai/rag-engine 1.1.6 → 1.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -250,7 +250,23 @@ function MessageBubble({
250
250
  }
251
251
  return { productsFromContent: products, cleanContent: content.trim() };
252
252
  }, [message.content, isUser]);
253
- const allProducts = [...productsFromSources, ...productsFromContent];
253
+ const allProducts = import_react4.default.useMemo(() => {
254
+ if (productsFromContent.length > 0) return productsFromContent;
255
+ const uniqueProducts = [];
256
+ const seenIds = /* @__PURE__ */ new Set();
257
+ const contentLower = message.content.toLowerCase();
258
+ for (const p of productsFromSources) {
259
+ const identifier = p.id || p.name;
260
+ if (seenIds.has(identifier)) continue;
261
+ const nameMatch = contentLower.includes(p.name.toLowerCase());
262
+ const brandMatch = p.brand ? contentLower.includes(p.brand.toLowerCase()) : false;
263
+ if (nameMatch || brandMatch) {
264
+ seenIds.add(identifier);
265
+ uniqueProducts.push(p);
266
+ }
267
+ }
268
+ return uniqueProducts;
269
+ }, [productsFromSources, productsFromContent, message.content]);
254
270
  const hasProducts = allProducts.length > 0;
255
271
  return /* @__PURE__ */ import_react4.default.createElement("div", { className: `flex gap-3 ${isUser ? "flex-row-reverse" : "flex-row"} items-start` }, /* @__PURE__ */ import_react4.default.createElement(
256
272
  "div",
package/dist/index.mjs CHANGED
@@ -208,7 +208,23 @@ function MessageBubble({
208
208
  }
209
209
  return { productsFromContent: products, cleanContent: content.trim() };
210
210
  }, [message.content, isUser]);
211
- const allProducts = [...productsFromSources, ...productsFromContent];
211
+ const allProducts = React4.useMemo(() => {
212
+ if (productsFromContent.length > 0) return productsFromContent;
213
+ const uniqueProducts = [];
214
+ const seenIds = /* @__PURE__ */ new Set();
215
+ const contentLower = message.content.toLowerCase();
216
+ for (const p of productsFromSources) {
217
+ const identifier = p.id || p.name;
218
+ if (seenIds.has(identifier)) continue;
219
+ const nameMatch = contentLower.includes(p.name.toLowerCase());
220
+ const brandMatch = p.brand ? contentLower.includes(p.brand.toLowerCase()) : false;
221
+ if (nameMatch || brandMatch) {
222
+ seenIds.add(identifier);
223
+ uniqueProducts.push(p);
224
+ }
225
+ }
226
+ return uniqueProducts;
227
+ }, [productsFromSources, productsFromContent, message.content]);
212
228
  const hasProducts = allProducts.length > 0;
213
229
  return /* @__PURE__ */ React4.createElement("div", { className: `flex gap-3 ${isUser ? "flex-row-reverse" : "flex-row"} items-start` }, /* @__PURE__ */ React4.createElement(
214
230
  "div",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retrivora-ai/rag-engine",
3
- "version": "1.1.6",
3
+ "version": "1.1.8",
4
4
  "description": "Retrivora AI is a plug-and-play AI engine for RAG chat experiences — generic vector DB + LLM provider, embeddable or standalone.",
5
5
  "author": "Abhinav Alkuchi",
6
6
  "license": "MIT",
@@ -75,6 +75,55 @@ body {
75
75
  }
76
76
 
77
77
  /* ─── Prose Overrides (markdown in chat) ───────────────────── */
78
+ .prose {
79
+ font-size: 0.875rem;
80
+ line-height: 1.5;
81
+ }
82
+
83
+ .prose strong {
84
+ font-weight: 700;
85
+ color: inherit;
86
+ }
87
+
88
+ .prose em {
89
+ font-style: italic;
90
+ }
91
+
92
+ .prose p {
93
+ margin: 0.5em 0;
94
+ }
95
+
96
+ .prose ul, .prose ol {
97
+ padding-left: 1.5em;
98
+ margin: 0.5em 0;
99
+ }
100
+
101
+ .prose li {
102
+ margin: 0.25em 0;
103
+ }
104
+
105
+ .prose table {
106
+ width: 100%;
107
+ border-collapse: collapse;
108
+ margin: 1em 0;
109
+ font-size: 0.8rem;
110
+ }
111
+
112
+ .prose th, .prose td {
113
+ border: 1px solid var(--border);
114
+ padding: 0.5rem;
115
+ text-align: left;
116
+ }
117
+
118
+ .prose th {
119
+ background: rgba(0, 0, 0, 0.05);
120
+ font-weight: 600;
121
+ }
122
+
123
+ .dark .prose th {
124
+ background: rgba(255, 255, 255, 0.05);
125
+ }
126
+
78
127
  .prose-invert {
79
128
  color: inherit;
80
129
  }
@@ -100,7 +100,33 @@ export function MessageBubble({
100
100
  return { productsFromContent: products, cleanContent: content.trim() };
101
101
  }, [message.content, isUser]);
102
102
 
103
- const allProducts = [...productsFromSources, ...productsFromContent];
103
+ const allProducts = React.useMemo(() => {
104
+ // If the LLM explicitly provided products in a structured format, only show those.
105
+ if (productsFromContent.length > 0) return productsFromContent;
106
+
107
+ // Fallback: Show unique products from sources, but ONLY if they are mentioned in the message text.
108
+ // This aligns the carousel with what the assistant is actually "displaying" in its response.
109
+ const uniqueProducts: Product[] = [];
110
+ const seenIds = new Set();
111
+ const contentLower = message.content.toLowerCase();
112
+
113
+ for (const p of productsFromSources) {
114
+ const identifier = p.id || p.name;
115
+ if (seenIds.has(identifier)) continue;
116
+
117
+ // Check if the product name or brand is mentioned in the assistant's text
118
+ const nameMatch = contentLower.includes(p.name.toLowerCase());
119
+ const brandMatch = p.brand ? contentLower.includes(p.brand.toLowerCase()) : false;
120
+
121
+ if (nameMatch || brandMatch) {
122
+ seenIds.add(identifier);
123
+ uniqueProducts.push(p);
124
+ }
125
+ }
126
+
127
+ return uniqueProducts;
128
+ }, [productsFromSources, productsFromContent, message.content]);
129
+
104
130
  const hasProducts = allProducts.length > 0;
105
131
 
106
132
  return (