drizzle-cube 0.4.16 → 0.4.18
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/adapters/express/index.cjs +1 -1
- package/dist/adapters/express/index.js +1 -1
- package/dist/adapters/fastify/index.cjs +1 -1
- package/dist/adapters/fastify/index.js +1 -1
- package/dist/adapters/{handler-BmTtVoRu.js → handler-DefTXJpi.js} +442 -309
- package/dist/adapters/handler-hwoGzGex.cjs +33 -0
- package/dist/adapters/hono/index.cjs +1 -1
- package/dist/adapters/hono/index.js +1 -1
- package/dist/adapters/nextjs/index.cjs +1 -1
- package/dist/adapters/nextjs/index.js +1 -1
- package/dist/client/charts.js +2 -2
- package/dist/client/chunks/{analysis-builder-C5e52Z3p.js → analysis-builder-3z9fHE2F.js} +5 -5
- package/dist/client/chunks/{analysis-builder-C5e52Z3p.js.map → analysis-builder-3z9fHE2F.js.map} +1 -1
- package/dist/client/chunks/{analysis-builder-shared-EnM-8plh.js → analysis-builder-shared-Da-vlQa_.js} +2 -2
- package/dist/client/chunks/{analysis-builder-shared-EnM-8plh.js.map → analysis-builder-shared-Da-vlQa_.js.map} +1 -1
- package/dist/client/chunks/{chart-data-table-D5G8nMnb.js → chart-data-table-BsAjHe7o.js} +2 -2
- package/dist/client/chunks/{chart-data-table-D5G8nMnb.js.map → chart-data-table-BsAjHe7o.js.map} +1 -1
- package/dist/client/chunks/{chart-kpi-delta-Dgg2eYRl.js → chart-kpi-delta-DUD3f8vL.js} +3 -3
- package/dist/client/chunks/{chart-kpi-delta-Dgg2eYRl.js.map → chart-kpi-delta-DUD3f8vL.js.map} +1 -1
- package/dist/client/chunks/{chart-kpi-number-DkoO99c1.js → chart-kpi-number-iJh-PzsM.js} +2 -2
- package/dist/client/chunks/{chart-kpi-number-DkoO99c1.js.map → chart-kpi-number-iJh-PzsM.js.map} +1 -1
- package/dist/client/chunks/{chart-kpi-text-1O6_lmz7.js → chart-kpi-text-x6pV9v9Q.js} +2 -2
- package/dist/client/chunks/{chart-kpi-text-1O6_lmz7.js.map → chart-kpi-text-x6pV9v9Q.js.map} +1 -1
- package/dist/client/chunks/{charts-loader-AW3T1nv5.js → charts-loader-B3tt5oKG.js} +5 -5
- package/dist/client/chunks/{charts-loader-AW3T1nv5.js.map → charts-loader-B3tt5oKG.js.map} +1 -1
- package/dist/client/chunks/{components-BkeSy9xv.js → components-CMGGxqOB.js} +4 -4
- package/dist/client/chunks/{components-BkeSy9xv.js.map → components-CMGGxqOB.js.map} +1 -1
- package/dist/client/chunks/{icons-DAeqv1iX.js → icons-M7shurcH.js} +172 -160
- package/dist/client/chunks/icons-M7shurcH.js.map +1 -0
- package/dist/client/components/AgenticNotebook/AgentChatPanel.d.ts +6 -0
- package/dist/client/components/AgenticNotebook/index.d.ts +6 -0
- package/dist/client/components.js +1 -1
- package/dist/client/hooks/useAgentChat.d.ts +2 -2
- package/dist/client/icons/types.d.ts +2 -0
- package/dist/client/icons.js +1 -1
- package/dist/client/index.js +707 -675
- package/dist/client/index.js.map +1 -1
- package/dist/client/utils.js +3 -3
- package/dist/client-bundle-stats.html +1 -1
- package/dist/server/index.cjs +49 -41
- package/dist/server/index.d.ts +45 -0
- package/dist/server/index.js +2795 -2662
- package/package.json +1 -1
- package/dist/adapters/handler-B6yAJw_O.cjs +0 -25
- package/dist/client/chunks/icons-DAeqv1iX.js.map +0 -1
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import { h as
|
|
2
|
-
import { handleDiscover as
|
|
3
|
-
function
|
|
4
|
-
if (
|
|
1
|
+
import { h as H, Q as B, j, D as Z } from "./mcp-transport-m1X1GtwG.js";
|
|
2
|
+
import { handleDiscover as U, handleLoad as G } from "./utils.js";
|
|
3
|
+
function K(l) {
|
|
4
|
+
if (l.length === 0)
|
|
5
5
|
return "No cubes are currently available.";
|
|
6
6
|
const t = ["## Available Cubes", ""];
|
|
7
|
-
for (const a of
|
|
7
|
+
for (const a of l) {
|
|
8
8
|
if (t.push(`### ${a.name}`), a.description && t.push(a.description), a.measures && a.measures.length > 0) {
|
|
9
9
|
t.push(""), t.push("**Measures:**");
|
|
10
|
-
for (const
|
|
11
|
-
const
|
|
12
|
-
t.push(`- \`${a.name}.${
|
|
10
|
+
for (const i of a.measures) {
|
|
11
|
+
const d = i.description ? ` - ${i.description}` : "";
|
|
12
|
+
t.push(`- \`${a.name}.${i.name}\` (${i.type})${d}`);
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
if (a.dimensions && a.dimensions.length > 0) {
|
|
16
16
|
t.push(""), t.push("**Dimensions:**");
|
|
17
|
-
for (const
|
|
18
|
-
const
|
|
19
|
-
t.push(`- \`${a.name}.${
|
|
17
|
+
for (const i of a.dimensions) {
|
|
18
|
+
const d = i.description ? ` - ${i.description}` : "";
|
|
19
|
+
t.push(`- \`${a.name}.${i.name}\` (${i.type})${d}`);
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
if (a.relationships && a.relationships.length > 0) {
|
|
23
23
|
t.push(""), t.push("**Joins:**");
|
|
24
|
-
for (const
|
|
25
|
-
t.push(`- → \`${
|
|
24
|
+
for (const i of a.relationships)
|
|
25
|
+
t.push(`- → \`${i.targetCube}\` (${i.relationship})`);
|
|
26
26
|
}
|
|
27
27
|
a.meta?.eventStream && (t.push(""), t.push("**Event Stream:** Yes (supports funnel, flow, retention queries)"), a.meta.eventStream.bindingKey && t.push(`- Binding key: \`${a.name}.${a.meta.eventStream.bindingKey}\``), a.meta.eventStream.timeDimension && t.push(`- Time dimension: \`${a.name}.${a.meta.eventStream.timeDimension}\``)), t.push("");
|
|
28
28
|
}
|
|
29
29
|
return t.join(`
|
|
30
30
|
`);
|
|
31
31
|
}
|
|
32
|
-
function
|
|
33
|
-
return
|
|
32
|
+
function I(l) {
|
|
33
|
+
return l.messages.map((t) => t.content.text).join(`
|
|
34
34
|
|
|
35
35
|
`);
|
|
36
36
|
}
|
|
37
|
-
function
|
|
37
|
+
function W(l) {
|
|
38
38
|
return [
|
|
39
39
|
"# Drizzle Cube Analytics Agent",
|
|
40
40
|
"",
|
|
@@ -160,19 +160,19 @@ function H(o) {
|
|
|
160
160
|
"",
|
|
161
161
|
"---",
|
|
162
162
|
"",
|
|
163
|
-
|
|
163
|
+
I(H),
|
|
164
164
|
"",
|
|
165
165
|
"---",
|
|
166
166
|
"",
|
|
167
|
-
|
|
167
|
+
I(B),
|
|
168
168
|
"",
|
|
169
169
|
"---",
|
|
170
170
|
"",
|
|
171
|
-
|
|
171
|
+
I(j),
|
|
172
172
|
"",
|
|
173
173
|
"---",
|
|
174
174
|
"",
|
|
175
|
-
|
|
175
|
+
I(Z),
|
|
176
176
|
"",
|
|
177
177
|
"---",
|
|
178
178
|
"",
|
|
@@ -226,11 +226,11 @@ function H(o) {
|
|
|
226
226
|
"",
|
|
227
227
|
"---",
|
|
228
228
|
"",
|
|
229
|
-
|
|
229
|
+
K(l)
|
|
230
230
|
].join(`
|
|
231
231
|
`);
|
|
232
232
|
}
|
|
233
|
-
const
|
|
233
|
+
const X = {
|
|
234
234
|
label: "Bar Chart",
|
|
235
235
|
description: "Compare values across categories",
|
|
236
236
|
useCase: "Best for comparing discrete categories, showing rankings, or displaying changes over time",
|
|
@@ -296,7 +296,7 @@ const $ = {
|
|
|
296
296
|
description: "Number formatting for right Y-axis"
|
|
297
297
|
}
|
|
298
298
|
]
|
|
299
|
-
},
|
|
299
|
+
}, J = {
|
|
300
300
|
label: "Line Chart",
|
|
301
301
|
description: "Show trends and changes over time",
|
|
302
302
|
useCase: "Best for continuous data, trends, time series, and showing relationships between multiple series",
|
|
@@ -379,7 +379,7 @@ const $ = {
|
|
|
379
379
|
description: "Number formatting for right Y-axis"
|
|
380
380
|
}
|
|
381
381
|
]
|
|
382
|
-
},
|
|
382
|
+
}, Q = {
|
|
383
383
|
label: "Area Chart",
|
|
384
384
|
description: "Emphasize magnitude of change over time",
|
|
385
385
|
useCase: "Best for showing cumulative totals, volume changes, or stacked comparisons over time",
|
|
@@ -451,7 +451,7 @@ const $ = {
|
|
|
451
451
|
description: "Number formatting for right Y-axis"
|
|
452
452
|
}
|
|
453
453
|
]
|
|
454
|
-
},
|
|
454
|
+
}, ee = {
|
|
455
455
|
label: "Pie Chart",
|
|
456
456
|
description: "Show proportions of a whole",
|
|
457
457
|
useCase: "Best for showing percentage distribution or composition of a total (limit to 5-7 slices)",
|
|
@@ -485,7 +485,7 @@ const $ = {
|
|
|
485
485
|
description: "Number formatting for values"
|
|
486
486
|
}
|
|
487
487
|
]
|
|
488
|
-
},
|
|
488
|
+
}, te = {
|
|
489
489
|
label: "Scatter Plot",
|
|
490
490
|
description: "Reveal correlations between variables",
|
|
491
491
|
useCase: "Best for identifying patterns, correlations, outliers, and relationships between two measures",
|
|
@@ -533,7 +533,7 @@ const $ = {
|
|
|
533
533
|
description: "Number formatting for Y-axis"
|
|
534
534
|
}
|
|
535
535
|
]
|
|
536
|
-
},
|
|
536
|
+
}, ae = {
|
|
537
537
|
label: "Bubble Chart",
|
|
538
538
|
description: "Compare three dimensions of data",
|
|
539
539
|
useCase: "Best for showing relationships between three variables (X, Y, and size), market analysis",
|
|
@@ -599,7 +599,7 @@ const $ = {
|
|
|
599
599
|
description: "Number formatting for Y-axis and values"
|
|
600
600
|
}
|
|
601
601
|
]
|
|
602
|
-
},
|
|
602
|
+
}, se = {
|
|
603
603
|
label: "Radar Chart",
|
|
604
604
|
description: "Compare multiple metrics across categories",
|
|
605
605
|
useCase: "Best for multivariate comparisons, performance metrics, strengths/weaknesses analysis",
|
|
@@ -638,7 +638,7 @@ const $ = {
|
|
|
638
638
|
description: "Number formatting for values"
|
|
639
639
|
}
|
|
640
640
|
]
|
|
641
|
-
},
|
|
641
|
+
}, ie = {
|
|
642
642
|
label: "Radial Bar Chart",
|
|
643
643
|
description: "Circular progress and KPI visualization",
|
|
644
644
|
useCase: "Best for showing progress toward goals, KPIs, or comparing percentages in a compact form",
|
|
@@ -670,7 +670,7 @@ const $ = {
|
|
|
670
670
|
description: "Number formatting for values"
|
|
671
671
|
}
|
|
672
672
|
]
|
|
673
|
-
},
|
|
673
|
+
}, oe = {
|
|
674
674
|
label: "TreeMap",
|
|
675
675
|
description: "Visualize hierarchical data with nested rectangles",
|
|
676
676
|
useCase: "Best for showing part-to-whole relationships in hierarchical data, disk usage, budget allocation",
|
|
@@ -712,7 +712,7 @@ const $ = {
|
|
|
712
712
|
}
|
|
713
713
|
],
|
|
714
714
|
clickableElements: { cell: !0 }
|
|
715
|
-
},
|
|
715
|
+
}, re = {
|
|
716
716
|
label: "Data Table",
|
|
717
717
|
description: "Display detailed tabular data",
|
|
718
718
|
useCase: "Best for precise values, detailed analysis, sortable/filterable data exploration",
|
|
@@ -735,7 +735,7 @@ const $ = {
|
|
|
735
735
|
description: "Number formatting for numeric values"
|
|
736
736
|
}
|
|
737
737
|
]
|
|
738
|
-
},
|
|
738
|
+
}, ne = {
|
|
739
739
|
label: "Activity Grid",
|
|
740
740
|
description: "GitHub-style activity grid showing temporal patterns across different time scales",
|
|
741
741
|
useCase: "Best for visualizing activity patterns over time. Supports hour (3hr blocks × days), day (days × weeks), week (weeks × months), month (months × quarters), and quarter (quarters × years) granularities",
|
|
@@ -769,8 +769,8 @@ const $ = {
|
|
|
769
769
|
description: "Automatically size blocks to fill portlet width and height while maintaining aspect ratio"
|
|
770
770
|
}
|
|
771
771
|
],
|
|
772
|
-
validate: (
|
|
773
|
-
const { dateField: t, valueField: a } =
|
|
772
|
+
validate: (l) => {
|
|
773
|
+
const { dateField: t, valueField: a } = l;
|
|
774
774
|
return !t || Array.isArray(t) && t.length === 0 ? {
|
|
775
775
|
isValid: !1,
|
|
776
776
|
message: "Time dimension is required for activity grid"
|
|
@@ -780,7 +780,7 @@ const $ = {
|
|
|
780
780
|
} : { isValid: !0 };
|
|
781
781
|
},
|
|
782
782
|
clickableElements: { cell: !0 }
|
|
783
|
-
},
|
|
783
|
+
}, le = {
|
|
784
784
|
label: "KPI Number",
|
|
785
785
|
description: "Display key performance indicators as large numbers",
|
|
786
786
|
useCase: "Perfect for showing important metrics like revenue, user count, or other key business metrics in a prominent, easy-to-read format",
|
|
@@ -850,7 +850,7 @@ const $ = {
|
|
|
850
850
|
}
|
|
851
851
|
],
|
|
852
852
|
displayOptions: ["hideHeader"]
|
|
853
|
-
},
|
|
853
|
+
}, de = {
|
|
854
854
|
label: "KPI Delta",
|
|
855
855
|
description: "Display change between latest and previous values with trend indicators",
|
|
856
856
|
useCase: "Perfect for showing performance changes over time, such as revenue growth, user acquisition changes, or other metrics where the trend and delta are more important than the absolute value",
|
|
@@ -938,11 +938,11 @@ const $ = {
|
|
|
938
938
|
}
|
|
939
939
|
],
|
|
940
940
|
displayOptions: ["hideHeader"],
|
|
941
|
-
validate: (
|
|
941
|
+
validate: (l) => !l.yAxis || Array.isArray(l.yAxis) && l.yAxis.length === 0 ? {
|
|
942
942
|
isValid: !1,
|
|
943
943
|
message: "A measure is required for KPI Delta charts"
|
|
944
944
|
} : { isValid: !0 }
|
|
945
|
-
},
|
|
945
|
+
}, pe = {
|
|
946
946
|
label: "KPI Text",
|
|
947
947
|
description: "Display key performance indicators as customizable text",
|
|
948
948
|
useCase: "Perfect for showing metrics with custom formatting, combining multiple values, or displaying contextual KPI information using templates",
|
|
@@ -984,7 +984,7 @@ const $ = {
|
|
|
984
984
|
}
|
|
985
985
|
],
|
|
986
986
|
displayOptions: ["hideHeader"]
|
|
987
|
-
},
|
|
987
|
+
}, ue = {
|
|
988
988
|
label: "Markdown",
|
|
989
989
|
description: "Display custom markdown content with formatting",
|
|
990
990
|
useCase: "Perfect for adding documentation, notes, section headers, instructions, or formatted text to dashboards",
|
|
@@ -1076,7 +1076,7 @@ Use --- for horizontal rules.`,
|
|
|
1076
1076
|
description: "Add an accent-colored border on one side of the content"
|
|
1077
1077
|
}
|
|
1078
1078
|
]
|
|
1079
|
-
},
|
|
1079
|
+
}, ce = {
|
|
1080
1080
|
label: "Funnel Chart",
|
|
1081
1081
|
description: "Show conversion through sequential steps",
|
|
1082
1082
|
useCase: "Best for visualizing user journey funnels, sales pipelines, or multi-step processes",
|
|
@@ -1163,7 +1163,7 @@ Use --- for horizontal rules.`,
|
|
|
1163
1163
|
description: "Display 90th percentile time to convert"
|
|
1164
1164
|
}
|
|
1165
1165
|
]
|
|
1166
|
-
},
|
|
1166
|
+
}, me = {
|
|
1167
1167
|
label: "Sankey Chart",
|
|
1168
1168
|
description: "Show flow between states or steps",
|
|
1169
1169
|
useCase: "Best for visualizing user journey flows, path analysis, or state transitions",
|
|
@@ -1219,7 +1219,7 @@ Use --- for horizontal rules.`,
|
|
|
1219
1219
|
description: "Hide the statistics footer below the chart"
|
|
1220
1220
|
}
|
|
1221
1221
|
]
|
|
1222
|
-
},
|
|
1222
|
+
}, ye = {
|
|
1223
1223
|
label: "Sunburst Chart",
|
|
1224
1224
|
description: "Show hierarchical flow as radial rings",
|
|
1225
1225
|
useCase: "Best for visualizing forward paths from a starting event in a compact radial layout",
|
|
@@ -1264,7 +1264,7 @@ Use --- for horizontal rules.`,
|
|
|
1264
1264
|
description: "Hide the statistics footer below the chart"
|
|
1265
1265
|
}
|
|
1266
1266
|
]
|
|
1267
|
-
},
|
|
1267
|
+
}, he = {
|
|
1268
1268
|
label: "Heatmap",
|
|
1269
1269
|
description: "Visualize intensity across two dimensions",
|
|
1270
1270
|
useCase: "Best for showing patterns in matrix data like correlations, schedules, or category comparisons",
|
|
@@ -1335,8 +1335,8 @@ Use --- for horizontal rules.`,
|
|
|
1335
1335
|
description: "Number formatting for cell values and legend"
|
|
1336
1336
|
}
|
|
1337
1337
|
],
|
|
1338
|
-
validate: (
|
|
1339
|
-
},
|
|
1338
|
+
validate: (l) => l.xAxis?.length ? l.yAxis?.length ? l.valueField?.length ? { isValid: !0 } : { isValid: !1, message: "Value measure required" } : { isValid: !1, message: "Y-axis dimension required" } : { isValid: !1, message: "X-axis dimension required" }
|
|
1339
|
+
}, fe = {
|
|
1340
1340
|
label: "Retention Matrix",
|
|
1341
1341
|
// RetentionHeatmap auto-configures from the retention data structure
|
|
1342
1342
|
// No drop zones needed as the chart maps directly to cohort × period matrix
|
|
@@ -1360,7 +1360,7 @@ Use --- for horizontal rules.`,
|
|
|
1360
1360
|
],
|
|
1361
1361
|
description: "Cohort retention matrix visualization",
|
|
1362
1362
|
useCase: "Visualize user retention over time by cohort"
|
|
1363
|
-
},
|
|
1363
|
+
}, be = {
|
|
1364
1364
|
label: "Retention Chart",
|
|
1365
1365
|
// RetentionCombinedChart auto-configures from the retention data structure
|
|
1366
1366
|
// No drop zones needed as the chart maps directly to retention result data
|
|
@@ -1403,7 +1403,7 @@ Use --- for horizontal rules.`,
|
|
|
1403
1403
|
],
|
|
1404
1404
|
description: "Combined retention visualization with line chart and heatmap modes",
|
|
1405
1405
|
useCase: "Visualize user retention over time with optional breakdown segmentation"
|
|
1406
|
-
},
|
|
1406
|
+
}, ge = {
|
|
1407
1407
|
label: "Box Plot",
|
|
1408
1408
|
description: "Show statistical distribution (median, IQR, whiskers) across categories",
|
|
1409
1409
|
useCase: "Best for P&L spread per symbol, trade size distribution, latency distribution across platforms",
|
|
@@ -1436,7 +1436,7 @@ Use --- for horizontal rules.`,
|
|
|
1436
1436
|
description: "Number formatting for the value axis"
|
|
1437
1437
|
}
|
|
1438
1438
|
]
|
|
1439
|
-
},
|
|
1439
|
+
}, xe = {
|
|
1440
1440
|
label: "Waterfall Chart",
|
|
1441
1441
|
description: "Show cumulative effect of sequential positive and negative values",
|
|
1442
1442
|
useCase: "Best for P&L decomposition, cash flow analysis, budget variance, or any sequential contribution breakdown",
|
|
@@ -1491,7 +1491,7 @@ Use --- for horizontal rules.`,
|
|
|
1491
1491
|
description: "Number formatting for the Y-axis"
|
|
1492
1492
|
}
|
|
1493
1493
|
]
|
|
1494
|
-
},
|
|
1494
|
+
}, we = {
|
|
1495
1495
|
label: "Candlestick Chart",
|
|
1496
1496
|
description: "Financial candlestick chart showing open/close body and high/low wicks",
|
|
1497
1497
|
useCase: "Best for EOD quotes (bid/ask spread per date/symbol), markout distribution bands, or OHLC price data",
|
|
@@ -1556,7 +1556,7 @@ Use --- for horizontal rules.`,
|
|
|
1556
1556
|
description: "Number formatting for the price axis"
|
|
1557
1557
|
}
|
|
1558
1558
|
]
|
|
1559
|
-
},
|
|
1559
|
+
}, ke = {
|
|
1560
1560
|
label: "Measure Profile",
|
|
1561
1561
|
description: "Plot N measures as sequential X-axis points to visualise a profile or shape across intervals",
|
|
1562
1562
|
useCase: "Best for markout interval analysis (e.g. avgMinus2m → avgAtEvent → avgPlus2h), metric profiles, or any pattern across ordered measures",
|
|
@@ -1621,7 +1621,7 @@ Use --- for horizontal rules.`,
|
|
|
1621
1621
|
description: "Number formatting for the Y-axis"
|
|
1622
1622
|
}
|
|
1623
1623
|
]
|
|
1624
|
-
},
|
|
1624
|
+
}, ve = {
|
|
1625
1625
|
label: "Gauge Chart",
|
|
1626
1626
|
description: "Half-circle arc gauge for a single KPI value versus a maximum target",
|
|
1627
1627
|
useCase: "Best for high-water marks vs equity, margin utilisation, or any single value progress toward a goal",
|
|
@@ -1680,133 +1680,133 @@ Use --- for horizontal rules.`,
|
|
|
1680
1680
|
description: "Number formatting for the displayed value and axis labels"
|
|
1681
1681
|
}
|
|
1682
1682
|
]
|
|
1683
|
-
},
|
|
1684
|
-
bar:
|
|
1685
|
-
line:
|
|
1686
|
-
area:
|
|
1687
|
-
pie:
|
|
1688
|
-
scatter:
|
|
1689
|
-
bubble:
|
|
1690
|
-
radar:
|
|
1691
|
-
radialBar:
|
|
1692
|
-
treemap:
|
|
1693
|
-
table:
|
|
1694
|
-
activityGrid:
|
|
1695
|
-
kpiNumber:
|
|
1696
|
-
kpiDelta:
|
|
1697
|
-
kpiText:
|
|
1698
|
-
markdown:
|
|
1699
|
-
funnel:
|
|
1700
|
-
sankey:
|
|
1701
|
-
sunburst:
|
|
1702
|
-
heatmap:
|
|
1703
|
-
retentionHeatmap:
|
|
1704
|
-
retentionCombined:
|
|
1705
|
-
boxPlot:
|
|
1706
|
-
waterfall:
|
|
1707
|
-
candlestick:
|
|
1708
|
-
measureProfile:
|
|
1709
|
-
gauge:
|
|
1683
|
+
}, P = {
|
|
1684
|
+
bar: X,
|
|
1685
|
+
line: J,
|
|
1686
|
+
area: Q,
|
|
1687
|
+
pie: ee,
|
|
1688
|
+
scatter: te,
|
|
1689
|
+
bubble: ae,
|
|
1690
|
+
radar: se,
|
|
1691
|
+
radialBar: ie,
|
|
1692
|
+
treemap: oe,
|
|
1693
|
+
table: re,
|
|
1694
|
+
activityGrid: ne,
|
|
1695
|
+
kpiNumber: le,
|
|
1696
|
+
kpiDelta: de,
|
|
1697
|
+
kpiText: pe,
|
|
1698
|
+
markdown: ue,
|
|
1699
|
+
funnel: ce,
|
|
1700
|
+
sankey: me,
|
|
1701
|
+
sunburst: ye,
|
|
1702
|
+
heatmap: he,
|
|
1703
|
+
retentionHeatmap: fe,
|
|
1704
|
+
retentionCombined: be,
|
|
1705
|
+
boxPlot: ge,
|
|
1706
|
+
waterfall: xe,
|
|
1707
|
+
candlestick: we,
|
|
1708
|
+
measureProfile: ke,
|
|
1709
|
+
gauge: ve
|
|
1710
1710
|
};
|
|
1711
|
-
function
|
|
1712
|
-
const
|
|
1713
|
-
if (!
|
|
1711
|
+
function Ce(l, t, a) {
|
|
1712
|
+
const i = P[l];
|
|
1713
|
+
if (!i)
|
|
1714
1714
|
return { isValid: !0, errors: [] };
|
|
1715
|
-
if (
|
|
1715
|
+
if (i.skipQuery)
|
|
1716
1716
|
return { isValid: !0, errors: [] };
|
|
1717
|
-
const
|
|
1718
|
-
for (const
|
|
1719
|
-
if (!
|
|
1720
|
-
const
|
|
1721
|
-
if (!(Array.isArray(
|
|
1722
|
-
const
|
|
1723
|
-
|
|
1724
|
-
`chartConfig.${
|
|
1717
|
+
const d = [];
|
|
1718
|
+
for (const u of i.dropZones) {
|
|
1719
|
+
if (!u.mandatory) continue;
|
|
1720
|
+
const e = t?.[u.key];
|
|
1721
|
+
if (!(Array.isArray(e) ? e.length > 0 : !!e)) {
|
|
1722
|
+
const r = u.acceptTypes?.join("/") ?? "fields";
|
|
1723
|
+
d.push(
|
|
1724
|
+
`chartConfig.${u.key} is required for ${l} chart (${u.label}). Accepts: ${r}.`
|
|
1725
1725
|
);
|
|
1726
1726
|
}
|
|
1727
1727
|
}
|
|
1728
|
-
if (
|
|
1729
|
-
const
|
|
1730
|
-
if (!(Array.isArray(
|
|
1731
|
-
const
|
|
1732
|
-
|
|
1728
|
+
if (l === "bar") {
|
|
1729
|
+
const u = t?.xAxis;
|
|
1730
|
+
if (!(Array.isArray(u) ? u.length > 0 : !!u)) {
|
|
1731
|
+
const o = a.dimensions ?? [], r = a.timeDimensions ?? [];
|
|
1732
|
+
o.length > 0 || r.length > 0 ? d.push(
|
|
1733
1733
|
"chartConfig.xAxis is required for bar charts. Put a dimension in xAxis so bars have category labels."
|
|
1734
|
-
) :
|
|
1734
|
+
) : d.push(
|
|
1735
1735
|
'Bar charts need an xAxis dimension for category labels. Add a dimension to the query or use "table" chart type instead.'
|
|
1736
1736
|
);
|
|
1737
1737
|
}
|
|
1738
1738
|
}
|
|
1739
1739
|
if (t?.xAxis && t?.series) {
|
|
1740
|
-
const
|
|
1740
|
+
const u = new Set(
|
|
1741
1741
|
Array.isArray(t.xAxis) ? t.xAxis : [t.xAxis]
|
|
1742
|
-
),
|
|
1743
|
-
|
|
1744
|
-
`chartConfig.series must not contain the same field as xAxis (found: ${
|
|
1742
|
+
), o = (Array.isArray(t.series) ? t.series : [t.series]).filter((r) => u.has(r));
|
|
1743
|
+
o.length > 0 && d.push(
|
|
1744
|
+
`chartConfig.series must not contain the same field as xAxis (found: ${o.join(", ")}). The series field is only for splitting into grouped/stacked sub-series by a DIFFERENT dimension. Remove the duplicate from series.`
|
|
1745
1745
|
);
|
|
1746
1746
|
}
|
|
1747
|
-
return { isValid:
|
|
1747
|
+
return { isValid: d.length === 0, errors: d };
|
|
1748
1748
|
}
|
|
1749
|
-
function
|
|
1750
|
-
const
|
|
1751
|
-
if (!
|
|
1749
|
+
function Te(l, t, a) {
|
|
1750
|
+
const i = P[l];
|
|
1751
|
+
if (!i)
|
|
1752
1752
|
return t ?? {};
|
|
1753
|
-
const
|
|
1754
|
-
for (const
|
|
1755
|
-
const m =
|
|
1753
|
+
const d = { ...t }, u = a.measures ?? [], e = a.dimensions ?? [], r = (a.timeDimensions ?? []).map((s) => s.dimension);
|
|
1754
|
+
for (const s of i.dropZones) {
|
|
1755
|
+
const m = d[s.key];
|
|
1756
1756
|
if (Array.isArray(m) ? m.length > 0 : !!m) continue;
|
|
1757
|
-
const
|
|
1758
|
-
if (
|
|
1759
|
-
if (
|
|
1760
|
-
const
|
|
1761
|
-
for (const
|
|
1762
|
-
if (
|
|
1763
|
-
const
|
|
1764
|
-
Array.isArray(
|
|
1757
|
+
const y = s.acceptTypes ?? [];
|
|
1758
|
+
if (s.key === "sizeField" || s.key === "colorField") {
|
|
1759
|
+
if (y.includes("measure")) {
|
|
1760
|
+
const g = /* @__PURE__ */ new Set();
|
|
1761
|
+
for (const C of i.dropZones) {
|
|
1762
|
+
if (C.key === s.key) continue;
|
|
1763
|
+
const k = d[C.key];
|
|
1764
|
+
Array.isArray(k) ? k.forEach((E) => g.add(E)) : typeof k == "string" && g.add(k);
|
|
1765
1765
|
}
|
|
1766
|
-
const
|
|
1767
|
-
|
|
1766
|
+
const A = u.filter((C) => !g.has(C));
|
|
1767
|
+
A.length > 0 && (d[s.key] = A[0]);
|
|
1768
1768
|
}
|
|
1769
1769
|
continue;
|
|
1770
1770
|
}
|
|
1771
|
-
const
|
|
1772
|
-
if (
|
|
1773
|
-
let
|
|
1774
|
-
if (
|
|
1775
|
-
const
|
|
1776
|
-
Array.isArray(
|
|
1771
|
+
const n = [];
|
|
1772
|
+
if (y.includes("dimension") && n.push(...e), y.includes("timeDimension") && n.push(...r), y.includes("measure") && n.push(...u), n.length === 0) continue;
|
|
1773
|
+
let x = n;
|
|
1774
|
+
if (s.key === "series") {
|
|
1775
|
+
const g = new Set(
|
|
1776
|
+
Array.isArray(d.xAxis) ? d.xAxis : d.xAxis ? [d.xAxis] : []
|
|
1777
1777
|
);
|
|
1778
|
-
if (
|
|
1778
|
+
if (x = n.filter((A) => !g.has(A)), x.length === 0) continue;
|
|
1779
1779
|
}
|
|
1780
|
-
const
|
|
1781
|
-
|
|
1780
|
+
const b = s.maxItems ?? 1 / 0, c = x.slice(0, b);
|
|
1781
|
+
c.length > 0 && (d[s.key] = c);
|
|
1782
1782
|
}
|
|
1783
|
-
return
|
|
1783
|
+
return d;
|
|
1784
1784
|
}
|
|
1785
|
-
function
|
|
1785
|
+
function Ae(l) {
|
|
1786
1786
|
const t = [`
|
|
1787
1787
|
Chart config requirements by type:`];
|
|
1788
|
-
for (const a of
|
|
1789
|
-
const
|
|
1790
|
-
if (!
|
|
1791
|
-
const
|
|
1792
|
-
if (
|
|
1793
|
-
t.push(` ${a}${
|
|
1788
|
+
for (const a of l) {
|
|
1789
|
+
const i = P[a];
|
|
1790
|
+
if (!i) continue;
|
|
1791
|
+
const d = i.description ?? "", u = i.useCase ?? "", e = [d, u].filter(Boolean).join(". "), o = e ? ` — ${e}.` : "", r = i.dropZones.filter((m) => m.mandatory);
|
|
1792
|
+
if (r.length === 0 && !i.skipQuery) {
|
|
1793
|
+
t.push(` ${a}${o} chartConfig auto-inferred from query.`);
|
|
1794
1794
|
continue;
|
|
1795
1795
|
}
|
|
1796
|
-
if (
|
|
1797
|
-
t.push(` ${a}${
|
|
1796
|
+
if (i.skipQuery) {
|
|
1797
|
+
t.push(` ${a}${o} No query needed.`);
|
|
1798
1798
|
continue;
|
|
1799
1799
|
}
|
|
1800
|
-
const
|
|
1801
|
-
const
|
|
1802
|
-
return `${m.key}=[${
|
|
1800
|
+
const s = r.map((m) => {
|
|
1801
|
+
const f = m.acceptTypes?.join("/") ?? "any", y = m.maxItems ? ` (max ${m.maxItems})` : "";
|
|
1802
|
+
return `${m.key}=[${f}]${y}`;
|
|
1803
1803
|
});
|
|
1804
|
-
t.push(` ${a}${
|
|
1804
|
+
t.push(` ${a}${o} Requires ${s.join(", ")}.`);
|
|
1805
1805
|
}
|
|
1806
1806
|
return t.join(`
|
|
1807
1807
|
`);
|
|
1808
1808
|
}
|
|
1809
|
-
const
|
|
1809
|
+
const N = [
|
|
1810
1810
|
"bar",
|
|
1811
1811
|
"line",
|
|
1812
1812
|
"area",
|
|
@@ -1826,7 +1826,7 @@ const _ = [
|
|
|
1826
1826
|
"boxPlot",
|
|
1827
1827
|
"markdown"
|
|
1828
1828
|
];
|
|
1829
|
-
function
|
|
1829
|
+
function De() {
|
|
1830
1830
|
return [
|
|
1831
1831
|
// Tool 1: discover_cubes
|
|
1832
1832
|
{
|
|
@@ -1978,7 +1978,7 @@ function ge() {
|
|
|
1978
1978
|
{
|
|
1979
1979
|
name: "add_portlet",
|
|
1980
1980
|
description: `Add a chart visualization to the notebook.
|
|
1981
|
-
` +
|
|
1981
|
+
` + Ae(N) + `
|
|
1982
1982
|
The query is validated before adding. The portlet fetches its own data.`,
|
|
1983
1983
|
input_schema: {
|
|
1984
1984
|
type: "object",
|
|
@@ -1990,7 +1990,7 @@ The query is validated before adding. The portlet fetches its own data.`,
|
|
|
1990
1990
|
},
|
|
1991
1991
|
chartType: {
|
|
1992
1992
|
type: "string",
|
|
1993
|
-
enum:
|
|
1993
|
+
enum: N,
|
|
1994
1994
|
description: "Chart type to render"
|
|
1995
1995
|
},
|
|
1996
1996
|
chartConfig: {
|
|
@@ -2050,7 +2050,7 @@ The query is validated before adding. The portlet fetches its own data.`,
|
|
|
2050
2050
|
title: { type: "string", description: "Portlet title" },
|
|
2051
2051
|
chartType: {
|
|
2052
2052
|
type: "string",
|
|
2053
|
-
enum:
|
|
2053
|
+
enum: N,
|
|
2054
2054
|
description: 'Chart type. Use "markdown" for section headers.'
|
|
2055
2055
|
},
|
|
2056
2056
|
query: {
|
|
@@ -2121,32 +2121,75 @@ The query is validated before adding. The portlet fetches its own data.`,
|
|
|
2121
2121
|
}
|
|
2122
2122
|
];
|
|
2123
2123
|
}
|
|
2124
|
-
function
|
|
2125
|
-
const { semanticLayer: t, securityContext: a } =
|
|
2126
|
-
|
|
2127
|
-
const
|
|
2124
|
+
function Se(l) {
|
|
2125
|
+
const { semanticLayer: t, securityContext: a } = l, i = /* @__PURE__ */ new Map();
|
|
2126
|
+
i.set("discover_cubes", async (e) => {
|
|
2127
|
+
const o = await U(t, {
|
|
2128
2128
|
topic: e.topic,
|
|
2129
2129
|
intent: e.intent,
|
|
2130
2130
|
limit: e.limit,
|
|
2131
2131
|
minScore: e.minScore
|
|
2132
2132
|
});
|
|
2133
|
-
return { result: JSON.stringify(
|
|
2134
|
-
}),
|
|
2133
|
+
return { result: JSON.stringify(o, null, 2) };
|
|
2134
|
+
}), i.set("get_cube_metadata", async () => {
|
|
2135
2135
|
const e = t.getMetadata();
|
|
2136
2136
|
return { result: JSON.stringify(e, null, 2) };
|
|
2137
|
-
})
|
|
2137
|
+
});
|
|
2138
|
+
const d = /* @__PURE__ */ new Map();
|
|
2139
|
+
for (const e of t.getMetadata())
|
|
2140
|
+
d.set(e.name, {
|
|
2141
|
+
measures: (e.measures || []).map((o) => o.name),
|
|
2142
|
+
dimensions: (e.dimensions || []).map((o) => o.name)
|
|
2143
|
+
});
|
|
2144
|
+
const u = (e, o) => {
|
|
2145
|
+
const r = d.get(e), s = o === "measures" ? r?.measures : r?.dimensions;
|
|
2146
|
+
return !s || s.length === 0 ? "" : ` Available ${o}: ${s.slice(0, 5).map((m) => `"${m}"`).join(", ")}`;
|
|
2147
|
+
};
|
|
2148
|
+
return i.set("execute_query", async (e) => {
|
|
2138
2149
|
try {
|
|
2139
|
-
const
|
|
2140
|
-
if (!Array.isArray(
|
|
2141
|
-
const
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2150
|
+
const o = (f, y) => {
|
|
2151
|
+
if (!Array.isArray(f)) return;
|
|
2152
|
+
const n = [], x = [];
|
|
2153
|
+
for (const b of f) {
|
|
2154
|
+
if (typeof b != "string") {
|
|
2155
|
+
x.push(b);
|
|
2156
|
+
continue;
|
|
2157
|
+
}
|
|
2158
|
+
const c = b.split(".");
|
|
2159
|
+
if (c.length === 1) {
|
|
2160
|
+
n.push(`"${b}" is not valid — must be "CubeName.fieldName".${u(b, y)}`);
|
|
2161
|
+
continue;
|
|
2162
|
+
}
|
|
2163
|
+
if (c.length === 3 && c[0] === c[1]) {
|
|
2164
|
+
const g = `${c[0]}.${c[2]}`;
|
|
2165
|
+
x.push(g);
|
|
2166
|
+
continue;
|
|
2167
|
+
}
|
|
2168
|
+
if (c.length === 2 && c[0] === c[1]) {
|
|
2169
|
+
n.push(`"${b}" is WRONG — "${c[0]}" is the cube name, not a ${y.replace(/s$/, "")}.${u(c[0], y)}`);
|
|
2170
|
+
continue;
|
|
2171
|
+
}
|
|
2172
|
+
x.push(b);
|
|
2173
|
+
}
|
|
2174
|
+
if (n.length > 0)
|
|
2175
|
+
throw new Error(`Invalid ${y}:
|
|
2176
|
+
${n.join(`
|
|
2177
|
+
`)}`);
|
|
2178
|
+
return x;
|
|
2146
2179
|
};
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2180
|
+
e.measures = o(e.measures, "measures") ?? e.measures, e.dimensions = o(e.dimensions, "dimensions") ?? e.dimensions;
|
|
2181
|
+
const r = (f) => {
|
|
2182
|
+
const y = f.split(".");
|
|
2183
|
+
return y.length === 3 && y[0] === y[1] ? `${y[0]}.${y[2]}` : f;
|
|
2184
|
+
};
|
|
2185
|
+
if (Array.isArray(e.filters))
|
|
2186
|
+
for (const f of e.filters)
|
|
2187
|
+
typeof f.member == "string" && (f.member = r(f.member));
|
|
2188
|
+
if (Array.isArray(e.timeDimensions))
|
|
2189
|
+
for (const f of e.timeDimensions)
|
|
2190
|
+
typeof f.dimension == "string" && (f.dimension = r(f.dimension));
|
|
2191
|
+
let s;
|
|
2192
|
+
e.funnel ? s = { funnel: e.funnel } : e.flow ? s = { flow: e.flow } : e.retention ? s = { retention: e.retention } : s = {
|
|
2150
2193
|
measures: e.measures,
|
|
2151
2194
|
dimensions: e.dimensions,
|
|
2152
2195
|
filters: e.filters,
|
|
@@ -2154,101 +2197,118 @@ function xe(o) {
|
|
|
2154
2197
|
order: e.order,
|
|
2155
2198
|
limit: e.limit
|
|
2156
2199
|
};
|
|
2157
|
-
const
|
|
2200
|
+
const m = await G(t, a, { query: s });
|
|
2158
2201
|
return {
|
|
2159
2202
|
result: JSON.stringify({
|
|
2160
|
-
rowCount:
|
|
2161
|
-
data:
|
|
2162
|
-
annotation:
|
|
2203
|
+
rowCount: m.data.length,
|
|
2204
|
+
data: m.data,
|
|
2205
|
+
annotation: m.annotation
|
|
2163
2206
|
}, null, 2)
|
|
2164
2207
|
};
|
|
2165
|
-
} catch (
|
|
2208
|
+
} catch (o) {
|
|
2209
|
+
const r = {
|
|
2210
|
+
measures: e.measures,
|
|
2211
|
+
dimensions: e.dimensions,
|
|
2212
|
+
filters: e.filters,
|
|
2213
|
+
timeDimensions: e.timeDimensions,
|
|
2214
|
+
order: e.order,
|
|
2215
|
+
limit: e.limit,
|
|
2216
|
+
...e.funnel ? { funnel: e.funnel } : {},
|
|
2217
|
+
...e.flow ? { flow: e.flow } : {},
|
|
2218
|
+
...e.retention ? { retention: e.retention } : {}
|
|
2219
|
+
};
|
|
2166
2220
|
return {
|
|
2167
|
-
result: `Query execution failed: ${
|
|
2221
|
+
result: `Query execution failed: ${o instanceof Error ? o.message : "Unknown error"}
|
|
2222
|
+
|
|
2223
|
+
Attempted query:
|
|
2224
|
+
${JSON.stringify(r, null, 2)}`,
|
|
2168
2225
|
isError: !0
|
|
2169
2226
|
};
|
|
2170
2227
|
}
|
|
2171
|
-
}),
|
|
2228
|
+
}), i.set("add_portlet", async (e) => {
|
|
2172
2229
|
const r = {
|
|
2173
2230
|
number: "kpiNumber",
|
|
2174
2231
|
retention: "retentionHeatmap"
|
|
2175
2232
|
}[e.chartType] ?? e.chartType;
|
|
2176
|
-
let
|
|
2233
|
+
let s;
|
|
2177
2234
|
try {
|
|
2178
|
-
|
|
2235
|
+
s = JSON.parse(e.query);
|
|
2179
2236
|
} catch {
|
|
2180
2237
|
return {
|
|
2181
2238
|
result: "Invalid query: could not parse JSON string. Ensure `query` is a valid JSON string.",
|
|
2182
2239
|
isError: !0
|
|
2183
2240
|
};
|
|
2184
2241
|
}
|
|
2185
|
-
const
|
|
2186
|
-
if (!
|
|
2242
|
+
const m = t.validateQuery(s);
|
|
2243
|
+
if (!m.isValid)
|
|
2187
2244
|
return {
|
|
2188
2245
|
result: `Invalid query — fix these errors and retry:
|
|
2189
|
-
${
|
|
2190
|
-
`)}
|
|
2246
|
+
${m.errors.join(`
|
|
2247
|
+
`)}
|
|
2248
|
+
|
|
2249
|
+
Attempted query:
|
|
2250
|
+
${JSON.stringify(s, null, 2)}`,
|
|
2191
2251
|
isError: !0
|
|
2192
2252
|
};
|
|
2193
|
-
const
|
|
2194
|
-
let
|
|
2195
|
-
if (
|
|
2196
|
-
|
|
2253
|
+
const f = !!(s.funnel || s.flow || s.retention);
|
|
2254
|
+
let y;
|
|
2255
|
+
if (f)
|
|
2256
|
+
y = e.chartConfig ?? {};
|
|
2197
2257
|
else {
|
|
2198
|
-
const
|
|
2199
|
-
if (!
|
|
2258
|
+
const b = Te(r, e.chartConfig, s), c = Ce(r, b, s);
|
|
2259
|
+
if (!c.isValid)
|
|
2200
2260
|
return {
|
|
2201
2261
|
result: `Chart config invalid — fix these errors and retry:
|
|
2202
|
-
${
|
|
2262
|
+
${c.errors.join(`
|
|
2203
2263
|
`)}`,
|
|
2204
2264
|
isError: !0
|
|
2205
2265
|
};
|
|
2206
|
-
|
|
2266
|
+
y = b;
|
|
2207
2267
|
}
|
|
2208
|
-
const n = `portlet-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
|
|
2268
|
+
const n = `portlet-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`, x = {
|
|
2209
2269
|
id: n,
|
|
2210
2270
|
title: e.title,
|
|
2211
2271
|
query: e.query,
|
|
2212
2272
|
chartType: r,
|
|
2213
|
-
chartConfig:
|
|
2273
|
+
chartConfig: y,
|
|
2214
2274
|
displayConfig: e.displayConfig
|
|
2215
2275
|
};
|
|
2216
2276
|
return {
|
|
2217
2277
|
result: `Portlet "${e.title}" added to notebook (id: ${n}, chart: ${r}). [Reminder: in your next response, start with a brief sentence about what you will do next BEFORE making any tool calls.]`,
|
|
2218
|
-
sideEffect: { type: "add_portlet", data:
|
|
2278
|
+
sideEffect: { type: "add_portlet", data: x }
|
|
2219
2279
|
};
|
|
2220
|
-
}),
|
|
2221
|
-
const
|
|
2222
|
-
id:
|
|
2280
|
+
}), i.set("add_markdown", async (e) => {
|
|
2281
|
+
const o = `markdown-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`, r = {
|
|
2282
|
+
id: o,
|
|
2223
2283
|
title: e.title,
|
|
2224
2284
|
content: e.content
|
|
2225
2285
|
};
|
|
2226
2286
|
return {
|
|
2227
|
-
result: `Markdown block added to notebook (id: ${
|
|
2287
|
+
result: `Markdown block added to notebook (id: ${o}). [Reminder: in your next response, start with a brief sentence about what you will do next BEFORE making any tool calls.]`,
|
|
2228
2288
|
sideEffect: { type: "add_markdown", data: r }
|
|
2229
2289
|
};
|
|
2230
|
-
}),
|
|
2290
|
+
}), i.set("save_as_dashboard", async (e) => {
|
|
2231
2291
|
try {
|
|
2232
|
-
const
|
|
2233
|
-
if (!
|
|
2292
|
+
const o = e.portlets;
|
|
2293
|
+
if (!o || o.length === 0)
|
|
2234
2294
|
return { result: "Dashboard must contain at least one portlet.", isError: !0 };
|
|
2235
2295
|
const r = [];
|
|
2236
|
-
for (const n of
|
|
2296
|
+
for (const n of o) {
|
|
2237
2297
|
if (n.chartType === "markdown") continue;
|
|
2238
|
-
const
|
|
2239
|
-
if (!
|
|
2298
|
+
const b = n.query;
|
|
2299
|
+
if (!b) {
|
|
2240
2300
|
r.push(`Portlet "${n.title}": missing query`);
|
|
2241
2301
|
continue;
|
|
2242
2302
|
}
|
|
2243
|
-
let
|
|
2303
|
+
let c;
|
|
2244
2304
|
try {
|
|
2245
|
-
|
|
2305
|
+
c = JSON.parse(b);
|
|
2246
2306
|
} catch {
|
|
2247
2307
|
r.push(`Portlet "${n.title}": invalid JSON query`);
|
|
2248
2308
|
continue;
|
|
2249
2309
|
}
|
|
2250
|
-
const
|
|
2251
|
-
|
|
2310
|
+
const g = t.validateQuery(c);
|
|
2311
|
+
g.isValid || r.push(`Portlet "${n.title}": ${g.errors.join(", ")}`);
|
|
2252
2312
|
}
|
|
2253
2313
|
if (r.length > 0)
|
|
2254
2314
|
return {
|
|
@@ -2257,32 +2317,32 @@ ${r.join(`
|
|
|
2257
2317
|
`)}`,
|
|
2258
2318
|
isError: !0
|
|
2259
2319
|
};
|
|
2260
|
-
const
|
|
2261
|
-
portlets:
|
|
2262
|
-
const
|
|
2263
|
-
let
|
|
2320
|
+
const s = {
|
|
2321
|
+
portlets: o.map((n) => {
|
|
2322
|
+
const x = n.chartType, b = x === "markdown", c = b ? "query" : n.analysisType || "query", g = c === "funnel" ? "funnel" : c === "flow" ? "flow" : c === "retention" ? "retention" : "query", A = n.query || "{}";
|
|
2323
|
+
let C;
|
|
2264
2324
|
try {
|
|
2265
|
-
|
|
2325
|
+
C = JSON.parse(A);
|
|
2266
2326
|
} catch {
|
|
2267
|
-
|
|
2327
|
+
C = {};
|
|
2268
2328
|
}
|
|
2269
|
-
const
|
|
2329
|
+
const k = {
|
|
2270
2330
|
version: 1,
|
|
2271
|
-
analysisType:
|
|
2331
|
+
analysisType: g,
|
|
2272
2332
|
activeView: "chart",
|
|
2273
2333
|
charts: {
|
|
2274
|
-
[
|
|
2275
|
-
chartType:
|
|
2334
|
+
[g]: {
|
|
2335
|
+
chartType: x,
|
|
2276
2336
|
chartConfig: n.chartConfig || {},
|
|
2277
2337
|
displayConfig: n.displayConfig || {}
|
|
2278
2338
|
}
|
|
2279
2339
|
},
|
|
2280
|
-
query:
|
|
2340
|
+
query: b ? {} : C
|
|
2281
2341
|
};
|
|
2282
2342
|
return {
|
|
2283
2343
|
id: n.id,
|
|
2284
2344
|
title: n.title,
|
|
2285
|
-
analysisConfig:
|
|
2345
|
+
analysisConfig: k,
|
|
2286
2346
|
dashboardFilterMapping: n.dashboardFilterMapping,
|
|
2287
2347
|
w: n.w,
|
|
2288
2348
|
h: n.h,
|
|
@@ -2292,35 +2352,35 @@ ${r.join(`
|
|
|
2292
2352
|
}),
|
|
2293
2353
|
filters: e.filters,
|
|
2294
2354
|
colorPalette: e.colorPalette
|
|
2295
|
-
},
|
|
2355
|
+
}, m = e.title, f = s.portlets.length, y = s.filters?.length || 0;
|
|
2296
2356
|
return {
|
|
2297
|
-
result: `Dashboard "${
|
|
2357
|
+
result: `Dashboard "${m}" created with ${f} portlets and ${y} filters.`,
|
|
2298
2358
|
sideEffect: {
|
|
2299
2359
|
type: "dashboard_saved",
|
|
2300
2360
|
data: {
|
|
2301
|
-
title:
|
|
2361
|
+
title: m,
|
|
2302
2362
|
description: e.description,
|
|
2303
|
-
dashboardConfig:
|
|
2363
|
+
dashboardConfig: s
|
|
2304
2364
|
}
|
|
2305
2365
|
}
|
|
2306
2366
|
};
|
|
2307
|
-
} catch (
|
|
2367
|
+
} catch (o) {
|
|
2308
2368
|
return {
|
|
2309
|
-
result: `Failed to save dashboard: ${
|
|
2369
|
+
result: `Failed to save dashboard: ${o instanceof Error ? o.message : "Unknown error"}`,
|
|
2310
2370
|
isError: !0
|
|
2311
2371
|
};
|
|
2312
2372
|
}
|
|
2313
|
-
}),
|
|
2373
|
+
}), i;
|
|
2314
2374
|
}
|
|
2315
|
-
async function*
|
|
2316
|
-
const { message: t,
|
|
2317
|
-
let
|
|
2375
|
+
async function* _e(l) {
|
|
2376
|
+
const { message: t, history: a, semanticLayer: i, securityContext: d, agentConfig: u, apiKey: e } = l, o = l.sessionId || crypto.randomUUID(), r = u.observability, s = crypto.randomUUID(), m = Date.now();
|
|
2377
|
+
let f;
|
|
2318
2378
|
try {
|
|
2319
|
-
const
|
|
2379
|
+
const h = await import(
|
|
2320
2380
|
/* webpackIgnore: true */
|
|
2321
2381
|
"@anthropic-ai/sdk"
|
|
2322
2382
|
);
|
|
2323
|
-
|
|
2383
|
+
f = h.default || h.Anthropic || h;
|
|
2324
2384
|
} catch {
|
|
2325
2385
|
yield {
|
|
2326
2386
|
type: "error",
|
|
@@ -2330,159 +2390,232 @@ async function* Ce(o) {
|
|
|
2330
2390
|
};
|
|
2331
2391
|
return;
|
|
2332
2392
|
}
|
|
2333
|
-
const
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2393
|
+
const y = new f({ apiKey: e }), n = De(), x = Se({ semanticLayer: i, securityContext: d }), b = i.getMetadata(), c = W(b), g = u.model || "claude-sonnet-4-6", A = u.maxTurns || 25, C = u.maxTokens || 4096;
|
|
2394
|
+
try {
|
|
2395
|
+
r?.onChatStart?.({
|
|
2396
|
+
traceId: s,
|
|
2397
|
+
sessionId: o,
|
|
2398
|
+
message: t,
|
|
2399
|
+
model: g,
|
|
2400
|
+
historyLength: a?.length ?? 0
|
|
2401
|
+
});
|
|
2402
|
+
} catch {
|
|
2403
|
+
}
|
|
2404
|
+
const k = [];
|
|
2405
|
+
if (a && a.length > 0) {
|
|
2406
|
+
for (const h of a)
|
|
2407
|
+
if (h.role === "user")
|
|
2408
|
+
k.push({ role: "user", content: h.content });
|
|
2409
|
+
else if (h.role === "assistant") {
|
|
2410
|
+
const F = [];
|
|
2411
|
+
if (h.content && F.push({ type: "text", text: h.content }), h.toolCalls && h.toolCalls.length > 0) {
|
|
2412
|
+
for (const w of h.toolCalls)
|
|
2413
|
+
F.push({
|
|
2343
2414
|
type: "tool_use",
|
|
2344
|
-
id:
|
|
2345
|
-
name:
|
|
2346
|
-
input:
|
|
2415
|
+
id: w.id,
|
|
2416
|
+
name: w.name,
|
|
2417
|
+
input: w.input || {}
|
|
2347
2418
|
});
|
|
2348
|
-
|
|
2419
|
+
k.push({ role: "assistant", content: F }), k.push({
|
|
2349
2420
|
role: "user",
|
|
2350
|
-
content:
|
|
2421
|
+
content: h.toolCalls.map((w) => ({
|
|
2351
2422
|
type: "tool_result",
|
|
2352
|
-
tool_use_id:
|
|
2353
|
-
content: typeof
|
|
2354
|
-
...
|
|
2423
|
+
tool_use_id: w.id,
|
|
2424
|
+
content: typeof w.result == "string" ? w.result : JSON.stringify(w.result ?? ""),
|
|
2425
|
+
...w.status === "error" ? { is_error: !0 } : {}
|
|
2355
2426
|
}))
|
|
2356
2427
|
});
|
|
2357
|
-
} else
|
|
2428
|
+
} else F.length > 0 && k.push({ role: "assistant", content: h.content });
|
|
2358
2429
|
}
|
|
2359
2430
|
}
|
|
2360
|
-
|
|
2431
|
+
k.push({ role: "user", content: t });
|
|
2432
|
+
let E = 0;
|
|
2361
2433
|
try {
|
|
2362
|
-
for (let
|
|
2363
|
-
|
|
2364
|
-
|
|
2434
|
+
for (let h = 0; h < A; h++) {
|
|
2435
|
+
E = h + 1;
|
|
2436
|
+
const F = await y.messages.create({
|
|
2437
|
+
model: g,
|
|
2365
2438
|
max_tokens: C,
|
|
2366
|
-
system:
|
|
2367
|
-
tools:
|
|
2368
|
-
messages:
|
|
2439
|
+
system: c,
|
|
2440
|
+
tools: n,
|
|
2441
|
+
messages: k,
|
|
2369
2442
|
stream: !0
|
|
2370
|
-
}),
|
|
2371
|
-
let
|
|
2372
|
-
|
|
2373
|
-
|
|
2443
|
+
}), w = [];
|
|
2444
|
+
let q = -1, V = "", O = "", L, M;
|
|
2445
|
+
const z = Date.now();
|
|
2446
|
+
for await (const v of F)
|
|
2447
|
+
switch (v.type) {
|
|
2374
2448
|
case "content_block_start": {
|
|
2375
|
-
|
|
2376
|
-
const
|
|
2377
|
-
|
|
2449
|
+
q++;
|
|
2450
|
+
const p = v.content_block;
|
|
2451
|
+
p.type === "tool_use" ? (w.push({ type: "tool_use", id: p.id, name: p.name, input: {} }), V = "", yield {
|
|
2378
2452
|
type: "tool_use_start",
|
|
2379
|
-
data: { id:
|
|
2380
|
-
}) :
|
|
2453
|
+
data: { id: p.id, name: p.name, input: void 0 }
|
|
2454
|
+
}) : p.type === "text" && w.push({ type: "text", text: "" });
|
|
2381
2455
|
break;
|
|
2382
2456
|
}
|
|
2383
2457
|
case "content_block_delta": {
|
|
2384
|
-
const
|
|
2385
|
-
if (
|
|
2386
|
-
const
|
|
2387
|
-
|
|
2388
|
-
} else
|
|
2458
|
+
const p = v.delta;
|
|
2459
|
+
if (p.type === "text_delta" && p.text) {
|
|
2460
|
+
const D = w[q];
|
|
2461
|
+
D && (D.text = (D.text || "") + p.text), yield { type: "text_delta", data: p.text };
|
|
2462
|
+
} else p.type === "input_json_delta" && p.partial_json && (V += p.partial_json);
|
|
2389
2463
|
break;
|
|
2390
2464
|
}
|
|
2391
2465
|
case "content_block_stop": {
|
|
2392
|
-
const
|
|
2393
|
-
if (
|
|
2466
|
+
const p = w[q];
|
|
2467
|
+
if (p?.type === "tool_use" && V) {
|
|
2394
2468
|
try {
|
|
2395
|
-
|
|
2469
|
+
p.input = JSON.parse(V);
|
|
2396
2470
|
} catch {
|
|
2397
|
-
|
|
2471
|
+
p.input = {};
|
|
2398
2472
|
}
|
|
2399
|
-
|
|
2473
|
+
V = "";
|
|
2400
2474
|
}
|
|
2401
2475
|
break;
|
|
2402
2476
|
}
|
|
2477
|
+
case "message_start": {
|
|
2478
|
+
const p = v.message;
|
|
2479
|
+
p?.usage?.input_tokens != null && (L = p.usage.input_tokens);
|
|
2480
|
+
break;
|
|
2481
|
+
}
|
|
2403
2482
|
case "message_delta": {
|
|
2404
|
-
const
|
|
2405
|
-
|
|
2483
|
+
const p = v.delta, D = v.usage;
|
|
2484
|
+
D?.output_tokens != null && (M = D.output_tokens), p.stop_reason && (O = p.stop_reason);
|
|
2406
2485
|
break;
|
|
2407
2486
|
}
|
|
2408
2487
|
}
|
|
2409
|
-
|
|
2488
|
+
try {
|
|
2489
|
+
r?.onGenerationEnd?.({
|
|
2490
|
+
traceId: s,
|
|
2491
|
+
turn: h,
|
|
2492
|
+
model: g,
|
|
2493
|
+
stopReason: O,
|
|
2494
|
+
inputTokens: L,
|
|
2495
|
+
outputTokens: M,
|
|
2496
|
+
durationMs: Date.now() - z
|
|
2497
|
+
});
|
|
2498
|
+
} catch {
|
|
2499
|
+
}
|
|
2500
|
+
if (k.push({ role: "assistant", content: w }), O !== "tool_use")
|
|
2410
2501
|
break;
|
|
2411
|
-
const
|
|
2412
|
-
for (const
|
|
2413
|
-
if (
|
|
2414
|
-
const
|
|
2415
|
-
if (!
|
|
2416
|
-
|
|
2502
|
+
const _ = [];
|
|
2503
|
+
for (const v of w) {
|
|
2504
|
+
if (v.type !== "tool_use") continue;
|
|
2505
|
+
const p = v.name, D = v.input || {}, S = v.id, R = x.get(p);
|
|
2506
|
+
if (!R) {
|
|
2507
|
+
_.push({
|
|
2417
2508
|
type: "tool_result",
|
|
2418
|
-
tool_use_id:
|
|
2419
|
-
content: `Unknown tool: ${
|
|
2509
|
+
tool_use_id: S,
|
|
2510
|
+
content: `Unknown tool: ${p}`,
|
|
2420
2511
|
is_error: !0
|
|
2421
2512
|
}), yield {
|
|
2422
2513
|
type: "tool_use_result",
|
|
2423
|
-
data: { id:
|
|
2514
|
+
data: { id: S, name: p, result: `Unknown tool: ${p}`, isError: !0 }
|
|
2424
2515
|
};
|
|
2425
2516
|
continue;
|
|
2426
2517
|
}
|
|
2518
|
+
const Y = Date.now();
|
|
2427
2519
|
try {
|
|
2428
|
-
const
|
|
2429
|
-
|
|
2520
|
+
const T = await R(D);
|
|
2521
|
+
T.sideEffect && (yield T.sideEffect), _.push({
|
|
2430
2522
|
type: "tool_result",
|
|
2431
|
-
tool_use_id:
|
|
2432
|
-
content:
|
|
2433
|
-
...
|
|
2523
|
+
tool_use_id: S,
|
|
2524
|
+
content: T.result,
|
|
2525
|
+
...T.isError ? { is_error: !0 } : {}
|
|
2434
2526
|
}), yield {
|
|
2435
2527
|
type: "tool_use_result",
|
|
2436
|
-
data: { id:
|
|
2528
|
+
data: { id: S, name: p, result: T.result, ...T.isError ? { isError: !0 } : {} }
|
|
2437
2529
|
};
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2530
|
+
try {
|
|
2531
|
+
r?.onToolEnd?.({
|
|
2532
|
+
traceId: s,
|
|
2533
|
+
turn: h,
|
|
2534
|
+
toolName: p,
|
|
2535
|
+
toolUseId: S,
|
|
2536
|
+
isError: !!T.isError,
|
|
2537
|
+
durationMs: Date.now() - Y
|
|
2538
|
+
});
|
|
2539
|
+
} catch {
|
|
2540
|
+
}
|
|
2541
|
+
} catch (T) {
|
|
2542
|
+
const $ = T instanceof Error ? T.message : "Tool execution failed";
|
|
2543
|
+
_.push({
|
|
2441
2544
|
type: "tool_result",
|
|
2442
|
-
tool_use_id:
|
|
2443
|
-
content:
|
|
2545
|
+
tool_use_id: S,
|
|
2546
|
+
content: $,
|
|
2444
2547
|
is_error: !0
|
|
2445
2548
|
}), yield {
|
|
2446
2549
|
type: "tool_use_result",
|
|
2447
|
-
data: { id:
|
|
2550
|
+
data: { id: S, name: p, result: $, isError: !0 }
|
|
2448
2551
|
};
|
|
2552
|
+
try {
|
|
2553
|
+
r?.onToolEnd?.({
|
|
2554
|
+
traceId: s,
|
|
2555
|
+
turn: h,
|
|
2556
|
+
toolName: p,
|
|
2557
|
+
toolUseId: S,
|
|
2558
|
+
isError: !0,
|
|
2559
|
+
durationMs: Date.now() - Y
|
|
2560
|
+
});
|
|
2561
|
+
} catch {
|
|
2562
|
+
}
|
|
2449
2563
|
}
|
|
2450
2564
|
}
|
|
2451
|
-
yield { type: "turn_complete", data: {} },
|
|
2565
|
+
yield { type: "turn_complete", data: {} }, k.push({ role: "user", content: _ });
|
|
2566
|
+
}
|
|
2567
|
+
try {
|
|
2568
|
+
r?.onChatEnd?.({
|
|
2569
|
+
traceId: s,
|
|
2570
|
+
sessionId: o,
|
|
2571
|
+
totalTurns: E,
|
|
2572
|
+
durationMs: Date.now() - m
|
|
2573
|
+
});
|
|
2574
|
+
} catch {
|
|
2452
2575
|
}
|
|
2453
2576
|
yield {
|
|
2454
2577
|
type: "done",
|
|
2455
|
-
data: { sessionId:
|
|
2578
|
+
data: { sessionId: o || "", traceId: s }
|
|
2456
2579
|
};
|
|
2457
|
-
} catch (
|
|
2580
|
+
} catch (h) {
|
|
2581
|
+
try {
|
|
2582
|
+
r?.onChatEnd?.({
|
|
2583
|
+
traceId: s,
|
|
2584
|
+
sessionId: o,
|
|
2585
|
+
totalTurns: 0,
|
|
2586
|
+
durationMs: Date.now() - m,
|
|
2587
|
+
error: h instanceof Error ? h.message : "Unknown error"
|
|
2588
|
+
});
|
|
2589
|
+
} catch {
|
|
2590
|
+
}
|
|
2458
2591
|
yield {
|
|
2459
2592
|
type: "error",
|
|
2460
2593
|
data: {
|
|
2461
|
-
message:
|
|
2594
|
+
message: Fe(h)
|
|
2462
2595
|
}
|
|
2463
2596
|
};
|
|
2464
2597
|
}
|
|
2465
2598
|
}
|
|
2466
|
-
function
|
|
2467
|
-
if (!
|
|
2599
|
+
function Fe(l) {
|
|
2600
|
+
if (!l || !(l instanceof Error))
|
|
2468
2601
|
return "Something went wrong. Please try again.";
|
|
2469
|
-
const t =
|
|
2602
|
+
const t = l.message || "", a = {
|
|
2470
2603
|
overloaded_error: "The AI service is temporarily overloaded. Please try again in a moment.",
|
|
2471
2604
|
rate_limit_error: "Too many requests. Please wait a moment and try again.",
|
|
2472
2605
|
api_error: "The AI service encountered an error. Please try again.",
|
|
2473
2606
|
authentication_error: "Authentication failed. Please check your API key configuration.",
|
|
2474
2607
|
invalid_request_error: "There was a problem with the request. Please try again."
|
|
2475
|
-
},
|
|
2476
|
-
if (
|
|
2477
|
-
const
|
|
2478
|
-
if (a[
|
|
2479
|
-
return a[
|
|
2608
|
+
}, i = l;
|
|
2609
|
+
if (i.status || i.type) {
|
|
2610
|
+
const d = i.error?.type || i.type || "";
|
|
2611
|
+
if (a[d])
|
|
2612
|
+
return a[d];
|
|
2480
2613
|
}
|
|
2481
2614
|
if (t.startsWith("{") || t.startsWith("Error: {")) {
|
|
2482
2615
|
try {
|
|
2483
|
-
const
|
|
2484
|
-
if (a[
|
|
2485
|
-
return a[
|
|
2616
|
+
const d = JSON.parse(t.replace(/^Error:\s*/, "")), u = d.error?.type || d.type || "";
|
|
2617
|
+
if (a[u])
|
|
2618
|
+
return a[u];
|
|
2486
2619
|
} catch {
|
|
2487
2620
|
}
|
|
2488
2621
|
return "The AI service encountered an error. Please try again.";
|
|
@@ -2490,5 +2623,5 @@ function we(o) {
|
|
|
2490
2623
|
return t;
|
|
2491
2624
|
}
|
|
2492
2625
|
export {
|
|
2493
|
-
|
|
2626
|
+
_e as handleAgentChat
|
|
2494
2627
|
};
|