drizzle-cube 0.4.8 → 0.4.10
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-odjn7MIB.js → handler-CySCodwi.js} +336 -210
- package/dist/adapters/{handler-BLcxTuwi.cjs → handler-e6zofK2k.cjs} +13 -13
- 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 +4 -4
- package/dist/client/chunks/{analysis-builder-Bov_gLsf.js → analysis-builder-BMmWeFPr.js} +138 -138
- package/dist/client/chunks/{analysis-builder-Bov_gLsf.js.map → analysis-builder-BMmWeFPr.js.map} +1 -1
- package/dist/client/chunks/{analysis-builder-shared-NBk6y0md.js → analysis-builder-shared-D56zYeV0.js} +713 -787
- package/dist/client/chunks/analysis-builder-shared-D56zYeV0.js.map +1 -0
- package/dist/client/chunks/{chart-area-QKKboTbq.js → chart-area-BJAgusst.js} +2 -2
- package/dist/client/chunks/{chart-area-QKKboTbq.js.map → chart-area-BJAgusst.js.map} +1 -1
- package/dist/client/chunks/chart-bar-Blypx8O4.js +267 -0
- package/dist/client/chunks/chart-bar-Blypx8O4.js.map +1 -0
- package/dist/client/chunks/{chart-line-C7YcMWBw.js → chart-line-zi6olZet.js} +2 -2
- package/dist/client/chunks/{chart-line-C7YcMWBw.js.map → chart-line-zi6olZet.js.map} +1 -1
- package/dist/client/chunks/{charts-loader-HYQFVOo4.js → charts-loader-CH0_S06T.js} +4 -4
- package/dist/client/chunks/{charts-loader-HYQFVOo4.js.map → charts-loader-CH0_S06T.js.map} +1 -1
- package/dist/client/chunks/{components-O0hh7ooo.js → components-ClQziOcT.js} +1495 -1416
- package/dist/client/chunks/components-ClQziOcT.js.map +1 -0
- package/dist/client/components/AgenticNotebook/NotebookPortletBlock.d.ts +1 -0
- package/dist/client/components.js +8 -8
- package/dist/client/index.js +655 -584
- package/dist/client/index.js.map +1 -1
- package/dist/client/stores/notebookStore.d.ts +2 -0
- package/dist/client/styles.css +1 -1
- package/dist/client/utils.js +1 -1
- package/dist/client-bundle-stats.html +1 -1
- package/dist/server/index.cjs +13 -13
- package/dist/server/index.js +1824 -1698
- package/package.json +1 -1
- package/dist/client/chunks/analysis-builder-shared-NBk6y0md.js.map +0 -1
- package/dist/client/chunks/chart-bar-HpXF42H1.js +0 -254
- package/dist/client/chunks/chart-bar-HpXF42H1.js.map +0 -1
- package/dist/client/chunks/components-O0hh7ooo.js.map +0 -1
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import { h as
|
|
2
|
-
import { handleDiscover as
|
|
3
|
-
function M(
|
|
4
|
-
if (
|
|
1
|
+
import { h as O, Q as q, j as P, D as Y } from "./mcp-transport-CU5g9bxj.js";
|
|
2
|
+
import { handleDiscover as z, handleLoad as R } from "./utils.js";
|
|
3
|
+
function M(o) {
|
|
4
|
+
if (o.length === 0)
|
|
5
5
|
return "No cubes are currently available.";
|
|
6
6
|
const t = ["## Available Cubes", ""];
|
|
7
|
-
for (const
|
|
8
|
-
if (t.push(`### ${
|
|
7
|
+
for (const i of o) {
|
|
8
|
+
if (t.push(`### ${i.name}`), i.description && t.push(i.description), i.measures && i.measures.length > 0) {
|
|
9
9
|
t.push(""), t.push("**Measures:**");
|
|
10
|
-
for (const
|
|
11
|
-
const e =
|
|
12
|
-
t.push(`- \`${
|
|
10
|
+
for (const s of i.measures) {
|
|
11
|
+
const e = s.description ? ` - ${s.description}` : "";
|
|
12
|
+
t.push(`- \`${i.name}.${s.name}\` (${s.type})${e}`);
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
if (
|
|
15
|
+
if (i.dimensions && i.dimensions.length > 0) {
|
|
16
16
|
t.push(""), t.push("**Dimensions:**");
|
|
17
|
-
for (const
|
|
18
|
-
const e =
|
|
19
|
-
t.push(`- \`${
|
|
17
|
+
for (const s of i.dimensions) {
|
|
18
|
+
const e = s.description ? ` - ${s.description}` : "";
|
|
19
|
+
t.push(`- \`${i.name}.${s.name}\` (${s.type})${e}`);
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
if (
|
|
22
|
+
if (i.relationships && i.relationships.length > 0) {
|
|
23
23
|
t.push(""), t.push("**Joins:**");
|
|
24
|
-
for (const
|
|
25
|
-
t.push(`- → \`${
|
|
24
|
+
for (const s of i.relationships)
|
|
25
|
+
t.push(`- → \`${s.targetCube}\` (${s.relationship})`);
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
i.meta?.eventStream && (t.push(""), t.push("**Event Stream:** Yes (supports funnel, flow, retention queries)"), i.meta.eventStream.bindingKey && t.push(`- Binding key: \`${i.name}.${i.meta.eventStream.bindingKey}\``), i.meta.eventStream.timeDimension && t.push(`- Time dimension: \`${i.name}.${i.meta.eventStream.timeDimension}\``)), t.push("");
|
|
28
28
|
}
|
|
29
29
|
return t.join(`
|
|
30
30
|
`);
|
|
31
31
|
}
|
|
32
|
-
function S(
|
|
33
|
-
return
|
|
32
|
+
function S(o) {
|
|
33
|
+
return o.messages.map((t) => t.content.text).join(`
|
|
34
34
|
|
|
35
35
|
`);
|
|
36
36
|
}
|
|
37
|
-
function
|
|
37
|
+
function L(o) {
|
|
38
38
|
return [
|
|
39
39
|
"# Drizzle Cube Analytics Agent",
|
|
40
40
|
"",
|
|
@@ -78,15 +78,14 @@ function R(s) {
|
|
|
78
78
|
"- Before calling `add_portlet`, verify the query is valid: all fields in `order` must also appear in `measures` or `dimensions`",
|
|
79
79
|
'- Never put data tables in markdown blocks — use `add_portlet` with chartType "table" instead',
|
|
80
80
|
"- Think out loud in the notebook: use `add_markdown` to share your reasoning at each step so users can follow along",
|
|
81
|
+
"- NEVER use emojis in text responses or markdown content — no 📊, 📈, ✅, 🔍, etc. Write in plain, professional language.",
|
|
81
82
|
"",
|
|
82
83
|
"## Chart Selection Guide",
|
|
83
84
|
"",
|
|
84
|
-
"Choose chart
|
|
85
|
+
"Choose the chart type that best communicates the answer to the user's question. Think about what the data represents and what insight the user needs — do NOT default to the first option in this table. Consider the number of data points, whether values are categorical or temporal, and whether the user is comparing, trending, or summarizing.",
|
|
85
86
|
"",
|
|
86
87
|
"| Intent / Data Shape | Chart Type |",
|
|
87
88
|
"|---|---|",
|
|
88
|
-
"| Single headline metric (total revenue, user count) | `kpiNumber` |",
|
|
89
|
-
"| Headline metric with period-over-period change | `kpiDelta` |",
|
|
90
89
|
"| Compare discrete categories or rankings | `bar` |",
|
|
91
90
|
"| Trend over time (one or few series) | `line` |",
|
|
92
91
|
"| Trend over time showing volume/magnitude | `area` |",
|
|
@@ -97,6 +96,8 @@ function R(s) {
|
|
|
97
96
|
"| Multi-variable comparison across categories | `radar` |",
|
|
98
97
|
"| Distribution/spread of values | `boxPlot` |",
|
|
99
98
|
"| Detailed row-level data or many columns | `table` |",
|
|
99
|
+
"| Single headline number — ONLY when user explicitly asks for a KPI card or single number | `kpiNumber` |",
|
|
100
|
+
"| Headline metric with period-over-period change — ONLY when user asks about change in a single metric | `kpiDelta` |",
|
|
100
101
|
"",
|
|
101
102
|
"Analysis-mode-specific chart types (require the corresponding analysis mode):",
|
|
102
103
|
"",
|
|
@@ -108,34 +109,52 @@ function R(s) {
|
|
|
108
109
|
"| Retention | `retentionHeatmap` | Cohort × period retention matrix |",
|
|
109
110
|
"| Retention | `retentionCombined` | Retention with line chart, heatmap, or combined modes |",
|
|
110
111
|
"",
|
|
111
|
-
|
|
112
|
+
'**Chart selection priorities:** Default to `bar` for categories, `line` for time series, `table` for exploratory data. Use `kpiNumber`/`kpiDelta` only as a last resort — they are appropriate only when the user explicitly asks for a single headline number or KPI card. If the query returns multiple rows or the user asks a general question like "show me revenue", prefer `bar` or `table` over `kpiNumber`.',
|
|
113
|
+
"",
|
|
114
|
+
"## Chart Axis Configuration Rules",
|
|
115
|
+
"",
|
|
116
|
+
"**Bar charts MUST have an xAxis.** Put a dimension in `chartConfig.xAxis` so bars have category labels. If your query has no dimensions, add one or use `table` instead.",
|
|
117
|
+
"",
|
|
118
|
+
"**Never duplicate xAxis in series.** Putting the same dimension in both `xAxis` and `series` creates a sparse, broken-looking chart. The `series` field is ONLY for splitting bars into grouped/stacked sub-series by a SECOND dimension.",
|
|
119
|
+
"",
|
|
120
|
+
"Correct bar chart examples:",
|
|
121
|
+
'- Categories only: `xAxis: ["Cube.category"], yAxis: ["Cube.count"]` — no series needed',
|
|
122
|
+
'- Grouped bars: `xAxis: ["Cube.category"], yAxis: ["Cube.count"], series: ["Cube.status"]` — series is a DIFFERENT dimension',
|
|
123
|
+
'- Multiple measures: `xAxis: ["Cube.category"], yAxis: ["Cube.count", "Cube.total"]` — each measure becomes a bar group',
|
|
124
|
+
"",
|
|
125
|
+
"Wrong:",
|
|
126
|
+
'- `xAxis: [], yAxis: ["Cube.avg1", "Cube.avg2"]` — missing xAxis, bars have no labels',
|
|
127
|
+
'- `xAxis: ["Cube.size"], series: ["Cube.size"]` — same field in both, creates sparse chart',
|
|
112
128
|
"",
|
|
113
129
|
"## Analysis Mode Decision Tree",
|
|
114
130
|
"",
|
|
115
131
|
"The default mode is **query** (standard measures/dimensions). Switch to a special mode only when the user's question matches:",
|
|
116
132
|
"",
|
|
117
|
-
'- **Funnel mode** — "What is the conversion rate from step A → B → C?"
|
|
133
|
+
'- **Funnel mode** — "What is the conversion rate from step A → B → C?"',
|
|
118
134
|
" - Requires: an event-stream cube with `capabilities.funnel = true` from `discover_cubes`",
|
|
119
|
-
|
|
120
|
-
"
|
|
135
|
+
" - Execute: `execute_query` with `funnel` param:",
|
|
136
|
+
' `{ bindingKey: "Events.userId", timeDimension: "Events.timestamp", steps: [{ name: "Signup", filter: { member: "Events.eventName", operator: "equals", values: ["signup"] }}, { name: "Purchase", filter: { member: "Events.eventName", operator: "equals", values: ["purchase"] }}] }`',
|
|
137
|
+
' - Visualize: `add_portlet` with `chartType: "funnel"` and `query` as JSON string containing `{ "funnel": { ... } }`',
|
|
121
138
|
"",
|
|
122
|
-
'- **Flow mode** — "What paths do users take after signup?"
|
|
139
|
+
'- **Flow mode** — "What paths do users take after signup?"',
|
|
123
140
|
" - Requires: `capabilities.flow = true` from `discover_cubes`",
|
|
124
|
-
|
|
125
|
-
"
|
|
141
|
+
" - Execute: `execute_query` with `flow` param:",
|
|
142
|
+
' `{ bindingKey: "Events.userId", timeDimension: "Events.timestamp", eventDimension: "Events.eventName", startingStep: { name: "Signup", filter: { member: "Events.eventName", operator: "equals", values: ["signup"] }}, stepsBefore: 0, stepsAfter: 3 }`',
|
|
143
|
+
' - Visualize: `add_portlet` with `chartType: "sankey"` (or `"sunburst"`) and `query` as JSON string containing `{ "flow": { ... } }`',
|
|
126
144
|
"",
|
|
127
|
-
'- **Retention mode** — "What % of users come back after 7 days?"
|
|
145
|
+
'- **Retention mode** — "What % of users come back after 7 days?"',
|
|
128
146
|
" - Requires: `capabilities.retention = true` from `discover_cubes`",
|
|
129
|
-
|
|
130
|
-
"
|
|
147
|
+
" - Execute: `execute_query` with `retention` param:",
|
|
148
|
+
' `{ timeDimension: "Events.timestamp", bindingKey: "Events.userId", dateRange: { start: "2024-01-01", end: "2024-03-31" }, granularity: "week", periods: 8, retentionType: "classic" }`',
|
|
149
|
+
' - Visualize: `add_portlet` with `chartType: "retentionCombined"` (or `"retentionHeatmap"`) and `query` as JSON string containing `{ "retention": { ... } }`',
|
|
131
150
|
"",
|
|
132
|
-
"Before using funnel/flow/retention, check the `capabilities` object returned by `discover_cubes`. If the required capability is `false`, explain to the user that the data model does not support that analysis mode
|
|
151
|
+
"Before using funnel/flow/retention, check the `capabilities` object returned by `discover_cubes`. If the required capability is `false`, explain to the user that the data model does not support that analysis mode.",
|
|
133
152
|
"",
|
|
134
153
|
"Event-stream cubes are marked in the Available Cubes section below with **Event Stream: Yes** and list their binding key and time dimension.",
|
|
135
154
|
"",
|
|
136
155
|
"---",
|
|
137
156
|
"",
|
|
138
|
-
S(
|
|
157
|
+
S(O),
|
|
139
158
|
"",
|
|
140
159
|
"---",
|
|
141
160
|
"",
|
|
@@ -143,19 +162,19 @@ function R(s) {
|
|
|
143
162
|
"",
|
|
144
163
|
"---",
|
|
145
164
|
"",
|
|
146
|
-
S(
|
|
165
|
+
S(P),
|
|
147
166
|
"",
|
|
148
167
|
"---",
|
|
149
168
|
"",
|
|
150
|
-
S(
|
|
169
|
+
S(Y),
|
|
151
170
|
"",
|
|
152
171
|
"---",
|
|
153
172
|
"",
|
|
154
|
-
M(
|
|
173
|
+
M(o)
|
|
155
174
|
].join(`
|
|
156
175
|
`);
|
|
157
176
|
}
|
|
158
|
-
const
|
|
177
|
+
const $ = {
|
|
159
178
|
label: "Bar Chart",
|
|
160
179
|
description: "Compare values across categories",
|
|
161
180
|
useCase: "Best for comparing discrete categories, showing rankings, or displaying changes over time",
|
|
@@ -221,7 +240,7 @@ const H = {
|
|
|
221
240
|
description: "Number formatting for right Y-axis"
|
|
222
241
|
}
|
|
223
242
|
]
|
|
224
|
-
},
|
|
243
|
+
}, B = {
|
|
225
244
|
label: "Line Chart",
|
|
226
245
|
description: "Show trends and changes over time",
|
|
227
246
|
useCase: "Best for continuous data, trends, time series, and showing relationships between multiple series",
|
|
@@ -304,7 +323,7 @@ const H = {
|
|
|
304
323
|
description: "Number formatting for right Y-axis"
|
|
305
324
|
}
|
|
306
325
|
]
|
|
307
|
-
},
|
|
326
|
+
}, H = {
|
|
308
327
|
label: "Area Chart",
|
|
309
328
|
description: "Emphasize magnitude of change over time",
|
|
310
329
|
useCase: "Best for showing cumulative totals, volume changes, or stacked comparisons over time",
|
|
@@ -410,7 +429,7 @@ const H = {
|
|
|
410
429
|
description: "Number formatting for values"
|
|
411
430
|
}
|
|
412
431
|
]
|
|
413
|
-
},
|
|
432
|
+
}, K = {
|
|
414
433
|
label: "Scatter Plot",
|
|
415
434
|
description: "Reveal correlations between variables",
|
|
416
435
|
useCase: "Best for identifying patterns, correlations, outliers, and relationships between two measures",
|
|
@@ -458,7 +477,7 @@ const H = {
|
|
|
458
477
|
description: "Number formatting for Y-axis"
|
|
459
478
|
}
|
|
460
479
|
]
|
|
461
|
-
},
|
|
480
|
+
}, G = {
|
|
462
481
|
label: "Bubble Chart",
|
|
463
482
|
description: "Compare three dimensions of data",
|
|
464
483
|
useCase: "Best for showing relationships between three variables (X, Y, and size), market analysis",
|
|
@@ -524,7 +543,7 @@ const H = {
|
|
|
524
543
|
description: "Number formatting for Y-axis and values"
|
|
525
544
|
}
|
|
526
545
|
]
|
|
527
|
-
},
|
|
546
|
+
}, Z = {
|
|
528
547
|
label: "Radar Chart",
|
|
529
548
|
description: "Compare multiple metrics across categories",
|
|
530
549
|
useCase: "Best for multivariate comparisons, performance metrics, strengths/weaknesses analysis",
|
|
@@ -563,7 +582,7 @@ const H = {
|
|
|
563
582
|
description: "Number formatting for values"
|
|
564
583
|
}
|
|
565
584
|
]
|
|
566
|
-
},
|
|
585
|
+
}, X = {
|
|
567
586
|
label: "Radial Bar Chart",
|
|
568
587
|
description: "Circular progress and KPI visualization",
|
|
569
588
|
useCase: "Best for showing progress toward goals, KPIs, or comparing percentages in a compact form",
|
|
@@ -595,7 +614,7 @@ const H = {
|
|
|
595
614
|
description: "Number formatting for values"
|
|
596
615
|
}
|
|
597
616
|
]
|
|
598
|
-
},
|
|
617
|
+
}, U = {
|
|
599
618
|
label: "TreeMap",
|
|
600
619
|
description: "Visualize hierarchical data with nested rectangles",
|
|
601
620
|
useCase: "Best for showing part-to-whole relationships in hierarchical data, disk usage, budget allocation",
|
|
@@ -637,7 +656,7 @@ const H = {
|
|
|
637
656
|
}
|
|
638
657
|
],
|
|
639
658
|
clickableElements: { cell: !0 }
|
|
640
|
-
},
|
|
659
|
+
}, W = {
|
|
641
660
|
label: "Data Table",
|
|
642
661
|
description: "Display detailed tabular data",
|
|
643
662
|
useCase: "Best for precise values, detailed analysis, sortable/filterable data exploration",
|
|
@@ -660,7 +679,7 @@ const H = {
|
|
|
660
679
|
description: "Number formatting for numeric values"
|
|
661
680
|
}
|
|
662
681
|
]
|
|
663
|
-
},
|
|
682
|
+
}, Q = {
|
|
664
683
|
label: "Activity Grid",
|
|
665
684
|
description: "GitHub-style activity grid showing temporal patterns across different time scales",
|
|
666
685
|
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",
|
|
@@ -694,12 +713,12 @@ const H = {
|
|
|
694
713
|
description: "Automatically size blocks to fill portlet width and height while maintaining aspect ratio"
|
|
695
714
|
}
|
|
696
715
|
],
|
|
697
|
-
validate: (
|
|
698
|
-
const { dateField: t, valueField:
|
|
716
|
+
validate: (o) => {
|
|
717
|
+
const { dateField: t, valueField: i } = o;
|
|
699
718
|
return !t || Array.isArray(t) && t.length === 0 ? {
|
|
700
719
|
isValid: !1,
|
|
701
720
|
message: "Time dimension is required for activity grid"
|
|
702
|
-
} : !
|
|
721
|
+
} : !i || Array.isArray(i) && i.length === 0 ? {
|
|
703
722
|
isValid: !1,
|
|
704
723
|
message: "Activity measure is required for intensity mapping"
|
|
705
724
|
} : { isValid: !0 };
|
|
@@ -863,7 +882,7 @@ const H = {
|
|
|
863
882
|
}
|
|
864
883
|
],
|
|
865
884
|
displayOptions: ["hideHeader"],
|
|
866
|
-
validate: (
|
|
885
|
+
validate: (o) => !o.yAxis || Array.isArray(o.yAxis) && o.yAxis.length === 0 ? {
|
|
867
886
|
isValid: !1,
|
|
868
887
|
message: "A measure is required for KPI Delta charts"
|
|
869
888
|
} : { isValid: !0 }
|
|
@@ -909,7 +928,7 @@ const H = {
|
|
|
909
928
|
}
|
|
910
929
|
],
|
|
911
930
|
displayOptions: ["hideHeader"]
|
|
912
|
-
},
|
|
931
|
+
}, ie = {
|
|
913
932
|
label: "Markdown",
|
|
914
933
|
description: "Display custom markdown content with formatting",
|
|
915
934
|
useCase: "Perfect for adding documentation, notes, section headers, instructions, or formatted text to dashboards",
|
|
@@ -1001,7 +1020,7 @@ Use --- for horizontal rules.`,
|
|
|
1001
1020
|
description: "Add an accent-colored border on one side of the content"
|
|
1002
1021
|
}
|
|
1003
1022
|
]
|
|
1004
|
-
},
|
|
1023
|
+
}, se = {
|
|
1005
1024
|
label: "Funnel Chart",
|
|
1006
1025
|
description: "Show conversion through sequential steps",
|
|
1007
1026
|
useCase: "Best for visualizing user journey funnels, sales pipelines, or multi-step processes",
|
|
@@ -1088,7 +1107,7 @@ Use --- for horizontal rules.`,
|
|
|
1088
1107
|
description: "Display 90th percentile time to convert"
|
|
1089
1108
|
}
|
|
1090
1109
|
]
|
|
1091
|
-
},
|
|
1110
|
+
}, ae = {
|
|
1092
1111
|
label: "Sankey Chart",
|
|
1093
1112
|
description: "Show flow between states or steps",
|
|
1094
1113
|
useCase: "Best for visualizing user journey flows, path analysis, or state transitions",
|
|
@@ -1144,7 +1163,7 @@ Use --- for horizontal rules.`,
|
|
|
1144
1163
|
description: "Hide the statistics footer below the chart"
|
|
1145
1164
|
}
|
|
1146
1165
|
]
|
|
1147
|
-
},
|
|
1166
|
+
}, oe = {
|
|
1148
1167
|
label: "Sunburst Chart",
|
|
1149
1168
|
description: "Show hierarchical flow as radial rings",
|
|
1150
1169
|
useCase: "Best for visualizing forward paths from a starting event in a compact radial layout",
|
|
@@ -1260,7 +1279,7 @@ Use --- for horizontal rules.`,
|
|
|
1260
1279
|
description: "Number formatting for cell values and legend"
|
|
1261
1280
|
}
|
|
1262
1281
|
],
|
|
1263
|
-
validate: (
|
|
1282
|
+
validate: (o) => o.xAxis?.length ? o.yAxis?.length ? o.valueField?.length ? { isValid: !0 } : { isValid: !1, message: "Value measure required" } : { isValid: !1, message: "Y-axis dimension required" } : { isValid: !1, message: "X-axis dimension required" }
|
|
1264
1283
|
}, ne = {
|
|
1265
1284
|
label: "Retention Matrix",
|
|
1266
1285
|
// RetentionHeatmap auto-configures from the retention data structure
|
|
@@ -1409,102 +1428,128 @@ Use --- for horizontal rules.`,
|
|
|
1409
1428
|
}
|
|
1410
1429
|
]
|
|
1411
1430
|
}, V = {
|
|
1412
|
-
bar:
|
|
1413
|
-
line:
|
|
1414
|
-
area:
|
|
1431
|
+
bar: $,
|
|
1432
|
+
line: B,
|
|
1433
|
+
area: H,
|
|
1415
1434
|
pie: j,
|
|
1416
|
-
scatter:
|
|
1417
|
-
bubble:
|
|
1418
|
-
radar:
|
|
1419
|
-
radialBar:
|
|
1420
|
-
treemap:
|
|
1421
|
-
table:
|
|
1422
|
-
activityGrid:
|
|
1435
|
+
scatter: K,
|
|
1436
|
+
bubble: G,
|
|
1437
|
+
radar: Z,
|
|
1438
|
+
radialBar: X,
|
|
1439
|
+
treemap: U,
|
|
1440
|
+
table: W,
|
|
1441
|
+
activityGrid: Q,
|
|
1423
1442
|
kpiNumber: J,
|
|
1424
1443
|
kpiDelta: ee,
|
|
1425
1444
|
kpiText: te,
|
|
1426
|
-
markdown:
|
|
1427
|
-
funnel:
|
|
1428
|
-
sankey:
|
|
1429
|
-
sunburst:
|
|
1445
|
+
markdown: ie,
|
|
1446
|
+
funnel: se,
|
|
1447
|
+
sankey: ae,
|
|
1448
|
+
sunburst: oe,
|
|
1430
1449
|
heatmap: re,
|
|
1431
1450
|
retentionHeatmap: ne,
|
|
1432
1451
|
retentionCombined: le,
|
|
1433
1452
|
boxPlot: de
|
|
1434
1453
|
};
|
|
1435
|
-
function pe(
|
|
1436
|
-
const
|
|
1437
|
-
if (!
|
|
1454
|
+
function pe(o, t, i) {
|
|
1455
|
+
const s = V[o];
|
|
1456
|
+
if (!s)
|
|
1438
1457
|
return { isValid: !0, errors: [] };
|
|
1439
|
-
if (
|
|
1458
|
+
if (s.skipQuery)
|
|
1440
1459
|
return { isValid: !0, errors: [] };
|
|
1441
1460
|
const e = [];
|
|
1442
|
-
for (const
|
|
1443
|
-
if (!
|
|
1444
|
-
const n = t?.[
|
|
1461
|
+
for (const a of s.dropZones) {
|
|
1462
|
+
if (!a.mandatory) continue;
|
|
1463
|
+
const n = t?.[a.key];
|
|
1445
1464
|
if (!(Array.isArray(n) ? n.length > 0 : !!n)) {
|
|
1446
|
-
const
|
|
1465
|
+
const u = a.acceptTypes?.join("/") ?? "fields";
|
|
1447
1466
|
e.push(
|
|
1448
|
-
`chartConfig.${
|
|
1467
|
+
`chartConfig.${a.key} is required for ${o} chart (${a.label}). Accepts: ${u}.`
|
|
1468
|
+
);
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
if (o === "bar") {
|
|
1472
|
+
const a = t?.xAxis;
|
|
1473
|
+
if (!(Array.isArray(a) ? a.length > 0 : !!a)) {
|
|
1474
|
+
const l = i.dimensions ?? [], u = i.timeDimensions ?? [];
|
|
1475
|
+
l.length > 0 || u.length > 0 ? e.push(
|
|
1476
|
+
"chartConfig.xAxis is required for bar charts. Put a dimension in xAxis so bars have category labels."
|
|
1477
|
+
) : e.push(
|
|
1478
|
+
'Bar charts need an xAxis dimension for category labels. Add a dimension to the query or use "table" chart type instead.'
|
|
1449
1479
|
);
|
|
1450
1480
|
}
|
|
1451
1481
|
}
|
|
1482
|
+
if (t?.xAxis && t?.series) {
|
|
1483
|
+
const a = new Set(
|
|
1484
|
+
Array.isArray(t.xAxis) ? t.xAxis : [t.xAxis]
|
|
1485
|
+
), l = (Array.isArray(t.series) ? t.series : [t.series]).filter((u) => a.has(u));
|
|
1486
|
+
l.length > 0 && e.push(
|
|
1487
|
+
`chartConfig.series must not contain the same field as xAxis (found: ${l.join(", ")}). The series field is only for splitting into grouped/stacked sub-series by a DIFFERENT dimension. Remove the duplicate from series.`
|
|
1488
|
+
);
|
|
1489
|
+
}
|
|
1452
1490
|
return { isValid: e.length === 0, errors: e };
|
|
1453
1491
|
}
|
|
1454
|
-
function ue(
|
|
1455
|
-
const
|
|
1456
|
-
if (!
|
|
1492
|
+
function ue(o, t, i) {
|
|
1493
|
+
const s = V[o];
|
|
1494
|
+
if (!s)
|
|
1457
1495
|
return t ?? {};
|
|
1458
|
-
const e = { ...t },
|
|
1459
|
-
for (const
|
|
1460
|
-
const
|
|
1461
|
-
if (Array.isArray(
|
|
1462
|
-
const
|
|
1463
|
-
if (
|
|
1464
|
-
if (
|
|
1465
|
-
const
|
|
1466
|
-
for (const
|
|
1467
|
-
if (
|
|
1468
|
-
const
|
|
1469
|
-
Array.isArray(
|
|
1496
|
+
const e = { ...t }, a = i.measures ?? [], n = i.dimensions ?? [], u = (i.timeDimensions ?? []).map((d) => d.dimension);
|
|
1497
|
+
for (const d of s.dropZones) {
|
|
1498
|
+
const p = e[d.key];
|
|
1499
|
+
if (Array.isArray(p) ? p.length > 0 : !!p) continue;
|
|
1500
|
+
const f = d.acceptTypes ?? [];
|
|
1501
|
+
if (d.key === "sizeField" || d.key === "colorField") {
|
|
1502
|
+
if (f.includes("measure")) {
|
|
1503
|
+
const m = /* @__PURE__ */ new Set();
|
|
1504
|
+
for (const y of s.dropZones) {
|
|
1505
|
+
if (y.key === d.key) continue;
|
|
1506
|
+
const g = e[y.key];
|
|
1507
|
+
Array.isArray(g) ? g.forEach((w) => m.add(w)) : typeof g == "string" && m.add(g);
|
|
1470
1508
|
}
|
|
1471
|
-
const
|
|
1472
|
-
|
|
1509
|
+
const C = a.filter((y) => !m.has(y));
|
|
1510
|
+
C.length > 0 && (e[d.key] = C[0]);
|
|
1473
1511
|
}
|
|
1474
1512
|
continue;
|
|
1475
1513
|
}
|
|
1476
|
-
const
|
|
1477
|
-
if (
|
|
1478
|
-
|
|
1479
|
-
|
|
1514
|
+
const c = [];
|
|
1515
|
+
if (f.includes("dimension") && c.push(...n), f.includes("timeDimension") && c.push(...u), f.includes("measure") && c.push(...a), c.length === 0) continue;
|
|
1516
|
+
let b = c;
|
|
1517
|
+
if (d.key === "series") {
|
|
1518
|
+
const m = new Set(
|
|
1519
|
+
Array.isArray(e.xAxis) ? e.xAxis : e.xAxis ? [e.xAxis] : []
|
|
1520
|
+
);
|
|
1521
|
+
if (b = c.filter((C) => !m.has(C)), b.length === 0) continue;
|
|
1522
|
+
}
|
|
1523
|
+
const F = d.maxItems ?? 1 / 0, v = b.slice(0, F);
|
|
1524
|
+
v.length > 0 && (e[d.key] = v);
|
|
1480
1525
|
}
|
|
1481
1526
|
return e;
|
|
1482
1527
|
}
|
|
1483
|
-
function
|
|
1528
|
+
function me(o) {
|
|
1484
1529
|
const t = [`
|
|
1485
1530
|
Chart config requirements by type:`];
|
|
1486
|
-
for (const
|
|
1487
|
-
const
|
|
1488
|
-
if (!
|
|
1489
|
-
const e =
|
|
1490
|
-
if (
|
|
1491
|
-
t.push(` ${
|
|
1531
|
+
for (const i of o) {
|
|
1532
|
+
const s = V[i];
|
|
1533
|
+
if (!s) continue;
|
|
1534
|
+
const e = s.description ?? "", a = s.useCase ?? "", n = [e, a].filter(Boolean).join(". "), l = n ? ` — ${n}.` : "", u = s.dropZones.filter((p) => p.mandatory);
|
|
1535
|
+
if (u.length === 0 && !s.skipQuery) {
|
|
1536
|
+
t.push(` ${i}${l} chartConfig auto-inferred from query.`);
|
|
1492
1537
|
continue;
|
|
1493
1538
|
}
|
|
1494
|
-
if (
|
|
1495
|
-
t.push(` ${
|
|
1539
|
+
if (s.skipQuery) {
|
|
1540
|
+
t.push(` ${i}${l} No query needed.`);
|
|
1496
1541
|
continue;
|
|
1497
1542
|
}
|
|
1498
|
-
const
|
|
1499
|
-
const
|
|
1500
|
-
return `${
|
|
1543
|
+
const d = u.map((p) => {
|
|
1544
|
+
const k = p.acceptTypes?.join("/") ?? "any", f = p.maxItems ? ` (max ${p.maxItems})` : "";
|
|
1545
|
+
return `${p.key}=[${k}]${f}`;
|
|
1501
1546
|
});
|
|
1502
|
-
t.push(` ${
|
|
1547
|
+
t.push(` ${i}${l} Requires ${d.join(", ")}.`);
|
|
1503
1548
|
}
|
|
1504
1549
|
return t.join(`
|
|
1505
1550
|
`);
|
|
1506
1551
|
}
|
|
1507
|
-
const
|
|
1552
|
+
const N = [
|
|
1508
1553
|
"bar",
|
|
1509
1554
|
"line",
|
|
1510
1555
|
"area",
|
|
@@ -1523,7 +1568,7 @@ const P = [
|
|
|
1523
1568
|
"retentionCombined",
|
|
1524
1569
|
"boxPlot"
|
|
1525
1570
|
];
|
|
1526
|
-
function
|
|
1571
|
+
function ce() {
|
|
1527
1572
|
return [
|
|
1528
1573
|
// Tool 1: discover_cubes
|
|
1529
1574
|
{
|
|
@@ -1551,7 +1596,7 @@ function me() {
|
|
|
1551
1596
|
// Tool 3: execute_query
|
|
1552
1597
|
{
|
|
1553
1598
|
name: "execute_query",
|
|
1554
|
-
description: "Execute a semantic query and return data results.
|
|
1599
|
+
description: "Execute a semantic query and return data results. Supports standard queries (measures/dimensions) and analysis modes (funnel/flow/retention). Only provide ONE mode per call.",
|
|
1555
1600
|
input_schema: {
|
|
1556
1601
|
type: "object",
|
|
1557
1602
|
properties: {
|
|
@@ -1598,6 +1643,75 @@ function me() {
|
|
|
1598
1643
|
limit: {
|
|
1599
1644
|
type: "number",
|
|
1600
1645
|
description: "Row limit"
|
|
1646
|
+
},
|
|
1647
|
+
funnel: {
|
|
1648
|
+
type: "object",
|
|
1649
|
+
properties: {
|
|
1650
|
+
bindingKey: { type: "string", description: 'Entity binding key (e.g., "Events.userId")' },
|
|
1651
|
+
timeDimension: { type: "string", description: 'Time dimension (e.g., "Events.timestamp")' },
|
|
1652
|
+
steps: {
|
|
1653
|
+
type: "array",
|
|
1654
|
+
items: {
|
|
1655
|
+
type: "object",
|
|
1656
|
+
properties: {
|
|
1657
|
+
name: { type: "string" },
|
|
1658
|
+
filter: {},
|
|
1659
|
+
timeToConvert: { type: "string", description: 'ISO 8601 duration (e.g., "P7D")' }
|
|
1660
|
+
},
|
|
1661
|
+
required: ["name"]
|
|
1662
|
+
},
|
|
1663
|
+
description: "Funnel steps (min 2)"
|
|
1664
|
+
},
|
|
1665
|
+
includeTimeMetrics: { type: "boolean" },
|
|
1666
|
+
globalTimeWindow: { type: "string" }
|
|
1667
|
+
},
|
|
1668
|
+
required: ["bindingKey", "timeDimension", "steps"],
|
|
1669
|
+
description: "Funnel analysis config. When provided, measures/dimensions are ignored."
|
|
1670
|
+
},
|
|
1671
|
+
flow: {
|
|
1672
|
+
type: "object",
|
|
1673
|
+
properties: {
|
|
1674
|
+
bindingKey: { type: "string" },
|
|
1675
|
+
timeDimension: { type: "string" },
|
|
1676
|
+
eventDimension: { type: "string", description: "Dimension whose values become node labels" },
|
|
1677
|
+
startingStep: {
|
|
1678
|
+
type: "object",
|
|
1679
|
+
properties: {
|
|
1680
|
+
name: { type: "string" },
|
|
1681
|
+
filter: {}
|
|
1682
|
+
},
|
|
1683
|
+
required: ["name"]
|
|
1684
|
+
},
|
|
1685
|
+
stepsBefore: { type: "number", description: "Steps before starting step (0-5)" },
|
|
1686
|
+
stepsAfter: { type: "number", description: "Steps after starting step (0-5)" },
|
|
1687
|
+
entityLimit: { type: "number" },
|
|
1688
|
+
outputMode: { type: "string", enum: ["sankey", "sunburst"] }
|
|
1689
|
+
},
|
|
1690
|
+
required: ["bindingKey", "timeDimension", "eventDimension", "startingStep"],
|
|
1691
|
+
description: "Flow analysis config. When provided, measures/dimensions are ignored."
|
|
1692
|
+
},
|
|
1693
|
+
retention: {
|
|
1694
|
+
type: "object",
|
|
1695
|
+
properties: {
|
|
1696
|
+
timeDimension: { type: "string" },
|
|
1697
|
+
bindingKey: { type: "string" },
|
|
1698
|
+
dateRange: {
|
|
1699
|
+
type: "object",
|
|
1700
|
+
properties: {
|
|
1701
|
+
start: { type: "string", description: "YYYY-MM-DD" },
|
|
1702
|
+
end: { type: "string", description: "YYYY-MM-DD" }
|
|
1703
|
+
},
|
|
1704
|
+
required: ["start", "end"]
|
|
1705
|
+
},
|
|
1706
|
+
granularity: { type: "string", enum: ["day", "week", "month"] },
|
|
1707
|
+
periods: { type: "number" },
|
|
1708
|
+
retentionType: { type: "string", enum: ["classic", "rolling"] },
|
|
1709
|
+
cohortFilters: {},
|
|
1710
|
+
activityFilters: {},
|
|
1711
|
+
breakdownDimensions: { type: "array", items: { type: "string" } }
|
|
1712
|
+
},
|
|
1713
|
+
required: ["timeDimension", "bindingKey", "dateRange", "granularity", "periods"],
|
|
1714
|
+
description: "Retention analysis config. When provided, measures/dimensions are ignored."
|
|
1601
1715
|
}
|
|
1602
1716
|
}
|
|
1603
1717
|
}
|
|
@@ -1606,16 +1720,19 @@ function me() {
|
|
|
1606
1720
|
{
|
|
1607
1721
|
name: "add_portlet",
|
|
1608
1722
|
description: `Add a chart visualization to the notebook.
|
|
1609
|
-
` +
|
|
1723
|
+
` + me(N) + `
|
|
1610
1724
|
The query is validated before adding. The portlet fetches its own data.`,
|
|
1611
1725
|
input_schema: {
|
|
1612
1726
|
type: "object",
|
|
1613
1727
|
properties: {
|
|
1614
1728
|
title: { type: "string", description: "Title for the visualization" },
|
|
1615
|
-
query: {
|
|
1729
|
+
query: {
|
|
1730
|
+
type: "string",
|
|
1731
|
+
description: 'JSON string of the query. Standard: {"measures":[...],"dimensions":[...]}. Funnel: {"funnel":{"bindingKey":"...","timeDimension":"...","steps":[...]}}. Flow: {"flow":{"bindingKey":"...","timeDimension":"...","eventDimension":"...","startingStep":{...}}}. Retention: {"retention":{"timeDimension":"...","bindingKey":"...","dateRange":{"start":"...","end":"..."},"granularity":"...","periods":N}}.'
|
|
1732
|
+
},
|
|
1616
1733
|
chartType: {
|
|
1617
1734
|
type: "string",
|
|
1618
|
-
enum:
|
|
1735
|
+
enum: N,
|
|
1619
1736
|
description: "Chart type to render"
|
|
1620
1737
|
},
|
|
1621
1738
|
chartConfig: {
|
|
@@ -1659,29 +1776,31 @@ The query is validated before adding. The portlet fetches its own data.`,
|
|
|
1659
1776
|
}
|
|
1660
1777
|
];
|
|
1661
1778
|
}
|
|
1662
|
-
function ye(
|
|
1663
|
-
const { semanticLayer: t, securityContext:
|
|
1664
|
-
return
|
|
1665
|
-
const
|
|
1779
|
+
function ye(o) {
|
|
1780
|
+
const { semanticLayer: t, securityContext: i } = o, s = /* @__PURE__ */ new Map();
|
|
1781
|
+
return s.set("discover_cubes", async (e) => {
|
|
1782
|
+
const a = await z(t, {
|
|
1666
1783
|
topic: e.topic,
|
|
1667
1784
|
intent: e.intent,
|
|
1668
1785
|
limit: e.limit,
|
|
1669
1786
|
minScore: e.minScore
|
|
1670
1787
|
});
|
|
1671
|
-
return { result: JSON.stringify(
|
|
1672
|
-
}),
|
|
1788
|
+
return { result: JSON.stringify(a, null, 2) };
|
|
1789
|
+
}), s.set("get_cube_metadata", async () => {
|
|
1673
1790
|
const e = t.getMetadata();
|
|
1674
1791
|
return { result: JSON.stringify(e, null, 2) };
|
|
1675
|
-
}),
|
|
1792
|
+
}), s.set("execute_query", async (e) => {
|
|
1676
1793
|
try {
|
|
1677
|
-
|
|
1794
|
+
let a;
|
|
1795
|
+
e.funnel ? a = { funnel: e.funnel } : e.flow ? a = { flow: e.flow } : e.retention ? a = { retention: e.retention } : a = {
|
|
1678
1796
|
measures: e.measures,
|
|
1679
1797
|
dimensions: e.dimensions,
|
|
1680
1798
|
filters: e.filters,
|
|
1681
1799
|
timeDimensions: e.timeDimensions,
|
|
1682
1800
|
order: e.order,
|
|
1683
1801
|
limit: e.limit
|
|
1684
|
-
}
|
|
1802
|
+
};
|
|
1803
|
+
const n = await R(t, i, { query: a });
|
|
1685
1804
|
return {
|
|
1686
1805
|
result: JSON.stringify({
|
|
1687
1806
|
rowCount: n.data.length,
|
|
@@ -1689,75 +1808,82 @@ function ye(s) {
|
|
|
1689
1808
|
annotation: n.annotation
|
|
1690
1809
|
}, null, 2)
|
|
1691
1810
|
};
|
|
1692
|
-
} catch (
|
|
1811
|
+
} catch (a) {
|
|
1693
1812
|
return {
|
|
1694
|
-
result: `Query execution failed: ${
|
|
1813
|
+
result: `Query execution failed: ${a instanceof Error ? a.message : "Unknown error"}`,
|
|
1695
1814
|
isError: !0
|
|
1696
1815
|
};
|
|
1697
1816
|
}
|
|
1698
|
-
}),
|
|
1817
|
+
}), s.set("add_portlet", async (e) => {
|
|
1699
1818
|
const n = {
|
|
1700
1819
|
number: "kpiNumber",
|
|
1701
1820
|
retention: "retentionHeatmap"
|
|
1702
1821
|
}[e.chartType] ?? e.chartType;
|
|
1703
|
-
let
|
|
1822
|
+
let l;
|
|
1704
1823
|
try {
|
|
1705
|
-
|
|
1824
|
+
l = JSON.parse(e.query);
|
|
1706
1825
|
} catch {
|
|
1707
1826
|
return {
|
|
1708
1827
|
result: "Invalid query: could not parse JSON string. Ensure `query` is a valid JSON string.",
|
|
1709
1828
|
isError: !0
|
|
1710
1829
|
};
|
|
1711
1830
|
}
|
|
1712
|
-
const
|
|
1713
|
-
if (!
|
|
1831
|
+
const u = t.validateQuery(l);
|
|
1832
|
+
if (!u.isValid)
|
|
1714
1833
|
return {
|
|
1715
1834
|
result: `Invalid query — fix these errors and retry:
|
|
1716
|
-
${
|
|
1835
|
+
${u.errors.join(`
|
|
1717
1836
|
`)}`,
|
|
1718
1837
|
isError: !0
|
|
1719
1838
|
};
|
|
1720
|
-
const
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1839
|
+
const d = !!(l.funnel || l.flow || l.retention);
|
|
1840
|
+
let p;
|
|
1841
|
+
if (d)
|
|
1842
|
+
p = e.chartConfig ?? {};
|
|
1843
|
+
else {
|
|
1844
|
+
const c = ue(n, e.chartConfig, l), b = pe(n, c, l);
|
|
1845
|
+
if (!b.isValid)
|
|
1846
|
+
return {
|
|
1847
|
+
result: `Chart config invalid — fix these errors and retry:
|
|
1848
|
+
${b.errors.join(`
|
|
1725
1849
|
`)}`,
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1850
|
+
isError: !0
|
|
1851
|
+
};
|
|
1852
|
+
p = c;
|
|
1853
|
+
}
|
|
1854
|
+
const k = `portlet-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`, f = {
|
|
1855
|
+
id: k,
|
|
1730
1856
|
title: e.title,
|
|
1731
1857
|
query: e.query,
|
|
1732
1858
|
chartType: n,
|
|
1733
|
-
chartConfig:
|
|
1859
|
+
chartConfig: p,
|
|
1734
1860
|
displayConfig: e.displayConfig
|
|
1735
1861
|
};
|
|
1736
1862
|
return {
|
|
1737
|
-
result: `Portlet "${e.title}" added to notebook (id: ${
|
|
1738
|
-
sideEffect: { type: "add_portlet", data:
|
|
1863
|
+
result: `Portlet "${e.title}" added to notebook (id: ${k}, chart: ${n}). [Reminder: in your next response, start with a brief sentence about what you will do next BEFORE making any tool calls.]`,
|
|
1864
|
+
sideEffect: { type: "add_portlet", data: f }
|
|
1739
1865
|
};
|
|
1740
|
-
}),
|
|
1741
|
-
const
|
|
1742
|
-
id:
|
|
1866
|
+
}), s.set("add_markdown", async (e) => {
|
|
1867
|
+
const a = `markdown-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`, n = {
|
|
1868
|
+
id: a,
|
|
1743
1869
|
title: e.title,
|
|
1744
1870
|
content: e.content
|
|
1745
1871
|
};
|
|
1746
1872
|
return {
|
|
1747
|
-
result: `Markdown block added to notebook (id: ${
|
|
1873
|
+
result: `Markdown block added to notebook (id: ${a}). [Reminder: in your next response, start with a brief sentence about what you will do next BEFORE making any tool calls.]`,
|
|
1748
1874
|
sideEffect: { type: "add_markdown", data: n }
|
|
1749
1875
|
};
|
|
1750
|
-
}),
|
|
1876
|
+
}), s;
|
|
1751
1877
|
}
|
|
1752
|
-
async function* be(
|
|
1753
|
-
const { message: t, sessionId:
|
|
1754
|
-
let
|
|
1878
|
+
async function* be(o) {
|
|
1879
|
+
const { message: t, sessionId: i, semanticLayer: s, securityContext: e, agentConfig: a, apiKey: n } = o;
|
|
1880
|
+
let l;
|
|
1755
1881
|
try {
|
|
1756
|
-
const
|
|
1882
|
+
const m = await import(
|
|
1757
1883
|
/* webpackIgnore: true */
|
|
1758
1884
|
"@anthropic-ai/sdk"
|
|
1759
1885
|
);
|
|
1760
|
-
|
|
1886
|
+
l = m.default || m.Anthropic || m;
|
|
1761
1887
|
} catch {
|
|
1762
1888
|
yield {
|
|
1763
1889
|
type: "error",
|
|
@@ -1767,110 +1893,110 @@ async function* be(s) {
|
|
|
1767
1893
|
};
|
|
1768
1894
|
return;
|
|
1769
1895
|
}
|
|
1770
|
-
const
|
|
1896
|
+
const u = new l({ apiKey: n }), d = ce(), p = ye({ semanticLayer: s, securityContext: e }), k = s.getMetadata(), f = L(k), c = a.model || "claude-sonnet-4-6", b = a.maxTurns || 25, F = a.maxTokens || 4096, v = [
|
|
1771
1897
|
{ role: "user", content: t }
|
|
1772
1898
|
];
|
|
1773
1899
|
try {
|
|
1774
|
-
for (let
|
|
1775
|
-
const
|
|
1776
|
-
model:
|
|
1777
|
-
max_tokens:
|
|
1778
|
-
system:
|
|
1779
|
-
tools:
|
|
1780
|
-
messages:
|
|
1900
|
+
for (let m = 0; m < b; m++) {
|
|
1901
|
+
const C = await u.messages.create({
|
|
1902
|
+
model: c,
|
|
1903
|
+
max_tokens: F,
|
|
1904
|
+
system: f,
|
|
1905
|
+
tools: d,
|
|
1906
|
+
messages: v,
|
|
1781
1907
|
stream: !0
|
|
1782
|
-
}),
|
|
1783
|
-
let
|
|
1784
|
-
for await (const
|
|
1785
|
-
switch (
|
|
1908
|
+
}), y = [];
|
|
1909
|
+
let g = -1, w = "", _ = "";
|
|
1910
|
+
for await (const h of C)
|
|
1911
|
+
switch (h.type) {
|
|
1786
1912
|
case "content_block_start": {
|
|
1787
|
-
|
|
1788
|
-
const
|
|
1789
|
-
|
|
1913
|
+
g++;
|
|
1914
|
+
const r = h.content_block;
|
|
1915
|
+
r.type === "tool_use" ? (y.push({ type: "tool_use", id: r.id, name: r.name, input: {} }), w = "", yield {
|
|
1790
1916
|
type: "tool_use_start",
|
|
1791
|
-
data: { id:
|
|
1792
|
-
}) :
|
|
1917
|
+
data: { id: r.id, name: r.name, input: void 0 }
|
|
1918
|
+
}) : r.type === "text" && y.push({ type: "text", text: "" });
|
|
1793
1919
|
break;
|
|
1794
1920
|
}
|
|
1795
1921
|
case "content_block_delta": {
|
|
1796
|
-
const
|
|
1797
|
-
if (
|
|
1798
|
-
const
|
|
1799
|
-
|
|
1800
|
-
} else
|
|
1922
|
+
const r = h.delta;
|
|
1923
|
+
if (r.type === "text_delta" && r.text) {
|
|
1924
|
+
const A = y[g];
|
|
1925
|
+
A && (A.text = (A.text || "") + r.text), yield { type: "text_delta", data: r.text };
|
|
1926
|
+
} else r.type === "input_json_delta" && r.partial_json && (w += r.partial_json);
|
|
1801
1927
|
break;
|
|
1802
1928
|
}
|
|
1803
1929
|
case "content_block_stop": {
|
|
1804
|
-
const
|
|
1805
|
-
if (
|
|
1930
|
+
const r = y[g];
|
|
1931
|
+
if (r?.type === "tool_use" && w) {
|
|
1806
1932
|
try {
|
|
1807
|
-
|
|
1933
|
+
r.input = JSON.parse(w);
|
|
1808
1934
|
} catch {
|
|
1809
|
-
|
|
1935
|
+
r.input = {};
|
|
1810
1936
|
}
|
|
1811
|
-
|
|
1937
|
+
w = "";
|
|
1812
1938
|
}
|
|
1813
1939
|
break;
|
|
1814
1940
|
}
|
|
1815
1941
|
case "message_delta": {
|
|
1816
|
-
const
|
|
1817
|
-
|
|
1942
|
+
const r = h.delta;
|
|
1943
|
+
r.stop_reason && (_ = r.stop_reason);
|
|
1818
1944
|
break;
|
|
1819
1945
|
}
|
|
1820
1946
|
}
|
|
1821
|
-
if (
|
|
1947
|
+
if (v.push({ role: "assistant", content: y }), _ !== "tool_use")
|
|
1822
1948
|
break;
|
|
1823
1949
|
const D = [];
|
|
1824
|
-
for (const
|
|
1825
|
-
if (
|
|
1826
|
-
const
|
|
1950
|
+
for (const h of y) {
|
|
1951
|
+
if (h.type !== "tool_use") continue;
|
|
1952
|
+
const r = h.name, A = h.input || {}, T = h.id, I = p.get(r);
|
|
1827
1953
|
if (!I) {
|
|
1828
1954
|
D.push({
|
|
1829
1955
|
type: "tool_result",
|
|
1830
|
-
tool_use_id:
|
|
1831
|
-
content: `Unknown tool: ${
|
|
1956
|
+
tool_use_id: T,
|
|
1957
|
+
content: `Unknown tool: ${r}`,
|
|
1832
1958
|
is_error: !0
|
|
1833
1959
|
}), yield {
|
|
1834
1960
|
type: "tool_use_result",
|
|
1835
|
-
data: { id:
|
|
1961
|
+
data: { id: T, name: r, result: `Unknown tool: ${r}` }
|
|
1836
1962
|
};
|
|
1837
1963
|
continue;
|
|
1838
1964
|
}
|
|
1839
1965
|
try {
|
|
1840
|
-
const
|
|
1841
|
-
|
|
1966
|
+
const x = await I(A);
|
|
1967
|
+
x.sideEffect && (yield x.sideEffect), D.push({
|
|
1842
1968
|
type: "tool_result",
|
|
1843
|
-
tool_use_id:
|
|
1844
|
-
content:
|
|
1845
|
-
...
|
|
1969
|
+
tool_use_id: T,
|
|
1970
|
+
content: x.result,
|
|
1971
|
+
...x.isError ? { is_error: !0 } : {}
|
|
1846
1972
|
}), yield {
|
|
1847
1973
|
type: "tool_use_result",
|
|
1848
|
-
data: { id:
|
|
1974
|
+
data: { id: T, name: r, result: x.result }
|
|
1849
1975
|
};
|
|
1850
|
-
} catch (
|
|
1851
|
-
const
|
|
1976
|
+
} catch (x) {
|
|
1977
|
+
const E = x instanceof Error ? x.message : "Tool execution failed";
|
|
1852
1978
|
D.push({
|
|
1853
1979
|
type: "tool_result",
|
|
1854
|
-
tool_use_id:
|
|
1855
|
-
content:
|
|
1980
|
+
tool_use_id: T,
|
|
1981
|
+
content: E,
|
|
1856
1982
|
is_error: !0
|
|
1857
1983
|
}), yield {
|
|
1858
1984
|
type: "tool_use_result",
|
|
1859
|
-
data: { id:
|
|
1985
|
+
data: { id: T, name: r, result: E }
|
|
1860
1986
|
};
|
|
1861
1987
|
}
|
|
1862
1988
|
}
|
|
1863
|
-
yield { type: "turn_complete", data: {} },
|
|
1989
|
+
yield { type: "turn_complete", data: {} }, v.push({ role: "user", content: D });
|
|
1864
1990
|
}
|
|
1865
1991
|
yield {
|
|
1866
1992
|
type: "done",
|
|
1867
|
-
data: { sessionId:
|
|
1993
|
+
data: { sessionId: i || "" }
|
|
1868
1994
|
};
|
|
1869
|
-
} catch (
|
|
1995
|
+
} catch (m) {
|
|
1870
1996
|
yield {
|
|
1871
1997
|
type: "error",
|
|
1872
1998
|
data: {
|
|
1873
|
-
message:
|
|
1999
|
+
message: m instanceof Error ? m.message : "Agent execution failed"
|
|
1874
2000
|
}
|
|
1875
2001
|
};
|
|
1876
2002
|
}
|