@retrivora-ai/rag-engine 1.7.8 → 1.8.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.
package/dist/index.js CHANGED
@@ -304,37 +304,12 @@ function DynamicChart({
304
304
  const finalXKey = String(resolvedXKey);
305
305
  const finalDataKeys = resolvedDataKeys.map(String).filter((k) => k !== "undefined");
306
306
  const pieDataKey = finalDataKeys[0] || "value";
307
- const stockAwareColor = (entry, index) => {
308
- var _a, _b, _c;
309
- const stockStatus = String(
310
- (_c = (_b = (_a = entry.stockStatus) != null ? _a : entry.status) != null ? _b : entry.availability) != null ? _c : ""
311
- ).toLowerCase();
312
- const inStockCount = typeof entry.inStockCount === "number" ? entry.inStockCount : void 0;
313
- const outOfStockCount = typeof entry.outOfStockCount === "number" ? entry.outOfStockCount : void 0;
314
- const inStockFlag = entry.inStock;
315
- if (stockStatus.includes("in stock")) return "#10b981";
316
- if (stockStatus.includes("out of stock")) return "#f97316";
317
- if (typeof inStockFlag === "string" && inStockFlag.toLowerCase() === "true") return "#10b981";
318
- if (inStockFlag === 1) return "#10b981";
319
- if (inStockFlag === 0) return "#f97316";
320
- if (typeof inStockCount === "number" || typeof outOfStockCount === "number") {
321
- const inCount = inStockCount != null ? inStockCount : 0;
322
- const outCount = outOfStockCount != null ? outOfStockCount : 0;
323
- if (inCount > outCount) return "#10b981";
324
- if (outCount > inCount) return "#f97316";
325
- }
326
- return colors[index % colors.length];
327
- };
328
307
  const tooltipLabelMap = {
329
- value: "Value",
308
+ value: "Total Items",
330
309
  count: "Count",
331
- inStock: "In stock",
332
- inStockCount: "In stock",
333
- outOfStockCount: "Out of stock",
334
- stockStatus: "Stock status",
335
- category: "Category",
336
- label: "Label",
337
- name: "Name"
310
+ inStockCount: "In Stock",
311
+ outOfStockCount: "Out of Stock",
312
+ stockStatus: "Status"
338
313
  };
339
314
  const renderTooltip = (row, label) => {
340
315
  var _a, _b;
@@ -343,6 +318,8 @@ function DynamicChart({
343
318
  var _a2;
344
319
  if (value === null || value === void 0 || key === finalXKey) return null;
345
320
  if (typeof value === "object") return null;
321
+ const forbiddenKeys = ["fill", "color", "payload", "percent", "stroke", "inStock"];
322
+ if (forbiddenKeys.includes(key)) return null;
346
323
  return /* @__PURE__ */ import_react4.default.createElement("div", { key, className: "flex items-center justify-between gap-3 text-slate-600 dark:text-white/70" }, /* @__PURE__ */ import_react4.default.createElement("span", null, (_a2 = tooltipLabelMap[key]) != null ? _a2 : key), /* @__PURE__ */ import_react4.default.createElement("span", { className: "font-medium text-slate-900 dark:text-white/90" }, String(value)));
347
324
  }));
348
325
  };
@@ -367,7 +344,7 @@ function DynamicChart({
367
344
  label: false,
368
345
  labelLine: false
369
346
  },
370
- sanitizedData.map((entry, index) => /* @__PURE__ */ import_react4.default.createElement(import_recharts.Cell, { key: `cell-${index}`, fill: stockAwareColor(entry, index) }))
347
+ sanitizedData.map((_entry, index) => /* @__PURE__ */ import_react4.default.createElement(import_recharts.Cell, { key: `cell-${index}`, fill: colors[index % colors.length] }))
371
348
  ), /* @__PURE__ */ import_react4.default.createElement(import_recharts.Tooltip, { content: (props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === "string" ? props.label : void 0) }), showLegend && !isCompact && /* @__PURE__ */ import_react4.default.createElement(import_recharts.Legend, { wrapperStyle: { fontSize: 12 }, verticalAlign: "bottom" })))));
372
349
  }
373
350
  return /* @__PURE__ */ import_react4.default.createElement("div", { ref: containerRef, className: "w-full min-w-0 mt-4 mb-2 select-none overflow-hidden" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "w-full aspect-[4/3]" }, /* @__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(
@@ -846,12 +823,15 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAd
846
823
  config2.view = "chart";
847
824
  config2.chartType = config2.chartType || "bar";
848
825
  }
849
- if (!config2.view) {
850
- if (config2.type === "products" || Array.isArray(config2.items) || hasProductLikeData) {
826
+ if (!config2.view || ["pie", "bar", "line", "pie_chart", "bar_chart", "line_chart"].includes(String(config2.view))) {
827
+ const viewStr = String(config2.view || "").toLowerCase();
828
+ if (viewStr.includes("carousel") || config2.type === "products" || Array.isArray(config2.items) || hasProductLikeData) {
851
829
  config2.view = "carousel";
852
- } else if (hasAggregationLikeData || typeof config2.type === "string" && ["pie", "bar", "line"].includes(config2.type) || typeof config2.chartType === "string" && ["pie", "bar", "line"].includes(config2.chartType)) {
830
+ } else if (viewStr.includes("chart") || viewStr.includes("pie") || viewStr.includes("bar") || viewStr.includes("line") || hasAggregationLikeData || typeof config2.type === "string" && ["pie", "bar", "line"].includes(config2.type) || typeof config2.chartType === "string" && ["pie", "bar", "line"].includes(config2.chartType)) {
853
831
  config2.view = "chart";
854
- config2.chartType = config2.chartType || config2.type || "bar";
832
+ config2.chartType = config2.chartType || viewStr.replace("_chart", "") || config2.type || "bar";
833
+ } else if (viewStr.includes("table")) {
834
+ config2.view = "table";
855
835
  } else {
856
836
  config2.view = "table";
857
837
  }
@@ -890,13 +870,13 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAd
890
870
  accentColor,
891
871
  viewportSize
892
872
  }
893
- ), hasInsights && /* @__PURE__ */ import_react5.default.createElement("div", { className: "mt-4 flex flex-wrap gap-2 px-2" }, (_a = config.insights) == null ? void 0 : _a.map((insight) => /* @__PURE__ */ import_react5.default.createElement(
873
+ ), hasInsights && /* @__PURE__ */ import_react5.default.createElement("div", { className: "mt-4 flex flex-wrap gap-2 px-2" }, (_a = config.insights) == null ? void 0 : _a.map((insight, i) => /* @__PURE__ */ import_react5.default.createElement(
894
874
  "span",
895
875
  {
896
- key: insight,
876
+ key: `insight-${i}`,
897
877
  className: `rounded-full border border-emerald-200 bg-emerald-50 ${isCompact ? "px-2.5 py-1 text-[10px]" : "px-3 py-1 text-[11px]"} font-medium text-emerald-700 dark:border-emerald-500/20 dark:bg-emerald-500/10 dark:text-emerald-300`
898
878
  },
899
- insight
879
+ String(insight)
900
880
  ))));
901
881
  case "carousel":
902
882
  return /* @__PURE__ */ import_react5.default.createElement("div", { className: "my-4" }, config.title && /* @__PURE__ */ import_react5.default.createElement("h4", { className: `${isCompact ? "mb-1.5 text-[11px]" : "mb-2 text-xs"} font-semibold text-slate-500` }, config.title), hasDescription && /* @__PURE__ */ import_react5.default.createElement("p", { className: `mb-3 ${isCompact ? "text-xs" : "text-sm"} text-slate-500 dark:text-white/60` }, config.description), /* @__PURE__ */ import_react5.default.createElement(ProductCarousel, { products: config.data.map((item) => {
@@ -1203,7 +1183,7 @@ ${match.trim()}
1203
1183
  onAddToCart,
1204
1184
  viewportSize
1205
1185
  }
1206
- ), !shouldRenderStructuredOnly && /* @__PURE__ */ import_react5.default.createElement(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default], components: markdownComponents }, processedMarkdown), !isUser && !structuredContent.payload && message.uiTransformation && /* @__PURE__ */ import_react5.default.createElement("div", { className: "mt-4 border-t border-slate-100 dark:border-white/5 pt-4" }, /* @__PURE__ */ import_react5.default.createElement(VisualizationRenderer, { data: message.uiTransformation })), isStreaming && message.content && /* @__PURE__ */ import_react5.default.createElement("span", { className: "inline-block w-1.5 h-3.5 ml-1 bg-emerald-500 animate-pulse align-middle" }))
1186
+ ), !shouldRenderStructuredOnly && /* @__PURE__ */ import_react5.default.createElement(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default], components: markdownComponents }, processedMarkdown), !isUser && !structuredContent.payload && !!message.uiTransformation && /* @__PURE__ */ import_react5.default.createElement("div", { className: "mt-4 border-t border-slate-100 dark:border-white/5 pt-4" }, /* @__PURE__ */ import_react5.default.createElement(VisualizationRenderer, { data: message.uiTransformation })), isStreaming && message.content && /* @__PURE__ */ import_react5.default.createElement("span", { className: "inline-block w-1.5 h-3.5 ml-1 bg-emerald-500 animate-pulse align-middle" }))
1207
1187
  ), !isUser && !hasStructuredProductBlock && allProducts.length > 0 && /* @__PURE__ */ import_react5.default.createElement("div", { className: "w-full mt-1" }, /* @__PURE__ */ import_react5.default.createElement(
1208
1188
  ProductCarousel,
1209
1189
  {
package/dist/index.mjs CHANGED
@@ -267,37 +267,12 @@ function DynamicChart({
267
267
  const finalXKey = String(resolvedXKey);
268
268
  const finalDataKeys = resolvedDataKeys.map(String).filter((k) => k !== "undefined");
269
269
  const pieDataKey = finalDataKeys[0] || "value";
270
- const stockAwareColor = (entry, index) => {
271
- var _a, _b, _c;
272
- const stockStatus = String(
273
- (_c = (_b = (_a = entry.stockStatus) != null ? _a : entry.status) != null ? _b : entry.availability) != null ? _c : ""
274
- ).toLowerCase();
275
- const inStockCount = typeof entry.inStockCount === "number" ? entry.inStockCount : void 0;
276
- const outOfStockCount = typeof entry.outOfStockCount === "number" ? entry.outOfStockCount : void 0;
277
- const inStockFlag = entry.inStock;
278
- if (stockStatus.includes("in stock")) return "#10b981";
279
- if (stockStatus.includes("out of stock")) return "#f97316";
280
- if (typeof inStockFlag === "string" && inStockFlag.toLowerCase() === "true") return "#10b981";
281
- if (inStockFlag === 1) return "#10b981";
282
- if (inStockFlag === 0) return "#f97316";
283
- if (typeof inStockCount === "number" || typeof outOfStockCount === "number") {
284
- const inCount = inStockCount != null ? inStockCount : 0;
285
- const outCount = outOfStockCount != null ? outOfStockCount : 0;
286
- if (inCount > outCount) return "#10b981";
287
- if (outCount > inCount) return "#f97316";
288
- }
289
- return colors[index % colors.length];
290
- };
291
270
  const tooltipLabelMap = {
292
- value: "Value",
271
+ value: "Total Items",
293
272
  count: "Count",
294
- inStock: "In stock",
295
- inStockCount: "In stock",
296
- outOfStockCount: "Out of stock",
297
- stockStatus: "Stock status",
298
- category: "Category",
299
- label: "Label",
300
- name: "Name"
273
+ inStockCount: "In Stock",
274
+ outOfStockCount: "Out of Stock",
275
+ stockStatus: "Status"
301
276
  };
302
277
  const renderTooltip = (row, label) => {
303
278
  var _a, _b;
@@ -306,6 +281,8 @@ function DynamicChart({
306
281
  var _a2;
307
282
  if (value === null || value === void 0 || key === finalXKey) return null;
308
283
  if (typeof value === "object") return null;
284
+ const forbiddenKeys = ["fill", "color", "payload", "percent", "stroke", "inStock"];
285
+ if (forbiddenKeys.includes(key)) return null;
309
286
  return /* @__PURE__ */ React5.createElement("div", { key, className: "flex items-center justify-between gap-3 text-slate-600 dark:text-white/70" }, /* @__PURE__ */ React5.createElement("span", null, (_a2 = tooltipLabelMap[key]) != null ? _a2 : key), /* @__PURE__ */ React5.createElement("span", { className: "font-medium text-slate-900 dark:text-white/90" }, String(value)));
310
287
  }));
311
288
  };
@@ -330,7 +307,7 @@ function DynamicChart({
330
307
  label: false,
331
308
  labelLine: false
332
309
  },
333
- sanitizedData.map((entry, index) => /* @__PURE__ */ React5.createElement(Cell, { key: `cell-${index}`, fill: stockAwareColor(entry, index) }))
310
+ sanitizedData.map((_entry, index) => /* @__PURE__ */ React5.createElement(Cell, { key: `cell-${index}`, fill: colors[index % colors.length] }))
334
311
  ), /* @__PURE__ */ React5.createElement(Tooltip, { content: (props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === "string" ? props.label : void 0) }), showLegend && !isCompact && /* @__PURE__ */ React5.createElement(Legend, { wrapperStyle: { fontSize: 12 }, verticalAlign: "bottom" })))));
335
312
  }
336
313
  return /* @__PURE__ */ React5.createElement("div", { ref: containerRef, className: "w-full min-w-0 mt-4 mb-2 select-none overflow-hidden" }, /* @__PURE__ */ React5.createElement("div", { className: "w-full aspect-[4/3]" }, /* @__PURE__ */ React5.createElement(ResponsiveContainer, { width: "100%", height: "100%" }, type === "bar" ? /* @__PURE__ */ React5.createElement(BarChart, { data: sanitizedData, margin: chartMargin }, /* @__PURE__ */ React5.createElement(CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ React5.createElement(XAxis, { dataKey: finalXKey, tick: axisTick, tickFormatter: truncateAxisLabel, tickLine: false, axisLine: { stroke: "#cbd5e1" }, interval: 0, minTickGap: isTiny ? 2 : isCompact ? 6 : 12 }), /* @__PURE__ */ React5.createElement(YAxis, { tick: axisTick, tickLine: false, axisLine: false }), /* @__PURE__ */ React5.createElement(Tooltip, { content: (props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === "string" ? props.label : void 0), cursor: { fill: "#f1f5f9" } }), showLegend && /* @__PURE__ */ React5.createElement(Legend, { wrapperStyle: { fontSize: isCompact ? 10 : 12 } }), finalDataKeys.map((key, index) => /* @__PURE__ */ React5.createElement(
@@ -809,12 +786,15 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAd
809
786
  config2.view = "chart";
810
787
  config2.chartType = config2.chartType || "bar";
811
788
  }
812
- if (!config2.view) {
813
- if (config2.type === "products" || Array.isArray(config2.items) || hasProductLikeData) {
789
+ if (!config2.view || ["pie", "bar", "line", "pie_chart", "bar_chart", "line_chart"].includes(String(config2.view))) {
790
+ const viewStr = String(config2.view || "").toLowerCase();
791
+ if (viewStr.includes("carousel") || config2.type === "products" || Array.isArray(config2.items) || hasProductLikeData) {
814
792
  config2.view = "carousel";
815
- } else if (hasAggregationLikeData || typeof config2.type === "string" && ["pie", "bar", "line"].includes(config2.type) || typeof config2.chartType === "string" && ["pie", "bar", "line"].includes(config2.chartType)) {
793
+ } else if (viewStr.includes("chart") || viewStr.includes("pie") || viewStr.includes("bar") || viewStr.includes("line") || hasAggregationLikeData || typeof config2.type === "string" && ["pie", "bar", "line"].includes(config2.type) || typeof config2.chartType === "string" && ["pie", "bar", "line"].includes(config2.chartType)) {
816
794
  config2.view = "chart";
817
- config2.chartType = config2.chartType || config2.type || "bar";
795
+ config2.chartType = config2.chartType || viewStr.replace("_chart", "") || config2.type || "bar";
796
+ } else if (viewStr.includes("table")) {
797
+ config2.view = "table";
818
798
  } else {
819
799
  config2.view = "table";
820
800
  }
@@ -853,13 +833,13 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAd
853
833
  accentColor,
854
834
  viewportSize
855
835
  }
856
- ), hasInsights && /* @__PURE__ */ React6.createElement("div", { className: "mt-4 flex flex-wrap gap-2 px-2" }, (_a = config.insights) == null ? void 0 : _a.map((insight) => /* @__PURE__ */ React6.createElement(
836
+ ), hasInsights && /* @__PURE__ */ React6.createElement("div", { className: "mt-4 flex flex-wrap gap-2 px-2" }, (_a = config.insights) == null ? void 0 : _a.map((insight, i) => /* @__PURE__ */ React6.createElement(
857
837
  "span",
858
838
  {
859
- key: insight,
839
+ key: `insight-${i}`,
860
840
  className: `rounded-full border border-emerald-200 bg-emerald-50 ${isCompact ? "px-2.5 py-1 text-[10px]" : "px-3 py-1 text-[11px]"} font-medium text-emerald-700 dark:border-emerald-500/20 dark:bg-emerald-500/10 dark:text-emerald-300`
861
841
  },
862
- insight
842
+ String(insight)
863
843
  ))));
864
844
  case "carousel":
865
845
  return /* @__PURE__ */ React6.createElement("div", { className: "my-4" }, config.title && /* @__PURE__ */ React6.createElement("h4", { className: `${isCompact ? "mb-1.5 text-[11px]" : "mb-2 text-xs"} font-semibold text-slate-500` }, config.title), hasDescription && /* @__PURE__ */ React6.createElement("p", { className: `mb-3 ${isCompact ? "text-xs" : "text-sm"} text-slate-500 dark:text-white/60` }, config.description), /* @__PURE__ */ React6.createElement(ProductCarousel, { products: config.data.map((item) => {
@@ -1166,7 +1146,7 @@ ${match.trim()}
1166
1146
  onAddToCart,
1167
1147
  viewportSize
1168
1148
  }
1169
- ), !shouldRenderStructuredOnly && /* @__PURE__ */ React6.createElement(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents }, processedMarkdown), !isUser && !structuredContent.payload && message.uiTransformation && /* @__PURE__ */ React6.createElement("div", { className: "mt-4 border-t border-slate-100 dark:border-white/5 pt-4" }, /* @__PURE__ */ React6.createElement(VisualizationRenderer, { data: message.uiTransformation })), isStreaming && message.content && /* @__PURE__ */ React6.createElement("span", { className: "inline-block w-1.5 h-3.5 ml-1 bg-emerald-500 animate-pulse align-middle" }))
1149
+ ), !shouldRenderStructuredOnly && /* @__PURE__ */ React6.createElement(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents }, processedMarkdown), !isUser && !structuredContent.payload && !!message.uiTransformation && /* @__PURE__ */ React6.createElement("div", { className: "mt-4 border-t border-slate-100 dark:border-white/5 pt-4" }, /* @__PURE__ */ React6.createElement(VisualizationRenderer, { data: message.uiTransformation })), isStreaming && message.content && /* @__PURE__ */ React6.createElement("span", { className: "inline-block w-1.5 h-3.5 ml-1 bg-emerald-500 animate-pulse align-middle" }))
1170
1150
  ), !isUser && !hasStructuredProductBlock && allProducts.length > 0 && /* @__PURE__ */ React6.createElement("div", { className: "w-full mt-1" }, /* @__PURE__ */ React6.createElement(
1171
1151
  ProductCarousel,
1172
1152
  {
package/dist/server.d.mts CHANGED
@@ -1,8 +1,8 @@
1
- import { j as VectorDBConfig, L as LLMConfig, E as EmbeddingConfig, h as RagConfig, I as IngestDocument, C as ChatMessage, d as ChatResponse, l as RetrievalResult, i as UpsertDocument, V as VectorMatch, G as GraphDBConfig, m as GraphNode, n as Edge, o as GraphSearchResult, k as VectorDBProvider, f as LLMProvider, e as EmbeddingProvider, g as RAGConfig, U as UIConfig, c as ChatOptions } from './index-DfsVx0a4.mjs';
2
- import { I as ILLMProvider, E as EmbedOptions } from './DocumentChunker-wKE98F_G.mjs';
3
- export { C as Chunk, a as ChunkOptions, D as DocumentChunker } from './DocumentChunker-wKE98F_G.mjs';
4
- import { H as HealthCheckResult, I as IProviderValidator, a as IProviderHealthChecker } from './index-B1u4loP6.mjs';
5
- export { C as ConfigValidator, V as ValidationError, b as VectorPlugin, c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, j as sseTextFrame } from './index-B1u4loP6.mjs';
1
+ import { j as VectorDBConfig, L as LLMConfig, E as EmbeddingConfig, h as RagConfig, I as IngestDocument, C as ChatMessage, d as ChatResponse, l as RetrievalResult, i as UpsertDocument, V as VectorMatch, G as GraphDBConfig, m as GraphNode, n as Edge, o as GraphSearchResult, k as VectorDBProvider, f as LLMProvider, e as EmbeddingProvider, g as RAGConfig, U as UIConfig, c as ChatOptions } from './index-DPsQodME.mjs';
2
+ import { I as ILLMProvider, E as EmbedOptions } from './DocumentChunker-CFEiRopR.mjs';
3
+ export { C as Chunk, a as ChunkOptions, D as DocumentChunker } from './DocumentChunker-CFEiRopR.mjs';
4
+ import { H as HealthCheckResult, I as IProviderValidator, a as IProviderHealthChecker } from './index-Bb2yEopi.mjs';
5
+ export { C as ConfigValidator, V as ValidationError, b as VectorPlugin, c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, j as sseTextFrame } from './index-Bb2yEopi.mjs';
6
6
  import 'next/server';
7
7
 
8
8
  /**
package/dist/server.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { j as VectorDBConfig, L as LLMConfig, E as EmbeddingConfig, h as RagConfig, I as IngestDocument, C as ChatMessage, d as ChatResponse, l as RetrievalResult, i as UpsertDocument, V as VectorMatch, G as GraphDBConfig, m as GraphNode, n as Edge, o as GraphSearchResult, k as VectorDBProvider, f as LLMProvider, e as EmbeddingProvider, g as RAGConfig, U as UIConfig, c as ChatOptions } from './index-DfsVx0a4.js';
2
- import { I as ILLMProvider, E as EmbedOptions } from './DocumentChunker-DMZVv6hi.js';
3
- export { C as Chunk, a as ChunkOptions, D as DocumentChunker } from './DocumentChunker-DMZVv6hi.js';
4
- import { H as HealthCheckResult, I as IProviderValidator, a as IProviderHealthChecker } from './index-D9w9fLjh.js';
5
- export { C as ConfigValidator, V as ValidationError, b as VectorPlugin, c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, j as sseTextFrame } from './index-D9w9fLjh.js';
1
+ import { j as VectorDBConfig, L as LLMConfig, E as EmbeddingConfig, h as RagConfig, I as IngestDocument, C as ChatMessage, d as ChatResponse, l as RetrievalResult, i as UpsertDocument, V as VectorMatch, G as GraphDBConfig, m as GraphNode, n as Edge, o as GraphSearchResult, k as VectorDBProvider, f as LLMProvider, e as EmbeddingProvider, g as RAGConfig, U as UIConfig, c as ChatOptions } from './index-DPsQodME.js';
2
+ import { I as ILLMProvider, E as EmbedOptions } from './DocumentChunker-C1GEEosY.js';
3
+ export { C as Chunk, a as ChunkOptions, D as DocumentChunker } from './DocumentChunker-C1GEEosY.js';
4
+ import { H as HealthCheckResult, I as IProviderValidator, a as IProviderHealthChecker } from './index-CkbTzj9J.js';
5
+ export { C as ConfigValidator, V as ValidationError, b as VectorPlugin, c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, j as sseTextFrame } from './index-CkbTzj9J.js';
6
6
  import 'next/server';
7
7
 
8
8
  /**
package/dist/server.js CHANGED
@@ -3945,11 +3945,15 @@ var UITransformer = class {
3945
3945
  static transformToPieChart(data) {
3946
3946
  const categories = this.detectCategories(data);
3947
3947
  const categoryData = this.aggregateByCategory(data, categories);
3948
- const pieData = Object.entries(categoryData).map(([label, count]) => ({
3949
- label,
3950
- value: count,
3951
- inStock: this.checkStockStatus(label, data)
3952
- }));
3948
+ const pieData = Object.entries(categoryData).map(([label, count]) => {
3949
+ const { inStockCount, outOfStockCount } = this.calculateStockCounts(label, data);
3950
+ return {
3951
+ label,
3952
+ value: count,
3953
+ inStockCount,
3954
+ outOfStockCount
3955
+ };
3956
+ });
3953
3957
  return {
3954
3958
  type: "pie_chart",
3955
3959
  title: "Distribution by Category",
@@ -3963,11 +3967,15 @@ var UITransformer = class {
3963
3967
  static transformToBarChart(data) {
3964
3968
  const categories = this.detectCategories(data);
3965
3969
  const categoryData = this.aggregateByCategory(data, categories);
3966
- const barData = Object.entries(categoryData).map(([category, value]) => ({
3967
- category,
3968
- value,
3969
- inStock: this.checkStockStatus(category, data)
3970
- }));
3970
+ const barData = Object.entries(categoryData).map(([category, value]) => {
3971
+ const { inStockCount, outOfStockCount } = this.calculateStockCounts(category, data);
3972
+ return {
3973
+ category,
3974
+ value,
3975
+ inStockCount,
3976
+ outOfStockCount
3977
+ };
3978
+ });
3971
3979
  return {
3972
3980
  type: "bar_chart",
3973
3981
  title: "Comparison by Category",
@@ -4164,14 +4172,23 @@ var UITransformer = class {
4164
4172
  });
4165
4173
  }
4166
4174
  /**
4167
- * Helper: Check stock status
4175
+ * Helper: Calculate stock counts by category
4168
4176
  */
4169
- static checkStockStatus(category, data) {
4170
- const item = data.find((d) => {
4177
+ static calculateStockCounts(category, data) {
4178
+ let inStock = 0;
4179
+ let outOfStock = 0;
4180
+ data.forEach((d) => {
4171
4181
  const meta = d.metadata || {};
4172
- return meta.category === category || meta.type === category;
4182
+ const itemCategory = meta.category || meta.type || "Other";
4183
+ if (itemCategory === category) {
4184
+ if (this.determineStockStatus(d)) {
4185
+ inStock++;
4186
+ } else {
4187
+ outOfStock++;
4188
+ }
4189
+ }
4173
4190
  });
4174
- return this.determineStockStatus(item || {});
4191
+ return { inStockCount: inStock, outOfStockCount: outOfStock };
4175
4192
  }
4176
4193
  /**
4177
4194
  * Helper: Determine if item is in stock
@@ -4280,19 +4297,19 @@ Classify the query into ONE of the following intents:
4280
4297
 
4281
4298
  ---
4282
4299
 
4283
- ## 2. VIEW MAPPING (STRICT)
4300
+ ## 2. VIEW SELECTION (DYNAMIC)
4284
4301
 
4285
- | Intent | View |
4286
- |----------|-----------|
4287
- | explore | carousel |
4288
- | analyze | chart |
4289
- | compare | table |
4290
- | detail | table |
4302
+ Choose the best primary "view" ("carousel", "chart", or "table") based on the data:
4303
+ - TRENDS/GROWTH \u2192 "chart" (type: "line")
4304
+ - DISTRIBUTIONS/RATIOS \u2192 "chart" (type: "pie")
4305
+ - COMPARISONS \u2192 "chart" (type: "bar")
4306
+ - PRODUCT LISTS \u2192 "carousel"
4307
+ - RAW DATA/SPECS \u2192 "table"
4291
4308
 
4292
- \u26A0\uFE0F Override Rules:
4293
- - If query contains "distribution", "percentage", "ratio" \u2192 ALWAYS chart
4294
- - If query contains "show products", "list items" \u2192 ALWAYS carousel
4295
- - NEVER mix views
4309
+ \u26A0\uFE0F Dynamic Overrides:
4310
+ - If query is "show products", ALWAYS use carousel.
4311
+ - If data is statistical, ALWAYS use a chart.
4312
+ - NEVER explain why you chose a view.
4296
4313
 
4297
4314
  ---
4298
4315
 
@@ -4350,7 +4367,8 @@ Classify the query into ONE of the following intents:
4350
4367
  {
4351
4368
  "label": "string",
4352
4369
  "value": number,
4353
- "inStock": boolean (optional)
4370
+ "inStockCount": number (optional),
4371
+ "outOfStockCount": number (optional)
4354
4372
  }
4355
4373
 
4356
4374
  ### \u{1F539} TABLE FORMAT
@@ -4361,14 +4379,14 @@ Classify the query into ONE of the following intents:
4361
4379
 
4362
4380
  ## 5. DATA RULES
4363
4381
 
4364
- - NEVER hallucinate fields or data
4365
- - ONLY use retrieved vector DB data
4366
- - NO placeholders ("...", "N/A")
4367
- - If image/link missing \u2192 REMOVE FIELD
4368
- - Aggregate BEFORE rendering chart
4369
- - IF NO DATA IS FOUND in the retrieved context:
4370
- \u2192 DO NOT output a \`\`\`ui\`\`\` block
4371
- \u2192 Instead, state clearly that no relevant products or data were found.
4382
+ - NEVER hallucinate fields or data.
4383
+ - ONLY use data provided in the retrieved context.
4384
+ - STRICT DATA ISOLATION: The labels and numbers in the EXAMPLES section below are placeholders. NEVER use them.
4385
+ - IF NO DATA IS FOUND: You MUST NOT generate a chart. You MUST NOT say "This example assumes" or provide hypothetical numbers. Simply state "No relevant data found in the database." and STOP.
4386
+ - NO META-COMMENTARY: NEVER talk about the task itself (e.g., "I've used JSON", "In a real-world app", "Dedicated library").
4387
+ - NEVER explain YOUR formatting choice.
4388
+ - Aggregate BEFORE rendering chart.
4389
+ - DYNAMIC INTELLIGENCE: Autonomously extract relevant categories/values from the context and calculate totals for the "data" array based on the user query.
4372
4390
 
4373
4391
  ---
4374
4392
 
@@ -4385,11 +4403,12 @@ Classify the query into ONE of the following intents:
4385
4403
 
4386
4404
  ## 7. OUTPUT RULES
4387
4405
 
4388
- - ALWAYS return EXACTLY ONE \`\`\`ui\`\`\` block
4389
- - JSON must be VALID
4390
- - No explanation inside block
4391
- - NEVER use ASCII charts, Markdown tables, or text-based drawings for data.
4392
- - If data is tabular or statistical, ALWAYS use the \`\`\`ui\`\`\` block.
4406
+ - ALWAYS return EXACTLY ONE \`\`\`ui\`\`\` block.
4407
+ - JSON must be VALID.
4408
+ - FIELD MAPPING (MANDATORY): Always use "label" for the name/category and "value" for the numeric count.
4409
+ - NO xKey or yKeys: Do not include these fields; the UI uses "label" and "value" by default.
4410
+ - SILENT DATA: If a chart is provided, DO NOT say "Here is the JSON" or "Below is the data". Simply output the block.
4411
+ - TEXT OUTSIDE THE BLOCK: One brief sentence maximum.
4393
4412
 
4394
4413
  ---
4395
4414
 
@@ -4400,8 +4419,8 @@ User: "show me beauty products"
4400
4419
  \`\`\`ui
4401
4420
  {
4402
4421
  "view": "carousel",
4403
- "title": "Beauty Products",
4404
- "description": "Browse available beauty items",
4422
+ "title": "TITLE",
4423
+ "description": "DESCRIPTION",
4405
4424
  "metadata": {
4406
4425
  "intent": "explore",
4407
4426
  "confidence": 0.95
@@ -4409,43 +4428,41 @@ User: "show me beauty products"
4409
4428
  "carousel": {
4410
4429
  "items": [
4411
4430
  {
4412
- "id": "1",
4413
- "name": "Mascara",
4414
- "brand": "Essence",
4415
- "price": 9.99,
4416
- "image": "https://example.com/mascara.jpg",
4417
- "link": "https://example.com/p1",
4431
+ "id": "ID",
4432
+ "name": "PRODUCT_NAME",
4433
+ "brand": "BRAND",
4434
+ "price": 0,
4435
+ "image": "URL",
4436
+ "link": "URL",
4418
4437
  "inStock": true
4419
4438
  }
4420
4439
  ]
4421
4440
  },
4422
- "insights": ["Most products are affordable"]
4441
+ "insights": ["INSIGHT"]
4423
4442
  }
4424
4443
  \`\`\`
4425
4444
 
4426
4445
  ---
4427
4446
 
4428
- User: "distribution of products across categories"
4447
+
4429
4448
 
4430
4449
  \`\`\`ui
4431
4450
  {
4432
4451
  "view": "chart",
4433
- "title": "Product Distribution",
4434
- "description": "Category-wise product distribution",
4452
+ "title": "TITLE",
4453
+ "description": "DESCRIPTION",
4435
4454
  "metadata": {
4436
4455
  "intent": "analyze",
4437
4456
  "confidence": 0.98
4438
4457
  },
4439
4458
  "chart": {
4440
4459
  "type": "pie",
4441
- "xKey": "label",
4442
- "yKeys": ["value"],
4443
4460
  "data": [
4444
- { "label": "Beauty", "value": 15 },
4445
- { "label": "Electronics", "value": 10 }
4461
+ { "label": "LABEL_A", "value": 0, "inStockCount": 0, "outOfStockCount": 0 },
4462
+ { "label": "LABEL_B", "value": 0, "inStockCount": 0, "outOfStockCount": 0 }
4446
4463
  ]
4447
4464
  },
4448
- "insights": ["Beauty dominates inventory"]
4465
+ "insights": ["INSIGHT"]
4449
4466
  }
4450
4467
  \`\`\`
4451
4468
  `;
@@ -4606,14 +4623,16 @@ User: "distribution of products across categories"
4606
4623
  let reply = "";
4607
4624
  let sources = [];
4608
4625
  let graphData;
4626
+ let uiTransformation;
4609
4627
  try {
4610
4628
  for (var iter = __forAwait(stream), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
4611
4629
  const chunk = temp.value;
4612
4630
  if (typeof chunk === "string") {
4613
4631
  reply += chunk;
4614
- } else if ("sources" in chunk) {
4615
- sources = chunk.sources;
4616
- graphData = chunk.graphData;
4632
+ } else if (typeof chunk === "object" && chunk !== null) {
4633
+ if ("sources" in chunk) sources = chunk.sources;
4634
+ if ("graphData" in chunk) graphData = chunk.graphData;
4635
+ if ("ui_transformation" in chunk) uiTransformation = chunk.ui_transformation;
4617
4636
  }
4618
4637
  }
4619
4638
  } catch (temp) {
@@ -4626,7 +4645,7 @@ User: "distribution of products across categories"
4626
4645
  throw error[0];
4627
4646
  }
4628
4647
  }
4629
- return { reply, sources, graphData };
4648
+ return { reply, sources, graphData, ui_transformation: uiTransformation };
4630
4649
  }
4631
4650
  /**
4632
4651
  * High-performance streaming RAG flow.
package/dist/server.mjs CHANGED
@@ -39,7 +39,7 @@ import {
39
39
  sseFrame,
40
40
  sseMetaFrame,
41
41
  sseTextFrame
42
- } from "./chunk-UHGYLTTY.mjs";
42
+ } from "./chunk-PV3MFHWU.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.7.8",
3
+ "version": "1.8.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",
@@ -143,42 +143,13 @@ export function DynamicChart({
143
143
  const finalDataKeys = resolvedDataKeys.map(String).filter(k => k !== 'undefined');
144
144
  const pieDataKey = finalDataKeys[0] || 'value';
145
145
 
146
- const stockAwareColor = (entry: Record<string, string | number | null>, index: number) => {
147
- const stockStatus = String(
148
- entry.stockStatus ??
149
- entry.status ??
150
- entry.availability ??
151
- '',
152
- ).toLowerCase();
153
- const inStockCount = typeof entry.inStockCount === 'number' ? entry.inStockCount : undefined;
154
- const outOfStockCount = typeof entry.outOfStockCount === 'number' ? entry.outOfStockCount : undefined;
155
- const inStockFlag = entry.inStock;
156
-
157
- if (stockStatus.includes('in stock')) return '#10b981';
158
- if (stockStatus.includes('out of stock')) return '#f97316';
159
- if (typeof inStockFlag === 'string' && inStockFlag.toLowerCase() === 'true') return '#10b981';
160
- if (inStockFlag === 1) return '#10b981';
161
- if (inStockFlag === 0) return '#f97316';
162
- if (typeof inStockCount === 'number' || typeof outOfStockCount === 'number') {
163
- const inCount = inStockCount ?? 0;
164
- const outCount = outOfStockCount ?? 0;
165
- if (inCount > outCount) return '#10b981';
166
- if (outCount > inCount) return '#f97316';
167
- }
168
-
169
- return colors[index % colors.length];
170
- };
171
146
 
172
147
  const tooltipLabelMap: Record<string, string> = {
173
- value: 'Value',
148
+ value: 'Total Items',
174
149
  count: 'Count',
175
- inStock: 'In stock',
176
- inStockCount: 'In stock',
177
- outOfStockCount: 'Out of stock',
178
- stockStatus: 'Stock status',
179
- category: 'Category',
180
- label: 'Label',
181
- name: 'Name',
150
+ inStockCount: 'In Stock',
151
+ outOfStockCount: 'Out of Stock',
152
+ stockStatus: 'Status',
182
153
  };
183
154
 
184
155
  const renderTooltip = (
@@ -196,6 +167,10 @@ export function DynamicChart({
196
167
  if (value === null || value === undefined || key === finalXKey) return null;
197
168
  if (typeof value === 'object') return null;
198
169
 
170
+ // Filter out technical Recharts/internal keys
171
+ const forbiddenKeys = ['fill', 'color', 'payload', 'percent', 'stroke', 'inStock'];
172
+ if (forbiddenKeys.includes(key)) return null;
173
+
199
174
  return (
200
175
  <div key={key} className="flex items-center justify-between gap-3 text-slate-600 dark:text-white/70">
201
176
  <span>{tooltipLabelMap[key] ?? key}</span>
@@ -235,8 +210,8 @@ export function DynamicChart({
235
210
  label={false}
236
211
  labelLine={false}
237
212
  >
238
- {sanitizedData.map((entry, index) => (
239
- <Cell key={`cell-${index}`} fill={stockAwareColor(entry, index)} />
213
+ {sanitizedData.map((_entry, index) => (
214
+ <Cell key={`cell-${index}`} fill={colors[index % colors.length]} />
240
215
  ))}
241
216
  </Pie>
242
217
  <Tooltip content={(props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === 'string' ? props.label : undefined)} />