@retrivora-ai/rag-engine 1.5.1 → 1.5.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.
@@ -2259,18 +2259,17 @@ var Pipeline = class {
2259
2259
  async initialize() {
2260
2260
  var _a, _b;
2261
2261
  if (this.initialised) return;
2262
- const CHART_MARKER = "<!-- VIZ_PROTOCOL_V1 -->";
2262
+ const CHART_MARKER = "<!-- VIZ_PROTOCOL_V2 -->";
2263
2263
  const chartInstruction = `
2264
2264
 
2265
2265
  ${CHART_MARKER}
2266
- ### DATA REPRESENTATION TOOLBOX:
2267
- You have two specialized formats for structured data. Choose the one (or both) that provides the most value to the user:
2268
- 1. \`\`\`chart\`\`\` block: Best for statistics, distributions, and comparisons.
2269
- Format: { "type": "bar" | "line" | "pie", "data": [ { "label": "X", "value": 10 } ] }
2270
- 2. \`\`\`json\`\`\` (products) block: Best for listing or browsing specific items.
2271
- Format: { "type": "products", "data": [...] }
2272
-
2273
- RULES: Output MUST be valid JSON. Data objects MUST be FLAT. Never draw charts with text or markdown tables.`;
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.`;
2274
2273
  if (!((_a = this.config.llm.systemPrompt) == null ? void 0 : _a.includes(CHART_MARKER))) {
2275
2274
  this.config.llm.systemPrompt = (this.config.llm.systemPrompt || "") + chartInstruction;
2276
2275
  }
@@ -3822,18 +3822,17 @@ var Pipeline = class {
3822
3822
  async initialize() {
3823
3823
  var _a, _b;
3824
3824
  if (this.initialised) return;
3825
- const CHART_MARKER = "<!-- VIZ_PROTOCOL_V1 -->";
3825
+ const CHART_MARKER = "<!-- VIZ_PROTOCOL_V2 -->";
3826
3826
  const chartInstruction = `
3827
3827
 
3828
3828
  ${CHART_MARKER}
3829
- ### DATA REPRESENTATION TOOLBOX:
3830
- You have two specialized formats for structured data. Choose the one (or both) that provides the most value to the user:
3831
- 1. \`\`\`chart\`\`\` block: Best for statistics, distributions, and comparisons.
3832
- Format: { "type": "bar" | "line" | "pie", "data": [ { "label": "X", "value": 10 } ] }
3833
- 2. \`\`\`json\`\`\` (products) block: Best for listing or browsing specific items.
3834
- Format: { "type": "products", "data": [...] }
3835
-
3836
- RULES: Output MUST be valid JSON. Data objects MUST be FLAT. Never draw charts with text or markdown tables.`;
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.`;
3837
3836
  if (!((_a = this.config.llm.systemPrompt) == null ? void 0 : _a.includes(CHART_MARKER))) {
3838
3837
  this.config.llm.systemPrompt = (this.config.llm.systemPrompt || "") + chartInstruction;
3839
3838
  }
@@ -9,7 +9,7 @@ import {
9
9
  sseFrame,
10
10
  sseMetaFrame,
11
11
  sseTextFrame
12
- } from "../chunk-NXEX6XM6.mjs";
12
+ } from "../chunk-C4UPQX3E.mjs";
13
13
  import "../chunk-YLTMFW4M.mjs";
14
14
  import "../chunk-X4TOT24V.mjs";
15
15
  export {
package/dist/index.js CHANGED
@@ -445,12 +445,11 @@ function ChartBlock({ rawContent, primaryColor, accentColor, isStreaming }) {
445
445
  if (isStreaming) return { loading: true };
446
446
  if (!rawContent || rawContent === "undefined") return { error: "Empty visualization config." };
447
447
  try {
448
- const sanitized = sanitizeJson(rawContent);
449
- const config2 = JSON.parse(sanitized);
448
+ const clean = rawContent.replace(/^```[a-z]*\s*/i, "").replace(/```\s*$/, "").trim();
449
+ const config2 = JSON.parse(sanitizeJson(clean));
450
450
  return { config: config2 };
451
451
  } catch (err) {
452
- const sanitized = sanitizeJson(rawContent);
453
- console.error("[ChartBlock] Parsing failed.\nError:", err, "\nSanitized:\n", sanitized);
452
+ console.error("[ChartBlock] Parsing failed.\nError:", err);
454
453
  return { error: String(err) };
455
454
  }
456
455
  }, [rawContent, isStreaming]);
@@ -550,6 +549,19 @@ function MessageBubble({
550
549
  const processedMarkdown = import_react5.default.useMemo(() => {
551
550
  let raw = cleanContent || message.content;
552
551
  raw = raw.replace(/([^\n])\n\|/g, "$1\n\n|").replace(/(\|[^\n]*\|)\n\n+(?=\|)/g, "$1\n");
552
+ if (!isStreaming) {
553
+ raw = raw.replace(/(?:^|\n)\s*\{\s*[\s\S]*?"type":\s*"(?:pie|bar|line|products)"[\s\S]*?\}\s*(?:\n|$)/g, (match) => {
554
+ if (match.includes("```")) return match;
555
+ const type = match.includes('"products"') ? "json" : "chart";
556
+ return `
557
+
558
+ \`\`\`${type}
559
+ ${match.trim()}
560
+ \`\`\`
561
+
562
+ `;
563
+ });
564
+ }
553
565
  if (isStreaming) {
554
566
  raw = raw.replace(/((?:^|\n)\|.*)+/g, (match) => {
555
567
  return `
package/dist/index.mjs CHANGED
@@ -408,12 +408,11 @@ function ChartBlock({ rawContent, primaryColor, accentColor, isStreaming }) {
408
408
  if (isStreaming) return { loading: true };
409
409
  if (!rawContent || rawContent === "undefined") return { error: "Empty visualization config." };
410
410
  try {
411
- const sanitized = sanitizeJson(rawContent);
412
- const config2 = JSON.parse(sanitized);
411
+ const clean = rawContent.replace(/^```[a-z]*\s*/i, "").replace(/```\s*$/, "").trim();
412
+ const config2 = JSON.parse(sanitizeJson(clean));
413
413
  return { config: config2 };
414
414
  } catch (err) {
415
- const sanitized = sanitizeJson(rawContent);
416
- console.error("[ChartBlock] Parsing failed.\nError:", err, "\nSanitized:\n", sanitized);
415
+ console.error("[ChartBlock] Parsing failed.\nError:", err);
417
416
  return { error: String(err) };
418
417
  }
419
418
  }, [rawContent, isStreaming]);
@@ -513,6 +512,19 @@ function MessageBubble({
513
512
  const processedMarkdown = React5.useMemo(() => {
514
513
  let raw = cleanContent || message.content;
515
514
  raw = raw.replace(/([^\n])\n\|/g, "$1\n\n|").replace(/(\|[^\n]*\|)\n\n+(?=\|)/g, "$1\n");
515
+ if (!isStreaming) {
516
+ raw = raw.replace(/(?:^|\n)\s*\{\s*[\s\S]*?"type":\s*"(?:pie|bar|line|products)"[\s\S]*?\}\s*(?:\n|$)/g, (match) => {
517
+ if (match.includes("```")) return match;
518
+ const type = match.includes('"products"') ? "json" : "chart";
519
+ return `
520
+
521
+ \`\`\`${type}
522
+ ${match.trim()}
523
+ \`\`\`
524
+
525
+ `;
526
+ });
527
+ }
516
528
  if (isStreaming) {
517
529
  raw = raw.replace(/((?:^|\n)\|.*)+/g, (match) => {
518
530
  return `
package/dist/server.js CHANGED
@@ -3913,18 +3913,17 @@ var Pipeline = class {
3913
3913
  async initialize() {
3914
3914
  var _a, _b;
3915
3915
  if (this.initialised) return;
3916
- const CHART_MARKER = "<!-- VIZ_PROTOCOL_V1 -->";
3916
+ const CHART_MARKER = "<!-- VIZ_PROTOCOL_V2 -->";
3917
3917
  const chartInstruction = `
3918
3918
 
3919
3919
  ${CHART_MARKER}
3920
- ### DATA REPRESENTATION TOOLBOX:
3921
- You have two specialized formats for structured data. Choose the one (or both) that provides the most value to the user:
3922
- 1. \`\`\`chart\`\`\` block: Best for statistics, distributions, and comparisons.
3923
- Format: { "type": "bar" | "line" | "pie", "data": [ { "label": "X", "value": 10 } ] }
3924
- 2. \`\`\`json\`\`\` (products) block: Best for listing or browsing specific items.
3925
- Format: { "type": "products", "data": [...] }
3926
-
3927
- RULES: Output MUST be valid JSON. Data objects MUST be FLAT. Never draw charts with text or markdown tables.`;
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.`;
3928
3927
  if (!((_a = this.config.llm.systemPrompt) == null ? void 0 : _a.includes(CHART_MARKER))) {
3929
3928
  this.config.llm.systemPrompt = (this.config.llm.systemPrompt || "") + chartInstruction;
3930
3929
  }
package/dist/server.mjs CHANGED
@@ -39,7 +39,7 @@ import {
39
39
  sseFrame,
40
40
  sseMetaFrame,
41
41
  sseTextFrame
42
- } from "./chunk-NXEX6XM6.mjs";
42
+ } from "./chunk-C4UPQX3E.mjs";
43
43
  import "./chunk-YLTMFW4M.mjs";
44
44
  import {
45
45
  PineconeProvider
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retrivora-ai/rag-engine",
3
- "version": "1.5.1",
3
+ "version": "1.5.3",
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",
@@ -228,12 +228,14 @@ function ChartBlock({ rawContent, primaryColor, accentColor, isStreaming }: Char
228
228
  if (isStreaming) return { loading: true };
229
229
  if (!rawContent || rawContent === 'undefined') return { error: 'Empty visualization config.' };
230
230
  try {
231
- const sanitized = sanitizeJson(rawContent);
232
- const config = JSON.parse(sanitized) as ParsedConfig;
231
+ const clean = rawContent
232
+ .replace(/^```[a-z]*\s*/i, '')
233
+ .replace(/```\s*$/, '')
234
+ .trim();
235
+ const config = JSON.parse(sanitizeJson(clean)) as ParsedConfig;
233
236
  return { config };
234
237
  } catch (err) {
235
- const sanitized = sanitizeJson(rawContent);
236
- console.error('[ChartBlock] Parsing failed.\nError:', err, '\nSanitized:\n', sanitized);
238
+ console.error('[ChartBlock] Parsing failed.\nError:', err);
237
239
  return { error: String(err) };
238
240
  }
239
241
  }, [rawContent, isStreaming]);
@@ -366,7 +368,19 @@ export function MessageBubble({
366
368
  raw = raw.replace(/([^\n])\n\|/g, '$1\n\n|') // Ensure blank line before table
367
369
  .replace(/(\|[^\n]*\|)\n\n+(?=\|)/g, '$1\n'); // Remove blank lines between rows
368
370
 
369
- // 2. HIJACKING: If streaming, hide table-like content to prevent raw markdown flashing.
371
+ // 2. HEALING: Detect naked JSON charts/products and wrap them if markers are missing
372
+ // This handles models (like Llama 3.2) that often omit the ```chart markers.
373
+ if (!isStreaming) {
374
+ // Look for objects that look like chart or product data
375
+ raw = raw.replace(/(?:^|\n)\s*\{\s*[\s\S]*?"type":\s*"(?:pie|bar|line|products)"[\s\S]*?\}\s*(?:\n|$)/g, (match) => {
376
+ // Only wrap if not already in a code block
377
+ if (match.includes('```')) return match;
378
+ const type = match.includes('"products"') ? 'json' : 'chart';
379
+ return `\n\n\`\`\`${type}\n${match.trim()}\n\`\`\`\n\n`;
380
+ });
381
+ }
382
+
383
+ // 3. HIJACKING: If streaming, hide table-like content to prevent raw markdown flashing.
370
384
  if (isStreaming) {
371
385
  raw = raw.replace(/((?:^|\n)\|.*)+/g, (match) => {
372
386
  return `\n\n\`\`\`table-loading\n${match.trim()}\n\`\`\`\n\n`;
@@ -101,16 +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 = '<!-- VIZ_PROTOCOL_V1 -->';
104
+ const CHART_MARKER = '<!-- VIZ_PROTOCOL_V2 -->';
105
105
  const chartInstruction = `\n\n${CHART_MARKER}
106
- ### DATA REPRESENTATION TOOLBOX:
107
- You have two specialized formats for structured data. Choose the one (or both) that provides the most value to the user:
108
- 1. \`\`\`chart\`\`\` block: Best for statistics, distributions, and comparisons.
109
- Format: { "type": "bar" | "line" | "pie", "data": [ { "label": "X", "value": 10 } ] }
110
- 2. \`\`\`json\`\`\` (products) block: Best for listing or browsing specific items.
111
- Format: { "type": "products", "data": [...] }
112
-
113
- RULES: Output MUST be valid JSON. Data objects MUST be FLAT. Never draw charts with text or markdown tables.`;
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.`;
114
113
 
115
114
  if (!this.config.llm.systemPrompt?.includes(CHART_MARKER)) {
116
115
  this.config.llm.systemPrompt = (this.config.llm.systemPrompt || '') + chartInstruction;