drizzle-cube 0.4.9 → 0.4.11

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 (40) hide show
  1. package/dist/adapters/express/index.cjs +1 -1
  2. package/dist/adapters/express/index.js +2 -2
  3. package/dist/adapters/fastify/index.cjs +1 -1
  4. package/dist/adapters/fastify/index.js +2 -2
  5. package/dist/adapters/{handler-CSHsefnC.js → handler-CQkIwtxp.js} +251 -178
  6. package/dist/adapters/{handler-Xe_2ItOo.cjs → handler-dnkqpznh.cjs} +13 -13
  7. package/dist/adapters/hono/index.cjs +1 -1
  8. package/dist/adapters/hono/index.js +2 -2
  9. package/dist/adapters/{mcp-transport-KX92EgkF.cjs → mcp-transport-8u9G5oNa.cjs} +9 -9
  10. package/dist/adapters/{mcp-transport-CU5g9bxj.js → mcp-transport-m1X1GtwG.js} +13 -4
  11. package/dist/adapters/nextjs/index.cjs +2 -2
  12. package/dist/adapters/nextjs/index.js +2 -2
  13. package/dist/client/charts.js +4 -4
  14. package/dist/client/chunks/{analysis-builder-DFt9p8tj.js → analysis-builder-BMmWeFPr.js} +4 -4
  15. package/dist/client/chunks/{analysis-builder-DFt9p8tj.js.map → analysis-builder-BMmWeFPr.js.map} +1 -1
  16. package/dist/client/chunks/{analysis-builder-shared-DOHV2W8A.js → analysis-builder-shared-D56zYeV0.js} +2 -2
  17. package/dist/client/chunks/{analysis-builder-shared-DOHV2W8A.js.map → analysis-builder-shared-D56zYeV0.js.map} +1 -1
  18. package/dist/client/chunks/{chart-area-QKKboTbq.js → chart-area-BJAgusst.js} +2 -2
  19. package/dist/client/chunks/{chart-area-QKKboTbq.js.map → chart-area-BJAgusst.js.map} +1 -1
  20. package/dist/client/chunks/chart-bar-Blypx8O4.js +267 -0
  21. package/dist/client/chunks/chart-bar-Blypx8O4.js.map +1 -0
  22. package/dist/client/chunks/{chart-line-C7YcMWBw.js → chart-line-zi6olZet.js} +2 -2
  23. package/dist/client/chunks/{chart-line-C7YcMWBw.js.map → chart-line-zi6olZet.js.map} +1 -1
  24. package/dist/client/chunks/{charts-loader-HYQFVOo4.js → charts-loader-CH0_S06T.js} +4 -4
  25. package/dist/client/chunks/{charts-loader-HYQFVOo4.js.map → charts-loader-CH0_S06T.js.map} +1 -1
  26. package/dist/client/chunks/{components-8FAXo62Z.js → components-ClQziOcT.js} +3 -3
  27. package/dist/client/chunks/{components-8FAXo62Z.js.map → components-ClQziOcT.js.map} +1 -1
  28. package/dist/client/components.js +1 -1
  29. package/dist/client/hooks/useAgentChat.d.ts +1 -1
  30. package/dist/client/index.js +443 -413
  31. package/dist/client/index.js.map +1 -1
  32. package/dist/client/stores/notebookStore.d.ts +3 -0
  33. package/dist/client/utils.js +1 -1
  34. package/dist/client-bundle-stats.html +1 -1
  35. package/dist/server/index.cjs +16 -16
  36. package/dist/server/index.d.ts +1 -0
  37. package/dist/server/index.js +161 -79
  38. package/package.json +1 -1
  39. package/dist/client/chunks/chart-bar-HpXF42H1.js +0 -254
  40. package/dist/client/chunks/chart-bar-HpXF42H1.js.map +0 -1
@@ -57,6 +57,7 @@ export declare type AgentSSEEvent = {
57
57
  id: string;
58
58
  name: string;
59
59
  result?: unknown;
60
+ isError?: boolean;
60
61
  };
61
62
  } | {
62
63
  type: 'add_portlet';
@@ -2050,14 +2050,14 @@ function B(r, e) {
2050
2050
  const t = typeof r == "function" ? r(e) : r;
2051
2051
  return lt(t);
2052
2052
  }
2053
- function ZT(r, e, t) {
2053
+ function zT(r, e, t) {
2054
2054
  return {
2055
2055
  ...r,
2056
2056
  cubes: e,
2057
2057
  currentCube: t
2058
2058
  };
2059
2059
  }
2060
- function zT(r, e) {
2060
+ function eA(r, e) {
2061
2061
  return {
2062
2062
  name: r,
2063
2063
  ...e
@@ -2291,7 +2291,7 @@ function gt(r) {
2291
2291
  e ^= r.charCodeAt(t), e = e * 16777619 >>> 0;
2292
2292
  return e.toString(16).padStart(8, "0");
2293
2293
  }
2294
- function eA(r, e) {
2294
+ function tA(r, e) {
2295
2295
  return `${e ?? "drizzle-cube:"}*${r}*`;
2296
2296
  }
2297
2297
  class Oe {
@@ -7545,7 +7545,7 @@ class Vn {
7545
7545
  return e;
7546
7546
  }
7547
7547
  }
7548
- class tA {
7548
+ class sA {
7549
7549
  name = "pipeline";
7550
7550
  passes;
7551
7551
  constructor(e = []) {
@@ -29594,7 +29594,10 @@ function ws(r, e) {
29594
29594
  t.push(`Cube '${a}' not found (referenced in measure '${E}')`);
29595
29595
  continue;
29596
29596
  }
29597
- o.measures[A] || t.push(`Measure '${A}' not found on cube '${a}'`);
29597
+ if (!o.measures[A]) {
29598
+ const R = A === a ? `. Did you mean one of: ${Object.keys(o.measures).slice(0, 5).map((S) => `'${a}.${S}'`).join(", ")}?` : "";
29599
+ t.push(`Measure '${A}' not found on cube '${a}'${R}`);
29600
+ }
29598
29601
  }
29599
29602
  if (e.dimensions)
29600
29603
  for (const E of e.dimensions) {
@@ -29609,7 +29612,10 @@ function ws(r, e) {
29609
29612
  t.push(`Cube '${a}' not found (referenced in dimension '${E}')`);
29610
29613
  continue;
29611
29614
  }
29612
- o.dimensions[A] || t.push(`Dimension '${A}' not found on cube '${a}'`);
29615
+ if (!o.dimensions[A]) {
29616
+ const R = A === a ? `. Did you mean one of: ${Object.keys(o.dimensions).slice(0, 5).map((S) => `'${a}.${S}'`).join(", ")}?` : "";
29617
+ t.push(`Dimension '${A}' not found on cube '${a}'${R}`);
29618
+ }
29613
29619
  }
29614
29620
  if (e.timeDimensions)
29615
29621
  for (const E of e.timeDimensions) {
@@ -29656,7 +29662,10 @@ function $s(r, e, t, s) {
29656
29662
  t.push(`Cube '${n}' not found (referenced in filter '${r.member}')`);
29657
29663
  return;
29658
29664
  }
29659
- !E.dimensions[i] && !E.measures[i] && t.push(`Filter field '${i}' not found on cube '${n}' (must be a dimension or measure)`);
29665
+ if (!E.dimensions[i] && !E.measures[i]) {
29666
+ const a = i === n ? `. Did you mean one of: ${[...Object.keys(E.dimensions), ...Object.keys(E.measures)].slice(0, 5).map((A) => `'${n}.${A}'`).join(", ")}?` : "";
29667
+ t.push(`Filter field '${i}' not found on cube '${n}' (must be a dimension or measure)${a}`);
29668
+ }
29660
29669
  }
29661
29670
  function zo(r) {
29662
29671
  if (typeof r == "string") {
@@ -29665,7 +29674,7 @@ function zo(r) {
29665
29674
  }
29666
29675
  return r.cube;
29667
29676
  }
29668
- class sA {
29677
+ class nA {
29669
29678
  cache = /* @__PURE__ */ new Map();
29670
29679
  defaultTtlMs;
29671
29680
  maxEntries;
@@ -29854,7 +29863,7 @@ Return ONLY valid JSON with no explanations:
29854
29863
  }
29855
29864
 
29856
29865
  CRITICAL: Be strict. When in doubt, reject. False positives are better than security breaches.`;
29857
- function nA(r) {
29866
+ function iA(r) {
29858
29867
  return eT.replace("{USER_PROMPT}", r);
29859
29868
  }
29860
29869
  const tT = `You are a helpful AI assistant for analyzing business data using Cube.js/Drizzle-Cube semantic layer.
@@ -29994,7 +30003,7 @@ USER QUERY:
29994
30003
  {USER_PROMPT}
29995
30004
 
29996
30005
  Return the JSON response:`;
29997
- function iA(r, e) {
30006
+ function rA(r, e) {
29998
30007
  return tT.replace("{CUBE_SCHEMA}", r).replace("{USER_PROMPT}", e);
29999
30008
  }
30000
30009
  const sT = `You are analyzing a data query request to determine its structure.
@@ -30026,7 +30035,7 @@ USER QUERY:
30026
30035
  {USER_PROMPT}
30027
30036
 
30028
30037
  Return ONLY valid JSON - no explanations or markdown:`;
30029
- function rA(r, e) {
30038
+ function EA(r, e) {
30030
30039
  return sT.replace("{CUBE_SCHEMA}", r).replace("{USER_PROMPT}", e);
30031
30040
  }
30032
30041
  const nT = `Complete the data query using actual dimension values from the database.
@@ -30086,7 +30095,7 @@ CRITICAL FILTER FORMAT RULES:
30086
30095
  - The time filter (inDateRange) goes ONLY on step 0's filter, not on other steps.
30087
30096
 
30088
30097
  Return ONLY valid JSON - no explanations or markdown:`;
30089
- function EA(r, e, t) {
30098
+ function aA(r, e, t) {
30090
30099
  const s = JSON.stringify(t, null, 2);
30091
30100
  return nT.replace("{CUBE_SCHEMA}", r).replace("{USER_PROMPT}", e).replace("{DIMENSION_VALUES}", s);
30092
30101
  }
@@ -30333,10 +30342,10 @@ RESPONSE FORMAT (JSON):
30333
30342
  }
30334
30343
 
30335
30344
  CRITICAL: Return ONLY valid JSON. No markdown, no explanations outside JSON.`;
30336
- function aA(r, e, t, s, n, i, E) {
30345
+ function oA(r, e, t, s, n, i, E) {
30337
30346
  return iT.replace("{DATABASE_TYPE}", r).replaceAll("{DATABASE_TYPE}", r).replace("{CUBE_SCHEMA}", e).replace("{SEMANTIC_QUERY}", t).replace("{SQL_QUERY}", s).replace("{NORMALIZED_PLAN}", n).replace("{RAW_EXPLAIN}", i).replace("{EXISTING_INDEXES}", E || "No index information available");
30338
30347
  }
30339
- function oA(r) {
30348
+ function TA(r) {
30340
30349
  const e = {};
30341
30350
  for (const t of r) {
30342
30351
  e[t.name] = {
@@ -30365,7 +30374,7 @@ function oA(r) {
30365
30374
  }
30366
30375
  return JSON.stringify({ cubes: e }, null, 2);
30367
30376
  }
30368
- function TA(r) {
30377
+ function AA(r) {
30369
30378
  if (!r || r.length === 0)
30370
30379
  return "No indexes found on the queried tables.";
30371
30380
  const e = {};
@@ -30433,7 +30442,7 @@ const rT = {
30433
30442
  type: "text",
30434
30443
  text: [
30435
30444
  "Rules (keep JSON only):",
30436
- "- Use only measures/dimensions/timeDimensions from schema.",
30445
+ "- Use only measures/dimensions/timeDimensions from schema. Fields are always `CubeName.fieldName` — never use just the cube name (e.g. `PullRequests.count` not `PullRequests`).",
30437
30446
  "- timeDimensions: include granularity when grouping; use inDateRange filter for relative windows; combine when both requested.",
30438
30447
  "- Funnel detection keywords: funnel, conversion, journey, drop off, step by step; use funnel format only if eventStream metadata exists.",
30439
30448
  "- Funnel rules: bindingKey/timeDimension from cube metadata; include time filter on step 0 (default last 6 months) using inDateRange; steps ordered; flat filters.",
@@ -30774,6 +30783,7 @@ function AT(r) {
30774
30783
  "## Important Guidelines",
30775
30784
  "",
30776
30785
  "- ALWAYS discover cubes first before attempting queries",
30786
+ "- Field names MUST be `CubeName.fieldName` (e.g. `PullRequests.count`, `Teams.name`). NEVER use just the cube name as a field — `PullRequests.PullRequests` is WRONG.",
30777
30787
  "- Use `add_portlet` to create visualizations after getting query results",
30778
30788
  "- Use `add_markdown` to explain your findings, methodology, and insights",
30779
30789
  "- Choose appropriate chart types: bar for categories, line for trends, table for detailed data",
@@ -30785,15 +30795,20 @@ function AT(r) {
30785
30795
  "### CRITICAL: Always think before acting",
30786
30796
  "- EVERY single turn MUST begin with a text message (1-2 sentences) BEFORE any tool calls. This is your #1 rule — never violate it.",
30787
30797
  "- This applies to EVERY turn, including turns where you are adding visualizations or explanations to the notebook.",
30788
- `- Even when adding multiple portlets/markdowns in sequence, each turn must start with text like "Now I'll add the productivity chart." or "Next, let me visualize the department breakdown."`,
30789
- '- Example good turn: "Let me discover what data is available." → discover_cubes',
30790
- `- Example good turn: "I'll add a bar chart showing the top employees." → add_markdown → add_portlet`,
30798
+ `- Even when adding multiple charts in sequence, each turn must start with a brief status like "Now I'll chart the productivity breakdown." or "Next, let me show the department comparison."`,
30799
+ '- Example good turn: "Let me see what data is available." → discover_cubes',
30800
+ `- Example good turn: "I'll add a chart showing the top employees." → add_markdown → add_portlet`,
30791
30801
  "- Example bad turn: (no text) → add_portlet ← NEVER do this",
30792
30802
  "",
30793
30803
  "### Text vs Notebook",
30794
30804
  "- ALL analysis, findings, methodology, and insights MUST go through `add_markdown` tool calls — never in your text responses",
30795
30805
  "- Your text responses must be 1-2 short sentences (under 50 words) summarizing what you are about to do next — status updates only",
30796
30806
  "- Never use markdown formatting (headers, bullets, bold, code blocks) in text responses — plain sentences only",
30807
+ "- Write text responses as a friendly analyst would — use plain business language the user understands",
30808
+ '- NEVER mention internal terms like "cube", "query syntax", "field names", "measures", "dimensions", "portlet", "prefix format", or tool names in text responses',
30809
+ '- Instead of "Let me correct the query syntax and retry" → "Let me fix that and try again"',
30810
+ `- Instead of "I'll query the PullRequests cube" → "I'll look at the pull request data"`,
30811
+ `- Instead of "Adding a portlet with the results" → "Here's a chart of the results"`,
30797
30812
  "",
30798
30813
  "### Notebook content rules",
30799
30814
  "- Before each `add_portlet`, ALWAYS call `add_markdown` first to explain WHY you are adding this visualization and what it shows",
@@ -30833,6 +30848,21 @@ function AT(r) {
30833
30848
  "",
30834
30849
  '**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`.',
30835
30850
  "",
30851
+ "## Chart Axis Configuration Rules",
30852
+ "",
30853
+ "**Bar charts MUST have an xAxis.** Put a dimension in `chartConfig.xAxis` so bars have category labels. If your query has no dimensions, add one or use `table` instead.",
30854
+ "",
30855
+ "**Never duplicate xAxis in series.** Putting the same dimension in both `xAxis` and `series` creates a sparse, broken-looking chart. The `series` field is ONLY for splitting bars into grouped/stacked sub-series by a SECOND dimension.",
30856
+ "",
30857
+ "Correct bar chart examples:",
30858
+ '- Categories only: `xAxis: ["Cube.category"], yAxis: ["Cube.count"]` — no series needed',
30859
+ '- Grouped bars: `xAxis: ["Cube.category"], yAxis: ["Cube.count"], series: ["Cube.status"]` — series is a DIFFERENT dimension',
30860
+ '- Multiple measures: `xAxis: ["Cube.category"], yAxis: ["Cube.count", "Cube.total"]` — each measure becomes a bar group',
30861
+ "",
30862
+ "Wrong:",
30863
+ '- `xAxis: [], yAxis: ["Cube.avg1", "Cube.avg2"]` — missing xAxis, bars have no labels',
30864
+ '- `xAxis: ["Cube.size"], series: ["Cube.size"]` — same field in both, creates sparse chart',
30865
+ "",
30836
30866
  "## Analysis Mode Decision Tree",
30837
30867
  "",
30838
30868
  "The default mode is **query** (standard measures/dimensions). Switch to a special mode only when the user's question matches:",
@@ -32175,6 +32205,25 @@ function bT(r, e, t) {
32175
32205
  );
32176
32206
  }
32177
32207
  }
32208
+ if (r === "bar") {
32209
+ const i = e?.xAxis;
32210
+ if (!(Array.isArray(i) ? i.length > 0 : !!i)) {
32211
+ const a = t.dimensions ?? [], A = t.timeDimensions ?? [];
32212
+ a.length > 0 || A.length > 0 ? n.push(
32213
+ "chartConfig.xAxis is required for bar charts. Put a dimension in xAxis so bars have category labels."
32214
+ ) : n.push(
32215
+ 'Bar charts need an xAxis dimension for category labels. Add a dimension to the query or use "table" chart type instead.'
32216
+ );
32217
+ }
32218
+ }
32219
+ if (e?.xAxis && e?.series) {
32220
+ const i = new Set(
32221
+ Array.isArray(e.xAxis) ? e.xAxis : [e.xAxis]
32222
+ ), a = (Array.isArray(e.series) ? e.series : [e.series]).filter((A) => i.has(A));
32223
+ a.length > 0 && n.push(
32224
+ `chartConfig.series must not contain the same field as xAxis (found: ${a.join(", ")}). The series field is only for splitting into grouped/stacked sub-series by a DIFFERENT dimension. Remove the duplicate from series.`
32225
+ );
32226
+ }
32178
32227
  return { isValid: n.length === 0, errors: n };
32179
32228
  }
32180
32229
  function GT(r, e, t) {
@@ -32188,21 +32237,28 @@ function GT(r, e, t) {
32188
32237
  const l = o.acceptTypes ?? [];
32189
32238
  if (o.key === "sizeField" || o.key === "colorField") {
32190
32239
  if (l.includes("measure")) {
32191
- const c = /* @__PURE__ */ new Set();
32192
- for (const d of s.dropZones) {
32193
- if (d.key === o.key) continue;
32194
- const p = n[d.key];
32195
- Array.isArray(p) ? p.forEach((f) => c.add(f)) : typeof p == "string" && c.add(p);
32240
+ const u = /* @__PURE__ */ new Set();
32241
+ for (const p of s.dropZones) {
32242
+ if (p.key === o.key) continue;
32243
+ const f = n[p.key];
32244
+ Array.isArray(f) ? f.forEach((m) => u.add(m)) : typeof f == "string" && u.add(f);
32196
32245
  }
32197
- const u = i.filter((d) => !c.has(d));
32198
- u.length > 0 && (n[o.key] = u[0]);
32246
+ const d = i.filter((p) => !u.has(p));
32247
+ d.length > 0 && (n[o.key] = d[0]);
32199
32248
  }
32200
32249
  continue;
32201
32250
  }
32202
32251
  const N = [];
32203
32252
  if (l.includes("dimension") && N.push(...E), l.includes("timeDimension") && N.push(...A), l.includes("measure") && N.push(...i), N.length === 0) continue;
32204
- const I = o.maxItems ?? 1 / 0, O = N.slice(0, I);
32205
- O.length > 0 && (n[o.key] = O);
32253
+ let I = N;
32254
+ if (o.key === "series") {
32255
+ const u = new Set(
32256
+ Array.isArray(n.xAxis) ? n.xAxis : n.xAxis ? [n.xAxis] : []
32257
+ );
32258
+ if (I = N.filter((d) => !u.has(d)), I.length === 0) continue;
32259
+ }
32260
+ const O = o.maxItems ?? 1 / 0, c = I.slice(0, O);
32261
+ c.length > 0 && (n[o.key] = c);
32206
32262
  }
32207
32263
  return n;
32208
32264
  }
@@ -32522,7 +32578,7 @@ ${A.errors.join(`
32522
32578
  if (o)
32523
32579
  R = n.chartConfig ?? {};
32524
32580
  else {
32525
- const N = GT(E, n.chartConfig, a), I = bT(E, N);
32581
+ const N = GT(E, n.chartConfig, a), I = bT(E, N, a);
32526
32582
  if (!I.isValid)
32527
32583
  return {
32528
32584
  result: `Chart config invalid — fix these errors and retry:
@@ -32556,7 +32612,7 @@ ${I.errors.join(`
32556
32612
  };
32557
32613
  }), s;
32558
32614
  }
32559
- async function* AA(r) {
32615
+ async function* RA(r) {
32560
32616
  const { message: e, sessionId: t, semanticLayer: s, securityContext: n, agentConfig: i, apiKey: E } = r;
32561
32617
  let a;
32562
32618
  try {
@@ -32639,7 +32695,7 @@ async function* AA(r) {
32639
32695
  is_error: !0
32640
32696
  }), yield {
32641
32697
  type: "tool_use_result",
32642
- data: { id: w, name: U, result: `Unknown tool: ${U}` }
32698
+ data: { id: w, name: U, result: `Unknown tool: ${U}`, isError: !0 }
32643
32699
  };
32644
32700
  continue;
32645
32701
  }
@@ -32652,7 +32708,7 @@ async function* AA(r) {
32652
32708
  ...x.isError ? { is_error: !0 } : {}
32653
32709
  }), yield {
32654
32710
  type: "tool_use_result",
32655
- data: { id: w, name: U, result: x.result }
32711
+ data: { id: w, name: U, result: x.result, ...x.isError ? { isError: !0 } : {} }
32656
32712
  };
32657
32713
  } catch (x) {
32658
32714
  const k = x instanceof Error ? x.message : "Tool execution failed";
@@ -32663,7 +32719,7 @@ async function* AA(r) {
32663
32719
  is_error: !0
32664
32720
  }), yield {
32665
32721
  type: "tool_use_result",
32666
- data: { id: w, name: U, result: k }
32722
+ data: { id: w, name: U, result: k, isError: !0 }
32667
32723
  };
32668
32724
  }
32669
32725
  }
@@ -32677,11 +32733,37 @@ async function* AA(r) {
32677
32733
  yield {
32678
32734
  type: "error",
32679
32735
  data: {
32680
- message: u instanceof Error ? u.message : "Agent execution failed"
32736
+ message: YT(u)
32681
32737
  }
32682
32738
  };
32683
32739
  }
32684
32740
  }
32741
+ function YT(r) {
32742
+ if (!r || !(r instanceof Error))
32743
+ return "Something went wrong. Please try again.";
32744
+ const e = r.message || "", t = {
32745
+ overloaded_error: "The AI service is temporarily overloaded. Please try again in a moment.",
32746
+ rate_limit_error: "Too many requests. Please wait a moment and try again.",
32747
+ api_error: "The AI service encountered an error. Please try again.",
32748
+ authentication_error: "Authentication failed. Please check your API key configuration.",
32749
+ invalid_request_error: "There was a problem with the request. Please try again."
32750
+ }, s = r;
32751
+ if (s.status || s.type) {
32752
+ const n = s.error?.type || s.type || "";
32753
+ if (t[n])
32754
+ return t[n];
32755
+ }
32756
+ if (e.startsWith("{") || e.startsWith("Error: {")) {
32757
+ try {
32758
+ const n = JSON.parse(e.replace(/^Error:\s*/, "")), i = n.error?.type || n.type || "";
32759
+ if (t[i])
32760
+ return t[i];
32761
+ } catch {
32762
+ }
32763
+ return "The AI service encountered an error. Please try again.";
32764
+ }
32765
+ return e;
32766
+ }
32685
32767
  const cs = {
32686
32768
  funnel: {
32687
32769
  description: "Track conversion through sequential steps. Entities (identified by bindingKey) move through ordered steps.",
@@ -32733,7 +32815,7 @@ const cs = {
32733
32815
  }
32734
32816
  }
32735
32817
  };
32736
- function YT(r, e) {
32818
+ function wT(r, e) {
32737
32819
  const t = [];
32738
32820
  for (let s = 0; s <= e.length; s++)
32739
32821
  t[s] = [s];
@@ -32757,7 +32839,7 @@ function X(r, e) {
32757
32839
  if (A === t) return 0.85;
32758
32840
  if (A.startsWith(t)) return 0.75;
32759
32841
  }
32760
- const i = YT(t, s), E = Math.max(t.length, s.length), a = 1 - i / E;
32842
+ const i = wT(t, s), E = Math.max(t.length, s.length), a = 1 - i / E;
32761
32843
  return a > 0.5 ? a * 0.7 : 0;
32762
32844
  }
32763
32845
  function Me(r, e) {
@@ -32768,7 +32850,7 @@ function Me(r, e) {
32768
32850
  }
32769
32851
  return t;
32770
32852
  }
32771
- function wT(r) {
32853
+ function $T(r) {
32772
32854
  const e = /* @__PURE__ */ new Set([
32773
32855
  "a",
32774
32856
  "an",
@@ -32862,7 +32944,7 @@ function wT(r) {
32862
32944
  ]);
32863
32945
  return r.toLowerCase().replace(/[^\w\s]/g, " ").split(/\s+/).filter((t) => t.length > 2 && !e.has(t));
32864
32946
  }
32865
- function $T(r, e) {
32947
+ function vT(r, e) {
32866
32948
  let t = 0;
32867
32949
  const s = [], n = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map();
32868
32950
  for (const o of e) {
@@ -32984,12 +33066,12 @@ function vs(r, e = {}) {
32984
33066
  querySchemas: N ? cs : void 0
32985
33067
  };
32986
33068
  });
32987
- const a = wT(E);
33069
+ const a = $T(E);
32988
33070
  if (a.length === 0)
32989
33071
  return [];
32990
33072
  const A = [];
32991
33073
  for (const o of r) {
32992
- const { score: R, matchedOn: S, suggestedMeasures: l, suggestedDimensions: N } = $T(o, a);
33074
+ const { score: R, matchedOn: S, suggestedMeasures: l, suggestedDimensions: N } = vT(o, a);
32993
33075
  if (R >= i) {
32994
33076
  const I = Ot(o), O = Cs(o), c = ds(o, O), u = I.funnel || I.flow || I.retention;
32995
33077
  A.push({
@@ -33027,7 +33109,7 @@ function mt(r, e, t) {
33027
33109
  }
33028
33110
  return s;
33029
33111
  }
33030
- function vT() {
33112
+ function VT() {
33031
33113
  const r = /* @__PURE__ */ new Date(), e = r.toISOString().split("T")[0], t = (a) => a.toISOString().split("T")[0], s = (a) => new Date(a.getFullYear(), a.getMonth(), 1), n = (a) => new Date(a.getFullYear(), 0, 1), i = (a) => {
33032
33114
  const A = Math.floor(a.getMonth() / 3);
33033
33115
  return new Date(a.getFullYear(), A * 3, 1);
@@ -33157,7 +33239,7 @@ const At = {
33157
33239
  flow: /\b(flows?|paths?|sequence|before|after|next|previous|user.?journey)\b/i,
33158
33240
  retention: /\b(retention|cohort|return|churn|comeback|retained|day.?\d+)\b/i
33159
33241
  };
33160
- function VT(r) {
33242
+ function WT(r) {
33161
33243
  const e = r.toLowerCase();
33162
33244
  return At.funnel.test(e) ? "funnel" : At.flow.test(e) ? "flow" : At.retention.test(e) ? "retention" : "query";
33163
33245
  }
@@ -33183,8 +33265,8 @@ function ms(r, e) {
33183
33265
  ];
33184
33266
  }
33185
33267
  }
33186
- function WT(r) {
33187
- const e = vT(), t = r.toLowerCase();
33268
+ function xT(r) {
33269
+ const e = VT(), t = r.toLowerCase();
33188
33270
  for (const s of e) {
33189
33271
  const n = t.match(s.pattern);
33190
33272
  if (n) {
@@ -33212,7 +33294,7 @@ function WT(r) {
33212
33294
  }
33213
33295
  return null;
33214
33296
  }
33215
- function xT(r) {
33297
+ function XT(r) {
33216
33298
  const e = r.toLowerCase(), t = [
33217
33299
  { pattern: /\b(total|sum|combined)\b/i, type: "sum" },
33218
33300
  { pattern: /\b(count|number of|how many)\b/i, type: "count" },
@@ -33225,7 +33307,7 @@ function xT(r) {
33225
33307
  return { type: n, confidence: 0.8 };
33226
33308
  return null;
33227
33309
  }
33228
- function XT(r) {
33310
+ function KT(r) {
33229
33311
  const e = r.toLowerCase(), t = [], s = /\bby\s+(\w+(?:\s+\w+)?)/gi;
33230
33312
  let n;
33231
33313
  for (; (n = s.exec(e)) !== null; )
@@ -33238,8 +33320,8 @@ function XT(r) {
33238
33320
  t.push(n[1].trim());
33239
33321
  return t;
33240
33322
  }
33241
- function RA(r, e, t) {
33242
- const s = [], n = [], i = {}, E = VT(e);
33323
+ function SA(r, e, t) {
33324
+ const s = [], n = [], i = {}, E = WT(e);
33243
33325
  let a;
33244
33326
  if (t) {
33245
33327
  const c = r.find((u) => u.name === t);
@@ -33259,7 +33341,7 @@ function RA(r, e, t) {
33259
33341
  }
33260
33342
  const A = a[0];
33261
33343
  let o = 0.5;
33262
- const R = xT(e);
33344
+ const R = XT(e);
33263
33345
  R && (s.push(`Detected ${R.type} aggregation intent`), o += 0.1);
33264
33346
  const S = [], l = e.toLowerCase();
33265
33347
  for (const c of A.measures) {
@@ -33286,7 +33368,7 @@ function RA(r, e, t) {
33286
33368
  }
33287
33369
  }
33288
33370
  S.length === 0 && A.measures.length > 0 && (S.push(A.measures[0].name), s.push(`Using default measure: ${A.measures[0].name}`), n.push("Could not determine specific measure from query, using default")), i.measures = S;
33289
- const N = XT(e), I = [];
33371
+ const N = KT(e), I = [];
33290
33372
  for (const c of N) {
33291
33373
  const u = mt(a, c, "dimension");
33292
33374
  u && (I.push(u.field), s.push(`Matched dimension '${u.field}' from grouping keyword '${c}'`), o += 0.1);
@@ -33305,7 +33387,7 @@ function RA(r, e, t) {
33305
33387
  }
33306
33388
  }
33307
33389
  I.length > 0 && (i.dimensions = I);
33308
- const O = WT(e);
33390
+ const O = xT(e);
33309
33391
  if (O) {
33310
33392
  const c = A.dimensions.find((u) => u.type === "time");
33311
33393
  if (c) {
@@ -33339,7 +33421,7 @@ function RA(r, e, t) {
33339
33421
  analysisMode: "query"
33340
33422
  };
33341
33423
  }
33342
- function KT(r, e) {
33424
+ function kT(r, e) {
33343
33425
  const t = [];
33344
33426
  for (let s = 0; s <= e.length; s++)
33345
33427
  t[s] = [s];
@@ -33357,12 +33439,12 @@ function KT(r, e) {
33357
33439
  function Se(r, e) {
33358
33440
  let t = null;
33359
33441
  for (const s of e) {
33360
- const n = KT(r.toLowerCase(), s.toLowerCase());
33442
+ const n = kT(r.toLowerCase(), s.toLowerCase());
33361
33443
  n <= 3 && (!t || n < t.distance) && (t = { field: s, distance: n });
33362
33444
  }
33363
33445
  return t;
33364
33446
  }
33365
- function kT(r, e, t, s) {
33447
+ function JT(r, e, t, s) {
33366
33448
  const n = r.split(".");
33367
33449
  if (n.length !== 2) {
33368
33450
  t.push({
@@ -33535,7 +33617,7 @@ function Ue(r, e, t, s) {
33535
33617
  }
33536
33618
  }
33537
33619
  }
33538
- function JT(r, e, t, s, n) {
33620
+ function QT(r, e, t, s, n) {
33539
33621
  const i = r.funnel;
33540
33622
  if (i)
33541
33623
  if (i.bindingKey ? typeof i.bindingKey == "string" && te(i.bindingKey, e, t, n) : t.push({
@@ -33564,7 +33646,7 @@ function JT(r, e, t, s, n) {
33564
33646
  }), a.filter && "member" in a.filter && Ue([a.filter], e, t, n);
33565
33647
  }
33566
33648
  }
33567
- function QT(r, e, t, s, n) {
33649
+ function qT(r, e, t, s, n) {
33568
33650
  const i = r.flow;
33569
33651
  i && (i.bindingKey ? typeof i.bindingKey == "string" && te(i.bindingKey, e, t, n) : t.push({
33570
33652
  type: "syntax_error",
@@ -33581,7 +33663,7 @@ function QT(r, e, t, s, n) {
33581
33663
  suggestion: "Set stepsBefore and/or stepsAfter to see event sequences"
33582
33664
  }));
33583
33665
  }
33584
- function qT(r, e, t, s, n) {
33666
+ function jT(r, e, t, s, n) {
33585
33667
  const i = r.retention;
33586
33668
  i && (i.bindingKey ? typeof i.bindingKey == "string" && te(i.bindingKey, e, t, n) : t.push({
33587
33669
  type: "syntax_error",
@@ -33599,10 +33681,10 @@ function qT(r, e, t, s, n) {
33599
33681
  suggestion: "Specify number of periods to analyze"
33600
33682
  }));
33601
33683
  }
33602
- function SA(r, e) {
33684
+ function lA(r, e) {
33603
33685
  const t = [], s = [], n = /* @__PURE__ */ new Map();
33604
33686
  if (r.funnel)
33605
- return JT(r, e, t, s, n), {
33687
+ return QT(r, e, t, s, n), {
33606
33688
  isValid: t.length === 0,
33607
33689
  errors: t,
33608
33690
  warnings: s,
@@ -33610,14 +33692,14 @@ function SA(r, e) {
33610
33692
  // Funnel corrections not implemented yet
33611
33693
  };
33612
33694
  if (r.flow)
33613
- return QT(r, e, t, s, n), {
33695
+ return qT(r, e, t, s, n), {
33614
33696
  isValid: t.length === 0,
33615
33697
  errors: t,
33616
33698
  warnings: s,
33617
33699
  correctedQuery: void 0
33618
33700
  };
33619
33701
  if (r.retention)
33620
- return qT(r, e, t, s, n), {
33702
+ return jT(r, e, t, s, n), {
33621
33703
  isValid: t.length === 0,
33622
33704
  errors: t,
33623
33705
  warnings: s,
@@ -33625,7 +33707,7 @@ function SA(r, e) {
33625
33707
  };
33626
33708
  if (r.measures)
33627
33709
  for (const E of r.measures)
33628
- kT(E, e, t, n);
33710
+ JT(E, e, t, n);
33629
33711
  if (r.dimensions)
33630
33712
  for (const E of r.dimensions)
33631
33713
  te(E, e, t, n);
@@ -33670,7 +33752,7 @@ function SA(r, e) {
33670
33752
  correctedQuery: n.size > 0 ? i : void 0
33671
33753
  };
33672
33754
  }
33673
- function lA(r) {
33755
+ function NA(r) {
33674
33756
  return new Ct({
33675
33757
  drizzle: r.drizzle,
33676
33758
  schema: r.schema
@@ -33691,9 +33773,9 @@ export {
33691
33773
  me as JoinPathResolver,
33692
33774
  vn as LogicalPlanBuilder,
33693
33775
  Mn as LogicalPlanner,
33694
- sA as MemoryCacheProvider,
33776
+ nA as MemoryCacheProvider,
33695
33777
  _s as MySQLExecutor,
33696
- tA as OptimiserPipeline,
33778
+ sA as OptimiserPipeline,
33697
33779
  nn as PostgresExecutor,
33698
33780
  Zn as QueryExecutor,
33699
33781
  $n as RetentionQueryBuilder,
@@ -33703,34 +33785,34 @@ export {
33703
33785
  nT as STEP2_SYSTEM_PROMPT,
33704
33786
  tT as SYSTEM_PROMPT_TEMPLATE,
33705
33787
  Ct as SemanticLayerCompiler,
33706
- SA as aiValidateQuery,
33788
+ lA as aiValidateQuery,
33707
33789
  AT as buildAgentSystemPrompt,
33708
- aA as buildExplainAnalysisPrompt,
33709
- nA as buildStep0Prompt,
33710
- rA as buildStep1Prompt,
33711
- EA as buildStep2Prompt,
33712
- iA as buildSystemPrompt,
33790
+ oA as buildExplainAnalysisPrompt,
33791
+ iA as buildStep0Prompt,
33792
+ EA as buildStep1Prompt,
33793
+ aA as buildStep2Prompt,
33794
+ rA as buildSystemPrompt,
33713
33795
  yt as createDatabaseExecutor,
33714
- lA as createDrizzleSemanticLayer,
33796
+ NA as createDrizzleSemanticLayer,
33715
33797
  un as createDuckDBExecutor,
33716
- ZT as createMultiCubeContext,
33798
+ zT as createMultiCubeContext,
33717
33799
  an as createMySQLExecutor,
33718
33800
  Mt as createPostgresExecutor,
33719
33801
  Ut as createSQLiteExecutor,
33720
33802
  HT as createToolExecutor,
33721
- zT as defineCube,
33803
+ eA as defineCube,
33722
33804
  vs as discoverCubes,
33723
33805
  mt as findBestFieldMatch,
33724
33806
  gt as fnv1aHash,
33725
- oA as formatCubeSchemaForExplain,
33726
- TA as formatExistingIndexes,
33807
+ TA as formatCubeSchemaForExplain,
33808
+ AA as formatExistingIndexes,
33727
33809
  Cn as generateCacheKey,
33728
- eA as getCubeInvalidationPattern,
33810
+ tA as getCubeInvalidationPattern,
33729
33811
  St as getJoinType,
33730
33812
  BT as getToolDefinitions,
33731
- AA as handleAgentChat,
33813
+ RA as handleAgentChat,
33732
33814
  dn as normalizeQuery,
33733
33815
  J as resolveCubeReference,
33734
33816
  B as resolveSqlExpression,
33735
- RA as suggestQuery
33817
+ SA as suggestQuery
33736
33818
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drizzle-cube",
3
- "version": "0.4.9",
3
+ "version": "0.4.11",
4
4
  "description": "Drizzle ORM-first semantic layer with Cube.js compatibility. Type-safe analytics and dashboards with SQL injection protection.",
5
5
  "main": "./dist/server/index.js",
6
6
  "types": "./dist/server/index.d.ts",