drizzle-cube 0.4.47 → 0.4.49
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/{compiler-O3T1u7jl.js → compiler-BXfrvebp.js} +4 -3
- package/dist/adapters/{compiler-CA6iopu7.cjs → compiler-CPE-YZfe.cjs} +2 -2
- package/dist/adapters/express/index.cjs +1 -1
- package/dist/adapters/express/index.js +4 -4
- package/dist/adapters/fastify/index.cjs +1 -1
- package/dist/adapters/fastify/index.js +39 -39
- package/dist/adapters/{handler-BO2nq6IS.cjs → handler-DumFgnNM.cjs} +10 -10
- package/dist/adapters/{handler-CjVc3ytc.js → handler-RItnSaEl.js} +128 -350
- package/dist/adapters/hono/index.cjs +1 -1
- package/dist/adapters/hono/index.js +4 -4
- package/dist/adapters/mcp-prompts-BUFyQLHQ.js +377 -0
- package/dist/adapters/mcp-prompts-B_NvEJT_.cjs +111 -0
- package/dist/adapters/mcp-tools.cjs +1 -1
- package/dist/adapters/mcp-tools.js +2 -2
- package/dist/adapters/mcp-transport-BhPqU0Ft.js +527 -0
- package/dist/adapters/mcp-transport-Kk_HTCeR.cjs +35 -0
- package/dist/adapters/mcp-transport.d.ts +310 -5
- package/dist/adapters/nextjs/index.cjs +1 -1
- package/dist/adapters/nextjs/index.js +4 -4
- package/dist/adapters/utils-CyBt-as9.cjs +15 -0
- package/dist/adapters/{utils-C7Nrw9Wb.js → utils-IH1ePsBd.js} +707 -655
- package/dist/adapters/utils.cjs +1 -1
- package/dist/adapters/utils.d.ts +11 -0
- package/dist/adapters/utils.js +2 -2
- package/dist/mcp-app/mcp-app.html +78 -44
- package/dist/server/index.cjs +144 -38
- package/dist/server/index.d.ts +24 -19
- package/dist/server/index.js +541 -676
- package/package.json +1 -1
- package/dist/adapters/mcp-prompts-BAutSQYA.js +0 -344
- package/dist/adapters/mcp-prompts-DsAkafVn.cjs +0 -5
- package/dist/adapters/mcp-transport-Cim_5cBN.js +0 -424
- package/dist/adapters/mcp-transport-DPpBCNea.cjs +0 -70
- package/dist/adapters/utils-tNZ6Cvzw.cjs +0 -15
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { d as e,
|
|
2
|
-
import {
|
|
1
|
+
import { d as e, g as t, p as n } from "./utils-IH1ePsBd.js";
|
|
2
|
+
import { a as r, n as i, r as a, t as o } from "./mcp-prompts-BUFyQLHQ.js";
|
|
3
3
|
//#region src/server/agent/system-prompt.ts
|
|
4
|
-
function
|
|
4
|
+
function s(e) {
|
|
5
5
|
if (e.length === 0) return "No cubes are currently available.";
|
|
6
6
|
let t = ["## Available Cubes", ""];
|
|
7
7
|
for (let n of e) {
|
|
@@ -27,10 +27,10 @@ function o(e) {
|
|
|
27
27
|
}
|
|
28
28
|
return t.join("\n");
|
|
29
29
|
}
|
|
30
|
-
function
|
|
30
|
+
function c(e) {
|
|
31
31
|
return e.messages.map((e) => e.content.text).join("\n\n");
|
|
32
32
|
}
|
|
33
|
-
function
|
|
33
|
+
function l(e) {
|
|
34
34
|
return [
|
|
35
35
|
"# Drizzle Cube Analytics Agent",
|
|
36
36
|
"",
|
|
@@ -53,7 +53,8 @@ function c(e) {
|
|
|
53
53
|
"## Important Guidelines",
|
|
54
54
|
"",
|
|
55
55
|
"- ALWAYS discover cubes first before attempting queries",
|
|
56
|
-
"- Field names MUST be `CubeName.fieldName`
|
|
56
|
+
"- Field names MUST be EXACTLY `CubeName.fieldName` — two parts separated by a single dot. Examples: `PullRequests.count`, `Teams.name`, `Employees.department`.",
|
|
57
|
+
" WRONG patterns that WILL FAIL: `Teams.Teams.name` (double-prefixed), `PullRequests.PullRequests.count` (double-prefixed), `PullRequests` (bare cube), `Teams_count` (underscore). Use the EXACT field names from discover results — copy them verbatim, do not prefix them again.",
|
|
57
58
|
"- Order keys MUST be one of the measures or dimensions already listed in that query. You CANNOT order by a field that is not in measures or dimensions — add it to measures first, or remove it from order.",
|
|
58
59
|
"- After EVERY `execute_query`, IMMEDIATELY call `add_markdown` and `add_portlet` in the SAME turn — never defer visualizations to a later turn",
|
|
59
60
|
"- Choose appropriate chart types: bar for categories, line for trends, table for detailed data",
|
|
@@ -132,6 +133,16 @@ function c(e) {
|
|
|
132
133
|
"- `xAxis: [], yAxis: [\"Cube.avg1\", \"Cube.avg2\"]` — missing xAxis, bars have no labels",
|
|
133
134
|
"- `xAxis: [\"Cube.size\"], series: [\"Cube.size\"]` — same field in both, creates sparse chart",
|
|
134
135
|
"",
|
|
136
|
+
"**Dual Y-axis for multi-measure charts.** When a `bar`, `line`, or `area` chart has 2+ measures with different scales (e.g. revenue in thousands vs conversion rate as a percentage), use `chartConfig.yAxisAssignment` to put them on separate axes:",
|
|
137
|
+
"```json",
|
|
138
|
+
"{",
|
|
139
|
+
" \"xAxis\": [\"Sales.month\"],",
|
|
140
|
+
" \"yAxis\": [\"Sales.revenue\", \"Sales.conversionRate\"],",
|
|
141
|
+
" \"yAxisAssignment\": { \"Sales.revenue\": \"left\", \"Sales.conversionRate\": \"right\" }",
|
|
142
|
+
"}",
|
|
143
|
+
"```",
|
|
144
|
+
"Only use dual axis when measures have genuinely different scales. If both measures share the same unit/scale, keep them on the same (left) axis — omit yAxisAssignment entirely.",
|
|
145
|
+
"",
|
|
135
146
|
"## Analysis Mode Decision Tree",
|
|
136
147
|
"",
|
|
137
148
|
"The default mode is **query** (standard measures/dimensions). Switch to a special mode only when the user's question matches:",
|
|
@@ -160,25 +171,21 @@ function c(e) {
|
|
|
160
171
|
"",
|
|
161
172
|
"---",
|
|
162
173
|
"",
|
|
163
|
-
|
|
174
|
+
c(i),
|
|
164
175
|
"",
|
|
165
176
|
"---",
|
|
166
177
|
"",
|
|
167
|
-
|
|
178
|
+
c(a),
|
|
168
179
|
"",
|
|
169
180
|
"---",
|
|
170
181
|
"",
|
|
171
|
-
|
|
172
|
-
"",
|
|
173
|
-
"---",
|
|
174
|
-
"",
|
|
175
|
-
s(a),
|
|
182
|
+
c(o),
|
|
176
183
|
"",
|
|
177
184
|
"---",
|
|
178
185
|
"",
|
|
179
186
|
"## Save as Dashboard",
|
|
180
187
|
"",
|
|
181
|
-
"
|
|
188
|
+
"ONLY call `save_as_dashboard` when the user EXPLICITLY asks to save, export, or convert the notebook into a dashboard. NEVER save a dashboard on your own initiative — wait for the user to request it.",
|
|
182
189
|
"",
|
|
183
190
|
"### Layout Rules",
|
|
184
191
|
"- Dashboard grid is 12 columns wide",
|
|
@@ -226,12 +233,12 @@ function c(e) {
|
|
|
226
233
|
"",
|
|
227
234
|
"---",
|
|
228
235
|
"",
|
|
229
|
-
|
|
236
|
+
s(e)
|
|
230
237
|
].join("\n");
|
|
231
238
|
}
|
|
232
239
|
//#endregion
|
|
233
240
|
//#region src/client/charts/chartConfigRegistry.ts
|
|
234
|
-
var
|
|
241
|
+
var u = {
|
|
235
242
|
bar: {
|
|
236
243
|
label: "Bar Chart",
|
|
237
244
|
description: "Compare values across categories",
|
|
@@ -1814,8 +1821,8 @@ var l = {
|
|
|
1814
1821
|
};
|
|
1815
1822
|
//#endregion
|
|
1816
1823
|
//#region src/server/agent/chart-validation.ts
|
|
1817
|
-
function
|
|
1818
|
-
let r =
|
|
1824
|
+
function d(e, t, n) {
|
|
1825
|
+
let r = u[e];
|
|
1819
1826
|
if (!r || r.skipQuery) return {
|
|
1820
1827
|
isValid: !0,
|
|
1821
1828
|
errors: []
|
|
@@ -1845,8 +1852,8 @@ function u(e, t, n) {
|
|
|
1845
1852
|
errors: i
|
|
1846
1853
|
};
|
|
1847
1854
|
}
|
|
1848
|
-
function
|
|
1849
|
-
let r =
|
|
1855
|
+
function f(e, t, n) {
|
|
1856
|
+
let r = u[e];
|
|
1850
1857
|
if (!r) return t ?? {};
|
|
1851
1858
|
let i = { ...t }, a = n.measures ?? [], o = n.dimensions ?? [], s = (n.timeDimensions ?? []).map((e) => e.dimension);
|
|
1852
1859
|
for (let e of r.dropZones) {
|
|
@@ -1878,10 +1885,10 @@ function d(e, t, n) {
|
|
|
1878
1885
|
}
|
|
1879
1886
|
return i;
|
|
1880
1887
|
}
|
|
1881
|
-
function
|
|
1888
|
+
function p(e) {
|
|
1882
1889
|
let t = ["\nChart config requirements by type:"];
|
|
1883
1890
|
for (let n of e) {
|
|
1884
|
-
let e =
|
|
1891
|
+
let e = u[n];
|
|
1885
1892
|
if (!e) continue;
|
|
1886
1893
|
let r = [e.description ?? "", e.useCase ?? ""].filter(Boolean).join(". "), i = r ? ` — ${r}.` : "", a = e.dropZones.filter((e) => e.mandatory);
|
|
1887
1894
|
if (a.length === 0 && !e.skipQuery) {
|
|
@@ -1902,7 +1909,7 @@ function f(e) {
|
|
|
1902
1909
|
}
|
|
1903
1910
|
//#endregion
|
|
1904
1911
|
//#region src/server/agent/tools.ts
|
|
1905
|
-
var
|
|
1912
|
+
var m = [
|
|
1906
1913
|
"bar",
|
|
1907
1914
|
"line",
|
|
1908
1915
|
"area",
|
|
@@ -1922,7 +1929,7 @@ var p = [
|
|
|
1922
1929
|
"boxPlot",
|
|
1923
1930
|
"markdown"
|
|
1924
1931
|
];
|
|
1925
|
-
function
|
|
1932
|
+
function h() {
|
|
1926
1933
|
return [
|
|
1927
1934
|
{
|
|
1928
1935
|
name: "discover_cubes",
|
|
@@ -1962,190 +1969,12 @@ function m() {
|
|
|
1962
1969
|
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.",
|
|
1963
1970
|
parameters: {
|
|
1964
1971
|
type: "object",
|
|
1965
|
-
properties:
|
|
1966
|
-
measures: {
|
|
1967
|
-
type: "array",
|
|
1968
|
-
items: {
|
|
1969
|
-
type: "string",
|
|
1970
|
-
pattern: "^[A-Z][a-zA-Z0-9]*\\.[a-zA-Z][a-zA-Z0-9]*$"
|
|
1971
|
-
},
|
|
1972
|
-
description: "Aggregation measures — MUST be \"CubeName.measureName\" format (e.g., [\"PullRequests.count\", \"Issues.openCount\"]). NEVER use just the cube name."
|
|
1973
|
-
},
|
|
1974
|
-
dimensions: {
|
|
1975
|
-
type: "array",
|
|
1976
|
-
items: {
|
|
1977
|
-
type: "string",
|
|
1978
|
-
pattern: "^[A-Z][a-zA-Z0-9]*\\.[a-zA-Z][a-zA-Z0-9]*$"
|
|
1979
|
-
},
|
|
1980
|
-
description: "Grouping dimensions — MUST be \"CubeName.dimensionName\" format (e.g., [\"Teams.name\", \"Employees.department\"]). NEVER use just the cube name."
|
|
1981
|
-
},
|
|
1982
|
-
filters: {
|
|
1983
|
-
type: "array",
|
|
1984
|
-
items: {
|
|
1985
|
-
type: "object",
|
|
1986
|
-
properties: {
|
|
1987
|
-
member: { type: "string" },
|
|
1988
|
-
operator: { type: "string" },
|
|
1989
|
-
values: {
|
|
1990
|
-
type: "array",
|
|
1991
|
-
items: {}
|
|
1992
|
-
}
|
|
1993
|
-
},
|
|
1994
|
-
required: ["member", "operator"]
|
|
1995
|
-
},
|
|
1996
|
-
description: "Filter conditions"
|
|
1997
|
-
},
|
|
1998
|
-
timeDimensions: {
|
|
1999
|
-
type: "array",
|
|
2000
|
-
items: {
|
|
2001
|
-
type: "object",
|
|
2002
|
-
properties: {
|
|
2003
|
-
dimension: { type: "string" },
|
|
2004
|
-
granularity: { type: "string" },
|
|
2005
|
-
dateRange: {}
|
|
2006
|
-
},
|
|
2007
|
-
required: ["dimension"]
|
|
2008
|
-
},
|
|
2009
|
-
description: "Time dimensions with optional granularity"
|
|
2010
|
-
},
|
|
2011
|
-
order: {
|
|
2012
|
-
type: "object",
|
|
2013
|
-
description: "Sort order. Keys MUST be a measure or dimension from this query in \"CubeName.fieldName\" format, values are \"asc\" or \"desc\". Example: {\"Teams.count\": \"desc\"}. WRONG: {\"Teams_count\": \"desc\"}"
|
|
2014
|
-
},
|
|
2015
|
-
limit: {
|
|
2016
|
-
type: "number",
|
|
2017
|
-
description: "Row limit"
|
|
2018
|
-
},
|
|
2019
|
-
funnel: {
|
|
2020
|
-
type: "object",
|
|
2021
|
-
properties: {
|
|
2022
|
-
bindingKey: {
|
|
2023
|
-
type: "string",
|
|
2024
|
-
description: "Entity binding key (e.g., \"Events.userId\")"
|
|
2025
|
-
},
|
|
2026
|
-
timeDimension: {
|
|
2027
|
-
type: "string",
|
|
2028
|
-
description: "Time dimension (e.g., \"Events.timestamp\")"
|
|
2029
|
-
},
|
|
2030
|
-
steps: {
|
|
2031
|
-
type: "array",
|
|
2032
|
-
items: {
|
|
2033
|
-
type: "object",
|
|
2034
|
-
properties: {
|
|
2035
|
-
name: { type: "string" },
|
|
2036
|
-
filter: {},
|
|
2037
|
-
timeToConvert: {
|
|
2038
|
-
type: "string",
|
|
2039
|
-
description: "ISO 8601 duration (e.g., \"P7D\")"
|
|
2040
|
-
}
|
|
2041
|
-
},
|
|
2042
|
-
required: ["name"]
|
|
2043
|
-
},
|
|
2044
|
-
description: "Funnel steps (min 2)"
|
|
2045
|
-
},
|
|
2046
|
-
includeTimeMetrics: { type: "boolean" },
|
|
2047
|
-
globalTimeWindow: { type: "string" }
|
|
2048
|
-
},
|
|
2049
|
-
required: [
|
|
2050
|
-
"bindingKey",
|
|
2051
|
-
"timeDimension",
|
|
2052
|
-
"steps"
|
|
2053
|
-
],
|
|
2054
|
-
description: "Funnel analysis config. When provided, measures/dimensions are ignored."
|
|
2055
|
-
},
|
|
2056
|
-
flow: {
|
|
2057
|
-
type: "object",
|
|
2058
|
-
properties: {
|
|
2059
|
-
bindingKey: { type: "string" },
|
|
2060
|
-
timeDimension: { type: "string" },
|
|
2061
|
-
eventDimension: {
|
|
2062
|
-
type: "string",
|
|
2063
|
-
description: "Dimension whose values become node labels"
|
|
2064
|
-
},
|
|
2065
|
-
startingStep: {
|
|
2066
|
-
type: "object",
|
|
2067
|
-
properties: {
|
|
2068
|
-
name: { type: "string" },
|
|
2069
|
-
filter: {}
|
|
2070
|
-
},
|
|
2071
|
-
required: ["name"]
|
|
2072
|
-
},
|
|
2073
|
-
stepsBefore: {
|
|
2074
|
-
type: "number",
|
|
2075
|
-
description: "Steps before starting step (0-5)"
|
|
2076
|
-
},
|
|
2077
|
-
stepsAfter: {
|
|
2078
|
-
type: "number",
|
|
2079
|
-
description: "Steps after starting step (0-5)"
|
|
2080
|
-
},
|
|
2081
|
-
entityLimit: { type: "number" },
|
|
2082
|
-
outputMode: {
|
|
2083
|
-
type: "string",
|
|
2084
|
-
enum: ["sankey", "sunburst"]
|
|
2085
|
-
}
|
|
2086
|
-
},
|
|
2087
|
-
required: [
|
|
2088
|
-
"bindingKey",
|
|
2089
|
-
"timeDimension",
|
|
2090
|
-
"eventDimension",
|
|
2091
|
-
"startingStep"
|
|
2092
|
-
],
|
|
2093
|
-
description: "Flow analysis config. When provided, measures/dimensions are ignored."
|
|
2094
|
-
},
|
|
2095
|
-
retention: {
|
|
2096
|
-
type: "object",
|
|
2097
|
-
properties: {
|
|
2098
|
-
timeDimension: { type: "string" },
|
|
2099
|
-
bindingKey: { type: "string" },
|
|
2100
|
-
dateRange: {
|
|
2101
|
-
type: "object",
|
|
2102
|
-
properties: {
|
|
2103
|
-
start: {
|
|
2104
|
-
type: "string",
|
|
2105
|
-
description: "YYYY-MM-DD"
|
|
2106
|
-
},
|
|
2107
|
-
end: {
|
|
2108
|
-
type: "string",
|
|
2109
|
-
description: "YYYY-MM-DD"
|
|
2110
|
-
}
|
|
2111
|
-
},
|
|
2112
|
-
required: ["start", "end"]
|
|
2113
|
-
},
|
|
2114
|
-
granularity: {
|
|
2115
|
-
type: "string",
|
|
2116
|
-
enum: [
|
|
2117
|
-
"day",
|
|
2118
|
-
"week",
|
|
2119
|
-
"month"
|
|
2120
|
-
]
|
|
2121
|
-
},
|
|
2122
|
-
periods: { type: "number" },
|
|
2123
|
-
retentionType: {
|
|
2124
|
-
type: "string",
|
|
2125
|
-
enum: ["classic", "rolling"]
|
|
2126
|
-
},
|
|
2127
|
-
cohortFilters: {},
|
|
2128
|
-
activityFilters: {},
|
|
2129
|
-
breakdownDimensions: {
|
|
2130
|
-
type: "array",
|
|
2131
|
-
items: { type: "string" }
|
|
2132
|
-
}
|
|
2133
|
-
},
|
|
2134
|
-
required: [
|
|
2135
|
-
"timeDimension",
|
|
2136
|
-
"bindingKey",
|
|
2137
|
-
"dateRange",
|
|
2138
|
-
"granularity",
|
|
2139
|
-
"periods"
|
|
2140
|
-
],
|
|
2141
|
-
description: "Retention analysis config. When provided, measures/dimensions are ignored."
|
|
2142
|
-
}
|
|
2143
|
-
}
|
|
1972
|
+
properties: r
|
|
2144
1973
|
}
|
|
2145
1974
|
},
|
|
2146
1975
|
{
|
|
2147
1976
|
name: "add_portlet",
|
|
2148
|
-
description: "Add a chart visualization to the notebook.\n" +
|
|
1977
|
+
description: "Add a chart visualization to the notebook.\n" + p(m) + "\nThe query is validated before adding. The portlet fetches its own data.",
|
|
2149
1978
|
parameters: {
|
|
2150
1979
|
type: "object",
|
|
2151
1980
|
properties: {
|
|
@@ -2159,7 +1988,7 @@ function m() {
|
|
|
2159
1988
|
},
|
|
2160
1989
|
chartType: {
|
|
2161
1990
|
type: "string",
|
|
2162
|
-
enum:
|
|
1991
|
+
enum: m,
|
|
2163
1992
|
description: "Chart type to render"
|
|
2164
1993
|
},
|
|
2165
1994
|
chartConfig: {
|
|
@@ -2178,7 +2007,11 @@ function m() {
|
|
|
2178
2007
|
items: { type: "string" }
|
|
2179
2008
|
},
|
|
2180
2009
|
sizeField: { type: "string" },
|
|
2181
|
-
colorField: { type: "string" }
|
|
2010
|
+
colorField: { type: "string" },
|
|
2011
|
+
yAxisAssignment: {
|
|
2012
|
+
type: "object",
|
|
2013
|
+
description: "Dual Y-axis: map measure fields to \"left\" or \"right\" axis. Only for bar, line, area charts with 2+ measures of different scales. Example: {\"Sales.revenue\": \"left\", \"Sales.conversionRate\": \"right\"}"
|
|
2014
|
+
}
|
|
2182
2015
|
},
|
|
2183
2016
|
description: "Chart axis configuration"
|
|
2184
2017
|
},
|
|
@@ -2251,7 +2084,7 @@ function m() {
|
|
|
2251
2084
|
},
|
|
2252
2085
|
chartType: {
|
|
2253
2086
|
type: "string",
|
|
2254
|
-
enum:
|
|
2087
|
+
enum: m,
|
|
2255
2088
|
description: "Chart type. Use \"markdown\" for section headers."
|
|
2256
2089
|
},
|
|
2257
2090
|
query: {
|
|
@@ -2375,10 +2208,10 @@ function m() {
|
|
|
2375
2208
|
}
|
|
2376
2209
|
];
|
|
2377
2210
|
}
|
|
2378
|
-
function
|
|
2379
|
-
let { semanticLayer:
|
|
2380
|
-
|
|
2381
|
-
let n = { cubes: (await e(
|
|
2211
|
+
function g(r) {
|
|
2212
|
+
let { semanticLayer: i, securityContext: a } = r, o = /* @__PURE__ */ new Map();
|
|
2213
|
+
o.set("discover_cubes", async (t) => {
|
|
2214
|
+
let n = { cubes: (await e(i, {
|
|
2382
2215
|
topic: t.topic,
|
|
2383
2216
|
intent: t.intent,
|
|
2384
2217
|
limit: t.limit,
|
|
@@ -2398,105 +2231,48 @@ function h(n) {
|
|
|
2398
2231
|
} } : {}
|
|
2399
2232
|
})) };
|
|
2400
2233
|
return { result: JSON.stringify(n) + "\n[IMPORTANT: Your next response MUST start with a brief text message BEFORE any tool calls.]" };
|
|
2401
|
-
}),
|
|
2402
|
-
let e =
|
|
2234
|
+
}), o.set("get_cube_metadata", async () => {
|
|
2235
|
+
let e = i.getMetadata();
|
|
2403
2236
|
return { result: JSON.stringify(e) };
|
|
2404
2237
|
});
|
|
2405
|
-
let
|
|
2406
|
-
for (let e of
|
|
2238
|
+
let s = /* @__PURE__ */ new Map();
|
|
2239
|
+
for (let e of i.getMetadata()) s.set(e.name, {
|
|
2407
2240
|
measures: (e.measures || []).map((e) => e.name),
|
|
2408
2241
|
dimensions: (e.dimensions || []).map((e) => e.name)
|
|
2409
2242
|
});
|
|
2410
|
-
let
|
|
2411
|
-
let n =
|
|
2243
|
+
let c = (e, t) => {
|
|
2244
|
+
let n = s.get(e), r = t === "measures" ? n?.measures : n?.dimensions;
|
|
2412
2245
|
return !r || r.length === 0 ? "" : ` Available ${t}: ${r.slice(0, 5).map((e) => `"${e}"`).join(", ")}`;
|
|
2413
2246
|
};
|
|
2414
|
-
return
|
|
2247
|
+
return o.set("execute_query", async (e) => {
|
|
2415
2248
|
try {
|
|
2416
|
-
let
|
|
2249
|
+
let t = (e, t) => {
|
|
2417
2250
|
if (!Array.isArray(e)) return;
|
|
2418
|
-
let n = []
|
|
2419
|
-
for (let
|
|
2420
|
-
if (typeof
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
}
|
|
2424
|
-
let e = i.split(".");
|
|
2425
|
-
if (e.length === 1) {
|
|
2426
|
-
n.push(`"${i}" is not valid — must be "CubeName.fieldName".${s(i, t)}`);
|
|
2427
|
-
continue;
|
|
2428
|
-
}
|
|
2429
|
-
if (e.length === 3 && e[0] === e[1]) {
|
|
2430
|
-
let t = `${e[0]}.${e[2]}`;
|
|
2431
|
-
r.push(t);
|
|
2432
|
-
continue;
|
|
2433
|
-
}
|
|
2434
|
-
if (e.length === 2 && e[0] === e[1]) {
|
|
2435
|
-
n.push(`"${i}" is WRONG — "${e[0]}" is the cube name, not a ${t.replace(/s$/, "")}.${s(e[0], t)}`);
|
|
2436
|
-
continue;
|
|
2437
|
-
}
|
|
2438
|
-
r.push(i);
|
|
2251
|
+
let n = [];
|
|
2252
|
+
for (let r of e) {
|
|
2253
|
+
if (typeof r != "string") continue;
|
|
2254
|
+
let e = r.split(".");
|
|
2255
|
+
e.length === 1 ? n.push(`"${r}" is not valid — must be "CubeName.fieldName".${c(r, t)}`) : e.length === 2 && e[0] === e[1] && n.push(`"${r}" is WRONG — "${e[0]}" is the cube name, not a ${t.replace(/s$/, "")}.${c(e[0], t)}`);
|
|
2439
2256
|
}
|
|
2440
2257
|
if (n.length > 0) throw Error(`Invalid ${t}:\n${n.join("\n")}`);
|
|
2441
|
-
return r;
|
|
2442
2258
|
};
|
|
2443
|
-
|
|
2444
|
-
let
|
|
2445
|
-
|
|
2446
|
-
return t.length === 3 && t[0] === t[1] ? `${t[0]}.${t[2]}` : e;
|
|
2447
|
-
};
|
|
2448
|
-
if (Array.isArray(e.filters)) for (let t of e.filters) typeof t.member == "string" && (t.member = a(t.member));
|
|
2449
|
-
if (Array.isArray(e.timeDimensions)) for (let t of e.timeDimensions) typeof t.dimension == "string" && (t.dimension = a(t.dimension));
|
|
2450
|
-
if (Array.isArray(e.order)) {
|
|
2451
|
-
let t = {};
|
|
2452
|
-
for (let n of e.order) n && typeof n == "object" && Object.assign(t, n);
|
|
2453
|
-
e.order = t;
|
|
2454
|
-
}
|
|
2455
|
-
if (e.order && typeof e.order == "object" && !Array.isArray(e.order)) {
|
|
2456
|
-
let t = new Set([...Array.isArray(e.measures) ? e.measures : [], ...Array.isArray(e.dimensions) ? e.dimensions : []]), n = {};
|
|
2457
|
-
for (let [r, i] of Object.entries(e.order)) {
|
|
2458
|
-
let e = a(r);
|
|
2459
|
-
if (t.has(e)) {
|
|
2460
|
-
n[e] = i;
|
|
2461
|
-
continue;
|
|
2462
|
-
}
|
|
2463
|
-
if (!r.includes(".") && r.includes("_")) {
|
|
2464
|
-
let e = a(r.replace(/_/g, "."));
|
|
2465
|
-
if (t.has(e)) {
|
|
2466
|
-
n[e] = i;
|
|
2467
|
-
continue;
|
|
2468
|
-
}
|
|
2469
|
-
let o = [...t].find((e) => {
|
|
2470
|
-
let t = e.split(".")[1];
|
|
2471
|
-
return t && (r.endsWith(`_${t}`) || r.endsWith(`.${t}`));
|
|
2472
|
-
});
|
|
2473
|
-
if (o) {
|
|
2474
|
-
n[o] = i;
|
|
2475
|
-
continue;
|
|
2476
|
-
}
|
|
2477
|
-
}
|
|
2478
|
-
t.size > 0 && !t.has(e) || (n[e] = i);
|
|
2479
|
-
}
|
|
2480
|
-
if (Object.keys(n).length === 0 && t.size > 0) {
|
|
2481
|
-
let t = Array.isArray(e.measures) ? e.measures[0] : void 0;
|
|
2482
|
-
t && (n[t] = "desc");
|
|
2483
|
-
}
|
|
2484
|
-
e.order = n;
|
|
2485
|
-
}
|
|
2486
|
-
let o;
|
|
2487
|
-
o = e.funnel ? { funnel: e.funnel } : e.flow ? { flow: e.flow } : e.retention ? { retention: e.retention } : {
|
|
2259
|
+
t(e.measures, "measures"), t(e.dimensions, "dimensions");
|
|
2260
|
+
let r;
|
|
2261
|
+
r = e.funnel ? { funnel: e.funnel } : e.flow ? { flow: e.flow } : e.retention ? { retention: e.retention } : {
|
|
2488
2262
|
measures: e.measures,
|
|
2489
2263
|
dimensions: e.dimensions,
|
|
2490
2264
|
filters: e.filters,
|
|
2491
2265
|
timeDimensions: e.timeDimensions,
|
|
2492
2266
|
order: e.order,
|
|
2493
|
-
limit: e.limit
|
|
2267
|
+
limit: e.limit,
|
|
2268
|
+
offset: e.offset,
|
|
2269
|
+
ungrouped: e.ungrouped
|
|
2494
2270
|
};
|
|
2495
|
-
let
|
|
2271
|
+
let o = await n(i, a, { query: r });
|
|
2496
2272
|
return { result: JSON.stringify({
|
|
2497
|
-
rowCount:
|
|
2498
|
-
data:
|
|
2499
|
-
annotation:
|
|
2273
|
+
rowCount: o.data.length,
|
|
2274
|
+
data: o.data,
|
|
2275
|
+
annotation: o.annotation
|
|
2500
2276
|
}) + "\n[IMPORTANT: Your next response MUST start with a brief text message BEFORE any tool calls. Now call add_markdown and add_portlet to visualize these results.]" };
|
|
2501
2277
|
} catch (t) {
|
|
2502
2278
|
let n = {
|
|
@@ -2515,50 +2291,51 @@ function h(n) {
|
|
|
2515
2291
|
isError: !0
|
|
2516
2292
|
};
|
|
2517
2293
|
}
|
|
2518
|
-
}),
|
|
2519
|
-
let
|
|
2294
|
+
}), o.set("add_portlet", async (e) => {
|
|
2295
|
+
let n = {
|
|
2520
2296
|
number: "kpiNumber",
|
|
2521
2297
|
retention: "retentionHeatmap"
|
|
2522
|
-
}[e.chartType] ?? e.chartType,
|
|
2298
|
+
}[e.chartType] ?? e.chartType, r;
|
|
2523
2299
|
try {
|
|
2524
|
-
|
|
2300
|
+
r = JSON.parse(e.query);
|
|
2525
2301
|
} catch {
|
|
2526
2302
|
return {
|
|
2527
2303
|
result: "Invalid query: could not parse JSON string. Ensure `query` is a valid JSON string.",
|
|
2528
2304
|
isError: !0
|
|
2529
2305
|
};
|
|
2530
2306
|
}
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2307
|
+
r = t(r);
|
|
2308
|
+
let a = i.validateQuery(r);
|
|
2309
|
+
if (!a.isValid) return {
|
|
2310
|
+
result: `Invalid query — fix these errors and retry:\n${a.errors.join("\n")}\n\nAttempted query:\n${JSON.stringify(r, null, 2)}`,
|
|
2534
2311
|
isError: !0
|
|
2535
2312
|
};
|
|
2536
|
-
let
|
|
2537
|
-
if (
|
|
2313
|
+
let o = !!(r.funnel || r.flow || r.retention), s;
|
|
2314
|
+
if (o) s = e.chartConfig ?? {};
|
|
2538
2315
|
else {
|
|
2539
|
-
let
|
|
2316
|
+
let t = f(n, e.chartConfig, r), i = d(n, t, r);
|
|
2540
2317
|
if (!i.isValid) return {
|
|
2541
2318
|
result: `Chart config invalid — fix these errors and retry:\n${i.errors.join("\n")}`,
|
|
2542
2319
|
isError: !0
|
|
2543
2320
|
};
|
|
2544
|
-
|
|
2321
|
+
s = t;
|
|
2545
2322
|
}
|
|
2546
|
-
let
|
|
2547
|
-
id:
|
|
2323
|
+
let c = `portlet-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`, l = {
|
|
2324
|
+
id: c,
|
|
2548
2325
|
title: e.title,
|
|
2549
2326
|
query: e.query,
|
|
2550
|
-
chartType:
|
|
2551
|
-
chartConfig:
|
|
2327
|
+
chartType: n,
|
|
2328
|
+
chartConfig: s,
|
|
2552
2329
|
displayConfig: e.displayConfig
|
|
2553
2330
|
};
|
|
2554
2331
|
return {
|
|
2555
|
-
result: `Portlet "${e.title}" added to notebook (id: ${
|
|
2332
|
+
result: `Portlet "${e.title}" added to notebook (id: ${c}, chart: ${n}). [Reminder: in your next response, start with a brief sentence about what you will do next BEFORE making any tool calls.]`,
|
|
2556
2333
|
sideEffect: {
|
|
2557
2334
|
type: "add_portlet",
|
|
2558
|
-
data:
|
|
2335
|
+
data: l
|
|
2559
2336
|
}
|
|
2560
2337
|
};
|
|
2561
|
-
}),
|
|
2338
|
+
}), o.set("add_markdown", async (e) => {
|
|
2562
2339
|
let t = `markdown-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`, n = e.content || e.text || e.markdown || "", r = {
|
|
2563
2340
|
id: t,
|
|
2564
2341
|
title: e.title,
|
|
@@ -2571,37 +2348,38 @@ function h(n) {
|
|
|
2571
2348
|
data: r
|
|
2572
2349
|
}
|
|
2573
2350
|
};
|
|
2574
|
-
}),
|
|
2351
|
+
}), o.set("save_as_dashboard", async (e) => {
|
|
2575
2352
|
try {
|
|
2576
|
-
let
|
|
2577
|
-
if (!
|
|
2353
|
+
let n = e.portlets;
|
|
2354
|
+
if (!n || n.length === 0) return {
|
|
2578
2355
|
result: "Dashboard must contain at least one portlet.",
|
|
2579
2356
|
isError: !0
|
|
2580
2357
|
};
|
|
2581
|
-
let
|
|
2582
|
-
for (let e of
|
|
2358
|
+
let r = [];
|
|
2359
|
+
for (let e of n) {
|
|
2583
2360
|
if (e.chartType === "markdown") continue;
|
|
2584
|
-
let
|
|
2585
|
-
if (!
|
|
2586
|
-
|
|
2361
|
+
let n = e.query;
|
|
2362
|
+
if (!n) {
|
|
2363
|
+
r.push(`Portlet "${e.title}": missing query`);
|
|
2587
2364
|
continue;
|
|
2588
2365
|
}
|
|
2589
|
-
let
|
|
2366
|
+
let a;
|
|
2590
2367
|
try {
|
|
2591
|
-
|
|
2368
|
+
a = JSON.parse(n);
|
|
2592
2369
|
} catch {
|
|
2593
|
-
|
|
2370
|
+
r.push(`Portlet "${e.title}": invalid JSON query`);
|
|
2594
2371
|
continue;
|
|
2595
2372
|
}
|
|
2596
|
-
|
|
2597
|
-
|
|
2373
|
+
a = t(a);
|
|
2374
|
+
let o = i.validateQuery(a);
|
|
2375
|
+
o.isValid || r.push(`Portlet "${e.title}": ${o.errors.join(", ")}`);
|
|
2598
2376
|
}
|
|
2599
|
-
if (
|
|
2600
|
-
result: `Dashboard has invalid portlets — fix these errors and retry:\n${
|
|
2377
|
+
if (r.length > 0) return {
|
|
2378
|
+
result: `Dashboard has invalid portlets — fix these errors and retry:\n${r.join("\n")}`,
|
|
2601
2379
|
isError: !0
|
|
2602
2380
|
};
|
|
2603
|
-
let
|
|
2604
|
-
portlets:
|
|
2381
|
+
let a = {
|
|
2382
|
+
portlets: n.map((e) => {
|
|
2605
2383
|
let t = e.chartType, n = t === "markdown", r = n ? "query" : e.analysisType || "query", i = r === "funnel" ? "funnel" : r === "flow" ? "flow" : r === "retention" ? "retention" : "query", a = e.query || "{}", o;
|
|
2606
2384
|
try {
|
|
2607
2385
|
o = JSON.parse(a);
|
|
@@ -2632,15 +2410,15 @@ function h(n) {
|
|
|
2632
2410
|
}),
|
|
2633
2411
|
filters: e.filters,
|
|
2634
2412
|
colorPalette: e.colorPalette
|
|
2635
|
-
},
|
|
2413
|
+
}, o = e.title;
|
|
2636
2414
|
return {
|
|
2637
|
-
result: `Dashboard "${
|
|
2415
|
+
result: `Dashboard "${o}" created with ${a.portlets.length} portlets and ${a.filters?.length || 0} filters.`,
|
|
2638
2416
|
sideEffect: {
|
|
2639
2417
|
type: "dashboard_saved",
|
|
2640
2418
|
data: {
|
|
2641
|
-
title:
|
|
2419
|
+
title: o,
|
|
2642
2420
|
description: e.description,
|
|
2643
|
-
dashboardConfig:
|
|
2421
|
+
dashboardConfig: a
|
|
2644
2422
|
}
|
|
2645
2423
|
}
|
|
2646
2424
|
};
|
|
@@ -2650,11 +2428,11 @@ function h(n) {
|
|
|
2650
2428
|
isError: !0
|
|
2651
2429
|
};
|
|
2652
2430
|
}
|
|
2653
|
-
}),
|
|
2431
|
+
}), o;
|
|
2654
2432
|
}
|
|
2655
2433
|
//#endregion
|
|
2656
2434
|
//#region src/server/agent/providers/factory.ts
|
|
2657
|
-
async function
|
|
2435
|
+
async function _(e, t, n) {
|
|
2658
2436
|
switch (e) {
|
|
2659
2437
|
case "anthropic": {
|
|
2660
2438
|
let { AnthropicProvider: e } = await import("./anthropic-DpEbCVvF.js");
|
|
@@ -2673,15 +2451,15 @@ async function g(e, t, n) {
|
|
|
2673
2451
|
}
|
|
2674
2452
|
//#endregion
|
|
2675
2453
|
//#region src/server/agent/handler.ts
|
|
2676
|
-
var
|
|
2454
|
+
var v = {
|
|
2677
2455
|
anthropic: "claude-sonnet-4-6",
|
|
2678
2456
|
openai: "gpt-4.1-mini",
|
|
2679
2457
|
google: "gemini-3-flash-preview"
|
|
2680
2458
|
};
|
|
2681
|
-
async function*
|
|
2682
|
-
let { message: t, history: n, semanticLayer: r, securityContext: i, agentConfig: a, apiKey: o } = e, s = e.sessionId || crypto.randomUUID(),
|
|
2459
|
+
async function* y(e) {
|
|
2460
|
+
let { message: t, history: n, semanticLayer: r, securityContext: i, agentConfig: a, apiKey: o } = e, s = e.sessionId || crypto.randomUUID(), c = a.observability, u = crypto.randomUUID(), d = Date.now(), f = e.providerOverride || a.provider || "anthropic", p = e.modelOverride || a.model || v[f] || "claude-sonnet-4-6", m = e.baseURLOverride || a.baseURL, y = a.maxTurns || 25, b = a.maxTokens || 4096, x;
|
|
2683
2461
|
try {
|
|
2684
|
-
x = await
|
|
2462
|
+
x = await _(f, o, { baseURL: m });
|
|
2685
2463
|
} catch (e) {
|
|
2686
2464
|
console.error("[agent] Failed to create %s provider: %s", String(f).replace(/\n|\r/g, ""), String(e instanceof Error ? e.message : e).replace(/\n|\r/g, "")), yield {
|
|
2687
2465
|
type: "error",
|
|
@@ -2689,13 +2467,13 @@ async function* v(e) {
|
|
|
2689
2467
|
};
|
|
2690
2468
|
return;
|
|
2691
2469
|
}
|
|
2692
|
-
let S =
|
|
2470
|
+
let S = h(), C = g({
|
|
2693
2471
|
semanticLayer: r,
|
|
2694
2472
|
securityContext: i
|
|
2695
|
-
}), w =
|
|
2473
|
+
}), w = l(r.getMetadata());
|
|
2696
2474
|
e.systemContext && (w += `\n\n## User Context\n\n${e.systemContext}`);
|
|
2697
2475
|
try {
|
|
2698
|
-
|
|
2476
|
+
c?.onChatStart?.({
|
|
2699
2477
|
traceId: u,
|
|
2700
2478
|
sessionId: s,
|
|
2701
2479
|
message: t,
|
|
@@ -2753,7 +2531,7 @@ async function* v(e) {
|
|
|
2753
2531
|
system: w,
|
|
2754
2532
|
tools: S,
|
|
2755
2533
|
messages: T
|
|
2756
|
-
}), n = [], r = "", i = "", a, o, s = Date.now(),
|
|
2534
|
+
}), n = [], r = "", i = "", a, o, s = Date.now(), l = !1;
|
|
2757
2535
|
for await (let e of x.parseStreamEvents(t)) {
|
|
2758
2536
|
let t = e;
|
|
2759
2537
|
switch (t.type) {
|
|
@@ -2769,7 +2547,7 @@ async function* v(e) {
|
|
|
2769
2547
|
break;
|
|
2770
2548
|
}
|
|
2771
2549
|
case "tool_use_start":
|
|
2772
|
-
if (
|
|
2550
|
+
if (l && r) {
|
|
2773
2551
|
let e = n[n.length - 1];
|
|
2774
2552
|
if (e?.type === "tool_use") try {
|
|
2775
2553
|
e.input = JSON.parse(r);
|
|
@@ -2781,7 +2559,7 @@ async function* v(e) {
|
|
|
2781
2559
|
name: t.name,
|
|
2782
2560
|
input: {},
|
|
2783
2561
|
...t.metadata ? { metadata: t.metadata } : {}
|
|
2784
|
-
}), r = "",
|
|
2562
|
+
}), r = "", l = !0, yield {
|
|
2785
2563
|
type: "tool_use_start",
|
|
2786
2564
|
data: {
|
|
2787
2565
|
id: t.id,
|
|
@@ -2797,7 +2575,7 @@ async function* v(e) {
|
|
|
2797
2575
|
if (t.id && t.input) {
|
|
2798
2576
|
let e = n.find((e) => e.type === "tool_use" && e.id === t.id);
|
|
2799
2577
|
e && (e.input = t.input);
|
|
2800
|
-
} else if (
|
|
2578
|
+
} else if (l) {
|
|
2801
2579
|
let e = n[n.length - 1];
|
|
2802
2580
|
if (e?.type === "tool_use" && r) {
|
|
2803
2581
|
try {
|
|
@@ -2807,7 +2585,7 @@ async function* v(e) {
|
|
|
2807
2585
|
}
|
|
2808
2586
|
r = "";
|
|
2809
2587
|
}
|
|
2810
|
-
|
|
2588
|
+
l = !1;
|
|
2811
2589
|
}
|
|
2812
2590
|
break;
|
|
2813
2591
|
case "message_meta":
|
|
@@ -2816,7 +2594,7 @@ async function* v(e) {
|
|
|
2816
2594
|
}
|
|
2817
2595
|
}
|
|
2818
2596
|
try {
|
|
2819
|
-
|
|
2597
|
+
c?.onGenerationEnd?.({
|
|
2820
2598
|
traceId: u,
|
|
2821
2599
|
turn: e,
|
|
2822
2600
|
model: p,
|
|
@@ -2871,7 +2649,7 @@ async function* v(e) {
|
|
|
2871
2649
|
}
|
|
2872
2650
|
};
|
|
2873
2651
|
try {
|
|
2874
|
-
|
|
2652
|
+
c?.onToolEnd?.({
|
|
2875
2653
|
traceId: u,
|
|
2876
2654
|
turn: e,
|
|
2877
2655
|
toolName: n,
|
|
@@ -2897,7 +2675,7 @@ async function* v(e) {
|
|
|
2897
2675
|
}
|
|
2898
2676
|
};
|
|
2899
2677
|
try {
|
|
2900
|
-
|
|
2678
|
+
c?.onToolEnd?.({
|
|
2901
2679
|
traceId: u,
|
|
2902
2680
|
turn: e,
|
|
2903
2681
|
toolName: n,
|
|
@@ -2917,7 +2695,7 @@ async function* v(e) {
|
|
|
2917
2695
|
else T.push(f);
|
|
2918
2696
|
}
|
|
2919
2697
|
try {
|
|
2920
|
-
|
|
2698
|
+
c?.onChatEnd?.({
|
|
2921
2699
|
traceId: u,
|
|
2922
2700
|
sessionId: s,
|
|
2923
2701
|
totalTurns: E,
|
|
@@ -2933,7 +2711,7 @@ async function* v(e) {
|
|
|
2933
2711
|
};
|
|
2934
2712
|
} catch (e) {
|
|
2935
2713
|
try {
|
|
2936
|
-
|
|
2714
|
+
c?.onChatEnd?.({
|
|
2937
2715
|
traceId: u,
|
|
2938
2716
|
sessionId: s,
|
|
2939
2717
|
totalTurns: 0,
|
|
@@ -2948,4 +2726,4 @@ async function* v(e) {
|
|
|
2948
2726
|
}
|
|
2949
2727
|
}
|
|
2950
2728
|
//#endregion
|
|
2951
|
-
export {
|
|
2729
|
+
export { y as handleAgentChat };
|