@retrivora-ai/rag-engine 1.5.8 → 1.5.9

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
@@ -248,6 +248,7 @@ function DynamicChart({
248
248
  const isCompact = viewportSize === "compact" || containerWidth > 0 && containerWidth < 420;
249
249
  const isMedium = !isCompact && (viewportSize === "medium" || containerWidth > 0 && containerWidth < 640);
250
250
  const chartHeightClass = isTiny ? "h-48 min-h-[180px]" : isCompact ? "h-56 min-h-[220px]" : isMedium ? "h-64 min-h-[250px]" : "h-72 min-h-[280px]";
251
+ const pieCanvasMaxWidthClass = isTiny ? "max-w-[11rem]" : isCompact ? "max-w-[14rem]" : isMedium ? "max-w-[16rem]" : "max-w-[18rem]";
251
252
  const pieOuterRadius = isTiny ? 44 : isCompact ? 56 : isMedium ? 68 : 80;
252
253
  const pieLabel = ({ name, percent }) => isTiny ? "" : isCompact ? `${name}` : `${name} ${((percent != null ? percent : 0) * 100).toFixed(0)}%`;
253
254
  const axisTick = { fontSize: isTiny ? 9 : isCompact ? 10 : 12, fill: "#64748b" };
@@ -357,7 +358,7 @@ function DynamicChart({
357
358
  return row;
358
359
  };
359
360
  if (type === "pie") {
360
- return /* @__PURE__ */ import_react4.default.createElement("div", { ref: containerRef, className: `w-full min-w-0 ${chartHeightClass} mt-4 mb-2 select-none overflow-hidden` }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.ResponsiveContainer, { width: "100%", height: "100%" }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.PieChart, null, /* @__PURE__ */ import_react4.default.createElement(
361
+ return /* @__PURE__ */ import_react4.default.createElement("div", { ref: containerRef, className: `w-full min-w-0 ${chartHeightClass} mt-4 mb-2 select-none overflow-hidden` }, /* @__PURE__ */ import_react4.default.createElement("div", { className: `mx-auto h-full w-full ${pieCanvasMaxWidthClass}` }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.ResponsiveContainer, { width: "100%", height: "100%" }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.PieChart, null, /* @__PURE__ */ import_react4.default.createElement(
361
362
  import_recharts.Pie,
362
363
  {
363
364
  data: sanitizedData,
@@ -369,7 +370,7 @@ function DynamicChart({
369
370
  label: isTiny ? false : pieLabel
370
371
  },
371
372
  sanitizedData.map((entry, index) => /* @__PURE__ */ import_react4.default.createElement(import_recharts.Cell, { key: `cell-${index}`, fill: stockAwareColor(entry, index) }))
372
- ), /* @__PURE__ */ import_react4.default.createElement(import_recharts.Tooltip, { content: (props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === "string" ? props.label : void 0) }), showLegend && /* @__PURE__ */ import_react4.default.createElement(import_recharts.Legend, { wrapperStyle: { fontSize: isCompact ? 10 : 12 } }))));
373
+ ), /* @__PURE__ */ import_react4.default.createElement(import_recharts.Tooltip, { content: (props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === "string" ? props.label : void 0) }), showLegend && /* @__PURE__ */ import_react4.default.createElement(import_recharts.Legend, { wrapperStyle: { fontSize: isCompact ? 10 : 12 }, verticalAlign: "bottom" })))));
373
374
  }
374
375
  return /* @__PURE__ */ import_react4.default.createElement("div", { ref: containerRef, className: `w-full min-w-0 ${chartHeightClass} mt-4 mb-2 select-none overflow-hidden` }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.ResponsiveContainer, { width: "100%", height: "100%" }, type === "bar" ? /* @__PURE__ */ import_react4.default.createElement(import_recharts.BarChart, { data: sanitizedData, margin: chartMargin }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ import_react4.default.createElement(import_recharts.XAxis, { dataKey: finalXKey, tick: axisTick, tickFormatter: truncateAxisLabel, tickLine: false, axisLine: { stroke: "#cbd5e1" }, interval: 0, minTickGap: isTiny ? 2 : isCompact ? 6 : 12 }), /* @__PURE__ */ import_react4.default.createElement(import_recharts.YAxis, { tick: axisTick, tickLine: false, axisLine: false }), /* @__PURE__ */ import_react4.default.createElement(import_recharts.Tooltip, { content: (props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === "string" ? props.label : void 0), cursor: { fill: "#f1f5f9" } }), showLegend && /* @__PURE__ */ import_react4.default.createElement(import_recharts.Legend, { wrapperStyle: { fontSize: isCompact ? 10 : 12 } }), finalDataKeys.map((key, index) => /* @__PURE__ */ import_react4.default.createElement(
375
376
  import_recharts.Bar,
@@ -459,6 +460,12 @@ function extractLikelyJsonBlock(raw) {
459
460
  function looksLikeStructuredPayload(raw) {
460
461
  return /"(view|chartType|type|data|items|rows|products|results)"\s*:/.test(raw);
461
462
  }
463
+ function stripMarkdownTables(raw) {
464
+ return raw.replace(
465
+ /(?:^|\n)\|[^\n]+\|\n\|(?:\s*:?-+:?\s*\|)+\n(?:\|[^\n]*\|\n?)*/g,
466
+ "\n\n"
467
+ );
468
+ }
462
469
  function resolveImage(data) {
463
470
  for (const key of ["image", "img", "thumbnail"]) {
464
471
  const v = data[key];
@@ -715,6 +722,7 @@ function MessageBubble({
715
722
  }, [productsFromSources, productsFromContent, message.content]);
716
723
  const processedMarkdown = import_react5.default.useMemo(() => {
717
724
  let raw = cleanContent || message.content;
725
+ const hasStructuredUiBlock = /```(?:ui|json|chart)\s*[\s\S]*?"(?:view|chartType|type|data|items|rows|products|results)"\s*:/i.test(raw);
718
726
  raw = raw.replace(/([^\n])\n\|/g, "$1\n\n|").replace(/(\|[^\n]*\|)\n\n+(?=\|)/g, "$1\n");
719
727
  if (!isStreaming) {
720
728
  raw = raw.replace(/(?:^|\n)\s*\{[\s\S]*\}\s*(?:\n|$)/g, (match) => {
@@ -730,6 +738,9 @@ ${match.trim()}
730
738
  `;
731
739
  });
732
740
  }
741
+ if (hasStructuredUiBlock) {
742
+ raw = stripMarkdownTables(raw).replace(/\n{3,}/g, "\n\n").trim();
743
+ }
733
744
  if (isStreaming) {
734
745
  raw = raw.replace(/((?:^|\n)\|.*)+/g, (match) => {
735
746
  return `
package/dist/index.mjs CHANGED
@@ -211,6 +211,7 @@ function DynamicChart({
211
211
  const isCompact = viewportSize === "compact" || containerWidth > 0 && containerWidth < 420;
212
212
  const isMedium = !isCompact && (viewportSize === "medium" || containerWidth > 0 && containerWidth < 640);
213
213
  const chartHeightClass = isTiny ? "h-48 min-h-[180px]" : isCompact ? "h-56 min-h-[220px]" : isMedium ? "h-64 min-h-[250px]" : "h-72 min-h-[280px]";
214
+ const pieCanvasMaxWidthClass = isTiny ? "max-w-[11rem]" : isCompact ? "max-w-[14rem]" : isMedium ? "max-w-[16rem]" : "max-w-[18rem]";
214
215
  const pieOuterRadius = isTiny ? 44 : isCompact ? 56 : isMedium ? 68 : 80;
215
216
  const pieLabel = ({ name, percent }) => isTiny ? "" : isCompact ? `${name}` : `${name} ${((percent != null ? percent : 0) * 100).toFixed(0)}%`;
216
217
  const axisTick = { fontSize: isTiny ? 9 : isCompact ? 10 : 12, fill: "#64748b" };
@@ -320,7 +321,7 @@ function DynamicChart({
320
321
  return row;
321
322
  };
322
323
  if (type === "pie") {
323
- return /* @__PURE__ */ React4.createElement("div", { ref: containerRef, className: `w-full min-w-0 ${chartHeightClass} mt-4 mb-2 select-none overflow-hidden` }, /* @__PURE__ */ React4.createElement(ResponsiveContainer, { width: "100%", height: "100%" }, /* @__PURE__ */ React4.createElement(PieChart, null, /* @__PURE__ */ React4.createElement(
324
+ return /* @__PURE__ */ React4.createElement("div", { ref: containerRef, className: `w-full min-w-0 ${chartHeightClass} mt-4 mb-2 select-none overflow-hidden` }, /* @__PURE__ */ React4.createElement("div", { className: `mx-auto h-full w-full ${pieCanvasMaxWidthClass}` }, /* @__PURE__ */ React4.createElement(ResponsiveContainer, { width: "100%", height: "100%" }, /* @__PURE__ */ React4.createElement(PieChart, null, /* @__PURE__ */ React4.createElement(
324
325
  Pie,
325
326
  {
326
327
  data: sanitizedData,
@@ -332,7 +333,7 @@ function DynamicChart({
332
333
  label: isTiny ? false : pieLabel
333
334
  },
334
335
  sanitizedData.map((entry, index) => /* @__PURE__ */ React4.createElement(Cell, { key: `cell-${index}`, fill: stockAwareColor(entry, index) }))
335
- ), /* @__PURE__ */ React4.createElement(Tooltip, { content: (props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === "string" ? props.label : void 0) }), showLegend && /* @__PURE__ */ React4.createElement(Legend, { wrapperStyle: { fontSize: isCompact ? 10 : 12 } }))));
336
+ ), /* @__PURE__ */ React4.createElement(Tooltip, { content: (props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === "string" ? props.label : void 0) }), showLegend && /* @__PURE__ */ React4.createElement(Legend, { wrapperStyle: { fontSize: isCompact ? 10 : 12 }, verticalAlign: "bottom" })))));
336
337
  }
337
338
  return /* @__PURE__ */ React4.createElement("div", { ref: containerRef, className: `w-full min-w-0 ${chartHeightClass} mt-4 mb-2 select-none overflow-hidden` }, /* @__PURE__ */ React4.createElement(ResponsiveContainer, { width: "100%", height: "100%" }, type === "bar" ? /* @__PURE__ */ React4.createElement(BarChart, { data: sanitizedData, margin: chartMargin }, /* @__PURE__ */ React4.createElement(CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ React4.createElement(XAxis, { dataKey: finalXKey, tick: axisTick, tickFormatter: truncateAxisLabel, tickLine: false, axisLine: { stroke: "#cbd5e1" }, interval: 0, minTickGap: isTiny ? 2 : isCompact ? 6 : 12 }), /* @__PURE__ */ React4.createElement(YAxis, { tick: axisTick, tickLine: false, axisLine: false }), /* @__PURE__ */ React4.createElement(Tooltip, { content: (props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === "string" ? props.label : void 0), cursor: { fill: "#f1f5f9" } }), showLegend && /* @__PURE__ */ React4.createElement(Legend, { wrapperStyle: { fontSize: isCompact ? 10 : 12 } }), finalDataKeys.map((key, index) => /* @__PURE__ */ React4.createElement(
338
339
  Bar,
@@ -422,6 +423,12 @@ function extractLikelyJsonBlock(raw) {
422
423
  function looksLikeStructuredPayload(raw) {
423
424
  return /"(view|chartType|type|data|items|rows|products|results)"\s*:/.test(raw);
424
425
  }
426
+ function stripMarkdownTables(raw) {
427
+ return raw.replace(
428
+ /(?:^|\n)\|[^\n]+\|\n\|(?:\s*:?-+:?\s*\|)+\n(?:\|[^\n]*\|\n?)*/g,
429
+ "\n\n"
430
+ );
431
+ }
425
432
  function resolveImage(data) {
426
433
  for (const key of ["image", "img", "thumbnail"]) {
427
434
  const v = data[key];
@@ -678,6 +685,7 @@ function MessageBubble({
678
685
  }, [productsFromSources, productsFromContent, message.content]);
679
686
  const processedMarkdown = React5.useMemo(() => {
680
687
  let raw = cleanContent || message.content;
688
+ const hasStructuredUiBlock = /```(?:ui|json|chart)\s*[\s\S]*?"(?:view|chartType|type|data|items|rows|products|results)"\s*:/i.test(raw);
681
689
  raw = raw.replace(/([^\n])\n\|/g, "$1\n\n|").replace(/(\|[^\n]*\|)\n\n+(?=\|)/g, "$1\n");
682
690
  if (!isStreaming) {
683
691
  raw = raw.replace(/(?:^|\n)\s*\{[\s\S]*\}\s*(?:\n|$)/g, (match) => {
@@ -693,6 +701,9 @@ ${match.trim()}
693
701
  `;
694
702
  });
695
703
  }
704
+ if (hasStructuredUiBlock) {
705
+ raw = stripMarkdownTables(raw).replace(/\n{3,}/g, "\n\n").trim();
706
+ }
696
707
  if (isStreaming) {
697
708
  raw = raw.replace(/((?:^|\n)\|.*)+/g, (match) => {
698
709
  return `
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retrivora-ai/rag-engine",
3
- "version": "1.5.8",
3
+ "version": "1.5.9",
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",
@@ -64,6 +64,13 @@ export function DynamicChart({
64
64
  : isMedium
65
65
  ? 'h-64 min-h-[250px]'
66
66
  : 'h-72 min-h-[280px]';
67
+ const pieCanvasMaxWidthClass = isTiny
68
+ ? 'max-w-[11rem]'
69
+ : isCompact
70
+ ? 'max-w-[14rem]'
71
+ : isMedium
72
+ ? 'max-w-[16rem]'
73
+ : 'max-w-[18rem]';
67
74
  const pieOuterRadius = isTiny ? 44 : isCompact ? 56 : isMedium ? 68 : 80;
68
75
  const pieLabel = ({ name, percent }: { name?: string; percent?: number }) =>
69
76
  isTiny
@@ -235,25 +242,27 @@ export function DynamicChart({
235
242
  if (type === 'pie') {
236
243
  return (
237
244
  <div ref={containerRef} className={`w-full min-w-0 ${chartHeightClass} mt-4 mb-2 select-none overflow-hidden`}>
238
- <ResponsiveContainer width="100%" height="100%">
239
- <PieChart>
240
- <Pie
241
- data={sanitizedData}
242
- dataKey={pieDataKey}
243
- nameKey={finalXKey}
244
- cx="50%"
245
- cy="50%"
246
- outerRadius={pieOuterRadius}
247
- label={isTiny ? false : pieLabel}
248
- >
249
- {sanitizedData.map((entry, index) => (
250
- <Cell key={`cell-${index}`} fill={stockAwareColor(entry, index)} />
251
- ))}
252
- </Pie>
253
- <Tooltip content={(props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === 'string' ? props.label : undefined)} />
254
- {showLegend && <Legend wrapperStyle={{ fontSize: isCompact ? 10 : 12 }} />}
255
- </PieChart>
256
- </ResponsiveContainer>
245
+ <div className={`mx-auto h-full w-full ${pieCanvasMaxWidthClass}`}>
246
+ <ResponsiveContainer width="100%" height="100%">
247
+ <PieChart>
248
+ <Pie
249
+ data={sanitizedData}
250
+ dataKey={pieDataKey}
251
+ nameKey={finalXKey}
252
+ cx="50%"
253
+ cy="50%"
254
+ outerRadius={pieOuterRadius}
255
+ label={isTiny ? false : pieLabel}
256
+ >
257
+ {sanitizedData.map((entry, index) => (
258
+ <Cell key={`cell-${index}`} fill={stockAwareColor(entry, index)} />
259
+ ))}
260
+ </Pie>
261
+ <Tooltip content={(props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === 'string' ? props.label : undefined)} />
262
+ {showLegend && <Legend wrapperStyle={{ fontSize: isCompact ? 10 : 12 }} verticalAlign="bottom" />}
263
+ </PieChart>
264
+ </ResponsiveContainer>
265
+ </div>
257
266
  </div>
258
267
  );
259
268
  }
@@ -106,6 +106,13 @@ function looksLikeStructuredPayload(raw: string): boolean {
106
106
  return /"(view|chartType|type|data|items|rows|products|results)"\s*:/.test(raw);
107
107
  }
108
108
 
109
+ function stripMarkdownTables(raw: string): string {
110
+ return raw.replace(
111
+ /(?:^|\n)\|[^\n]+\|\n\|(?:\s*:?-+:?\s*\|)+\n(?:\|[^\n]*\|\n?)*/g,
112
+ '\n\n',
113
+ );
114
+ }
115
+
109
116
  // ─── Tiny helpers ─────────────────────────────────────────────────────────────
110
117
 
111
118
  function resolveImage(data: Record<string, unknown>): string | undefined {
@@ -533,6 +540,7 @@ export function MessageBubble({
533
540
 
534
541
  const processedMarkdown = React.useMemo(() => {
535
542
  let raw = cleanContent || message.content;
543
+ const hasStructuredUiBlock = /```(?:ui|json|chart)\s*[\s\S]*?"(?:view|chartType|type|data|items|rows|products|results)"\s*:/i.test(raw);
536
544
 
537
545
  // 1. Structural fixes
538
546
  raw = raw.replace(/([^\n])\n\|/g, '$1\n\n|') // Ensure blank line before table
@@ -553,6 +561,14 @@ export function MessageBubble({
553
561
  });
554
562
  }
555
563
 
564
+ // 2b. If the model already provided a structured UI block, suppress duplicated
565
+ // markdown tables that often follow as a fallback explanation.
566
+ if (hasStructuredUiBlock) {
567
+ raw = stripMarkdownTables(raw)
568
+ .replace(/\n{3,}/g, '\n\n')
569
+ .trim();
570
+ }
571
+
556
572
  // 3. HIJACKING: If streaming, hide table-like content to prevent raw markdown flashing.
557
573
  if (isStreaming) {
558
574
  raw = raw.replace(/((?:^|\n)\|.*)+/g, (match) => {