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.
Files changed (34) hide show
  1. package/dist/adapters/{compiler-O3T1u7jl.js → compiler-BXfrvebp.js} +4 -3
  2. package/dist/adapters/{compiler-CA6iopu7.cjs → compiler-CPE-YZfe.cjs} +2 -2
  3. package/dist/adapters/express/index.cjs +1 -1
  4. package/dist/adapters/express/index.js +4 -4
  5. package/dist/adapters/fastify/index.cjs +1 -1
  6. package/dist/adapters/fastify/index.js +39 -39
  7. package/dist/adapters/{handler-BO2nq6IS.cjs → handler-DumFgnNM.cjs} +10 -10
  8. package/dist/adapters/{handler-CjVc3ytc.js → handler-RItnSaEl.js} +128 -350
  9. package/dist/adapters/hono/index.cjs +1 -1
  10. package/dist/adapters/hono/index.js +4 -4
  11. package/dist/adapters/mcp-prompts-BUFyQLHQ.js +377 -0
  12. package/dist/adapters/mcp-prompts-B_NvEJT_.cjs +111 -0
  13. package/dist/adapters/mcp-tools.cjs +1 -1
  14. package/dist/adapters/mcp-tools.js +2 -2
  15. package/dist/adapters/mcp-transport-BhPqU0Ft.js +527 -0
  16. package/dist/adapters/mcp-transport-Kk_HTCeR.cjs +35 -0
  17. package/dist/adapters/mcp-transport.d.ts +310 -5
  18. package/dist/adapters/nextjs/index.cjs +1 -1
  19. package/dist/adapters/nextjs/index.js +4 -4
  20. package/dist/adapters/utils-CyBt-as9.cjs +15 -0
  21. package/dist/adapters/{utils-C7Nrw9Wb.js → utils-IH1ePsBd.js} +707 -655
  22. package/dist/adapters/utils.cjs +1 -1
  23. package/dist/adapters/utils.d.ts +11 -0
  24. package/dist/adapters/utils.js +2 -2
  25. package/dist/mcp-app/mcp-app.html +78 -44
  26. package/dist/server/index.cjs +144 -38
  27. package/dist/server/index.d.ts +24 -19
  28. package/dist/server/index.js +541 -676
  29. package/package.json +1 -1
  30. package/dist/adapters/mcp-prompts-BAutSQYA.js +0 -344
  31. package/dist/adapters/mcp-prompts-DsAkafVn.cjs +0 -5
  32. package/dist/adapters/mcp-transport-Cim_5cBN.js +0 -424
  33. package/dist/adapters/mcp-transport-DPpBCNea.cjs +0 -70
  34. package/dist/adapters/utils-tNZ6Cvzw.cjs +0 -15
@@ -1,7 +1,7 @@
1
- import { d as e, p as t } from "./utils-C7Nrw9Wb.js";
2
- import { i as n, n as r, r as i, t as a } from "./mcp-prompts-BAutSQYA.js";
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 o(e) {
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 s(e) {
30
+ function c(e) {
31
31
  return e.messages.map((e) => e.content.text).join("\n\n");
32
32
  }
33
- function c(e) {
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` with a DOT separator (e.g. `PullRequests.count`, `Teams.name`). NEVER use underscores, NEVER use just the cube name as a field — `PullRequests.PullRequests` and `Teams_count` are WRONG.",
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
- s(r),
174
+ c(i),
164
175
  "",
165
176
  "---",
166
177
  "",
167
- s(n),
178
+ c(a),
168
179
  "",
169
180
  "---",
170
181
  "",
171
- s(i),
172
- "",
173
- "---",
174
- "",
175
- s(a),
182
+ c(o),
176
183
  "",
177
184
  "---",
178
185
  "",
179
186
  "## Save as Dashboard",
180
187
  "",
181
- "When the user asks to save, export, or convert the notebook into a dashboard, use the `save_as_dashboard` tool.",
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
- o(e)
236
+ s(e)
230
237
  ].join("\n");
231
238
  }
232
239
  //#endregion
233
240
  //#region src/client/charts/chartConfigRegistry.ts
234
- var l = {
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 u(e, t, n) {
1818
- let r = l[e];
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 d(e, t, n) {
1849
- let r = l[e];
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 f(e) {
1888
+ function p(e) {
1882
1889
  let t = ["\nChart config requirements by type:"];
1883
1890
  for (let n of e) {
1884
- let e = l[n];
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 p = [
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 m() {
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" + f(p) + "\nThe query is validated before adding. The portlet fetches its own data.",
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: p,
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: p,
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 h(n) {
2379
- let { semanticLayer: r, securityContext: i } = n, a = /* @__PURE__ */ new Map();
2380
- a.set("discover_cubes", async (t) => {
2381
- let n = { cubes: (await e(r, {
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
- }), a.set("get_cube_metadata", async () => {
2402
- let e = r.getMetadata();
2234
+ }), o.set("get_cube_metadata", async () => {
2235
+ let e = i.getMetadata();
2403
2236
  return { result: JSON.stringify(e) };
2404
2237
  });
2405
- let o = /* @__PURE__ */ new Map();
2406
- for (let e of r.getMetadata()) o.set(e.name, {
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 s = (e, t) => {
2411
- let n = o.get(e), r = t === "measures" ? n?.measures : n?.dimensions;
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 a.set("execute_query", async (e) => {
2247
+ return o.set("execute_query", async (e) => {
2415
2248
  try {
2416
- let n = (e, t) => {
2249
+ let t = (e, t) => {
2417
2250
  if (!Array.isArray(e)) return;
2418
- let n = [], r = [];
2419
- for (let i of e) {
2420
- if (typeof i != "string") {
2421
- r.push(i);
2422
- continue;
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
- e.measures = n(e.measures, "measures") ?? e.measures, e.dimensions = n(e.dimensions, "dimensions") ?? e.dimensions;
2444
- let a = (e) => {
2445
- let t = e.split(".");
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 c = await t(r, i, { query: o });
2271
+ let o = await n(i, a, { query: r });
2496
2272
  return { result: JSON.stringify({
2497
- rowCount: c.data.length,
2498
- data: c.data,
2499
- annotation: c.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
- }), a.set("add_portlet", async (e) => {
2519
- let t = {
2294
+ }), o.set("add_portlet", async (e) => {
2295
+ let n = {
2520
2296
  number: "kpiNumber",
2521
2297
  retention: "retentionHeatmap"
2522
- }[e.chartType] ?? e.chartType, n;
2298
+ }[e.chartType] ?? e.chartType, r;
2523
2299
  try {
2524
- n = JSON.parse(e.query);
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
- let i = r.validateQuery(n);
2532
- if (!i.isValid) return {
2533
- result: `Invalid query — fix these errors and retry:\n${i.errors.join("\n")}\n\nAttempted query:\n${JSON.stringify(n, null, 2)}`,
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 a = !!(n.funnel || n.flow || n.retention), o;
2537
- if (a) o = e.chartConfig ?? {};
2313
+ let o = !!(r.funnel || r.flow || r.retention), s;
2314
+ if (o) s = e.chartConfig ?? {};
2538
2315
  else {
2539
- let r = d(t, e.chartConfig, n), i = u(t, r, n);
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
- o = r;
2321
+ s = t;
2545
2322
  }
2546
- let s = `portlet-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`, c = {
2547
- id: s,
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: t,
2551
- chartConfig: o,
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: ${s}, chart: ${t}). [Reminder: in your next response, start with a brief sentence about what you will do next BEFORE making any tool calls.]`,
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: c
2335
+ data: l
2559
2336
  }
2560
2337
  };
2561
- }), a.set("add_markdown", async (e) => {
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
- }), a.set("save_as_dashboard", async (e) => {
2351
+ }), o.set("save_as_dashboard", async (e) => {
2575
2352
  try {
2576
- let t = e.portlets;
2577
- if (!t || t.length === 0) return {
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 n = [];
2582
- for (let e of t) {
2358
+ let r = [];
2359
+ for (let e of n) {
2583
2360
  if (e.chartType === "markdown") continue;
2584
- let t = e.query;
2585
- if (!t) {
2586
- n.push(`Portlet "${e.title}": missing query`);
2361
+ let n = e.query;
2362
+ if (!n) {
2363
+ r.push(`Portlet "${e.title}": missing query`);
2587
2364
  continue;
2588
2365
  }
2589
- let i;
2366
+ let a;
2590
2367
  try {
2591
- i = JSON.parse(t);
2368
+ a = JSON.parse(n);
2592
2369
  } catch {
2593
- n.push(`Portlet "${e.title}": invalid JSON query`);
2370
+ r.push(`Portlet "${e.title}": invalid JSON query`);
2594
2371
  continue;
2595
2372
  }
2596
- let a = r.validateQuery(i);
2597
- a.isValid || n.push(`Portlet "${e.title}": ${a.errors.join(", ")}`);
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 (n.length > 0) return {
2600
- result: `Dashboard has invalid portlets — fix these errors and retry:\n${n.join("\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 i = {
2604
- portlets: t.map((e) => {
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
- }, a = e.title;
2413
+ }, o = e.title;
2636
2414
  return {
2637
- result: `Dashboard "${a}" created with ${i.portlets.length} portlets and ${i.filters?.length || 0} filters.`,
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: a,
2419
+ title: o,
2642
2420
  description: e.description,
2643
- dashboardConfig: i
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
- }), a;
2431
+ }), o;
2654
2432
  }
2655
2433
  //#endregion
2656
2434
  //#region src/server/agent/providers/factory.ts
2657
- async function g(e, t, n) {
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* v(e) {
2682
- let { message: t, history: n, semanticLayer: r, securityContext: i, agentConfig: a, apiKey: o } = e, s = e.sessionId || crypto.randomUUID(), l = a.observability, u = crypto.randomUUID(), d = Date.now(), f = e.providerOverride || a.provider || "anthropic", p = e.modelOverride || a.model || _[f] || "claude-sonnet-4-6", v = e.baseURLOverride || a.baseURL, y = a.maxTurns || 25, b = a.maxTokens || 4096, x;
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 g(f, o, { baseURL: v });
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 = m(), C = h({
2470
+ let S = h(), C = g({
2693
2471
  semanticLayer: r,
2694
2472
  securityContext: i
2695
- }), w = c(r.getMetadata());
2473
+ }), w = l(r.getMetadata());
2696
2474
  e.systemContext && (w += `\n\n## User Context\n\n${e.systemContext}`);
2697
2475
  try {
2698
- l?.onChatStart?.({
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(), c = !1;
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 (c && r) {
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 = "", c = !0, yield {
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 (c) {
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
- c = !1;
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
- l?.onGenerationEnd?.({
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
- l?.onToolEnd?.({
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
- l?.onToolEnd?.({
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
- l?.onChatEnd?.({
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
- l?.onChatEnd?.({
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 { v as handleAgentChat };
2729
+ export { y as handleAgentChat };