@retrivora-ai/rag-engine 1.3.1 → 1.3.2
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/{chunk-AYOQ4LF4.mjs → chunk-FQ7OYZLF.mjs} +4 -2
- package/dist/handlers/index.js +4 -2
- package/dist/handlers/index.mjs +1 -1
- package/dist/index.js +35 -15
- package/dist/index.mjs +35 -15
- package/dist/server.js +4 -2
- package/dist/server.mjs +1 -1
- package/package.json +1 -1
- package/src/components/DynamicChart.tsx +29 -15
- package/src/components/MessageBubble.tsx +15 -3
- package/src/core/LangChainAgent.ts +2 -1
- package/src/core/Pipeline.ts +2 -1
|
@@ -1703,7 +1703,8 @@ When presenting structured data, statistics, or comparisons, decide if it is bes
|
|
|
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.
|
|
1706
|
+
4. data objects MUST be FLAT (no nested objects or arrays).
|
|
1707
|
+
5. DO NOT output naked JSON; it MUST be wrapped in \`\`\`chart ... \`\`\`.
|
|
1707
1708
|
\`\`\`chart
|
|
1708
1709
|
{
|
|
1709
1710
|
"type": "bar" | "line" | "pie",
|
|
@@ -2265,7 +2266,8 @@ When presenting structured data, statistics, or comparisons, decide if it is bes
|
|
|
2265
2266
|
1. Use ONLY valid JSON (double quotes, no trailing commas).
|
|
2266
2267
|
2. NO math expressions (e.g., use 100, NOT 50+50).
|
|
2267
2268
|
3. dataKeys MUST exactly match the property names in the data objects.
|
|
2268
|
-
4.
|
|
2269
|
+
4. data objects MUST be FLAT (no nested objects or arrays).
|
|
2270
|
+
5. DO NOT output naked JSON; it MUST be wrapped in \`\`\`chart ... \`\`\`.
|
|
2269
2271
|
\`\`\`chart
|
|
2270
2272
|
{
|
|
2271
2273
|
"type": "bar" | "line" | "pie",
|
package/dist/handlers/index.js
CHANGED
|
@@ -3272,7 +3272,8 @@ When presenting structured data, statistics, or comparisons, decide if it is bes
|
|
|
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.
|
|
3275
|
+
4. data objects MUST be FLAT (no nested objects or arrays).
|
|
3276
|
+
5. DO NOT output naked JSON; it MUST be wrapped in \`\`\`chart ... \`\`\`.
|
|
3276
3277
|
\`\`\`chart
|
|
3277
3278
|
{
|
|
3278
3279
|
"type": "bar" | "line" | "pie",
|
|
@@ -3828,7 +3829,8 @@ When presenting structured data, statistics, or comparisons, decide if it is bes
|
|
|
3828
3829
|
1. Use ONLY valid JSON (double quotes, no trailing commas).
|
|
3829
3830
|
2. NO math expressions (e.g., use 100, NOT 50+50).
|
|
3830
3831
|
3. dataKeys MUST exactly match the property names in the data objects.
|
|
3831
|
-
4.
|
|
3832
|
+
4. data objects MUST be FLAT (no nested objects or arrays).
|
|
3833
|
+
5. DO NOT output naked JSON; it MUST be wrapped in \`\`\`chart ... \`\`\`.
|
|
3832
3834
|
\`\`\`chart
|
|
3833
3835
|
{
|
|
3834
3836
|
"type": "bar" | "line" | "pie",
|
package/dist/handlers/index.mjs
CHANGED
package/dist/index.js
CHANGED
|
@@ -223,6 +223,30 @@ var DEFAULT_COLORS = ["#6366f1", "#10b981", "#f59e0b", "#ef4444", "#8b5cf6", "#e
|
|
|
223
223
|
function DynamicChart({ config, primaryColor = "#6366f1", accentColor = "#8b5cf6" }) {
|
|
224
224
|
const { type, data } = config;
|
|
225
225
|
const colors = config.colors || [primaryColor, accentColor, ...DEFAULT_COLORS];
|
|
226
|
+
const sanitizedData = import_react4.default.useMemo(() => {
|
|
227
|
+
if (!data) return [];
|
|
228
|
+
return data.map((item) => {
|
|
229
|
+
const newItem = {};
|
|
230
|
+
Object.keys(item).forEach((k) => {
|
|
231
|
+
const val = item[k];
|
|
232
|
+
if (Array.isArray(val)) {
|
|
233
|
+
val.forEach((subItem) => {
|
|
234
|
+
if (typeof subItem === "object" && subItem !== null) {
|
|
235
|
+
Object.keys(subItem).forEach((sk) => {
|
|
236
|
+
const subVal = subItem[sk];
|
|
237
|
+
if (typeof subVal !== "object" || subVal === null) {
|
|
238
|
+
newItem[sk] = subVal;
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
} else if (typeof val !== "object" || val === null) {
|
|
244
|
+
newItem[k] = val;
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
return newItem;
|
|
248
|
+
});
|
|
249
|
+
}, [data]);
|
|
226
250
|
if (!data || data.length === 0) {
|
|
227
251
|
return /* @__PURE__ */ import_react4.default.createElement("div", { className: "p-4 text-sm text-slate-500" }, "No data available for chart.");
|
|
228
252
|
}
|
|
@@ -238,18 +262,6 @@ function DynamicChart({ config, primaryColor = "#6366f1", accentColor = "#8b5cf6
|
|
|
238
262
|
}).slice(0, 5);
|
|
239
263
|
const finalXKey = String(resolvedXKey);
|
|
240
264
|
const finalDataKeys = resolvedDataKeys.map(String).filter((k) => k !== "undefined");
|
|
241
|
-
const sanitizedData = import_react4.default.useMemo(() => {
|
|
242
|
-
return data.map((item) => {
|
|
243
|
-
const newItem = {};
|
|
244
|
-
Object.keys(item).forEach((k) => {
|
|
245
|
-
const val = item[k];
|
|
246
|
-
if (typeof val !== "object" || val === null) {
|
|
247
|
-
newItem[k] = val;
|
|
248
|
-
}
|
|
249
|
-
});
|
|
250
|
-
return newItem;
|
|
251
|
-
});
|
|
252
|
-
}, [data]);
|
|
253
265
|
if (type === "pie") {
|
|
254
266
|
const pieDataKey = finalDataKeys[0] || "value";
|
|
255
267
|
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(
|
|
@@ -415,11 +427,11 @@ function MessageBubble({
|
|
|
415
427
|
},
|
|
416
428
|
th: (_c) => {
|
|
417
429
|
var _d = _c, { children } = _d, props = __objRest(_d, ["children"]);
|
|
418
|
-
return /* @__PURE__ */ import_react5.default.createElement("th", __spreadValues({ className: "p-3 font-semibold text-slate-700 dark:text-white/90 first:rounded-tl-xl last:rounded-tr-xl" }, props), typeof children === "object" && children !== null && !Array.isArray(children) && !children
|
|
430
|
+
return /* @__PURE__ */ import_react5.default.createElement("th", __spreadValues({ className: "p-3 font-semibold text-slate-700 dark:text-white/90 first:rounded-tl-xl last:rounded-tr-xl" }, props), typeof children === "object" && children !== null && !Array.isArray(children) && !import_react5.default.isValidElement(children) ? JSON.stringify(children) : children);
|
|
419
431
|
},
|
|
420
432
|
td: (_e) => {
|
|
421
433
|
var _f = _e, { children } = _f, props = __objRest(_f, ["children"]);
|
|
422
|
-
return /* @__PURE__ */ import_react5.default.createElement("td", __spreadValues({ className: "p-3 border-b border-slate-100 dark:border-white/5 last:border-0 text-slate-600 dark:text-white/70" }, props), typeof children === "object" && children !== null && !Array.isArray(children) && !children
|
|
434
|
+
return /* @__PURE__ */ import_react5.default.createElement("td", __spreadValues({ className: "p-3 border-b border-slate-100 dark:border-white/5 last:border-0 text-slate-600 dark:text-white/70" }, props), typeof children === "object" && children !== null && !Array.isArray(children) && !import_react5.default.isValidElement(children) ? JSON.stringify(children) : children);
|
|
423
435
|
},
|
|
424
436
|
code(_g) {
|
|
425
437
|
var _h = _g, { inline, className, children } = _h, props = __objRest(_h, ["inline", "className", "children"]);
|
|
@@ -431,7 +443,15 @@ function MessageBubble({
|
|
|
431
443
|
return null;
|
|
432
444
|
}
|
|
433
445
|
const sanitizeJson = (json) => {
|
|
434
|
-
|
|
446
|
+
const firstBrace = json.indexOf("{");
|
|
447
|
+
const firstBracket = json.indexOf("[");
|
|
448
|
+
const start = firstBrace !== -1 && (firstBracket === -1 || firstBrace < firstBracket) ? firstBrace : firstBracket;
|
|
449
|
+
const lastBrace = json.lastIndexOf("}");
|
|
450
|
+
const lastBracket = json.lastIndexOf("]");
|
|
451
|
+
const end = Math.max(lastBrace, lastBracket);
|
|
452
|
+
if (start === -1 || end === -1 || end < start) return json;
|
|
453
|
+
const trimmed = json.substring(start, end + 1);
|
|
454
|
+
return trimmed.replace(/:\s*(\d+(\.\d+)?)\s*([\+\-\*\/])\s*(\d+(\.\d+)?)/g, (_, n1, __, op, n2) => {
|
|
435
455
|
var _a;
|
|
436
456
|
const v1 = parseFloat(n1);
|
|
437
457
|
const v2 = parseFloat(n2);
|
package/dist/index.mjs
CHANGED
|
@@ -186,6 +186,30 @@ var DEFAULT_COLORS = ["#6366f1", "#10b981", "#f59e0b", "#ef4444", "#8b5cf6", "#e
|
|
|
186
186
|
function DynamicChart({ config, primaryColor = "#6366f1", accentColor = "#8b5cf6" }) {
|
|
187
187
|
const { type, data } = config;
|
|
188
188
|
const colors = config.colors || [primaryColor, accentColor, ...DEFAULT_COLORS];
|
|
189
|
+
const sanitizedData = React4.useMemo(() => {
|
|
190
|
+
if (!data) return [];
|
|
191
|
+
return data.map((item) => {
|
|
192
|
+
const newItem = {};
|
|
193
|
+
Object.keys(item).forEach((k) => {
|
|
194
|
+
const val = item[k];
|
|
195
|
+
if (Array.isArray(val)) {
|
|
196
|
+
val.forEach((subItem) => {
|
|
197
|
+
if (typeof subItem === "object" && subItem !== null) {
|
|
198
|
+
Object.keys(subItem).forEach((sk) => {
|
|
199
|
+
const subVal = subItem[sk];
|
|
200
|
+
if (typeof subVal !== "object" || subVal === null) {
|
|
201
|
+
newItem[sk] = subVal;
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
} else if (typeof val !== "object" || val === null) {
|
|
207
|
+
newItem[k] = val;
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
return newItem;
|
|
211
|
+
});
|
|
212
|
+
}, [data]);
|
|
189
213
|
if (!data || data.length === 0) {
|
|
190
214
|
return /* @__PURE__ */ React4.createElement("div", { className: "p-4 text-sm text-slate-500" }, "No data available for chart.");
|
|
191
215
|
}
|
|
@@ -201,18 +225,6 @@ function DynamicChart({ config, primaryColor = "#6366f1", accentColor = "#8b5cf6
|
|
|
201
225
|
}).slice(0, 5);
|
|
202
226
|
const finalXKey = String(resolvedXKey);
|
|
203
227
|
const finalDataKeys = resolvedDataKeys.map(String).filter((k) => k !== "undefined");
|
|
204
|
-
const sanitizedData = React4.useMemo(() => {
|
|
205
|
-
return data.map((item) => {
|
|
206
|
-
const newItem = {};
|
|
207
|
-
Object.keys(item).forEach((k) => {
|
|
208
|
-
const val = item[k];
|
|
209
|
-
if (typeof val !== "object" || val === null) {
|
|
210
|
-
newItem[k] = val;
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
return newItem;
|
|
214
|
-
});
|
|
215
|
-
}, [data]);
|
|
216
228
|
if (type === "pie") {
|
|
217
229
|
const pieDataKey = finalDataKeys[0] || "value";
|
|
218
230
|
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(
|
|
@@ -378,11 +390,11 @@ function MessageBubble({
|
|
|
378
390
|
},
|
|
379
391
|
th: (_c) => {
|
|
380
392
|
var _d = _c, { children } = _d, props = __objRest(_d, ["children"]);
|
|
381
|
-
return /* @__PURE__ */ React5.createElement("th", __spreadValues({ className: "p-3 font-semibold text-slate-700 dark:text-white/90 first:rounded-tl-xl last:rounded-tr-xl" }, props), typeof children === "object" && children !== null && !Array.isArray(children) && !children
|
|
393
|
+
return /* @__PURE__ */ React5.createElement("th", __spreadValues({ className: "p-3 font-semibold text-slate-700 dark:text-white/90 first:rounded-tl-xl last:rounded-tr-xl" }, props), typeof children === "object" && children !== null && !Array.isArray(children) && !React5.isValidElement(children) ? JSON.stringify(children) : children);
|
|
382
394
|
},
|
|
383
395
|
td: (_e) => {
|
|
384
396
|
var _f = _e, { children } = _f, props = __objRest(_f, ["children"]);
|
|
385
|
-
return /* @__PURE__ */ React5.createElement("td", __spreadValues({ className: "p-3 border-b border-slate-100 dark:border-white/5 last:border-0 text-slate-600 dark:text-white/70" }, props), typeof children === "object" && children !== null && !Array.isArray(children) && !children
|
|
397
|
+
return /* @__PURE__ */ React5.createElement("td", __spreadValues({ className: "p-3 border-b border-slate-100 dark:border-white/5 last:border-0 text-slate-600 dark:text-white/70" }, props), typeof children === "object" && children !== null && !Array.isArray(children) && !React5.isValidElement(children) ? JSON.stringify(children) : children);
|
|
386
398
|
},
|
|
387
399
|
code(_g) {
|
|
388
400
|
var _h = _g, { inline, className, children } = _h, props = __objRest(_h, ["inline", "className", "children"]);
|
|
@@ -394,7 +406,15 @@ function MessageBubble({
|
|
|
394
406
|
return null;
|
|
395
407
|
}
|
|
396
408
|
const sanitizeJson = (json) => {
|
|
397
|
-
|
|
409
|
+
const firstBrace = json.indexOf("{");
|
|
410
|
+
const firstBracket = json.indexOf("[");
|
|
411
|
+
const start = firstBrace !== -1 && (firstBracket === -1 || firstBrace < firstBracket) ? firstBrace : firstBracket;
|
|
412
|
+
const lastBrace = json.lastIndexOf("}");
|
|
413
|
+
const lastBracket = json.lastIndexOf("]");
|
|
414
|
+
const end = Math.max(lastBrace, lastBracket);
|
|
415
|
+
if (start === -1 || end === -1 || end < start) return json;
|
|
416
|
+
const trimmed = json.substring(start, end + 1);
|
|
417
|
+
return trimmed.replace(/:\s*(\d+(\.\d+)?)\s*([\+\-\*\/])\s*(\d+(\.\d+)?)/g, (_, n1, __, op, n2) => {
|
|
398
418
|
var _a;
|
|
399
419
|
const v1 = parseFloat(n1);
|
|
400
420
|
const v2 = parseFloat(n2);
|
package/dist/server.js
CHANGED
|
@@ -3357,7 +3357,8 @@ When presenting structured data, statistics, or comparisons, decide if it is bes
|
|
|
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.
|
|
3360
|
+
4. data objects MUST be FLAT (no nested objects or arrays).
|
|
3361
|
+
5. DO NOT output naked JSON; it MUST be wrapped in \`\`\`chart ... \`\`\`.
|
|
3361
3362
|
\`\`\`chart
|
|
3362
3363
|
{
|
|
3363
3364
|
"type": "bar" | "line" | "pie",
|
|
@@ -3919,7 +3920,8 @@ When presenting structured data, statistics, or comparisons, decide if it is bes
|
|
|
3919
3920
|
1. Use ONLY valid JSON (double quotes, no trailing commas).
|
|
3920
3921
|
2. NO math expressions (e.g., use 100, NOT 50+50).
|
|
3921
3922
|
3. dataKeys MUST exactly match the property names in the data objects.
|
|
3922
|
-
4.
|
|
3923
|
+
4. data objects MUST be FLAT (no nested objects or arrays).
|
|
3924
|
+
5. DO NOT output naked JSON; it MUST be wrapped in \`\`\`chart ... \`\`\`.
|
|
3923
3925
|
\`\`\`chart
|
|
3924
3926
|
{
|
|
3925
3927
|
"type": "bar" | "line" | "pie",
|
package/dist/server.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@retrivora-ai/rag-engine",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
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",
|
|
@@ -26,6 +26,35 @@ export function DynamicChart({ config, primaryColor = '#6366f1', accentColor = '
|
|
|
26
26
|
const { type, data } = config;
|
|
27
27
|
const colors = config.colors || [primaryColor, accentColor, ...DEFAULT_COLORS];
|
|
28
28
|
|
|
29
|
+
// CRITICAL: Sanitize the data array to remove any non-primitive values (objects/arrays)
|
|
30
|
+
// This prevents the "Objects are not valid as a React child" error in Tooltips/Legends
|
|
31
|
+
// This hook MUST be called before any early returns to satisfy React rules
|
|
32
|
+
const sanitizedData = React.useMemo(() => {
|
|
33
|
+
if (!data) return [];
|
|
34
|
+
return data.map(item => {
|
|
35
|
+
const newItem: Record<string, string | number | null> = {};
|
|
36
|
+
Object.keys(item).forEach(k => {
|
|
37
|
+
const val = item[k];
|
|
38
|
+
if (Array.isArray(val)) {
|
|
39
|
+
// If the LLM output nested arrays, attempt to flatten them
|
|
40
|
+
val.forEach(subItem => {
|
|
41
|
+
if (typeof subItem === 'object' && subItem !== null) {
|
|
42
|
+
Object.keys(subItem).forEach(sk => {
|
|
43
|
+
const subVal = (subItem as Record<string, unknown>)[sk];
|
|
44
|
+
if (typeof subVal !== 'object' || subVal === null) {
|
|
45
|
+
newItem[sk] = subVal as string | number | null;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
} else if (typeof val !== 'object' || val === null) {
|
|
51
|
+
newItem[k] = val as string | number | null;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
return newItem;
|
|
55
|
+
});
|
|
56
|
+
}, [data]);
|
|
57
|
+
|
|
29
58
|
if (!data || data.length === 0) {
|
|
30
59
|
return <div className="p-4 text-sm text-slate-500">No data available for chart.</div>;
|
|
31
60
|
}
|
|
@@ -58,21 +87,6 @@ export function DynamicChart({ config, primaryColor = '#6366f1', accentColor = '
|
|
|
58
87
|
const finalXKey = String(resolvedXKey);
|
|
59
88
|
const finalDataKeys = resolvedDataKeys.map(String).filter(k => k !== 'undefined');
|
|
60
89
|
|
|
61
|
-
// CRITICAL: Sanitize the data array to remove any non-primitive values (objects/arrays)
|
|
62
|
-
// This prevents the "Objects are not valid as a React child" error in Tooltips/Legends
|
|
63
|
-
const sanitizedData = React.useMemo(() => {
|
|
64
|
-
return data.map(item => {
|
|
65
|
-
const newItem: Record<string, any> = {};
|
|
66
|
-
Object.keys(item).forEach(k => {
|
|
67
|
-
const val = item[k];
|
|
68
|
-
if (typeof val !== 'object' || val === null) {
|
|
69
|
-
newItem[k] = val;
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
return newItem;
|
|
73
|
-
});
|
|
74
|
-
}, [data]);
|
|
75
|
-
|
|
76
90
|
// Handle Pie Chart separately as it has a different structure
|
|
77
91
|
if (type === 'pie') {
|
|
78
92
|
const pieDataKey = finalDataKeys[0] || 'value';
|
|
@@ -169,12 +169,12 @@ export function MessageBubble({
|
|
|
169
169
|
),
|
|
170
170
|
th: ({children, ...props}) => (
|
|
171
171
|
<th className="p-3 font-semibold text-slate-700 dark:text-white/90 first:rounded-tl-xl last:rounded-tr-xl" {...props}>
|
|
172
|
-
{typeof children === 'object' && children !== null && !Array.isArray(children) && !(children
|
|
172
|
+
{typeof children === 'object' && children !== null && !Array.isArray(children) && !React.isValidElement(children) ? JSON.stringify(children) : children}
|
|
173
173
|
</th>
|
|
174
174
|
),
|
|
175
175
|
td: ({children, ...props}) => (
|
|
176
176
|
<td className="p-3 border-b border-slate-100 dark:border-white/5 last:border-0 text-slate-600 dark:text-white/70" {...props}>
|
|
177
|
-
{typeof children === 'object' && children !== null && !Array.isArray(children) && !(children
|
|
177
|
+
{typeof children === 'object' && children !== null && !Array.isArray(children) && !React.isValidElement(children) ? JSON.stringify(children) : children}
|
|
178
178
|
</td>
|
|
179
179
|
),
|
|
180
180
|
code({ inline, className, children, ...props }: React.HTMLAttributes<HTMLElement> & { inline?: boolean }) {
|
|
@@ -190,7 +190,19 @@ export function MessageBubble({
|
|
|
190
190
|
|
|
191
191
|
// Optimized sanitization helper to handle LLM quirks
|
|
192
192
|
const sanitizeJson = (json: string) => {
|
|
193
|
-
|
|
193
|
+
// 0. Boundary detection: find the actual JSON object/array start/end
|
|
194
|
+
// This removes stray backticks or text the LLM might have included
|
|
195
|
+
const firstBrace = json.indexOf('{');
|
|
196
|
+
const firstBracket = json.indexOf('[');
|
|
197
|
+
const start = (firstBrace !== -1 && (firstBracket === -1 || firstBrace < firstBracket)) ? firstBrace : firstBracket;
|
|
198
|
+
const lastBrace = json.lastIndexOf('}');
|
|
199
|
+
const lastBracket = json.lastIndexOf(']');
|
|
200
|
+
const end = Math.max(lastBrace, lastBracket);
|
|
201
|
+
|
|
202
|
+
if (start === -1 || end === -1 || end < start) return json;
|
|
203
|
+
const trimmed = json.substring(start, end + 1);
|
|
204
|
+
|
|
205
|
+
return trimmed
|
|
194
206
|
// 1. Resolve arithmetic: "value": 495 / 1000 => "value": 0.495
|
|
195
207
|
.replace(/:\s*(\d+(\.\d+)?)\s*([\+\-\*\/])\s*(\d+(\.\d+)?)/g, (_, n1, __, op, n2) => {
|
|
196
208
|
const v1 = parseFloat(n1); const v2 = parseFloat(n2);
|
|
@@ -57,7 +57,8 @@ export class LangChainAgent {
|
|
|
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.
|
|
60
|
+
4. data objects MUST be FLAT (no nested objects or arrays).
|
|
61
|
+
5. DO NOT output naked JSON; it MUST be wrapped in \`\`\`chart ... \`\`\`.
|
|
61
62
|
\`\`\`chart
|
|
62
63
|
{
|
|
63
64
|
"type": "bar" | "line" | "pie",
|
package/src/core/Pipeline.ts
CHANGED
|
@@ -107,7 +107,8 @@ export class Pipeline {
|
|
|
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.
|
|
110
|
+
4. data objects MUST be FLAT (no nested objects or arrays).
|
|
111
|
+
5. DO NOT output naked JSON; it MUST be wrapped in \`\`\`chart ... \`\`\`.
|
|
111
112
|
\`\`\`chart
|
|
112
113
|
{
|
|
113
114
|
"type": "bar" | "line" | "pie",
|