@retrivora-ai/rag-engine 1.4.9 → 1.5.0

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.
@@ -2263,18 +2263,18 @@ var Pipeline = class {
2263
2263
  const chartInstruction = `
2264
2264
 
2265
2265
  ${CHART_MARKER}
2266
- ### MASTER DATA VISUALIZATION PROTOCOL:
2267
- You are an expert data analyst. When asked to visualize or compare data retrieved from the context:
2268
- 1. DECIDE the best chart type: 'pie' (for parts-of-a-whole), 'bar' (for category comparisons), or 'line' (for trends).
2269
- 2. TRANSFORM arbitrary metadata from the context into a FLAT list of objects. Extract relevant keys dynamically.
2270
- 3. OUTPUT a \`\`\`chart\`\`\` code block using this JSON format:
2271
- {
2272
- "type": "bar" | "line" | "pie",
2273
- "xAxisKey": "key_for_labels",
2274
- "dataKeys": ["key_for_values"],
2275
- "data": [ { "key_for_labels": "Category A", "key_for_values": 100 }, ... ]
2276
- }
2277
- 4. RULES: Valid JSON only. No math. No text-based charts. No markdown tables for graphs. If showing a chart, DO NOT output a "products" JSON carousel.`;
2266
+ ### MANDATORY CHART PROTOCOL:
2267
+ If asked for a chart (pie, bar, line), you MUST output exactly ONE block using this structure:
2268
+ \`\`\`chart
2269
+ {
2270
+ "type": "pie",
2271
+ "data": [ { "label": "Item A", "value": 10 }, { "label": "Item B", "value": 20 } ]
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).`;
2278
2278
  if (!((_a = this.config.llm.systemPrompt) == null ? void 0 : _a.includes(CHART_MARKER))) {
2279
2279
  this.config.llm.systemPrompt = (this.config.llm.systemPrompt || "") + chartInstruction;
2280
2280
  }
@@ -3826,18 +3826,18 @@ var Pipeline = class {
3826
3826
  const chartInstruction = `
3827
3827
 
3828
3828
  ${CHART_MARKER}
3829
- ### MASTER DATA VISUALIZATION PROTOCOL:
3830
- You are an expert data analyst. When asked to visualize or compare data retrieved from the context:
3831
- 1. DECIDE the best chart type: 'pie' (for parts-of-a-whole), 'bar' (for category comparisons), or 'line' (for trends).
3832
- 2. TRANSFORM arbitrary metadata from the context into a FLAT list of objects. Extract relevant keys dynamically.
3833
- 3. OUTPUT a \`\`\`chart\`\`\` code block using this JSON format:
3834
- {
3835
- "type": "bar" | "line" | "pie",
3836
- "xAxisKey": "key_for_labels",
3837
- "dataKeys": ["key_for_values"],
3838
- "data": [ { "key_for_labels": "Category A", "key_for_values": 100 }, ... ]
3839
- }
3840
- 4. RULES: Valid JSON only. No math. No text-based charts. No markdown tables for graphs. If showing a chart, DO NOT output a "products" JSON carousel.`;
3829
+ ### MANDATORY CHART PROTOCOL:
3830
+ If asked for a chart (pie, bar, line), you MUST output exactly ONE block using this structure:
3831
+ \`\`\`chart
3832
+ {
3833
+ "type": "pie",
3834
+ "data": [ { "label": "Item A", "value": 10 }, { "label": "Item B", "value": 20 } ]
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).`;
3841
3841
  if (!((_a = this.config.llm.systemPrompt) == null ? void 0 : _a.includes(CHART_MARKER))) {
3842
3842
  this.config.llm.systemPrompt = (this.config.llm.systemPrompt || "") + chartInstruction;
3843
3843
  }
@@ -9,7 +9,7 @@ import {
9
9
  sseFrame,
10
10
  sseMetaFrame,
11
11
  sseTextFrame
12
- } from "../chunk-FHNGNXXS.mjs";
12
+ } from "../chunk-YTL3SLQU.mjs";
13
13
  import "../chunk-YLTMFW4M.mjs";
14
14
  import "../chunk-X4TOT24V.mjs";
15
15
  export {
package/dist/index.js CHANGED
@@ -503,10 +503,13 @@ 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]);
506
511
  const { productsFromContent, cleanContent } = import_react5.default.useMemo(() => {
507
- if (isUser) return { productsFromContent: [], cleanContent: message.content };
508
- const isVisualization = message.content.includes("```chart") || message.content.toLowerCase().includes("pie chart") || message.content.toLowerCase().includes("bar chart") || message.content.toLowerCase().includes("distribution");
509
- if (isVisualization) {
512
+ if (isUser || isVisualizationRequested) {
510
513
  return { productsFromContent: [], cleanContent: message.content };
511
514
  }
512
515
  const jsonRegex = /```json\s*([\s\S]*?)\s*```/g;
@@ -532,7 +535,7 @@ function MessageBubble({
532
535
  }
533
536
  }
534
537
  return { productsFromContent: products, cleanContent: content.trim() };
535
- }, [message.content, isUser]);
538
+ }, [message.content, isUser, isVisualizationRequested]);
536
539
  const allProducts = import_react5.default.useMemo(() => {
537
540
  if (productsFromContent.length > 0) return productsFromContent;
538
541
  const seen = /* @__PURE__ */ new Set();
package/dist/index.mjs CHANGED
@@ -466,10 +466,13 @@ 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]);
469
474
  const { productsFromContent, cleanContent } = React5.useMemo(() => {
470
- if (isUser) return { productsFromContent: [], cleanContent: message.content };
471
- const isVisualization = message.content.includes("```chart") || message.content.toLowerCase().includes("pie chart") || message.content.toLowerCase().includes("bar chart") || message.content.toLowerCase().includes("distribution");
472
- if (isVisualization) {
475
+ if (isUser || isVisualizationRequested) {
473
476
  return { productsFromContent: [], cleanContent: message.content };
474
477
  }
475
478
  const jsonRegex = /```json\s*([\s\S]*?)\s*```/g;
@@ -495,7 +498,7 @@ function MessageBubble({
495
498
  }
496
499
  }
497
500
  return { productsFromContent: products, cleanContent: content.trim() };
498
- }, [message.content, isUser]);
501
+ }, [message.content, isUser, isVisualizationRequested]);
499
502
  const allProducts = React5.useMemo(() => {
500
503
  if (productsFromContent.length > 0) return productsFromContent;
501
504
  const seen = /* @__PURE__ */ new Set();
package/dist/server.js CHANGED
@@ -3917,18 +3917,18 @@ var Pipeline = class {
3917
3917
  const chartInstruction = `
3918
3918
 
3919
3919
  ${CHART_MARKER}
3920
- ### MASTER DATA VISUALIZATION PROTOCOL:
3921
- You are an expert data analyst. When asked to visualize or compare data retrieved from the context:
3922
- 1. DECIDE the best chart type: 'pie' (for parts-of-a-whole), 'bar' (for category comparisons), or 'line' (for trends).
3923
- 2. TRANSFORM arbitrary metadata from the context into a FLAT list of objects. Extract relevant keys dynamically.
3924
- 3. OUTPUT a \`\`\`chart\`\`\` code block using this JSON format:
3925
- {
3926
- "type": "bar" | "line" | "pie",
3927
- "xAxisKey": "key_for_labels",
3928
- "dataKeys": ["key_for_values"],
3929
- "data": [ { "key_for_labels": "Category A", "key_for_values": 100 }, ... ]
3930
- }
3931
- 4. RULES: Valid JSON only. No math. No text-based charts. No markdown tables for graphs. If showing a chart, DO NOT output a "products" JSON carousel.`;
3920
+ ### MANDATORY CHART PROTOCOL:
3921
+ If asked for a chart (pie, bar, line), you MUST output exactly ONE block using this structure:
3922
+ \`\`\`chart
3923
+ {
3924
+ "type": "pie",
3925
+ "data": [ { "label": "Item A", "value": 10 }, { "label": "Item B", "value": 20 } ]
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).`;
3932
3932
  if (!((_a = this.config.llm.systemPrompt) == null ? void 0 : _a.includes(CHART_MARKER))) {
3933
3933
  this.config.llm.systemPrompt = (this.config.llm.systemPrompt || "") + chartInstruction;
3934
3934
  }
package/dist/server.mjs CHANGED
@@ -39,7 +39,7 @@ import {
39
39
  sseFrame,
40
40
  sseMetaFrame,
41
41
  sseTextFrame
42
- } from "./chunk-FHNGNXXS.mjs";
42
+ } from "./chunk-YTL3SLQU.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.4.9",
3
+ "version": "1.5.0",
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,18 +309,23 @@ 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
+
312
326
  // ── Products + cleaned content from structured JSON blocks in the message ──
313
327
  const { productsFromContent, cleanContent } = React.useMemo(() => {
314
- if (isUser) return { productsFromContent: [] as Product[], cleanContent: message.content };
315
-
316
- // If the message contains a chart or refers to visualization, suppress the product carousel
317
- const isVisualization =
318
- message.content.includes('```chart') ||
319
- message.content.toLowerCase().includes('pie chart') ||
320
- message.content.toLowerCase().includes('bar chart') ||
321
- message.content.toLowerCase().includes('distribution');
322
-
323
- if (isVisualization) {
328
+ if (isUser || isVisualizationRequested) {
324
329
  return { productsFromContent: [] as Product[], cleanContent: message.content };
325
330
  }
326
331
 
@@ -348,7 +353,7 @@ export function MessageBubble({
348
353
  }
349
354
 
350
355
  return { productsFromContent: products, cleanContent: content.trim() };
351
- }, [message.content, isUser]);
356
+ }, [message.content, isUser, isVisualizationRequested]);
352
357
 
353
358
  // ── Merge & deduplicate products ───────────────────────────────────────────
354
359
  const allProducts = React.useMemo<Product[]>(() => {
@@ -103,18 +103,18 @@ export class Pipeline {
103
103
  // We use a unique marker to ensure this is only injected once but is ALWAYS present.
104
104
  const CHART_MARKER = '<!-- VIZ_PROTOCOL_V1 -->';
105
105
  const chartInstruction = `\n\n${CHART_MARKER}
106
- ### MASTER DATA VISUALIZATION PROTOCOL:
107
- You are an expert data analyst. When asked to visualize or compare data retrieved from the context:
108
- 1. DECIDE the best chart type: 'pie' (for parts-of-a-whole), 'bar' (for category comparisons), or 'line' (for trends).
109
- 2. TRANSFORM arbitrary metadata from the context into a FLAT list of objects. Extract relevant keys dynamically.
110
- 3. OUTPUT a \`\`\`chart\`\`\` code block using this JSON format:
111
- {
112
- "type": "bar" | "line" | "pie",
113
- "xAxisKey": "key_for_labels",
114
- "dataKeys": ["key_for_values"],
115
- "data": [ { "key_for_labels": "Category A", "key_for_values": 100 }, ... ]
116
- }
117
- 4. RULES: Valid JSON only. No math. No text-based charts. No markdown tables for graphs. If showing a chart, DO NOT output a "products" JSON carousel.`;
106
+ ### MANDATORY CHART PROTOCOL:
107
+ If asked for a chart (pie, bar, line), you MUST output exactly ONE block using this structure:
108
+ \`\`\`chart
109
+ {
110
+ "type": "pie",
111
+ "data": [ { "label": "Item A", "value": 10 }, { "label": "Item B", "value": 20 } ]
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).`;
118
118
 
119
119
  if (!this.config.llm.systemPrompt?.includes(CHART_MARKER)) {
120
120
  this.config.llm.systemPrompt = (this.config.llm.systemPrompt || '') + chartInstruction;