@retrivora-ai/rag-engine 1.5.0 → 1.5.2
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-YTL3SLQU.mjs → chunk-C4UPQX3E.mjs} +8 -13
- package/dist/handlers/index.js +8 -13
- package/dist/handlers/index.mjs +1 -1
- package/dist/index.js +15 -7
- package/dist/index.mjs +15 -7
- package/dist/server.js +8 -13
- package/dist/server.mjs +1 -1
- package/package.json +1 -1
- package/src/components/MessageBubble.tsx +15 -17
- package/src/core/Pipeline.ts +8 -13
|
@@ -2259,22 +2259,17 @@ var Pipeline = class {
|
|
|
2259
2259
|
async initialize() {
|
|
2260
2260
|
var _a, _b;
|
|
2261
2261
|
if (this.initialised) return;
|
|
2262
|
-
const CHART_MARKER = "<!--
|
|
2262
|
+
const CHART_MARKER = "<!-- VIZ_PROTOCOL_V2 -->";
|
|
2263
2263
|
const chartInstruction = `
|
|
2264
2264
|
|
|
2265
2265
|
${CHART_MARKER}
|
|
2266
|
-
### MANDATORY
|
|
2267
|
-
If asked for
|
|
2268
|
-
\`\`\`chart
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
\`\`\`
|
|
2274
|
-
- RULES:
|
|
2275
|
-
1. You MUST include the \`\`\`chart and \`\`\` markers. Naked JSON will NOT render.
|
|
2276
|
-
2. Output ONLY the chart block. No Python snippets. No "here is the data" text.
|
|
2277
|
-
3. Data objects MUST be FLAT. No math (e.g. use 10, NOT 5+5).`;
|
|
2266
|
+
### MANDATORY VISUALIZATION RULES:
|
|
2267
|
+
- If asked for statistics, distribution, or comparisons: You MUST use the \`\`\`chart block.
|
|
2268
|
+
- FORMAT: \`\`\`chart { "type": "pie" | "bar" | "line", "data": [ { "label": "X", "value": 10 } ] } \`\`\`
|
|
2269
|
+
- RULES:
|
|
2270
|
+
1. ALWAYS include the \`\`\`chart and \`\`\` markers.
|
|
2271
|
+
2. NEVER use text, tables, or ASCII art for charts.
|
|
2272
|
+
3. Output ONLY the chart block. No Python, no text descriptions.`;
|
|
2278
2273
|
if (!((_a = this.config.llm.systemPrompt) == null ? void 0 : _a.includes(CHART_MARKER))) {
|
|
2279
2274
|
this.config.llm.systemPrompt = (this.config.llm.systemPrompt || "") + chartInstruction;
|
|
2280
2275
|
}
|
package/dist/handlers/index.js
CHANGED
|
@@ -3822,22 +3822,17 @@ var Pipeline = class {
|
|
|
3822
3822
|
async initialize() {
|
|
3823
3823
|
var _a, _b;
|
|
3824
3824
|
if (this.initialised) return;
|
|
3825
|
-
const CHART_MARKER = "<!--
|
|
3825
|
+
const CHART_MARKER = "<!-- VIZ_PROTOCOL_V2 -->";
|
|
3826
3826
|
const chartInstruction = `
|
|
3827
3827
|
|
|
3828
3828
|
${CHART_MARKER}
|
|
3829
|
-
### MANDATORY
|
|
3830
|
-
If asked for
|
|
3831
|
-
\`\`\`chart
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
\`\`\`
|
|
3837
|
-
- RULES:
|
|
3838
|
-
1. You MUST include the \`\`\`chart and \`\`\` markers. Naked JSON will NOT render.
|
|
3839
|
-
2. Output ONLY the chart block. No Python snippets. No "here is the data" text.
|
|
3840
|
-
3. Data objects MUST be FLAT. No math (e.g. use 10, NOT 5+5).`;
|
|
3829
|
+
### MANDATORY VISUALIZATION RULES:
|
|
3830
|
+
- If asked for statistics, distribution, or comparisons: You MUST use the \`\`\`chart block.
|
|
3831
|
+
- FORMAT: \`\`\`chart { "type": "pie" | "bar" | "line", "data": [ { "label": "X", "value": 10 } ] } \`\`\`
|
|
3832
|
+
- RULES:
|
|
3833
|
+
1. ALWAYS include the \`\`\`chart and \`\`\` markers.
|
|
3834
|
+
2. NEVER use text, tables, or ASCII art for charts.
|
|
3835
|
+
3. Output ONLY the chart block. No Python, no text descriptions.`;
|
|
3841
3836
|
if (!((_a = this.config.llm.systemPrompt) == null ? void 0 : _a.includes(CHART_MARKER))) {
|
|
3842
3837
|
this.config.llm.systemPrompt = (this.config.llm.systemPrompt || "") + chartInstruction;
|
|
3843
3838
|
}
|
package/dist/handlers/index.mjs
CHANGED
package/dist/index.js
CHANGED
|
@@ -503,13 +503,8 @@ function MessageBubble({
|
|
|
503
503
|
};
|
|
504
504
|
});
|
|
505
505
|
}, [sources, isUser]);
|
|
506
|
-
const isVisualizationRequested = import_react5.default.useMemo(() => {
|
|
507
|
-
if (isUser) return false;
|
|
508
|
-
const text = message.content.toLowerCase();
|
|
509
|
-
return message.content.includes("```chart") || text.includes("pie chart") || text.includes("bar chart") || text.includes("line chart") || text.includes("distribution across");
|
|
510
|
-
}, [message.content, isUser]);
|
|
511
506
|
const { productsFromContent, cleanContent } = import_react5.default.useMemo(() => {
|
|
512
|
-
if (isUser
|
|
507
|
+
if (isUser) {
|
|
513
508
|
return { productsFromContent: [], cleanContent: message.content };
|
|
514
509
|
}
|
|
515
510
|
const jsonRegex = /```json\s*([\s\S]*?)\s*```/g;
|
|
@@ -535,7 +530,7 @@ function MessageBubble({
|
|
|
535
530
|
}
|
|
536
531
|
}
|
|
537
532
|
return { productsFromContent: products, cleanContent: content.trim() };
|
|
538
|
-
}, [message.content, isUser
|
|
533
|
+
}, [message.content, isUser]);
|
|
539
534
|
const allProducts = import_react5.default.useMemo(() => {
|
|
540
535
|
if (productsFromContent.length > 0) return productsFromContent;
|
|
541
536
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -555,6 +550,19 @@ function MessageBubble({
|
|
|
555
550
|
const processedMarkdown = import_react5.default.useMemo(() => {
|
|
556
551
|
let raw = cleanContent || message.content;
|
|
557
552
|
raw = raw.replace(/([^\n])\n\|/g, "$1\n\n|").replace(/(\|[^\n]*\|)\n\n+(?=\|)/g, "$1\n");
|
|
553
|
+
if (!isStreaming) {
|
|
554
|
+
raw = raw.replace(/(?:^|\n)\s*\{\s*[\s\S]*?"type":\s*"(?:pie|bar|line|products)"[\s\S]*?\}\s*(?:\n|$)/g, (match) => {
|
|
555
|
+
if (match.includes("```")) return match;
|
|
556
|
+
const type = match.includes('"products"') ? "json" : "chart";
|
|
557
|
+
return `
|
|
558
|
+
|
|
559
|
+
\`\`\`${type}
|
|
560
|
+
${match.trim()}
|
|
561
|
+
\`\`\`
|
|
562
|
+
|
|
563
|
+
`;
|
|
564
|
+
});
|
|
565
|
+
}
|
|
558
566
|
if (isStreaming) {
|
|
559
567
|
raw = raw.replace(/((?:^|\n)\|.*)+/g, (match) => {
|
|
560
568
|
return `
|
package/dist/index.mjs
CHANGED
|
@@ -466,13 +466,8 @@ function MessageBubble({
|
|
|
466
466
|
};
|
|
467
467
|
});
|
|
468
468
|
}, [sources, isUser]);
|
|
469
|
-
const isVisualizationRequested = React5.useMemo(() => {
|
|
470
|
-
if (isUser) return false;
|
|
471
|
-
const text = message.content.toLowerCase();
|
|
472
|
-
return message.content.includes("```chart") || text.includes("pie chart") || text.includes("bar chart") || text.includes("line chart") || text.includes("distribution across");
|
|
473
|
-
}, [message.content, isUser]);
|
|
474
469
|
const { productsFromContent, cleanContent } = React5.useMemo(() => {
|
|
475
|
-
if (isUser
|
|
470
|
+
if (isUser) {
|
|
476
471
|
return { productsFromContent: [], cleanContent: message.content };
|
|
477
472
|
}
|
|
478
473
|
const jsonRegex = /```json\s*([\s\S]*?)\s*```/g;
|
|
@@ -498,7 +493,7 @@ function MessageBubble({
|
|
|
498
493
|
}
|
|
499
494
|
}
|
|
500
495
|
return { productsFromContent: products, cleanContent: content.trim() };
|
|
501
|
-
}, [message.content, isUser
|
|
496
|
+
}, [message.content, isUser]);
|
|
502
497
|
const allProducts = React5.useMemo(() => {
|
|
503
498
|
if (productsFromContent.length > 0) return productsFromContent;
|
|
504
499
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -518,6 +513,19 @@ function MessageBubble({
|
|
|
518
513
|
const processedMarkdown = React5.useMemo(() => {
|
|
519
514
|
let raw = cleanContent || message.content;
|
|
520
515
|
raw = raw.replace(/([^\n])\n\|/g, "$1\n\n|").replace(/(\|[^\n]*\|)\n\n+(?=\|)/g, "$1\n");
|
|
516
|
+
if (!isStreaming) {
|
|
517
|
+
raw = raw.replace(/(?:^|\n)\s*\{\s*[\s\S]*?"type":\s*"(?:pie|bar|line|products)"[\s\S]*?\}\s*(?:\n|$)/g, (match) => {
|
|
518
|
+
if (match.includes("```")) return match;
|
|
519
|
+
const type = match.includes('"products"') ? "json" : "chart";
|
|
520
|
+
return `
|
|
521
|
+
|
|
522
|
+
\`\`\`${type}
|
|
523
|
+
${match.trim()}
|
|
524
|
+
\`\`\`
|
|
525
|
+
|
|
526
|
+
`;
|
|
527
|
+
});
|
|
528
|
+
}
|
|
521
529
|
if (isStreaming) {
|
|
522
530
|
raw = raw.replace(/((?:^|\n)\|.*)+/g, (match) => {
|
|
523
531
|
return `
|
package/dist/server.js
CHANGED
|
@@ -3913,22 +3913,17 @@ var Pipeline = class {
|
|
|
3913
3913
|
async initialize() {
|
|
3914
3914
|
var _a, _b;
|
|
3915
3915
|
if (this.initialised) return;
|
|
3916
|
-
const CHART_MARKER = "<!--
|
|
3916
|
+
const CHART_MARKER = "<!-- VIZ_PROTOCOL_V2 -->";
|
|
3917
3917
|
const chartInstruction = `
|
|
3918
3918
|
|
|
3919
3919
|
${CHART_MARKER}
|
|
3920
|
-
### MANDATORY
|
|
3921
|
-
If asked for
|
|
3922
|
-
\`\`\`chart
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
\`\`\`
|
|
3928
|
-
- RULES:
|
|
3929
|
-
1. You MUST include the \`\`\`chart and \`\`\` markers. Naked JSON will NOT render.
|
|
3930
|
-
2. Output ONLY the chart block. No Python snippets. No "here is the data" text.
|
|
3931
|
-
3. Data objects MUST be FLAT. No math (e.g. use 10, NOT 5+5).`;
|
|
3920
|
+
### MANDATORY VISUALIZATION RULES:
|
|
3921
|
+
- If asked for statistics, distribution, or comparisons: You MUST use the \`\`\`chart block.
|
|
3922
|
+
- FORMAT: \`\`\`chart { "type": "pie" | "bar" | "line", "data": [ { "label": "X", "value": 10 } ] } \`\`\`
|
|
3923
|
+
- RULES:
|
|
3924
|
+
1. ALWAYS include the \`\`\`chart and \`\`\` markers.
|
|
3925
|
+
2. NEVER use text, tables, or ASCII art for charts.
|
|
3926
|
+
3. Output ONLY the chart block. No Python, no text descriptions.`;
|
|
3932
3927
|
if (!((_a = this.config.llm.systemPrompt) == null ? void 0 : _a.includes(CHART_MARKER))) {
|
|
3933
3928
|
this.config.llm.systemPrompt = (this.config.llm.systemPrompt || "") + chartInstruction;
|
|
3934
3929
|
}
|
package/dist/server.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@retrivora-ai/rag-engine",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
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",
|
|
@@ -309,23 +309,9 @@ export function MessageBubble({
|
|
|
309
309
|
});
|
|
310
310
|
}, [sources, isUser]);
|
|
311
311
|
|
|
312
|
-
// ── Visualization Intent Detection ────────────────────────────────────────
|
|
313
|
-
// Robust detection to prevent UI clutter and ensure atomic rendering.
|
|
314
|
-
const isVisualizationRequested = React.useMemo(() => {
|
|
315
|
-
if (isUser) return false;
|
|
316
|
-
const text = message.content.toLowerCase();
|
|
317
|
-
return (
|
|
318
|
-
message.content.includes('```chart') ||
|
|
319
|
-
text.includes('pie chart') ||
|
|
320
|
-
text.includes('bar chart') ||
|
|
321
|
-
text.includes('line chart') ||
|
|
322
|
-
text.includes('distribution across')
|
|
323
|
-
);
|
|
324
|
-
}, [message.content, isUser]);
|
|
325
|
-
|
|
326
312
|
// ── Products + cleaned content from structured JSON blocks in the message ──
|
|
327
313
|
const { productsFromContent, cleanContent } = React.useMemo(() => {
|
|
328
|
-
if (isUser
|
|
314
|
+
if (isUser) {
|
|
329
315
|
return { productsFromContent: [] as Product[], cleanContent: message.content };
|
|
330
316
|
}
|
|
331
317
|
|
|
@@ -353,7 +339,7 @@ export function MessageBubble({
|
|
|
353
339
|
}
|
|
354
340
|
|
|
355
341
|
return { productsFromContent: products, cleanContent: content.trim() };
|
|
356
|
-
}, [message.content, isUser
|
|
342
|
+
}, [message.content, isUser]);
|
|
357
343
|
|
|
358
344
|
// ── Merge & deduplicate products ───────────────────────────────────────────
|
|
359
345
|
const allProducts = React.useMemo<Product[]>(() => {
|
|
@@ -380,7 +366,19 @@ export function MessageBubble({
|
|
|
380
366
|
raw = raw.replace(/([^\n])\n\|/g, '$1\n\n|') // Ensure blank line before table
|
|
381
367
|
.replace(/(\|[^\n]*\|)\n\n+(?=\|)/g, '$1\n'); // Remove blank lines between rows
|
|
382
368
|
|
|
383
|
-
// 2.
|
|
369
|
+
// 2. HEALING: Detect naked JSON charts/products and wrap them if markers are missing
|
|
370
|
+
// This handles models (like Llama 3.2) that often omit the ```chart markers.
|
|
371
|
+
if (!isStreaming) {
|
|
372
|
+
// Look for objects that look like chart or product data
|
|
373
|
+
raw = raw.replace(/(?:^|\n)\s*\{\s*[\s\S]*?"type":\s*"(?:pie|bar|line|products)"[\s\S]*?\}\s*(?:\n|$)/g, (match) => {
|
|
374
|
+
// Only wrap if not already in a code block
|
|
375
|
+
if (match.includes('```')) return match;
|
|
376
|
+
const type = match.includes('"products"') ? 'json' : 'chart';
|
|
377
|
+
return `\n\n\`\`\`${type}\n${match.trim()}\n\`\`\`\n\n`;
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// 3. HIJACKING: If streaming, hide table-like content to prevent raw markdown flashing.
|
|
384
382
|
if (isStreaming) {
|
|
385
383
|
raw = raw.replace(/((?:^|\n)\|.*)+/g, (match) => {
|
|
386
384
|
return `\n\n\`\`\`table-loading\n${match.trim()}\n\`\`\`\n\n`;
|
package/src/core/Pipeline.ts
CHANGED
|
@@ -101,20 +101,15 @@ export class Pipeline {
|
|
|
101
101
|
|
|
102
102
|
// Augment system prompt with a Universal Visualization Protocol
|
|
103
103
|
// We use a unique marker to ensure this is only injected once but is ALWAYS present.
|
|
104
|
-
const CHART_MARKER = '<!--
|
|
104
|
+
const CHART_MARKER = '<!-- VIZ_PROTOCOL_V2 -->';
|
|
105
105
|
const chartInstruction = `\n\n${CHART_MARKER}
|
|
106
|
-
### MANDATORY
|
|
107
|
-
If asked for
|
|
108
|
-
\`\`\`chart
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
\`\`\`
|
|
114
|
-
- RULES:
|
|
115
|
-
1. You MUST include the \`\`\`chart and \`\`\` markers. Naked JSON will NOT render.
|
|
116
|
-
2. Output ONLY the chart block. No Python snippets. No "here is the data" text.
|
|
117
|
-
3. Data objects MUST be FLAT. No math (e.g. use 10, NOT 5+5).`;
|
|
106
|
+
### MANDATORY VISUALIZATION RULES:
|
|
107
|
+
- If asked for statistics, distribution, or comparisons: You MUST use the \`\`\`chart block.
|
|
108
|
+
- FORMAT: \`\`\`chart { "type": "pie" | "bar" | "line", "data": [ { "label": "X", "value": 10 } ] } \`\`\`
|
|
109
|
+
- RULES:
|
|
110
|
+
1. ALWAYS include the \`\`\`chart and \`\`\` markers.
|
|
111
|
+
2. NEVER use text, tables, or ASCII art for charts.
|
|
112
|
+
3. Output ONLY the chart block. No Python, no text descriptions.`;
|
|
118
113
|
|
|
119
114
|
if (!this.config.llm.systemPrompt?.includes(CHART_MARKER)) {
|
|
120
115
|
this.config.llm.systemPrompt = (this.config.llm.systemPrompt || '') + chartInstruction;
|