drizzle-cube 0.4.8 → 0.4.9
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-CSHsefnC.js} +270 -185
- package/dist/adapters/{handler-BLcxTuwi.cjs → handler-Xe_2ItOo.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/chunks/{analysis-builder-Bov_gLsf.js → analysis-builder-DFt9p8tj.js} +137 -137
- package/dist/client/chunks/{analysis-builder-Bov_gLsf.js.map → analysis-builder-DFt9p8tj.js.map} +1 -1
- package/dist/client/chunks/{analysis-builder-shared-NBk6y0md.js → analysis-builder-shared-DOHV2W8A.js} +713 -787
- package/dist/client/chunks/analysis-builder-shared-DOHV2W8A.js.map +1 -0
- package/dist/client/chunks/{components-O0hh7ooo.js → components-8FAXo62Z.js} +1495 -1416
- package/dist/client/chunks/components-8FAXo62Z.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-bundle-stats.html +1 -1
- package/dist/server/index.cjs +13 -13
- package/dist/server/index.js +1775 -1690
- package/package.json +1 -1
- package/dist/client/chunks/analysis-builder-shared-NBk6y0md.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
|
|
4
|
-
if (
|
|
1
|
+
import { h as q, Q as N, j as P, D as Y } from "./mcp-transport-CU5g9bxj.js";
|
|
2
|
+
import { handleDiscover as z, handleLoad as M } from "./utils.js";
|
|
3
|
+
function R(r) {
|
|
4
|
+
if (r.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 r) {
|
|
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 a of i.measures) {
|
|
11
|
+
const e = a.description ? ` - ${a.description}` : "";
|
|
12
|
+
t.push(`- \`${i.name}.${a.name}\` (${a.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 a of i.dimensions) {
|
|
18
|
+
const e = a.description ? ` - ${a.description}` : "";
|
|
19
|
+
t.push(`- \`${i.name}.${a.name}\` (${a.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 a of i.relationships)
|
|
25
|
+
t.push(`- → \`${a.targetCube}\` (${a.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
|
|
33
|
-
return
|
|
32
|
+
function F(r) {
|
|
33
|
+
return r.messages.map((t) => t.content.text).join(`
|
|
34
34
|
|
|
35
35
|
`);
|
|
36
36
|
}
|
|
37
|
-
function
|
|
37
|
+
function L(r) {
|
|
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,50 +109,53 @@ 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`.',
|
|
112
113
|
"",
|
|
113
114
|
"## Analysis Mode Decision Tree",
|
|
114
115
|
"",
|
|
115
116
|
"The default mode is **query** (standard measures/dimensions). Switch to a special mode only when the user's question matches:",
|
|
116
117
|
"",
|
|
117
|
-
'- **Funnel mode** — "What is the conversion rate from step A → B → C?"
|
|
118
|
+
'- **Funnel mode** — "What is the conversion rate from step A → B → C?"',
|
|
118
119
|
" - Requires: an event-stream cube with `capabilities.funnel = true` from `discover_cubes`",
|
|
119
|
-
|
|
120
|
-
"
|
|
120
|
+
" - Execute: `execute_query` with `funnel` param:",
|
|
121
|
+
' `{ 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"] }}] }`',
|
|
122
|
+
' - Visualize: `add_portlet` with `chartType: "funnel"` and `query` as JSON string containing `{ "funnel": { ... } }`',
|
|
121
123
|
"",
|
|
122
|
-
'- **Flow mode** — "What paths do users take after signup?"
|
|
124
|
+
'- **Flow mode** — "What paths do users take after signup?"',
|
|
123
125
|
" - Requires: `capabilities.flow = true` from `discover_cubes`",
|
|
124
|
-
|
|
125
|
-
"
|
|
126
|
+
" - Execute: `execute_query` with `flow` param:",
|
|
127
|
+
' `{ bindingKey: "Events.userId", timeDimension: "Events.timestamp", eventDimension: "Events.eventName", startingStep: { name: "Signup", filter: { member: "Events.eventName", operator: "equals", values: ["signup"] }}, stepsBefore: 0, stepsAfter: 3 }`',
|
|
128
|
+
' - Visualize: `add_portlet` with `chartType: "sankey"` (or `"sunburst"`) and `query` as JSON string containing `{ "flow": { ... } }`',
|
|
126
129
|
"",
|
|
127
|
-
'- **Retention mode** — "What % of users come back after 7 days?"
|
|
130
|
+
'- **Retention mode** — "What % of users come back after 7 days?"',
|
|
128
131
|
" - Requires: `capabilities.retention = true` from `discover_cubes`",
|
|
129
|
-
|
|
130
|
-
"
|
|
132
|
+
" - Execute: `execute_query` with `retention` param:",
|
|
133
|
+
' `{ timeDimension: "Events.timestamp", bindingKey: "Events.userId", dateRange: { start: "2024-01-01", end: "2024-03-31" }, granularity: "week", periods: 8, retentionType: "classic" }`',
|
|
134
|
+
' - Visualize: `add_portlet` with `chartType: "retentionCombined"` (or `"retentionHeatmap"`) and `query` as JSON string containing `{ "retention": { ... } }`',
|
|
131
135
|
"",
|
|
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
|
|
136
|
+
"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
137
|
"",
|
|
134
138
|
"Event-stream cubes are marked in the Available Cubes section below with **Event Stream: Yes** and list their binding key and time dimension.",
|
|
135
139
|
"",
|
|
136
140
|
"---",
|
|
137
141
|
"",
|
|
138
|
-
|
|
142
|
+
F(q),
|
|
139
143
|
"",
|
|
140
144
|
"---",
|
|
141
145
|
"",
|
|
142
|
-
|
|
146
|
+
F(N),
|
|
143
147
|
"",
|
|
144
148
|
"---",
|
|
145
149
|
"",
|
|
146
|
-
|
|
150
|
+
F(P),
|
|
147
151
|
"",
|
|
148
152
|
"---",
|
|
149
153
|
"",
|
|
150
|
-
|
|
154
|
+
F(Y),
|
|
151
155
|
"",
|
|
152
156
|
"---",
|
|
153
157
|
"",
|
|
154
|
-
|
|
158
|
+
R(r)
|
|
155
159
|
].join(`
|
|
156
160
|
`);
|
|
157
161
|
}
|
|
@@ -410,7 +414,7 @@ const H = {
|
|
|
410
414
|
description: "Number formatting for values"
|
|
411
415
|
}
|
|
412
416
|
]
|
|
413
|
-
},
|
|
417
|
+
}, K = {
|
|
414
418
|
label: "Scatter Plot",
|
|
415
419
|
description: "Reveal correlations between variables",
|
|
416
420
|
useCase: "Best for identifying patterns, correlations, outliers, and relationships between two measures",
|
|
@@ -458,7 +462,7 @@ const H = {
|
|
|
458
462
|
description: "Number formatting for Y-axis"
|
|
459
463
|
}
|
|
460
464
|
]
|
|
461
|
-
},
|
|
465
|
+
}, G = {
|
|
462
466
|
label: "Bubble Chart",
|
|
463
467
|
description: "Compare three dimensions of data",
|
|
464
468
|
useCase: "Best for showing relationships between three variables (X, Y, and size), market analysis",
|
|
@@ -524,7 +528,7 @@ const H = {
|
|
|
524
528
|
description: "Number formatting for Y-axis and values"
|
|
525
529
|
}
|
|
526
530
|
]
|
|
527
|
-
},
|
|
531
|
+
}, Z = {
|
|
528
532
|
label: "Radar Chart",
|
|
529
533
|
description: "Compare multiple metrics across categories",
|
|
530
534
|
useCase: "Best for multivariate comparisons, performance metrics, strengths/weaknesses analysis",
|
|
@@ -563,7 +567,7 @@ const H = {
|
|
|
563
567
|
description: "Number formatting for values"
|
|
564
568
|
}
|
|
565
569
|
]
|
|
566
|
-
},
|
|
570
|
+
}, X = {
|
|
567
571
|
label: "Radial Bar Chart",
|
|
568
572
|
description: "Circular progress and KPI visualization",
|
|
569
573
|
useCase: "Best for showing progress toward goals, KPIs, or comparing percentages in a compact form",
|
|
@@ -595,7 +599,7 @@ const H = {
|
|
|
595
599
|
description: "Number formatting for values"
|
|
596
600
|
}
|
|
597
601
|
]
|
|
598
|
-
},
|
|
602
|
+
}, U = {
|
|
599
603
|
label: "TreeMap",
|
|
600
604
|
description: "Visualize hierarchical data with nested rectangles",
|
|
601
605
|
useCase: "Best for showing part-to-whole relationships in hierarchical data, disk usage, budget allocation",
|
|
@@ -637,7 +641,7 @@ const H = {
|
|
|
637
641
|
}
|
|
638
642
|
],
|
|
639
643
|
clickableElements: { cell: !0 }
|
|
640
|
-
},
|
|
644
|
+
}, W = {
|
|
641
645
|
label: "Data Table",
|
|
642
646
|
description: "Display detailed tabular data",
|
|
643
647
|
useCase: "Best for precise values, detailed analysis, sortable/filterable data exploration",
|
|
@@ -660,7 +664,7 @@ const H = {
|
|
|
660
664
|
description: "Number formatting for numeric values"
|
|
661
665
|
}
|
|
662
666
|
]
|
|
663
|
-
},
|
|
667
|
+
}, Q = {
|
|
664
668
|
label: "Activity Grid",
|
|
665
669
|
description: "GitHub-style activity grid showing temporal patterns across different time scales",
|
|
666
670
|
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 +698,12 @@ const H = {
|
|
|
694
698
|
description: "Automatically size blocks to fill portlet width and height while maintaining aspect ratio"
|
|
695
699
|
}
|
|
696
700
|
],
|
|
697
|
-
validate: (
|
|
698
|
-
const { dateField: t, valueField:
|
|
701
|
+
validate: (r) => {
|
|
702
|
+
const { dateField: t, valueField: i } = r;
|
|
699
703
|
return !t || Array.isArray(t) && t.length === 0 ? {
|
|
700
704
|
isValid: !1,
|
|
701
705
|
message: "Time dimension is required for activity grid"
|
|
702
|
-
} : !
|
|
706
|
+
} : !i || Array.isArray(i) && i.length === 0 ? {
|
|
703
707
|
isValid: !1,
|
|
704
708
|
message: "Activity measure is required for intensity mapping"
|
|
705
709
|
} : { isValid: !0 };
|
|
@@ -863,7 +867,7 @@ const H = {
|
|
|
863
867
|
}
|
|
864
868
|
],
|
|
865
869
|
displayOptions: ["hideHeader"],
|
|
866
|
-
validate: (
|
|
870
|
+
validate: (r) => !r.yAxis || Array.isArray(r.yAxis) && r.yAxis.length === 0 ? {
|
|
867
871
|
isValid: !1,
|
|
868
872
|
message: "A measure is required for KPI Delta charts"
|
|
869
873
|
} : { isValid: !0 }
|
|
@@ -909,7 +913,7 @@ const H = {
|
|
|
909
913
|
}
|
|
910
914
|
],
|
|
911
915
|
displayOptions: ["hideHeader"]
|
|
912
|
-
},
|
|
916
|
+
}, ie = {
|
|
913
917
|
label: "Markdown",
|
|
914
918
|
description: "Display custom markdown content with formatting",
|
|
915
919
|
useCase: "Perfect for adding documentation, notes, section headers, instructions, or formatted text to dashboards",
|
|
@@ -1001,7 +1005,7 @@ Use --- for horizontal rules.`,
|
|
|
1001
1005
|
description: "Add an accent-colored border on one side of the content"
|
|
1002
1006
|
}
|
|
1003
1007
|
]
|
|
1004
|
-
},
|
|
1008
|
+
}, ae = {
|
|
1005
1009
|
label: "Funnel Chart",
|
|
1006
1010
|
description: "Show conversion through sequential steps",
|
|
1007
1011
|
useCase: "Best for visualizing user journey funnels, sales pipelines, or multi-step processes",
|
|
@@ -1088,7 +1092,7 @@ Use --- for horizontal rules.`,
|
|
|
1088
1092
|
description: "Display 90th percentile time to convert"
|
|
1089
1093
|
}
|
|
1090
1094
|
]
|
|
1091
|
-
},
|
|
1095
|
+
}, se = {
|
|
1092
1096
|
label: "Sankey Chart",
|
|
1093
1097
|
description: "Show flow between states or steps",
|
|
1094
1098
|
useCase: "Best for visualizing user journey flows, path analysis, or state transitions",
|
|
@@ -1144,7 +1148,7 @@ Use --- for horizontal rules.`,
|
|
|
1144
1148
|
description: "Hide the statistics footer below the chart"
|
|
1145
1149
|
}
|
|
1146
1150
|
]
|
|
1147
|
-
},
|
|
1151
|
+
}, oe = {
|
|
1148
1152
|
label: "Sunburst Chart",
|
|
1149
1153
|
description: "Show hierarchical flow as radial rings",
|
|
1150
1154
|
useCase: "Best for visualizing forward paths from a starting event in a compact radial layout",
|
|
@@ -1260,7 +1264,7 @@ Use --- for horizontal rules.`,
|
|
|
1260
1264
|
description: "Number formatting for cell values and legend"
|
|
1261
1265
|
}
|
|
1262
1266
|
],
|
|
1263
|
-
validate: (
|
|
1267
|
+
validate: (r) => r.xAxis?.length ? r.yAxis?.length ? r.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
1268
|
}, ne = {
|
|
1265
1269
|
label: "Retention Matrix",
|
|
1266
1270
|
// RetentionHeatmap auto-configures from the retention data structure
|
|
@@ -1413,98 +1417,98 @@ Use --- for horizontal rules.`,
|
|
|
1413
1417
|
line: $,
|
|
1414
1418
|
area: B,
|
|
1415
1419
|
pie: j,
|
|
1416
|
-
scatter:
|
|
1417
|
-
bubble:
|
|
1418
|
-
radar:
|
|
1419
|
-
radialBar:
|
|
1420
|
-
treemap:
|
|
1421
|
-
table:
|
|
1422
|
-
activityGrid:
|
|
1420
|
+
scatter: K,
|
|
1421
|
+
bubble: G,
|
|
1422
|
+
radar: Z,
|
|
1423
|
+
radialBar: X,
|
|
1424
|
+
treemap: U,
|
|
1425
|
+
table: W,
|
|
1426
|
+
activityGrid: Q,
|
|
1423
1427
|
kpiNumber: J,
|
|
1424
1428
|
kpiDelta: ee,
|
|
1425
1429
|
kpiText: te,
|
|
1426
|
-
markdown:
|
|
1427
|
-
funnel:
|
|
1428
|
-
sankey:
|
|
1429
|
-
sunburst:
|
|
1430
|
+
markdown: ie,
|
|
1431
|
+
funnel: ae,
|
|
1432
|
+
sankey: se,
|
|
1433
|
+
sunburst: oe,
|
|
1430
1434
|
heatmap: re,
|
|
1431
1435
|
retentionHeatmap: ne,
|
|
1432
1436
|
retentionCombined: le,
|
|
1433
1437
|
boxPlot: de
|
|
1434
1438
|
};
|
|
1435
|
-
function pe(
|
|
1436
|
-
const
|
|
1437
|
-
if (!
|
|
1439
|
+
function pe(r, t, i) {
|
|
1440
|
+
const a = V[r];
|
|
1441
|
+
if (!a)
|
|
1438
1442
|
return { isValid: !0, errors: [] };
|
|
1439
|
-
if (
|
|
1443
|
+
if (a.skipQuery)
|
|
1440
1444
|
return { isValid: !0, errors: [] };
|
|
1441
1445
|
const e = [];
|
|
1442
|
-
for (const
|
|
1443
|
-
if (!
|
|
1444
|
-
const n = t?.[
|
|
1446
|
+
for (const s of a.dropZones) {
|
|
1447
|
+
if (!s.mandatory) continue;
|
|
1448
|
+
const n = t?.[s.key];
|
|
1445
1449
|
if (!(Array.isArray(n) ? n.length > 0 : !!n)) {
|
|
1446
|
-
const
|
|
1450
|
+
const m = s.acceptTypes?.join("/") ?? "fields";
|
|
1447
1451
|
e.push(
|
|
1448
|
-
`chartConfig.${
|
|
1452
|
+
`chartConfig.${s.key} is required for ${r} chart (${s.label}). Accepts: ${m}.`
|
|
1449
1453
|
);
|
|
1450
1454
|
}
|
|
1451
1455
|
}
|
|
1452
1456
|
return { isValid: e.length === 0, errors: e };
|
|
1453
1457
|
}
|
|
1454
|
-
function ue(
|
|
1455
|
-
const
|
|
1456
|
-
if (!
|
|
1458
|
+
function ue(r, t, i) {
|
|
1459
|
+
const a = V[r];
|
|
1460
|
+
if (!a)
|
|
1457
1461
|
return t ?? {};
|
|
1458
|
-
const e = { ...t },
|
|
1459
|
-
for (const l of
|
|
1462
|
+
const e = { ...t }, s = i.measures ?? [], n = i.dimensions ?? [], m = (i.timeDimensions ?? []).map((l) => l.dimension);
|
|
1463
|
+
for (const l of a.dropZones) {
|
|
1460
1464
|
const d = e[l.key];
|
|
1461
1465
|
if (Array.isArray(d) ? d.length > 0 : !!d) continue;
|
|
1462
1466
|
const y = l.acceptTypes ?? [];
|
|
1463
1467
|
if (l.key === "sizeField" || l.key === "colorField") {
|
|
1464
1468
|
if (y.includes("measure")) {
|
|
1465
1469
|
const x = /* @__PURE__ */ new Set();
|
|
1466
|
-
for (const
|
|
1467
|
-
if (
|
|
1468
|
-
const
|
|
1469
|
-
Array.isArray(
|
|
1470
|
+
for (const w of a.dropZones) {
|
|
1471
|
+
if (w.key === l.key) continue;
|
|
1472
|
+
const c = e[w.key];
|
|
1473
|
+
Array.isArray(c) ? c.forEach((C) => x.add(C)) : typeof c == "string" && x.add(c);
|
|
1470
1474
|
}
|
|
1471
|
-
const u =
|
|
1475
|
+
const u = s.filter((w) => !x.has(w));
|
|
1472
1476
|
u.length > 0 && (e[l.key] = u[0]);
|
|
1473
1477
|
}
|
|
1474
1478
|
continue;
|
|
1475
1479
|
}
|
|
1476
|
-
const
|
|
1477
|
-
if (y.includes("dimension") &&
|
|
1478
|
-
const
|
|
1479
|
-
|
|
1480
|
+
const f = [];
|
|
1481
|
+
if (y.includes("dimension") && f.push(...n), y.includes("timeDimension") && f.push(...m), y.includes("measure") && f.push(...s), f.length === 0) continue;
|
|
1482
|
+
const k = l.maxItems ?? 1 / 0, D = f.slice(0, k);
|
|
1483
|
+
D.length > 0 && (e[l.key] = D);
|
|
1480
1484
|
}
|
|
1481
1485
|
return e;
|
|
1482
1486
|
}
|
|
1483
|
-
function
|
|
1487
|
+
function me(r) {
|
|
1484
1488
|
const t = [`
|
|
1485
1489
|
Chart config requirements by type:`];
|
|
1486
|
-
for (const
|
|
1487
|
-
const
|
|
1488
|
-
if (!
|
|
1489
|
-
const e =
|
|
1490
|
-
if (
|
|
1491
|
-
t.push(` ${
|
|
1490
|
+
for (const i of r) {
|
|
1491
|
+
const a = V[i];
|
|
1492
|
+
if (!a) continue;
|
|
1493
|
+
const e = a.description ?? "", s = a.useCase ?? "", n = [e, s].filter(Boolean).join(". "), p = n ? ` — ${n}.` : "", m = a.dropZones.filter((d) => d.mandatory);
|
|
1494
|
+
if (m.length === 0 && !a.skipQuery) {
|
|
1495
|
+
t.push(` ${i}${p} chartConfig auto-inferred from query.`);
|
|
1492
1496
|
continue;
|
|
1493
1497
|
}
|
|
1494
|
-
if (
|
|
1495
|
-
t.push(` ${
|
|
1498
|
+
if (a.skipQuery) {
|
|
1499
|
+
t.push(` ${i}${p} No query needed.`);
|
|
1496
1500
|
continue;
|
|
1497
1501
|
}
|
|
1498
|
-
const l =
|
|
1499
|
-
const
|
|
1500
|
-
return `${d.key}=[${
|
|
1502
|
+
const l = m.map((d) => {
|
|
1503
|
+
const g = d.acceptTypes?.join("/") ?? "any", y = d.maxItems ? ` (max ${d.maxItems})` : "";
|
|
1504
|
+
return `${d.key}=[${g}]${y}`;
|
|
1501
1505
|
});
|
|
1502
|
-
t.push(` ${
|
|
1506
|
+
t.push(` ${i}${p} Requires ${l.join(", ")}.`);
|
|
1503
1507
|
}
|
|
1504
1508
|
return t.join(`
|
|
1505
1509
|
`);
|
|
1506
1510
|
}
|
|
1507
|
-
const
|
|
1511
|
+
const O = [
|
|
1508
1512
|
"bar",
|
|
1509
1513
|
"line",
|
|
1510
1514
|
"area",
|
|
@@ -1523,7 +1527,7 @@ const P = [
|
|
|
1523
1527
|
"retentionCombined",
|
|
1524
1528
|
"boxPlot"
|
|
1525
1529
|
];
|
|
1526
|
-
function
|
|
1530
|
+
function ce() {
|
|
1527
1531
|
return [
|
|
1528
1532
|
// Tool 1: discover_cubes
|
|
1529
1533
|
{
|
|
@@ -1551,7 +1555,7 @@ function me() {
|
|
|
1551
1555
|
// Tool 3: execute_query
|
|
1552
1556
|
{
|
|
1553
1557
|
name: "execute_query",
|
|
1554
|
-
description: "Execute a semantic query and return data results.
|
|
1558
|
+
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
1559
|
input_schema: {
|
|
1556
1560
|
type: "object",
|
|
1557
1561
|
properties: {
|
|
@@ -1598,6 +1602,75 @@ function me() {
|
|
|
1598
1602
|
limit: {
|
|
1599
1603
|
type: "number",
|
|
1600
1604
|
description: "Row limit"
|
|
1605
|
+
},
|
|
1606
|
+
funnel: {
|
|
1607
|
+
type: "object",
|
|
1608
|
+
properties: {
|
|
1609
|
+
bindingKey: { type: "string", description: 'Entity binding key (e.g., "Events.userId")' },
|
|
1610
|
+
timeDimension: { type: "string", description: 'Time dimension (e.g., "Events.timestamp")' },
|
|
1611
|
+
steps: {
|
|
1612
|
+
type: "array",
|
|
1613
|
+
items: {
|
|
1614
|
+
type: "object",
|
|
1615
|
+
properties: {
|
|
1616
|
+
name: { type: "string" },
|
|
1617
|
+
filter: {},
|
|
1618
|
+
timeToConvert: { type: "string", description: 'ISO 8601 duration (e.g., "P7D")' }
|
|
1619
|
+
},
|
|
1620
|
+
required: ["name"]
|
|
1621
|
+
},
|
|
1622
|
+
description: "Funnel steps (min 2)"
|
|
1623
|
+
},
|
|
1624
|
+
includeTimeMetrics: { type: "boolean" },
|
|
1625
|
+
globalTimeWindow: { type: "string" }
|
|
1626
|
+
},
|
|
1627
|
+
required: ["bindingKey", "timeDimension", "steps"],
|
|
1628
|
+
description: "Funnel analysis config. When provided, measures/dimensions are ignored."
|
|
1629
|
+
},
|
|
1630
|
+
flow: {
|
|
1631
|
+
type: "object",
|
|
1632
|
+
properties: {
|
|
1633
|
+
bindingKey: { type: "string" },
|
|
1634
|
+
timeDimension: { type: "string" },
|
|
1635
|
+
eventDimension: { type: "string", description: "Dimension whose values become node labels" },
|
|
1636
|
+
startingStep: {
|
|
1637
|
+
type: "object",
|
|
1638
|
+
properties: {
|
|
1639
|
+
name: { type: "string" },
|
|
1640
|
+
filter: {}
|
|
1641
|
+
},
|
|
1642
|
+
required: ["name"]
|
|
1643
|
+
},
|
|
1644
|
+
stepsBefore: { type: "number", description: "Steps before starting step (0-5)" },
|
|
1645
|
+
stepsAfter: { type: "number", description: "Steps after starting step (0-5)" },
|
|
1646
|
+
entityLimit: { type: "number" },
|
|
1647
|
+
outputMode: { type: "string", enum: ["sankey", "sunburst"] }
|
|
1648
|
+
},
|
|
1649
|
+
required: ["bindingKey", "timeDimension", "eventDimension", "startingStep"],
|
|
1650
|
+
description: "Flow analysis config. When provided, measures/dimensions are ignored."
|
|
1651
|
+
},
|
|
1652
|
+
retention: {
|
|
1653
|
+
type: "object",
|
|
1654
|
+
properties: {
|
|
1655
|
+
timeDimension: { type: "string" },
|
|
1656
|
+
bindingKey: { type: "string" },
|
|
1657
|
+
dateRange: {
|
|
1658
|
+
type: "object",
|
|
1659
|
+
properties: {
|
|
1660
|
+
start: { type: "string", description: "YYYY-MM-DD" },
|
|
1661
|
+
end: { type: "string", description: "YYYY-MM-DD" }
|
|
1662
|
+
},
|
|
1663
|
+
required: ["start", "end"]
|
|
1664
|
+
},
|
|
1665
|
+
granularity: { type: "string", enum: ["day", "week", "month"] },
|
|
1666
|
+
periods: { type: "number" },
|
|
1667
|
+
retentionType: { type: "string", enum: ["classic", "rolling"] },
|
|
1668
|
+
cohortFilters: {},
|
|
1669
|
+
activityFilters: {},
|
|
1670
|
+
breakdownDimensions: { type: "array", items: { type: "string" } }
|
|
1671
|
+
},
|
|
1672
|
+
required: ["timeDimension", "bindingKey", "dateRange", "granularity", "periods"],
|
|
1673
|
+
description: "Retention analysis config. When provided, measures/dimensions are ignored."
|
|
1601
1674
|
}
|
|
1602
1675
|
}
|
|
1603
1676
|
}
|
|
@@ -1606,16 +1679,19 @@ function me() {
|
|
|
1606
1679
|
{
|
|
1607
1680
|
name: "add_portlet",
|
|
1608
1681
|
description: `Add a chart visualization to the notebook.
|
|
1609
|
-
` +
|
|
1682
|
+
` + me(O) + `
|
|
1610
1683
|
The query is validated before adding. The portlet fetches its own data.`,
|
|
1611
1684
|
input_schema: {
|
|
1612
1685
|
type: "object",
|
|
1613
1686
|
properties: {
|
|
1614
1687
|
title: { type: "string", description: "Title for the visualization" },
|
|
1615
|
-
query: {
|
|
1688
|
+
query: {
|
|
1689
|
+
type: "string",
|
|
1690
|
+
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}}.'
|
|
1691
|
+
},
|
|
1616
1692
|
chartType: {
|
|
1617
1693
|
type: "string",
|
|
1618
|
-
enum:
|
|
1694
|
+
enum: O,
|
|
1619
1695
|
description: "Chart type to render"
|
|
1620
1696
|
},
|
|
1621
1697
|
chartConfig: {
|
|
@@ -1659,29 +1735,31 @@ The query is validated before adding. The portlet fetches its own data.`,
|
|
|
1659
1735
|
}
|
|
1660
1736
|
];
|
|
1661
1737
|
}
|
|
1662
|
-
function ye(
|
|
1663
|
-
const { semanticLayer: t, securityContext:
|
|
1664
|
-
return
|
|
1665
|
-
const
|
|
1738
|
+
function ye(r) {
|
|
1739
|
+
const { semanticLayer: t, securityContext: i } = r, a = /* @__PURE__ */ new Map();
|
|
1740
|
+
return a.set("discover_cubes", async (e) => {
|
|
1741
|
+
const s = await z(t, {
|
|
1666
1742
|
topic: e.topic,
|
|
1667
1743
|
intent: e.intent,
|
|
1668
1744
|
limit: e.limit,
|
|
1669
1745
|
minScore: e.minScore
|
|
1670
1746
|
});
|
|
1671
|
-
return { result: JSON.stringify(
|
|
1672
|
-
}),
|
|
1747
|
+
return { result: JSON.stringify(s, null, 2) };
|
|
1748
|
+
}), a.set("get_cube_metadata", async () => {
|
|
1673
1749
|
const e = t.getMetadata();
|
|
1674
1750
|
return { result: JSON.stringify(e, null, 2) };
|
|
1675
|
-
}),
|
|
1751
|
+
}), a.set("execute_query", async (e) => {
|
|
1676
1752
|
try {
|
|
1677
|
-
|
|
1753
|
+
let s;
|
|
1754
|
+
e.funnel ? s = { funnel: e.funnel } : e.flow ? s = { flow: e.flow } : e.retention ? s = { retention: e.retention } : s = {
|
|
1678
1755
|
measures: e.measures,
|
|
1679
1756
|
dimensions: e.dimensions,
|
|
1680
1757
|
filters: e.filters,
|
|
1681
1758
|
timeDimensions: e.timeDimensions,
|
|
1682
1759
|
order: e.order,
|
|
1683
1760
|
limit: e.limit
|
|
1684
|
-
}
|
|
1761
|
+
};
|
|
1762
|
+
const n = await M(t, i, { query: s });
|
|
1685
1763
|
return {
|
|
1686
1764
|
result: JSON.stringify({
|
|
1687
1765
|
rowCount: n.data.length,
|
|
@@ -1689,13 +1767,13 @@ function ye(s) {
|
|
|
1689
1767
|
annotation: n.annotation
|
|
1690
1768
|
}, null, 2)
|
|
1691
1769
|
};
|
|
1692
|
-
} catch (
|
|
1770
|
+
} catch (s) {
|
|
1693
1771
|
return {
|
|
1694
|
-
result: `Query execution failed: ${
|
|
1772
|
+
result: `Query execution failed: ${s instanceof Error ? s.message : "Unknown error"}`,
|
|
1695
1773
|
isError: !0
|
|
1696
1774
|
};
|
|
1697
1775
|
}
|
|
1698
|
-
}),
|
|
1776
|
+
}), a.set("add_portlet", async (e) => {
|
|
1699
1777
|
const n = {
|
|
1700
1778
|
number: "kpiNumber",
|
|
1701
1779
|
retention: "retentionHeatmap"
|
|
@@ -1709,48 +1787,55 @@ function ye(s) {
|
|
|
1709
1787
|
isError: !0
|
|
1710
1788
|
};
|
|
1711
1789
|
}
|
|
1712
|
-
const
|
|
1713
|
-
if (!
|
|
1790
|
+
const m = t.validateQuery(p);
|
|
1791
|
+
if (!m.isValid)
|
|
1714
1792
|
return {
|
|
1715
1793
|
result: `Invalid query — fix these errors and retry:
|
|
1716
|
-
${
|
|
1794
|
+
${m.errors.join(`
|
|
1717
1795
|
`)}`,
|
|
1718
1796
|
isError: !0
|
|
1719
1797
|
};
|
|
1720
|
-
const l =
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1798
|
+
const l = !!(p.funnel || p.flow || p.retention);
|
|
1799
|
+
let d;
|
|
1800
|
+
if (l)
|
|
1801
|
+
d = e.chartConfig ?? {};
|
|
1802
|
+
else {
|
|
1803
|
+
const f = ue(n, e.chartConfig, p), k = pe(n, f);
|
|
1804
|
+
if (!k.isValid)
|
|
1805
|
+
return {
|
|
1806
|
+
result: `Chart config invalid — fix these errors and retry:
|
|
1807
|
+
${k.errors.join(`
|
|
1725
1808
|
`)}`,
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1809
|
+
isError: !0
|
|
1810
|
+
};
|
|
1811
|
+
d = f;
|
|
1812
|
+
}
|
|
1813
|
+
const g = `portlet-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`, y = {
|
|
1814
|
+
id: g,
|
|
1730
1815
|
title: e.title,
|
|
1731
1816
|
query: e.query,
|
|
1732
1817
|
chartType: n,
|
|
1733
|
-
chartConfig:
|
|
1818
|
+
chartConfig: d,
|
|
1734
1819
|
displayConfig: e.displayConfig
|
|
1735
1820
|
};
|
|
1736
1821
|
return {
|
|
1737
|
-
result: `Portlet "${e.title}" added to notebook (id: ${
|
|
1822
|
+
result: `Portlet "${e.title}" added to notebook (id: ${g}, chart: ${n}). [Reminder: in your next response, start with a brief sentence about what you will do next BEFORE making any tool calls.]`,
|
|
1738
1823
|
sideEffect: { type: "add_portlet", data: y }
|
|
1739
1824
|
};
|
|
1740
|
-
}),
|
|
1741
|
-
const
|
|
1742
|
-
id:
|
|
1825
|
+
}), a.set("add_markdown", async (e) => {
|
|
1826
|
+
const s = `markdown-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`, n = {
|
|
1827
|
+
id: s,
|
|
1743
1828
|
title: e.title,
|
|
1744
1829
|
content: e.content
|
|
1745
1830
|
};
|
|
1746
1831
|
return {
|
|
1747
|
-
result: `Markdown block added to notebook (id: ${
|
|
1832
|
+
result: `Markdown block added to notebook (id: ${s}). [Reminder: in your next response, start with a brief sentence about what you will do next BEFORE making any tool calls.]`,
|
|
1748
1833
|
sideEffect: { type: "add_markdown", data: n }
|
|
1749
1834
|
};
|
|
1750
|
-
}),
|
|
1835
|
+
}), a;
|
|
1751
1836
|
}
|
|
1752
|
-
async function* be(
|
|
1753
|
-
const { message: t, sessionId:
|
|
1837
|
+
async function* be(r) {
|
|
1838
|
+
const { message: t, sessionId: i, semanticLayer: a, securityContext: e, agentConfig: s, apiKey: n } = r;
|
|
1754
1839
|
let p;
|
|
1755
1840
|
try {
|
|
1756
1841
|
const u = await import(
|
|
@@ -1767,104 +1852,104 @@ async function* be(s) {
|
|
|
1767
1852
|
};
|
|
1768
1853
|
return;
|
|
1769
1854
|
}
|
|
1770
|
-
const
|
|
1855
|
+
const m = new p({ apiKey: n }), l = ce(), d = ye({ semanticLayer: a, securityContext: e }), g = a.getMetadata(), y = L(g), f = s.model || "claude-sonnet-4-6", k = s.maxTurns || 25, D = s.maxTokens || 4096, x = [
|
|
1771
1856
|
{ role: "user", content: t }
|
|
1772
1857
|
];
|
|
1773
1858
|
try {
|
|
1774
|
-
for (let u = 0; u <
|
|
1775
|
-
const
|
|
1776
|
-
model:
|
|
1777
|
-
max_tokens:
|
|
1859
|
+
for (let u = 0; u < k; u++) {
|
|
1860
|
+
const w = await m.messages.create({
|
|
1861
|
+
model: f,
|
|
1862
|
+
max_tokens: D,
|
|
1778
1863
|
system: y,
|
|
1779
1864
|
tools: l,
|
|
1780
1865
|
messages: x,
|
|
1781
1866
|
stream: !0
|
|
1782
|
-
}),
|
|
1783
|
-
let
|
|
1784
|
-
for await (const
|
|
1785
|
-
switch (
|
|
1867
|
+
}), c = [];
|
|
1868
|
+
let C = -1, T = "", _ = "";
|
|
1869
|
+
for await (const h of w)
|
|
1870
|
+
switch (h.type) {
|
|
1786
1871
|
case "content_block_start": {
|
|
1787
|
-
|
|
1788
|
-
const o =
|
|
1789
|
-
o.type === "tool_use" ? (
|
|
1872
|
+
C++;
|
|
1873
|
+
const o = h.content_block;
|
|
1874
|
+
o.type === "tool_use" ? (c.push({ type: "tool_use", id: o.id, name: o.name, input: {} }), T = "", yield {
|
|
1790
1875
|
type: "tool_use_start",
|
|
1791
1876
|
data: { id: o.id, name: o.name, input: void 0 }
|
|
1792
|
-
}) : o.type === "text" &&
|
|
1877
|
+
}) : o.type === "text" && c.push({ type: "text", text: "" });
|
|
1793
1878
|
break;
|
|
1794
1879
|
}
|
|
1795
1880
|
case "content_block_delta": {
|
|
1796
|
-
const o =
|
|
1881
|
+
const o = h.delta;
|
|
1797
1882
|
if (o.type === "text_delta" && o.text) {
|
|
1798
|
-
const
|
|
1799
|
-
|
|
1800
|
-
} else o.type === "input_json_delta" && o.partial_json && (
|
|
1883
|
+
const A = c[C];
|
|
1884
|
+
A && (A.text = (A.text || "") + o.text), yield { type: "text_delta", data: o.text };
|
|
1885
|
+
} else o.type === "input_json_delta" && o.partial_json && (T += o.partial_json);
|
|
1801
1886
|
break;
|
|
1802
1887
|
}
|
|
1803
1888
|
case "content_block_stop": {
|
|
1804
|
-
const o =
|
|
1805
|
-
if (o?.type === "tool_use" &&
|
|
1889
|
+
const o = c[C];
|
|
1890
|
+
if (o?.type === "tool_use" && T) {
|
|
1806
1891
|
try {
|
|
1807
|
-
o.input = JSON.parse(
|
|
1892
|
+
o.input = JSON.parse(T);
|
|
1808
1893
|
} catch {
|
|
1809
1894
|
o.input = {};
|
|
1810
1895
|
}
|
|
1811
|
-
|
|
1896
|
+
T = "";
|
|
1812
1897
|
}
|
|
1813
1898
|
break;
|
|
1814
1899
|
}
|
|
1815
1900
|
case "message_delta": {
|
|
1816
|
-
const o =
|
|
1901
|
+
const o = h.delta;
|
|
1817
1902
|
o.stop_reason && (_ = o.stop_reason);
|
|
1818
1903
|
break;
|
|
1819
1904
|
}
|
|
1820
1905
|
}
|
|
1821
|
-
if (x.push({ role: "assistant", content:
|
|
1906
|
+
if (x.push({ role: "assistant", content: c }), _ !== "tool_use")
|
|
1822
1907
|
break;
|
|
1823
|
-
const
|
|
1824
|
-
for (const
|
|
1825
|
-
if (
|
|
1826
|
-
const o =
|
|
1908
|
+
const S = [];
|
|
1909
|
+
for (const h of c) {
|
|
1910
|
+
if (h.type !== "tool_use") continue;
|
|
1911
|
+
const o = h.name, A = h.input || {}, v = h.id, I = d.get(o);
|
|
1827
1912
|
if (!I) {
|
|
1828
|
-
|
|
1913
|
+
S.push({
|
|
1829
1914
|
type: "tool_result",
|
|
1830
|
-
tool_use_id:
|
|
1915
|
+
tool_use_id: v,
|
|
1831
1916
|
content: `Unknown tool: ${o}`,
|
|
1832
1917
|
is_error: !0
|
|
1833
1918
|
}), yield {
|
|
1834
1919
|
type: "tool_use_result",
|
|
1835
|
-
data: { id:
|
|
1920
|
+
data: { id: v, name: o, result: `Unknown tool: ${o}` }
|
|
1836
1921
|
};
|
|
1837
1922
|
continue;
|
|
1838
1923
|
}
|
|
1839
1924
|
try {
|
|
1840
|
-
const
|
|
1841
|
-
|
|
1925
|
+
const b = await I(A);
|
|
1926
|
+
b.sideEffect && (yield b.sideEffect), S.push({
|
|
1842
1927
|
type: "tool_result",
|
|
1843
|
-
tool_use_id:
|
|
1844
|
-
content:
|
|
1845
|
-
...
|
|
1928
|
+
tool_use_id: v,
|
|
1929
|
+
content: b.result,
|
|
1930
|
+
...b.isError ? { is_error: !0 } : {}
|
|
1846
1931
|
}), yield {
|
|
1847
1932
|
type: "tool_use_result",
|
|
1848
|
-
data: { id:
|
|
1933
|
+
data: { id: v, name: o, result: b.result }
|
|
1849
1934
|
};
|
|
1850
|
-
} catch (
|
|
1851
|
-
const
|
|
1852
|
-
|
|
1935
|
+
} catch (b) {
|
|
1936
|
+
const E = b instanceof Error ? b.message : "Tool execution failed";
|
|
1937
|
+
S.push({
|
|
1853
1938
|
type: "tool_result",
|
|
1854
|
-
tool_use_id:
|
|
1855
|
-
content:
|
|
1939
|
+
tool_use_id: v,
|
|
1940
|
+
content: E,
|
|
1856
1941
|
is_error: !0
|
|
1857
1942
|
}), yield {
|
|
1858
1943
|
type: "tool_use_result",
|
|
1859
|
-
data: { id:
|
|
1944
|
+
data: { id: v, name: o, result: E }
|
|
1860
1945
|
};
|
|
1861
1946
|
}
|
|
1862
1947
|
}
|
|
1863
|
-
yield { type: "turn_complete", data: {} }, x.push({ role: "user", content:
|
|
1948
|
+
yield { type: "turn_complete", data: {} }, x.push({ role: "user", content: S });
|
|
1864
1949
|
}
|
|
1865
1950
|
yield {
|
|
1866
1951
|
type: "done",
|
|
1867
|
-
data: { sessionId:
|
|
1952
|
+
data: { sessionId: i || "" }
|
|
1868
1953
|
};
|
|
1869
1954
|
} catch (u) {
|
|
1870
1955
|
yield {
|