@retrivora-ai/rag-engine 1.2.7 → 1.2.8

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.
@@ -1698,11 +1698,12 @@ Sources Used: ${JSON.stringify(
1698
1698
 
1699
1699
  When presenting structured data, statistics, or comparisons, decide if it is best presented as a table or a chart.
1700
1700
  - For tables: use standard Markdown tables.
1701
- - For charts (bar, line, pie): Output a JSON code block with language 'chart'.
1701
+ - For charts (bar, line, pie): You MUST output a fenced code block with the language 'chart'.
1702
1702
  - CRITICAL RULES:
1703
1703
  1. Use ONLY valid JSON (double quotes, no trailing commas).
1704
1704
  2. NO math expressions (e.g., use 100, NOT 50+50).
1705
1705
  3. dataKeys MUST exactly match the property names in the data objects.
1706
+ 4. DO NOT output naked JSON; it MUST be wrapped in \`\`\`chart ... \`\`\`.
1706
1707
  \`\`\`chart
1707
1708
  {
1708
1709
  "type": "bar" | "line" | "pie",
@@ -2259,11 +2260,12 @@ var Pipeline = class {
2259
2260
 
2260
2261
  When presenting structured data, statistics, or comparisons, decide if it is best presented as a table or a chart.
2261
2262
  - For tables: use standard Markdown tables.
2262
- - For charts (bar, line, pie): Output a JSON code block with language 'chart'.
2263
+ - For charts (bar, line, pie): You MUST output a fenced code block with the language 'chart'.
2263
2264
  - CRITICAL RULES:
2264
2265
  1. Use ONLY valid JSON (double quotes, no trailing commas).
2265
2266
  2. NO math expressions (e.g., use 100, NOT 50+50).
2266
2267
  3. dataKeys MUST exactly match the property names in the data objects.
2268
+ 4. DO NOT output naked JSON; it MUST be wrapped in \`\`\`chart ... \`\`\`.
2267
2269
  \`\`\`chart
2268
2270
  {
2269
2271
  "type": "bar" | "line" | "pie",
@@ -3267,11 +3267,12 @@ Sources Used: ${JSON.stringify(
3267
3267
 
3268
3268
  When presenting structured data, statistics, or comparisons, decide if it is best presented as a table or a chart.
3269
3269
  - For tables: use standard Markdown tables.
3270
- - For charts (bar, line, pie): Output a JSON code block with language 'chart'.
3270
+ - For charts (bar, line, pie): You MUST output a fenced code block with the language 'chart'.
3271
3271
  - CRITICAL RULES:
3272
3272
  1. Use ONLY valid JSON (double quotes, no trailing commas).
3273
3273
  2. NO math expressions (e.g., use 100, NOT 50+50).
3274
3274
  3. dataKeys MUST exactly match the property names in the data objects.
3275
+ 4. DO NOT output naked JSON; it MUST be wrapped in \`\`\`chart ... \`\`\`.
3275
3276
  \`\`\`chart
3276
3277
  {
3277
3278
  "type": "bar" | "line" | "pie",
@@ -3822,11 +3823,12 @@ var Pipeline = class {
3822
3823
 
3823
3824
  When presenting structured data, statistics, or comparisons, decide if it is best presented as a table or a chart.
3824
3825
  - For tables: use standard Markdown tables.
3825
- - For charts (bar, line, pie): Output a JSON code block with language 'chart'.
3826
+ - For charts (bar, line, pie): You MUST output a fenced code block with the language 'chart'.
3826
3827
  - CRITICAL RULES:
3827
3828
  1. Use ONLY valid JSON (double quotes, no trailing commas).
3828
3829
  2. NO math expressions (e.g., use 100, NOT 50+50).
3829
3830
  3. dataKeys MUST exactly match the property names in the data objects.
3831
+ 4. DO NOT output naked JSON; it MUST be wrapped in \`\`\`chart ... \`\`\`.
3830
3832
  \`\`\`chart
3831
3833
  {
3832
3834
  "type": "bar" | "line" | "pie",
@@ -9,7 +9,7 @@ import {
9
9
  sseFrame,
10
10
  sseMetaFrame,
11
11
  sseTextFrame
12
- } from "../chunk-6WBJNJ5M.mjs";
12
+ } from "../chunk-AYOQ4LF4.mjs";
13
13
  import "../chunk-YLTMFW4M.mjs";
14
14
  import "../chunk-X4TOT24V.mjs";
15
15
  export {
package/dist/index.js CHANGED
@@ -221,19 +221,26 @@ var import_react4 = __toESM(require("react"));
221
221
  var import_recharts = require("recharts");
222
222
  var DEFAULT_COLORS = ["#6366f1", "#10b981", "#f59e0b", "#ef4444", "#8b5cf6", "#ec4899"];
223
223
  function DynamicChart({ config, primaryColor = "#6366f1", accentColor = "#8b5cf6" }) {
224
- const { type, data, xAxisKey = "name", dataKeys = [] } = config;
224
+ const { type, data } = config;
225
225
  const colors = config.colors || [primaryColor, accentColor, ...DEFAULT_COLORS];
226
226
  if (!data || data.length === 0) {
227
227
  return /* @__PURE__ */ import_react4.default.createElement("div", { className: "p-4 text-sm text-slate-500" }, "No data available for chart.");
228
228
  }
229
+ const firstItem = data[0];
230
+ const allKeys = Object.keys(firstItem);
231
+ const resolvedXKey = config.xAxisKey && firstItem[config.xAxisKey] !== void 0 ? config.xAxisKey : allKeys.find((k) => k.toLowerCase() === "name" || k.toLowerCase() === "label" || k.toLowerCase() === "category") || allKeys.find((k) => typeof firstItem[k] === "string") || allKeys[0];
232
+ const resolvedDataKeys = config.dataKeys && config.dataKeys.every((k) => firstItem[k] !== void 0) ? config.dataKeys : allKeys.filter((k) => k !== resolvedXKey && (typeof firstItem[k] === "number" || k.toLowerCase() === "value" || k.toLowerCase() === "count")).slice(0, 5);
233
+ if (resolvedDataKeys.length === 0 && allKeys.length > 1) {
234
+ resolvedDataKeys.push(allKeys.find((k) => k !== resolvedXKey) || allKeys[1]);
235
+ }
229
236
  if (type === "pie") {
230
- const pieDataKey = dataKeys[0] || Object.keys(data[0]).find((k) => k !== xAxisKey) || "value";
237
+ const pieDataKey = resolvedDataKeys[0] || "value";
231
238
  return /* @__PURE__ */ import_react4.default.createElement("div", { className: "w-full h-72 min-h-[280px] mt-4 mb-2 select-none overflow-hidden" }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.ResponsiveContainer, { width: "99%", height: "100%" }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.PieChart, null, /* @__PURE__ */ import_react4.default.createElement(
232
239
  import_recharts.Pie,
233
240
  {
234
241
  data,
235
242
  dataKey: pieDataKey,
236
- nameKey: xAxisKey,
243
+ nameKey: resolvedXKey,
237
244
  cx: "50%",
238
245
  cy: "50%",
239
246
  outerRadius: 80,
@@ -247,13 +254,13 @@ function DynamicChart({ config, primaryColor = "#6366f1", accentColor = "#8b5cf6
247
254
  }
248
255
  ), /* @__PURE__ */ import_react4.default.createElement(import_recharts.Legend, null))));
249
256
  }
250
- return /* @__PURE__ */ import_react4.default.createElement("div", { className: "w-full h-72 min-h-[280px] mt-4 mb-2 select-none overflow-hidden" }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.ResponsiveContainer, { width: "99%", height: "100%" }, type === "bar" ? /* @__PURE__ */ import_react4.default.createElement(import_recharts.BarChart, { data, margin: { top: 10, right: 10, left: -20, bottom: 0 } }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ import_react4.default.createElement(import_recharts.XAxis, { dataKey: xAxisKey, tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: { stroke: "#cbd5e1" } }), /* @__PURE__ */ import_react4.default.createElement(import_recharts.YAxis, { tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: false }), /* @__PURE__ */ import_react4.default.createElement(
257
+ return /* @__PURE__ */ import_react4.default.createElement("div", { className: "w-full h-72 min-h-[280px] mt-4 mb-2 select-none overflow-hidden" }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.ResponsiveContainer, { width: "99%", height: "100%" }, type === "bar" ? /* @__PURE__ */ import_react4.default.createElement(import_recharts.BarChart, { data, margin: { top: 10, right: 10, left: -20, bottom: 0 } }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ import_react4.default.createElement(import_recharts.XAxis, { dataKey: resolvedXKey, tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: { stroke: "#cbd5e1" } }), /* @__PURE__ */ import_react4.default.createElement(import_recharts.YAxis, { tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: false }), /* @__PURE__ */ import_react4.default.createElement(
251
258
  import_recharts.Tooltip,
252
259
  {
253
260
  contentStyle: { borderRadius: "8px", border: "none", boxShadow: "0 4px 6px -1px rgb(0 0 0 / 0.1)" },
254
261
  cursor: { fill: "#f1f5f9" }
255
262
  }
256
- ), /* @__PURE__ */ import_react4.default.createElement(import_recharts.Legend, { wrapperStyle: { fontSize: 12 } }), dataKeys.map((key, index) => /* @__PURE__ */ import_react4.default.createElement(
263
+ ), /* @__PURE__ */ import_react4.default.createElement(import_recharts.Legend, { wrapperStyle: { fontSize: 12 } }), resolvedDataKeys.map((key, index) => /* @__PURE__ */ import_react4.default.createElement(
257
264
  import_recharts.Bar,
258
265
  {
259
266
  key,
@@ -262,12 +269,12 @@ function DynamicChart({ config, primaryColor = "#6366f1", accentColor = "#8b5cf6
262
269
  radius: [4, 4, 0, 0],
263
270
  barSize: Math.max(20, 60 / data.length)
264
271
  }
265
- ))) : /* @__PURE__ */ import_react4.default.createElement(import_recharts.LineChart, { data, margin: { top: 10, right: 10, left: -20, bottom: 0 } }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ import_react4.default.createElement(import_recharts.XAxis, { dataKey: xAxisKey, tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: { stroke: "#cbd5e1" } }), /* @__PURE__ */ import_react4.default.createElement(import_recharts.YAxis, { tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: false }), /* @__PURE__ */ import_react4.default.createElement(
272
+ ))) : /* @__PURE__ */ import_react4.default.createElement(import_recharts.LineChart, { data, margin: { top: 10, right: 10, left: -20, bottom: 0 } }, /* @__PURE__ */ import_react4.default.createElement(import_recharts.CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ import_react4.default.createElement(import_recharts.XAxis, { dataKey: resolvedXKey, tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: { stroke: "#cbd5e1" } }), /* @__PURE__ */ import_react4.default.createElement(import_recharts.YAxis, { tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: false }), /* @__PURE__ */ import_react4.default.createElement(
266
273
  import_recharts.Tooltip,
267
274
  {
268
275
  contentStyle: { borderRadius: "8px", border: "none", boxShadow: "0 4px 6px -1px rgb(0 0 0 / 0.1)" }
269
276
  }
270
- ), /* @__PURE__ */ import_react4.default.createElement(import_recharts.Legend, { wrapperStyle: { fontSize: 12 } }), dataKeys.map((key, index) => /* @__PURE__ */ import_react4.default.createElement(
277
+ ), /* @__PURE__ */ import_react4.default.createElement(import_recharts.Legend, { wrapperStyle: { fontSize: 12 } }), resolvedDataKeys.map((key, index) => /* @__PURE__ */ import_react4.default.createElement(
271
278
  import_recharts.Line,
272
279
  {
273
280
  key,
package/dist/index.mjs CHANGED
@@ -184,19 +184,26 @@ import {
184
184
  } from "recharts";
185
185
  var DEFAULT_COLORS = ["#6366f1", "#10b981", "#f59e0b", "#ef4444", "#8b5cf6", "#ec4899"];
186
186
  function DynamicChart({ config, primaryColor = "#6366f1", accentColor = "#8b5cf6" }) {
187
- const { type, data, xAxisKey = "name", dataKeys = [] } = config;
187
+ const { type, data } = config;
188
188
  const colors = config.colors || [primaryColor, accentColor, ...DEFAULT_COLORS];
189
189
  if (!data || data.length === 0) {
190
190
  return /* @__PURE__ */ React4.createElement("div", { className: "p-4 text-sm text-slate-500" }, "No data available for chart.");
191
191
  }
192
+ const firstItem = data[0];
193
+ const allKeys = Object.keys(firstItem);
194
+ const resolvedXKey = config.xAxisKey && firstItem[config.xAxisKey] !== void 0 ? config.xAxisKey : allKeys.find((k) => k.toLowerCase() === "name" || k.toLowerCase() === "label" || k.toLowerCase() === "category") || allKeys.find((k) => typeof firstItem[k] === "string") || allKeys[0];
195
+ const resolvedDataKeys = config.dataKeys && config.dataKeys.every((k) => firstItem[k] !== void 0) ? config.dataKeys : allKeys.filter((k) => k !== resolvedXKey && (typeof firstItem[k] === "number" || k.toLowerCase() === "value" || k.toLowerCase() === "count")).slice(0, 5);
196
+ if (resolvedDataKeys.length === 0 && allKeys.length > 1) {
197
+ resolvedDataKeys.push(allKeys.find((k) => k !== resolvedXKey) || allKeys[1]);
198
+ }
192
199
  if (type === "pie") {
193
- const pieDataKey = dataKeys[0] || Object.keys(data[0]).find((k) => k !== xAxisKey) || "value";
200
+ const pieDataKey = resolvedDataKeys[0] || "value";
194
201
  return /* @__PURE__ */ React4.createElement("div", { className: "w-full h-72 min-h-[280px] mt-4 mb-2 select-none overflow-hidden" }, /* @__PURE__ */ React4.createElement(ResponsiveContainer, { width: "99%", height: "100%" }, /* @__PURE__ */ React4.createElement(PieChart, null, /* @__PURE__ */ React4.createElement(
195
202
  Pie,
196
203
  {
197
204
  data,
198
205
  dataKey: pieDataKey,
199
- nameKey: xAxisKey,
206
+ nameKey: resolvedXKey,
200
207
  cx: "50%",
201
208
  cy: "50%",
202
209
  outerRadius: 80,
@@ -210,13 +217,13 @@ function DynamicChart({ config, primaryColor = "#6366f1", accentColor = "#8b5cf6
210
217
  }
211
218
  ), /* @__PURE__ */ React4.createElement(Legend, null))));
212
219
  }
213
- return /* @__PURE__ */ React4.createElement("div", { className: "w-full h-72 min-h-[280px] mt-4 mb-2 select-none overflow-hidden" }, /* @__PURE__ */ React4.createElement(ResponsiveContainer, { width: "99%", height: "100%" }, type === "bar" ? /* @__PURE__ */ React4.createElement(BarChart, { data, margin: { top: 10, right: 10, left: -20, bottom: 0 } }, /* @__PURE__ */ React4.createElement(CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ React4.createElement(XAxis, { dataKey: xAxisKey, tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: { stroke: "#cbd5e1" } }), /* @__PURE__ */ React4.createElement(YAxis, { tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: false }), /* @__PURE__ */ React4.createElement(
220
+ return /* @__PURE__ */ React4.createElement("div", { className: "w-full h-72 min-h-[280px] mt-4 mb-2 select-none overflow-hidden" }, /* @__PURE__ */ React4.createElement(ResponsiveContainer, { width: "99%", height: "100%" }, type === "bar" ? /* @__PURE__ */ React4.createElement(BarChart, { data, margin: { top: 10, right: 10, left: -20, bottom: 0 } }, /* @__PURE__ */ React4.createElement(CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ React4.createElement(XAxis, { dataKey: resolvedXKey, tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: { stroke: "#cbd5e1" } }), /* @__PURE__ */ React4.createElement(YAxis, { tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: false }), /* @__PURE__ */ React4.createElement(
214
221
  Tooltip,
215
222
  {
216
223
  contentStyle: { borderRadius: "8px", border: "none", boxShadow: "0 4px 6px -1px rgb(0 0 0 / 0.1)" },
217
224
  cursor: { fill: "#f1f5f9" }
218
225
  }
219
- ), /* @__PURE__ */ React4.createElement(Legend, { wrapperStyle: { fontSize: 12 } }), dataKeys.map((key, index) => /* @__PURE__ */ React4.createElement(
226
+ ), /* @__PURE__ */ React4.createElement(Legend, { wrapperStyle: { fontSize: 12 } }), resolvedDataKeys.map((key, index) => /* @__PURE__ */ React4.createElement(
220
227
  Bar,
221
228
  {
222
229
  key,
@@ -225,12 +232,12 @@ function DynamicChart({ config, primaryColor = "#6366f1", accentColor = "#8b5cf6
225
232
  radius: [4, 4, 0, 0],
226
233
  barSize: Math.max(20, 60 / data.length)
227
234
  }
228
- ))) : /* @__PURE__ */ React4.createElement(LineChart, { data, margin: { top: 10, right: 10, left: -20, bottom: 0 } }, /* @__PURE__ */ React4.createElement(CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ React4.createElement(XAxis, { dataKey: xAxisKey, tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: { stroke: "#cbd5e1" } }), /* @__PURE__ */ React4.createElement(YAxis, { tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: false }), /* @__PURE__ */ React4.createElement(
235
+ ))) : /* @__PURE__ */ React4.createElement(LineChart, { data, margin: { top: 10, right: 10, left: -20, bottom: 0 } }, /* @__PURE__ */ React4.createElement(CartesianGrid, { strokeDasharray: "3 3", vertical: false, stroke: "#e2e8f0" }), /* @__PURE__ */ React4.createElement(XAxis, { dataKey: resolvedXKey, tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: { stroke: "#cbd5e1" } }), /* @__PURE__ */ React4.createElement(YAxis, { tick: { fontSize: 12, fill: "#64748b" }, tickLine: false, axisLine: false }), /* @__PURE__ */ React4.createElement(
229
236
  Tooltip,
230
237
  {
231
238
  contentStyle: { borderRadius: "8px", border: "none", boxShadow: "0 4px 6px -1px rgb(0 0 0 / 0.1)" }
232
239
  }
233
- ), /* @__PURE__ */ React4.createElement(Legend, { wrapperStyle: { fontSize: 12 } }), dataKeys.map((key, index) => /* @__PURE__ */ React4.createElement(
240
+ ), /* @__PURE__ */ React4.createElement(Legend, { wrapperStyle: { fontSize: 12 } }), resolvedDataKeys.map((key, index) => /* @__PURE__ */ React4.createElement(
234
241
  Line,
235
242
  {
236
243
  key,
package/dist/server.js CHANGED
@@ -3352,11 +3352,12 @@ Sources Used: ${JSON.stringify(
3352
3352
 
3353
3353
  When presenting structured data, statistics, or comparisons, decide if it is best presented as a table or a chart.
3354
3354
  - For tables: use standard Markdown tables.
3355
- - For charts (bar, line, pie): Output a JSON code block with language 'chart'.
3355
+ - For charts (bar, line, pie): You MUST output a fenced code block with the language 'chart'.
3356
3356
  - CRITICAL RULES:
3357
3357
  1. Use ONLY valid JSON (double quotes, no trailing commas).
3358
3358
  2. NO math expressions (e.g., use 100, NOT 50+50).
3359
3359
  3. dataKeys MUST exactly match the property names in the data objects.
3360
+ 4. DO NOT output naked JSON; it MUST be wrapped in \`\`\`chart ... \`\`\`.
3360
3361
  \`\`\`chart
3361
3362
  {
3362
3363
  "type": "bar" | "line" | "pie",
@@ -3913,11 +3914,12 @@ var Pipeline = class {
3913
3914
 
3914
3915
  When presenting structured data, statistics, or comparisons, decide if it is best presented as a table or a chart.
3915
3916
  - For tables: use standard Markdown tables.
3916
- - For charts (bar, line, pie): Output a JSON code block with language 'chart'.
3917
+ - For charts (bar, line, pie): You MUST output a fenced code block with the language 'chart'.
3917
3918
  - CRITICAL RULES:
3918
3919
  1. Use ONLY valid JSON (double quotes, no trailing commas).
3919
3920
  2. NO math expressions (e.g., use 100, NOT 50+50).
3920
3921
  3. dataKeys MUST exactly match the property names in the data objects.
3922
+ 4. DO NOT output naked JSON; it MUST be wrapped in \`\`\`chart ... \`\`\`.
3921
3923
  \`\`\`chart
3922
3924
  {
3923
3925
  "type": "bar" | "line" | "pie",
package/dist/server.mjs CHANGED
@@ -39,7 +39,7 @@ import {
39
39
  sseFrame,
40
40
  sseMetaFrame,
41
41
  sseTextFrame
42
- } from "./chunk-6WBJNJ5M.mjs";
42
+ } from "./chunk-AYOQ4LF4.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.2.7",
3
+ "version": "1.2.8",
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",
@@ -23,16 +23,38 @@ interface DynamicChartProps {
23
23
  const DEFAULT_COLORS = ['#6366f1', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#ec4899'];
24
24
 
25
25
  export function DynamicChart({ config, primaryColor = '#6366f1', accentColor = '#8b5cf6' }: DynamicChartProps) {
26
- const { type, data, xAxisKey = 'name', dataKeys = [] } = config;
26
+ const { type, data } = config;
27
27
  const colors = config.colors || [primaryColor, accentColor, ...DEFAULT_COLORS];
28
28
 
29
29
  if (!data || data.length === 0) {
30
30
  return <div className="p-4 text-sm text-slate-500">No data available for chart.</div>;
31
31
  }
32
32
 
33
+ // Smart key resolution: if the provided keys don't exist in the data, try to guess them
34
+ const firstItem = data[0];
35
+ const allKeys = Object.keys(firstItem);
36
+
37
+ // Resolve xAxisKey: use provided, fallback to 'name', 'label', 'category', or the first string key
38
+ const resolvedXKey = config.xAxisKey && firstItem[config.xAxisKey] !== undefined
39
+ ? config.xAxisKey
40
+ : allKeys.find(k => k.toLowerCase() === 'name' || k.toLowerCase() === 'label' || k.toLowerCase() === 'category')
41
+ || allKeys.find(k => typeof firstItem[k] === 'string')
42
+ || allKeys[0];
43
+
44
+ // Resolve dataKeys: use provided, fallback to 'value', 'count', 'amount', or all numeric keys
45
+ const resolvedDataKeys = config.dataKeys && config.dataKeys.every(k => firstItem[k] !== undefined)
46
+ ? config.dataKeys
47
+ : allKeys.filter(k => k !== resolvedXKey && (typeof firstItem[k] === 'number' || k.toLowerCase() === 'value' || k.toLowerCase() === 'count'))
48
+ .slice(0, 5); // Limit to 5 series for sanity
49
+
50
+ if (resolvedDataKeys.length === 0 && allKeys.length > 1) {
51
+ // Last resort: just use the second key
52
+ resolvedDataKeys.push(allKeys.find(k => k !== resolvedXKey) || allKeys[1]);
53
+ }
54
+
33
55
  // Handle Pie Chart separately as it has a different structure
34
56
  if (type === 'pie') {
35
- const pieDataKey = dataKeys[0] || Object.keys(data[0]).find(k => k !== xAxisKey) || 'value';
57
+ const pieDataKey = resolvedDataKeys[0] || 'value';
36
58
 
37
59
  return (
38
60
  <div className="w-full h-72 min-h-[280px] mt-4 mb-2 select-none overflow-hidden">
@@ -41,7 +63,7 @@ export function DynamicChart({ config, primaryColor = '#6366f1', accentColor = '
41
63
  <Pie
42
64
  data={data}
43
65
  dataKey={pieDataKey}
44
- nameKey={xAxisKey}
66
+ nameKey={resolvedXKey}
45
67
  cx="50%"
46
68
  cy="50%"
47
69
  outerRadius={80}
@@ -68,14 +90,14 @@ export function DynamicChart({ config, primaryColor = '#6366f1', accentColor = '
68
90
  {type === 'bar' ? (
69
91
  <BarChart data={data} margin={{ top: 10, right: 10, left: -20, bottom: 0 }}>
70
92
  <CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#e2e8f0" />
71
- <XAxis dataKey={xAxisKey} tick={{ fontSize: 12, fill: '#64748b' }} tickLine={false} axisLine={{ stroke: '#cbd5e1' }} />
93
+ <XAxis dataKey={resolvedXKey} tick={{ fontSize: 12, fill: '#64748b' }} tickLine={false} axisLine={{ stroke: '#cbd5e1' }} />
72
94
  <YAxis tick={{ fontSize: 12, fill: '#64748b' }} tickLine={false} axisLine={false} />
73
95
  <Tooltip
74
96
  contentStyle={{ borderRadius: '8px', border: 'none', boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1)' }}
75
97
  cursor={{ fill: '#f1f5f9' }}
76
98
  />
77
99
  <Legend wrapperStyle={{ fontSize: 12 }} />
78
- {dataKeys.map((key, index) => (
100
+ {resolvedDataKeys.map((key, index) => (
79
101
  <Bar
80
102
  key={key}
81
103
  dataKey={key}
@@ -88,13 +110,13 @@ export function DynamicChart({ config, primaryColor = '#6366f1', accentColor = '
88
110
  ) : (
89
111
  <LineChart data={data} margin={{ top: 10, right: 10, left: -20, bottom: 0 }}>
90
112
  <CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#e2e8f0" />
91
- <XAxis dataKey={xAxisKey} tick={{ fontSize: 12, fill: '#64748b' }} tickLine={false} axisLine={{ stroke: '#cbd5e1' }} />
113
+ <XAxis dataKey={resolvedXKey} tick={{ fontSize: 12, fill: '#64748b' }} tickLine={false} axisLine={{ stroke: '#cbd5e1' }} />
92
114
  <YAxis tick={{ fontSize: 12, fill: '#64748b' }} tickLine={false} axisLine={false} />
93
115
  <Tooltip
94
116
  contentStyle={{ borderRadius: '8px', border: 'none', boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1)' }}
95
117
  />
96
118
  <Legend wrapperStyle={{ fontSize: 12 }} />
97
- {dataKeys.map((key, index) => (
119
+ {resolvedDataKeys.map((key, index) => (
98
120
  <Line
99
121
  key={key}
100
122
  type="monotone"
@@ -52,11 +52,12 @@ export class LangChainAgent {
52
52
 
53
53
  const chartInstruction = `\n\nWhen presenting structured data, statistics, or comparisons, decide if it is best presented as a table or a chart.
54
54
  - For tables: use standard Markdown tables.
55
- - For charts (bar, line, pie): Output a JSON code block with language 'chart'.
55
+ - For charts (bar, line, pie): You MUST output a fenced code block with the language 'chart'.
56
56
  - CRITICAL RULES:
57
57
  1. Use ONLY valid JSON (double quotes, no trailing commas).
58
58
  2. NO math expressions (e.g., use 100, NOT 50+50).
59
59
  3. dataKeys MUST exactly match the property names in the data objects.
60
+ 4. DO NOT output naked JSON; it MUST be wrapped in \`\`\`chart ... \`\`\`.
60
61
  \`\`\`chart
61
62
  {
62
63
  "type": "bar" | "line" | "pie",
@@ -102,11 +102,12 @@ export class Pipeline {
102
102
  // Augment system prompt with Chart/Table instructions if not already present
103
103
  const chartInstruction = `\n\nWhen presenting structured data, statistics, or comparisons, decide if it is best presented as a table or a chart.
104
104
  - For tables: use standard Markdown tables.
105
- - For charts (bar, line, pie): Output a JSON code block with language 'chart'.
105
+ - For charts (bar, line, pie): You MUST output a fenced code block with the language 'chart'.
106
106
  - CRITICAL RULES:
107
107
  1. Use ONLY valid JSON (double quotes, no trailing commas).
108
108
  2. NO math expressions (e.g., use 100, NOT 50+50).
109
109
  3. dataKeys MUST exactly match the property names in the data objects.
110
+ 4. DO NOT output naked JSON; it MUST be wrapped in \`\`\`chart ... \`\`\`.
110
111
  \`\`\`chart
111
112
  {
112
113
  "type": "bar" | "line" | "pie",