@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 +13 -2
- package/dist/index.mjs +13 -2
- package/package.json +1 -1
- package/src/components/DynamicChart.tsx +28 -19
- package/src/components/MessageBubble.tsx +16 -0
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.
|
|
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
|
-
<
|
|
239
|
-
<
|
|
240
|
-
<
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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) => {
|