@retrivora-ai/rag-engine 1.3.3 → 1.3.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/index.js +11 -14
- package/dist/index.mjs +11 -14
- package/package.json +1 -1
- package/src/components/MessageBubble.tsx +25 -19
package/dist/index.js
CHANGED
|
@@ -335,10 +335,9 @@ function sanitizeJson(raw) {
|
|
|
335
335
|
s = s.replace(/,\s*([}\]])/g, "$1");
|
|
336
336
|
s = s.replace(/([{,])\s*""\s*(?=[,}])/g, "$1");
|
|
337
337
|
{
|
|
338
|
+
const stack = [];
|
|
338
339
|
let inString = false;
|
|
339
340
|
let escape = false;
|
|
340
|
-
let braces = 0;
|
|
341
|
-
let brackets = 0;
|
|
342
341
|
for (const ch of s) {
|
|
343
342
|
if (escape) {
|
|
344
343
|
escape = false;
|
|
@@ -353,23 +352,21 @@ function sanitizeJson(raw) {
|
|
|
353
352
|
continue;
|
|
354
353
|
}
|
|
355
354
|
if (inString) continue;
|
|
356
|
-
if (ch === "{")
|
|
357
|
-
|
|
358
|
-
else if (ch === "
|
|
359
|
-
|
|
355
|
+
if (ch === "{" || ch === "[") {
|
|
356
|
+
stack.push(ch);
|
|
357
|
+
} else if (ch === "}") {
|
|
358
|
+
if (stack[stack.length - 1] === "{") stack.pop();
|
|
359
|
+
} else if (ch === "]") {
|
|
360
|
+
if (stack[stack.length - 1] === "[") stack.pop();
|
|
361
|
+
}
|
|
360
362
|
}
|
|
361
363
|
if (inString) s += '"';
|
|
362
|
-
|
|
363
|
-
s += "]";
|
|
364
|
-
brackets--;
|
|
365
|
-
}
|
|
366
|
-
while (braces > 0) {
|
|
367
|
-
s += "}";
|
|
368
|
-
braces--;
|
|
364
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
365
|
+
s += stack[i] === "{" ? "}" : "]";
|
|
369
366
|
}
|
|
370
367
|
}
|
|
371
368
|
const lastClose = Math.max(s.lastIndexOf("}"), s.lastIndexOf("]"));
|
|
372
|
-
if (lastClose !== -1 && lastClose < s.length - 1) {
|
|
369
|
+
if (lastClose !== -1 && lastClose < s.length - 1 && /\S/.test(s.slice(lastClose + 1))) {
|
|
373
370
|
s = s.substring(0, lastClose + 1);
|
|
374
371
|
}
|
|
375
372
|
return s;
|
package/dist/index.mjs
CHANGED
|
@@ -298,10 +298,9 @@ function sanitizeJson(raw) {
|
|
|
298
298
|
s = s.replace(/,\s*([}\]])/g, "$1");
|
|
299
299
|
s = s.replace(/([{,])\s*""\s*(?=[,}])/g, "$1");
|
|
300
300
|
{
|
|
301
|
+
const stack = [];
|
|
301
302
|
let inString = false;
|
|
302
303
|
let escape = false;
|
|
303
|
-
let braces = 0;
|
|
304
|
-
let brackets = 0;
|
|
305
304
|
for (const ch of s) {
|
|
306
305
|
if (escape) {
|
|
307
306
|
escape = false;
|
|
@@ -316,23 +315,21 @@ function sanitizeJson(raw) {
|
|
|
316
315
|
continue;
|
|
317
316
|
}
|
|
318
317
|
if (inString) continue;
|
|
319
|
-
if (ch === "{")
|
|
320
|
-
|
|
321
|
-
else if (ch === "
|
|
322
|
-
|
|
318
|
+
if (ch === "{" || ch === "[") {
|
|
319
|
+
stack.push(ch);
|
|
320
|
+
} else if (ch === "}") {
|
|
321
|
+
if (stack[stack.length - 1] === "{") stack.pop();
|
|
322
|
+
} else if (ch === "]") {
|
|
323
|
+
if (stack[stack.length - 1] === "[") stack.pop();
|
|
324
|
+
}
|
|
323
325
|
}
|
|
324
326
|
if (inString) s += '"';
|
|
325
|
-
|
|
326
|
-
s += "]";
|
|
327
|
-
brackets--;
|
|
328
|
-
}
|
|
329
|
-
while (braces > 0) {
|
|
330
|
-
s += "}";
|
|
331
|
-
braces--;
|
|
327
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
328
|
+
s += stack[i] === "{" ? "}" : "]";
|
|
332
329
|
}
|
|
333
330
|
}
|
|
334
331
|
const lastClose = Math.max(s.lastIndexOf("}"), s.lastIndexOf("]"));
|
|
335
|
-
if (lastClose !== -1 && lastClose < s.length - 1) {
|
|
332
|
+
if (lastClose !== -1 && lastClose < s.length - 1 && /\S/.test(s.slice(lastClose + 1))) {
|
|
336
333
|
s = s.substring(0, lastClose + 1);
|
|
337
334
|
}
|
|
338
335
|
return s;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@retrivora-ai/rag-engine",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
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",
|
|
@@ -46,36 +46,45 @@ function sanitizeJson(raw: string): string {
|
|
|
46
46
|
// 6. Remove completely empty key-value pairs left by prior cleanup
|
|
47
47
|
s = s.replace(/([{,])\s*""\s*(?=[,}])/g, '$1');
|
|
48
48
|
|
|
49
|
-
// 7.
|
|
50
|
-
//
|
|
49
|
+
// 7. Stack-based structure balancer.
|
|
50
|
+
// Walk every character, maintain a stack of openers so we close each
|
|
51
|
+
// unclosed structure with its exact matching closer — in the right order.
|
|
52
|
+
// This is the critical fix: a flat counter approach appends all ]'s then
|
|
53
|
+
// all }'s, which corrupts nested structures like {..., [..., {...}]}.
|
|
51
54
|
{
|
|
55
|
+
const stack: ('{' | '[')[] = [];
|
|
52
56
|
let inString = false;
|
|
53
57
|
let escape = false;
|
|
54
|
-
let braces = 0;
|
|
55
|
-
let brackets = 0;
|
|
56
58
|
|
|
57
59
|
for (const ch of s) {
|
|
58
60
|
if (escape) { escape = false; continue; }
|
|
59
61
|
if (ch === '\\' && inString) { escape = true; continue; }
|
|
60
62
|
if (ch === '"') { inString = !inString; continue; }
|
|
61
63
|
if (inString) continue;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
else if (ch === '
|
|
64
|
+
|
|
65
|
+
if (ch === '{' || ch === '[') {
|
|
66
|
+
stack.push(ch);
|
|
67
|
+
} else if (ch === '}') {
|
|
68
|
+
if (stack[stack.length - 1] === '{') stack.pop();
|
|
69
|
+
// mismatched closer — leave stack alone (sanitize step 5 handles trailing commas)
|
|
70
|
+
} else if (ch === ']') {
|
|
71
|
+
if (stack[stack.length - 1] === '[') stack.pop();
|
|
72
|
+
}
|
|
66
73
|
}
|
|
67
74
|
|
|
68
|
-
// Close any
|
|
75
|
+
// Close any unterminated string literal first
|
|
69
76
|
if (inString) s += '"';
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
77
|
+
|
|
78
|
+
// Close every unclosed opener in reverse (innermost first)
|
|
79
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
80
|
+
s += stack[i] === '{' ? '}' : ']';
|
|
81
|
+
}
|
|
73
82
|
}
|
|
74
83
|
|
|
75
|
-
// 8. Trim
|
|
76
|
-
//
|
|
84
|
+
// 8. Trim trailing garbage that appears after the outermost closing char.
|
|
85
|
+
// Only fires when something non-whitespace follows the last } or ].
|
|
77
86
|
const lastClose = Math.max(s.lastIndexOf('}'), s.lastIndexOf(']'));
|
|
78
|
-
if (lastClose !== -1 && lastClose < s.length - 1) {
|
|
87
|
+
if (lastClose !== -1 && lastClose < s.length - 1 && /\S/.test(s.slice(lastClose + 1))) {
|
|
79
88
|
s = s.substring(0, lastClose + 1);
|
|
80
89
|
}
|
|
81
90
|
|
|
@@ -211,10 +220,7 @@ export function MessageBubble({
|
|
|
211
220
|
const mentioned =
|
|
212
221
|
contentLower.includes(p.name.toLowerCase()) ||
|
|
213
222
|
(p.brand ? contentLower.includes(p.brand.toLowerCase()) : false);
|
|
214
|
-
if (mentioned) {
|
|
215
|
-
seen.add(id);
|
|
216
|
-
return true;
|
|
217
|
-
}
|
|
223
|
+
if (mentioned) { seen.add(id); return true; }
|
|
218
224
|
return false;
|
|
219
225
|
});
|
|
220
226
|
}, [productsFromSources, productsFromContent, message.content]);
|