drizzle-cube 0.4.13 → 0.4.14

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 (116) hide show
  1. package/README.md +1 -0
  2. package/dist/adapters/express/index.cjs +6 -6
  3. package/dist/adapters/express/index.js +73 -72
  4. package/dist/adapters/fastify/index.cjs +5 -5
  5. package/dist/adapters/fastify/index.js +110 -109
  6. package/dist/adapters/{handler-CQkIwtxp.js → handler-DZnCbydH.js} +719 -272
  7. package/dist/adapters/handler-ZDYlokiM.cjs +25 -0
  8. package/dist/adapters/hono/index.cjs +6 -6
  9. package/dist/adapters/hono/index.js +121 -120
  10. package/dist/adapters/nextjs/index.cjs +5 -5
  11. package/dist/adapters/nextjs/index.js +92 -91
  12. package/dist/client/charts.js +67 -59
  13. package/dist/client/charts.js.map +1 -1
  14. package/dist/client/chunks/{RetentionCombinedChart-CEI8KQ3t.js → RetentionCombinedChart-CLq89aOJ.js} +2 -2
  15. package/dist/client/chunks/{RetentionCombinedChart-CEI8KQ3t.js.map → RetentionCombinedChart-CLq89aOJ.js.map} +1 -1
  16. package/dist/client/chunks/{analysis-builder-BMmWeFPr.js → analysis-builder-C5e52Z3p.js} +419 -411
  17. package/dist/client/chunks/analysis-builder-C5e52Z3p.js.map +1 -0
  18. package/dist/client/chunks/{analysis-builder-shared-D56zYeV0.js → analysis-builder-shared-EnM-8plh.js} +2 -2
  19. package/dist/client/chunks/{analysis-builder-shared-D56zYeV0.js.map → analysis-builder-shared-EnM-8plh.js.map} +1 -1
  20. package/dist/client/chunks/{chart-activity-grid-CE7xGFQo.js → chart-activity-grid-CPGcTSuh.js} +2 -2
  21. package/dist/client/chunks/{chart-activity-grid-CE7xGFQo.js.map → chart-activity-grid-CPGcTSuh.js.map} +1 -1
  22. package/dist/client/chunks/{chart-area-BJAgusst.js → chart-area-ByJQ7NZd.js} +3 -3
  23. package/dist/client/chunks/{chart-area-BJAgusst.js.map → chart-area-ByJQ7NZd.js.map} +1 -1
  24. package/dist/client/chunks/{chart-bar-Blypx8O4.js → chart-bar-dj14frMt.js} +2 -2
  25. package/dist/client/chunks/{chart-bar-Blypx8O4.js.map → chart-bar-dj14frMt.js.map} +1 -1
  26. package/dist/client/chunks/chart-box-plot-ZatBpatq.js +322 -0
  27. package/dist/client/chunks/chart-box-plot-ZatBpatq.js.map +1 -0
  28. package/dist/client/chunks/{chart-bubble-Bf42A1-B.js → chart-bubble-CemotLx-.js} +2 -2
  29. package/dist/client/chunks/{chart-bubble-Bf42A1-B.js.map → chart-bubble-CemotLx-.js.map} +1 -1
  30. package/dist/client/chunks/chart-candlestick-BIR4uGGt.js +269 -0
  31. package/dist/client/chunks/chart-candlestick-BIR4uGGt.js.map +1 -0
  32. package/dist/client/chunks/chart-config-box-plot-D_E_SSc2.js +38 -0
  33. package/dist/client/chunks/chart-config-box-plot-D_E_SSc2.js.map +1 -0
  34. package/dist/client/chunks/chart-config-candlestick-CRCpD43-.js +70 -0
  35. package/dist/client/chunks/chart-config-candlestick-CRCpD43-.js.map +1 -0
  36. package/dist/client/chunks/chart-config-gauge-CQx9w3d4.js +64 -0
  37. package/dist/client/chunks/chart-config-gauge-CQx9w3d4.js.map +1 -0
  38. package/dist/client/chunks/chart-config-measure-profile-ZYaMrtws.js +70 -0
  39. package/dist/client/chunks/chart-config-measure-profile-ZYaMrtws.js.map +1 -0
  40. package/dist/client/chunks/chart-config-waterfall-DTyXV_fo.js +60 -0
  41. package/dist/client/chunks/chart-config-waterfall-DTyXV_fo.js.map +1 -0
  42. package/dist/client/chunks/{chart-data-table-Ba_6tuJw.js → chart-data-table-D5G8nMnb.js} +2 -2
  43. package/dist/client/chunks/{chart-data-table-Ba_6tuJw.js.map → chart-data-table-D5G8nMnb.js.map} +1 -1
  44. package/dist/client/chunks/{chart-funnel-C9kenCpp.js → chart-funnel-dofnhD24.js} +2 -2
  45. package/dist/client/chunks/{chart-funnel-C9kenCpp.js.map → chart-funnel-dofnhD24.js.map} +1 -1
  46. package/dist/client/chunks/chart-gauge-CKJJ8m3b.js +374 -0
  47. package/dist/client/chunks/chart-gauge-CKJJ8m3b.js.map +1 -0
  48. package/dist/client/chunks/{chart-heat-map-CYGemyPB.js → chart-heat-map-BVuPUKHT.js} +2 -2
  49. package/dist/client/chunks/{chart-heat-map-CYGemyPB.js.map → chart-heat-map-BVuPUKHT.js.map} +1 -1
  50. package/dist/client/chunks/{chart-kpi-delta-D9XJoKuA.js → chart-kpi-delta-Dgg2eYRl.js} +3 -3
  51. package/dist/client/chunks/{chart-kpi-delta-D9XJoKuA.js.map → chart-kpi-delta-Dgg2eYRl.js.map} +1 -1
  52. package/dist/client/chunks/{chart-kpi-number-C29Vj2g8.js → chart-kpi-number-DkoO99c1.js} +2 -2
  53. package/dist/client/chunks/{chart-kpi-number-C29Vj2g8.js.map → chart-kpi-number-DkoO99c1.js.map} +1 -1
  54. package/dist/client/chunks/{chart-kpi-text-CgjjrurK.js → chart-kpi-text-1O6_lmz7.js} +3 -3
  55. package/dist/client/chunks/{chart-kpi-text-CgjjrurK.js.map → chart-kpi-text-1O6_lmz7.js.map} +1 -1
  56. package/dist/client/chunks/{chart-line-zi6olZet.js → chart-line-DzyZkugh.js} +3 -3
  57. package/dist/client/chunks/{chart-line-zi6olZet.js.map → chart-line-DzyZkugh.js.map} +1 -1
  58. package/dist/client/chunks/chart-measure-profile-C2IkBG3V.js +114 -0
  59. package/dist/client/chunks/chart-measure-profile-C2IkBG3V.js.map +1 -0
  60. package/dist/client/chunks/{chart-pie-C4SuxKSN.js → chart-pie-akbfRfb9.js} +2 -2
  61. package/dist/client/chunks/{chart-pie-C4SuxKSN.js.map → chart-pie-akbfRfb9.js.map} +1 -1
  62. package/dist/client/chunks/{chart-radar-BW3Z_-Ly.js → chart-radar-BaN-Kjww.js} +2 -2
  63. package/dist/client/chunks/{chart-radar-BW3Z_-Ly.js.map → chart-radar-BaN-Kjww.js.map} +1 -1
  64. package/dist/client/chunks/{chart-radial-bar-0Fa3aeP5.js → chart-radial-bar-DpptEL3s.js} +2 -2
  65. package/dist/client/chunks/{chart-radial-bar-0Fa3aeP5.js.map → chart-radial-bar-DpptEL3s.js.map} +1 -1
  66. package/dist/client/chunks/{chart-sankey-DBghfbg1.js → chart-sankey-CG-3hHmX.js} +2 -2
  67. package/dist/client/chunks/{chart-sankey-DBghfbg1.js.map → chart-sankey-CG-3hHmX.js.map} +1 -1
  68. package/dist/client/chunks/{chart-scatter-DOVu1TNq.js → chart-scatter-l_yTVxF3.js} +2 -2
  69. package/dist/client/chunks/{chart-scatter-DOVu1TNq.js.map → chart-scatter-l_yTVxF3.js.map} +1 -1
  70. package/dist/client/chunks/{chart-sunburst-LfNthFlZ.js → chart-sunburst-KhDcKhmZ.js} +2 -2
  71. package/dist/client/chunks/{chart-sunburst-LfNthFlZ.js.map → chart-sunburst-KhDcKhmZ.js.map} +1 -1
  72. package/dist/client/chunks/{chart-tree-map-DZtQPyWX.js → chart-tree-map-CBbiaBXV.js} +2 -2
  73. package/dist/client/chunks/{chart-tree-map-DZtQPyWX.js.map → chart-tree-map-CBbiaBXV.js.map} +1 -1
  74. package/dist/client/chunks/chart-waterfall-CX3vx_lI.js +191 -0
  75. package/dist/client/chunks/chart-waterfall-CX3vx_lI.js.map +1 -0
  76. package/dist/client/chunks/{charts-core-DmGfleFz.js → charts-core-CU9u_HtL.js} +2 -1
  77. package/dist/client/chunks/charts-core-CU9u_HtL.js.map +1 -0
  78. package/dist/client/chunks/{charts-loader-CH0_S06T.js → charts-loader-AW3T1nv5.js} +58 -42
  79. package/dist/client/chunks/charts-loader-AW3T1nv5.js.map +1 -0
  80. package/dist/client/chunks/{components-ClQziOcT.js → components-BkeSy9xv.js} +4 -4
  81. package/dist/client/chunks/components-BkeSy9xv.js.map +1 -0
  82. package/dist/client/components/AgenticNotebook/AgentChatPanel.d.ts +10 -0
  83. package/dist/client/components/AgenticNotebook/ChatMessage.d.ts +2 -0
  84. package/dist/client/components/AgenticNotebook/index.d.ts +11 -1
  85. package/dist/client/components/LoadingIndicator.d.ts +2 -2
  86. package/dist/client/components/charts/BoxPlotChart.config.d.ts +1 -7
  87. package/dist/client/components/charts/CandlestickChart.config.d.ts +5 -0
  88. package/dist/client/components/charts/CandlestickChart.d.ts +4 -0
  89. package/dist/client/components/charts/GaugeChart.config.d.ts +5 -0
  90. package/dist/client/components/charts/GaugeChart.d.ts +4 -0
  91. package/dist/client/components/charts/MeasureProfileChart.config.d.ts +5 -0
  92. package/dist/client/components/charts/MeasureProfileChart.d.ts +4 -0
  93. package/dist/client/components/charts/WaterfallChart.config.d.ts +5 -0
  94. package/dist/client/components/charts/WaterfallChart.d.ts +4 -0
  95. package/dist/client/components/charts/index.d.ts +4 -0
  96. package/dist/client/components.js +1 -1
  97. package/dist/client/hooks/useAgentChat.d.ts +20 -2
  98. package/dist/client/index.js +583 -522
  99. package/dist/client/index.js.map +1 -1
  100. package/dist/client/styles.css +1 -1
  101. package/dist/client/types.d.ts +19 -1
  102. package/dist/client/utils.js +4 -4
  103. package/dist/client-bundle-stats.html +1 -1
  104. package/dist/server/index.cjs +47 -45
  105. package/dist/server/index.d.ts +37 -0
  106. package/dist/server/index.js +1745 -1298
  107. package/package.json +4 -1
  108. package/dist/adapters/handler-dnkqpznh.cjs +0 -23
  109. package/dist/client/chunks/analysis-builder-BMmWeFPr.js.map +0 -1
  110. package/dist/client/chunks/chart-box-plot-Dja4LS3O.js +0 -313
  111. package/dist/client/chunks/chart-box-plot-Dja4LS3O.js.map +0 -1
  112. package/dist/client/chunks/chart-config-box-plot-D3DA7_pr.js +0 -85
  113. package/dist/client/chunks/chart-config-box-plot-D3DA7_pr.js.map +0 -1
  114. package/dist/client/chunks/charts-core-DmGfleFz.js.map +0 -1
  115. package/dist/client/chunks/charts-loader-CH0_S06T.js.map +0 -1
  116. package/dist/client/chunks/components-ClQziOcT.js.map +0 -1
@@ -1,40 +1,40 @@
1
- import { h as N, Q as P, j as O, D as R } from "./mcp-transport-m1X1GtwG.js";
1
+ import { h as N, Q as P, j as L, D as R } from "./mcp-transport-m1X1GtwG.js";
2
2
  import { handleDiscover as Y, handleLoad as M } from "./utils.js";
3
3
  function z(o) {
4
4
  if (o.length === 0)
5
5
  return "No cubes are currently available.";
6
6
  const t = ["## Available Cubes", ""];
7
- for (const i of o) {
8
- if (t.push(`### ${i.name}`), i.description && t.push(i.description), i.measures && i.measures.length > 0) {
7
+ for (const a of o) {
8
+ if (t.push(`### ${a.name}`), a.description && t.push(a.description), a.measures && a.measures.length > 0) {
9
9
  t.push(""), t.push("**Measures:**");
10
- for (const s of i.measures) {
11
- const e = s.description ? ` - ${s.description}` : "";
12
- t.push(`- \`${i.name}.${s.name}\` (${s.type})${e}`);
10
+ for (const i of a.measures) {
11
+ const e = i.description ? ` - ${i.description}` : "";
12
+ t.push(`- \`${a.name}.${i.name}\` (${i.type})${e}`);
13
13
  }
14
14
  }
15
- if (i.dimensions && i.dimensions.length > 0) {
15
+ if (a.dimensions && a.dimensions.length > 0) {
16
16
  t.push(""), t.push("**Dimensions:**");
17
- for (const s of i.dimensions) {
18
- const e = s.description ? ` - ${s.description}` : "";
19
- t.push(`- \`${i.name}.${s.name}\` (${s.type})${e}`);
17
+ for (const i of a.dimensions) {
18
+ const e = i.description ? ` - ${i.description}` : "";
19
+ t.push(`- \`${a.name}.${i.name}\` (${i.type})${e}`);
20
20
  }
21
21
  }
22
- if (i.relationships && i.relationships.length > 0) {
22
+ if (a.relationships && a.relationships.length > 0) {
23
23
  t.push(""), t.push("**Joins:**");
24
- for (const s of i.relationships)
25
- t.push(`- → \`${s.targetCube}\` (${s.relationship})`);
24
+ for (const i of a.relationships)
25
+ t.push(`- → \`${i.targetCube}\` (${i.relationship})`);
26
26
  }
27
- i.meta?.eventStream && (t.push(""), t.push("**Event Stream:** Yes (supports funnel, flow, retention queries)"), i.meta.eventStream.bindingKey && t.push(`- Binding key: \`${i.name}.${i.meta.eventStream.bindingKey}\``), i.meta.eventStream.timeDimension && t.push(`- Time dimension: \`${i.name}.${i.meta.eventStream.timeDimension}\``)), t.push("");
27
+ a.meta?.eventStream && (t.push(""), t.push("**Event Stream:** Yes (supports funnel, flow, retention queries)"), a.meta.eventStream.bindingKey && t.push(`- Binding key: \`${a.name}.${a.meta.eventStream.bindingKey}\``), a.meta.eventStream.timeDimension && t.push(`- Time dimension: \`${a.name}.${a.meta.eventStream.timeDimension}\``)), t.push("");
28
28
  }
29
29
  return t.join(`
30
30
  `);
31
31
  }
32
- function S(o) {
32
+ function V(o) {
33
33
  return o.messages.map((t) => t.content.text).join(`
34
34
 
35
35
  `);
36
36
  }
37
- function L(o) {
37
+ function H(o) {
38
38
  return [
39
39
  "# Drizzle Cube Analytics Agent",
40
40
  "",
@@ -160,19 +160,69 @@ function L(o) {
160
160
  "",
161
161
  "---",
162
162
  "",
163
- S(N),
163
+ V(N),
164
164
  "",
165
165
  "---",
166
166
  "",
167
- S(P),
167
+ V(P),
168
168
  "",
169
169
  "---",
170
170
  "",
171
- S(O),
171
+ V(L),
172
172
  "",
173
173
  "---",
174
174
  "",
175
- S(R),
175
+ V(R),
176
+ "",
177
+ "---",
178
+ "",
179
+ "## Save as Dashboard",
180
+ "",
181
+ "When the user asks to save, export, or convert the notebook into a dashboard, use the `save_as_dashboard` tool.",
182
+ "",
183
+ "### Layout Rules",
184
+ "- Dashboard grid is 12 columns wide",
185
+ "- KPI cards: w=3, h=3 — place at the top in a row of 4",
186
+ "- Overview charts (bar, line, area): w=6, h=4",
187
+ "- Wide charts (heatmap, table): w=12, h=5",
188
+ "- Section headers (markdown): w=12, h=1",
189
+ "",
190
+ "### Section Headers",
191
+ 'Use `chartType: "markdown"` portlets as section headers to organize the dashboard:',
192
+ "```json",
193
+ "{",
194
+ ' "id": "header-overview",',
195
+ ' "title": "Overview",',
196
+ ' "chartType": "markdown",',
197
+ ' "displayConfig": {',
198
+ ' "content": "## Overview",',
199
+ ' "hideHeader": true,',
200
+ ' "transparentBackground": true,',
201
+ ' "autoHeight": true',
202
+ " },",
203
+ ' "w": 12, "h": 1, "x": 0, "y": 0',
204
+ "}",
205
+ "```",
206
+ "",
207
+ "### Dashboard Filters",
208
+ "- ALWAYS include a universal date filter with `isUniversalTime: true`",
209
+ "- Add dimension filters for key fields used across portlets (e.g., department, status, region)",
210
+ '- Use human-readable labels (e.g., "Department" not "Employees.departmentName")',
211
+ "- Map filters to portlets using `dashboardFilterMapping` — list the filter IDs that apply",
212
+ "- When promoting a hardcoded filter to a dashboard filter, REMOVE that filter from the portlet query",
213
+ "",
214
+ "### Analysis Types",
215
+ '- Standard query portlets: `analysisType: "query"` (default)',
216
+ '- Funnel portlets: `analysisType: "funnel"`, query contains `{ "funnel": {...} }`, chartType `"funnel"`',
217
+ '- Flow portlets: `analysisType: "flow"`, query contains `{ "flow": {...} }`, chartType `"sankey"` or `"sunburst"`',
218
+ '- Retention portlets: `analysisType: "retention"`, query contains `{ "retention": {...} }`, chartType `"retentionHeatmap"` or `"retentionCombined"`',
219
+ "",
220
+ "### CRITICAL: Only use portlets from the notebook",
221
+ "- ONLY include portlets that you already added to the notebook via `add_portlet` during this conversation",
222
+ "- Do NOT invent new queries or charts that were not part of the analysis — the dashboard is a direct conversion of the notebook",
223
+ "- Reuse the exact same queries, chart types, and chart configs from the notebook portlets",
224
+ "- Arrange the existing portlets in a sensible layout (KPIs at top, charts in middle, tables at bottom)",
225
+ "- You may add section header markdown portlets to organize the layout, but do not add new data portlets",
176
226
  "",
177
227
  "---",
178
228
  "",
@@ -180,7 +230,7 @@ function L(o) {
180
230
  ].join(`
181
231
  `);
182
232
  }
183
- const H = {
233
+ const B = {
184
234
  label: "Bar Chart",
185
235
  description: "Compare values across categories",
186
236
  useCase: "Best for comparing discrete categories, showing rankings, or displaying changes over time",
@@ -329,7 +379,7 @@ const H = {
329
379
  description: "Number formatting for right Y-axis"
330
380
  }
331
381
  ]
332
- }, B = {
382
+ }, j = {
333
383
  label: "Area Chart",
334
384
  description: "Emphasize magnitude of change over time",
335
385
  useCase: "Best for showing cumulative totals, volume changes, or stacked comparisons over time",
@@ -401,7 +451,7 @@ const H = {
401
451
  description: "Number formatting for right Y-axis"
402
452
  }
403
453
  ]
404
- }, j = {
454
+ }, G = {
405
455
  label: "Pie Chart",
406
456
  description: "Show proportions of a whole",
407
457
  useCase: "Best for showing percentage distribution or composition of a total (limit to 5-7 slices)",
@@ -435,7 +485,7 @@ const H = {
435
485
  description: "Number formatting for values"
436
486
  }
437
487
  ]
438
- }, G = {
488
+ }, K = {
439
489
  label: "Scatter Plot",
440
490
  description: "Reveal correlations between variables",
441
491
  useCase: "Best for identifying patterns, correlations, outliers, and relationships between two measures",
@@ -483,7 +533,7 @@ const H = {
483
533
  description: "Number formatting for Y-axis"
484
534
  }
485
535
  ]
486
- }, K = {
536
+ }, Z = {
487
537
  label: "Bubble Chart",
488
538
  description: "Compare three dimensions of data",
489
539
  useCase: "Best for showing relationships between three variables (X, Y, and size), market analysis",
@@ -549,7 +599,7 @@ const H = {
549
599
  description: "Number formatting for Y-axis and values"
550
600
  }
551
601
  ]
552
- }, Z = {
602
+ }, U = {
553
603
  label: "Radar Chart",
554
604
  description: "Compare multiple metrics across categories",
555
605
  useCase: "Best for multivariate comparisons, performance metrics, strengths/weaknesses analysis",
@@ -588,7 +638,7 @@ const H = {
588
638
  description: "Number formatting for values"
589
639
  }
590
640
  ]
591
- }, X = {
641
+ }, W = {
592
642
  label: "Radial Bar Chart",
593
643
  description: "Circular progress and KPI visualization",
594
644
  useCase: "Best for showing progress toward goals, KPIs, or comparing percentages in a compact form",
@@ -620,7 +670,7 @@ const H = {
620
670
  description: "Number formatting for values"
621
671
  }
622
672
  ]
623
- }, U = {
673
+ }, X = {
624
674
  label: "TreeMap",
625
675
  description: "Visualize hierarchical data with nested rectangles",
626
676
  useCase: "Best for showing part-to-whole relationships in hierarchical data, disk usage, budget allocation",
@@ -662,7 +712,7 @@ const H = {
662
712
  }
663
713
  ],
664
714
  clickableElements: { cell: !0 }
665
- }, W = {
715
+ }, J = {
666
716
  label: "Data Table",
667
717
  description: "Display detailed tabular data",
668
718
  useCase: "Best for precise values, detailed analysis, sortable/filterable data exploration",
@@ -685,7 +735,7 @@ const H = {
685
735
  description: "Number formatting for numeric values"
686
736
  }
687
737
  ]
688
- }, J = {
738
+ }, Q = {
689
739
  label: "Activity Grid",
690
740
  description: "GitHub-style activity grid showing temporal patterns across different time scales",
691
741
  useCase: "Best for visualizing activity patterns over time. Supports hour (3hr blocks × days), day (days × weeks), week (weeks × months), month (months × quarters), and quarter (quarters × years) granularities",
@@ -720,17 +770,17 @@ const H = {
720
770
  }
721
771
  ],
722
772
  validate: (o) => {
723
- const { dateField: t, valueField: i } = o;
773
+ const { dateField: t, valueField: a } = o;
724
774
  return !t || Array.isArray(t) && t.length === 0 ? {
725
775
  isValid: !1,
726
776
  message: "Time dimension is required for activity grid"
727
- } : !i || Array.isArray(i) && i.length === 0 ? {
777
+ } : !a || Array.isArray(a) && a.length === 0 ? {
728
778
  isValid: !1,
729
779
  message: "Activity measure is required for intensity mapping"
730
780
  } : { isValid: !0 };
731
781
  },
732
782
  clickableElements: { cell: !0 }
733
- }, Q = {
783
+ }, ee = {
734
784
  label: "KPI Number",
735
785
  description: "Display key performance indicators as large numbers",
736
786
  useCase: "Perfect for showing important metrics like revenue, user count, or other key business metrics in a prominent, easy-to-read format",
@@ -800,7 +850,7 @@ const H = {
800
850
  }
801
851
  ],
802
852
  displayOptions: ["hideHeader"]
803
- }, ee = {
853
+ }, te = {
804
854
  label: "KPI Delta",
805
855
  description: "Display change between latest and previous values with trend indicators",
806
856
  useCase: "Perfect for showing performance changes over time, such as revenue growth, user acquisition changes, or other metrics where the trend and delta are more important than the absolute value",
@@ -892,7 +942,7 @@ const H = {
892
942
  isValid: !1,
893
943
  message: "A measure is required for KPI Delta charts"
894
944
  } : { isValid: !0 }
895
- }, te = {
945
+ }, ae = {
896
946
  label: "KPI Text",
897
947
  description: "Display key performance indicators as customizable text",
898
948
  useCase: "Perfect for showing metrics with custom formatting, combining multiple values, or displaying contextual KPI information using templates",
@@ -1113,7 +1163,7 @@ Use --- for horizontal rules.`,
1113
1163
  description: "Display 90th percentile time to convert"
1114
1164
  }
1115
1165
  ]
1116
- }, ae = {
1166
+ }, oe = {
1117
1167
  label: "Sankey Chart",
1118
1168
  description: "Show flow between states or steps",
1119
1169
  useCase: "Best for visualizing user journey flows, path analysis, or state transitions",
@@ -1169,7 +1219,7 @@ Use --- for horizontal rules.`,
1169
1219
  description: "Hide the statistics footer below the chart"
1170
1220
  }
1171
1221
  ]
1172
- }, oe = {
1222
+ }, re = {
1173
1223
  label: "Sunburst Chart",
1174
1224
  description: "Show hierarchical flow as radial rings",
1175
1225
  useCase: "Best for visualizing forward paths from a starting event in a compact radial layout",
@@ -1214,7 +1264,7 @@ Use --- for horizontal rules.`,
1214
1264
  description: "Hide the statistics footer below the chart"
1215
1265
  }
1216
1266
  ]
1217
- }, re = {
1267
+ }, ne = {
1218
1268
  label: "Heatmap",
1219
1269
  description: "Visualize intensity across two dimensions",
1220
1270
  useCase: "Best for showing patterns in matrix data like correlations, schedules, or category comparisons",
@@ -1286,7 +1336,7 @@ Use --- for horizontal rules.`,
1286
1336
  }
1287
1337
  ],
1288
1338
  validate: (o) => o.xAxis?.length ? o.yAxis?.length ? o.valueField?.length ? { isValid: !0 } : { isValid: !1, message: "Value measure required" } : { isValid: !1, message: "Y-axis dimension required" } : { isValid: !1, message: "X-axis dimension required" }
1289
- }, ne = {
1339
+ }, le = {
1290
1340
  label: "Retention Matrix",
1291
1341
  // RetentionHeatmap auto-configures from the retention data structure
1292
1342
  // No drop zones needed as the chart maps directly to cohort × period matrix
@@ -1310,7 +1360,7 @@ Use --- for horizontal rules.`,
1310
1360
  ],
1311
1361
  description: "Cohort retention matrix visualization",
1312
1362
  useCase: "Visualize user retention over time by cohort"
1313
- }, le = {
1363
+ }, de = {
1314
1364
  label: "Retention Chart",
1315
1365
  // RetentionCombinedChart auto-configures from the retention data structure
1316
1366
  // No drop zones needed as the chart maps directly to retention result data
@@ -1353,10 +1403,11 @@ Use --- for horizontal rules.`,
1353
1403
  ],
1354
1404
  description: "Combined retention visualization with line chart and heatmap modes",
1355
1405
  useCase: "Visualize user retention over time with optional breakdown segmentation"
1356
- }, de = {
1406
+ }, pe = {
1357
1407
  label: "Box Plot",
1358
1408
  description: "Show statistical distribution (median, IQR, whiskers) across categories",
1359
1409
  useCase: "Best for P&L spread per symbol, trade size distribution, latency distribution across platforms",
1410
+ displayOptions: ["hideHeader"],
1360
1411
  dropZones: [
1361
1412
  {
1362
1413
  key: "xAxis",
@@ -1370,115 +1421,315 @@ Use --- for horizontal rules.`,
1370
1421
  {
1371
1422
  key: "yAxis",
1372
1423
  label: "Y-Axis (Measures)",
1373
- description: "For auto mode: drop 1 measure here. For 3-measure mode set avg/stddev/median fields in Display Options.",
1374
- mandatory: !1,
1424
+ description: "Drop 1 measure for auto mode, 3 for avg/stddev/median mode, or 5 for min/q1/median/q3/max mode",
1425
+ mandatory: !0,
1426
+ maxItems: 5,
1375
1427
  acceptTypes: ["measure"],
1376
- emptyText: "Drop a measure here (or configure 3/5-measure mode below)"
1428
+ emptyText: "Drop 1, 3, or 5 measures here"
1377
1429
  }
1378
1430
  ],
1379
1431
  displayOptionsConfig: [
1380
1432
  {
1381
- key: "avgField",
1382
- label: "Avg Field (3-measure mode)",
1383
- type: "string",
1384
- placeholder: "e.g. Trades.avgPnl",
1385
- description: "Average measure for 3-measure mode (mean ± σ whiskers)"
1433
+ key: "leftYAxisFormat",
1434
+ label: "Y-Axis Format",
1435
+ type: "axisFormat",
1436
+ description: "Number formatting for the value axis"
1437
+ }
1438
+ ]
1439
+ }, ue = {
1440
+ label: "Waterfall Chart",
1441
+ description: "Show cumulative effect of sequential positive and negative values",
1442
+ useCase: "Best for P&L decomposition, cash flow analysis, budget variance, or any sequential contribution breakdown",
1443
+ clickableElements: { bar: !0 },
1444
+ displayOptions: ["showTooltip", "hideHeader"],
1445
+ dropZones: [
1446
+ {
1447
+ key: "xAxis",
1448
+ label: "X-Axis (Categories)",
1449
+ description: "Dimension labels for each bar segment (e.g. symbol, transaction type)",
1450
+ mandatory: !0,
1451
+ maxItems: 1,
1452
+ acceptTypes: ["dimension", "timeDimension"],
1453
+ emptyText: "Drop a dimension here"
1386
1454
  },
1387
1455
  {
1388
- key: "stddevField",
1389
- label: "Stddev Field (3-measure mode)",
1390
- type: "string",
1391
- placeholder: "e.g. Trades.stddevPnl",
1392
- description: "Standard deviation measure for 3-measure mode"
1456
+ key: "yAxis",
1457
+ label: "Y-Axis (Value)",
1458
+ description: "Single measure whose values are summed cumulatively",
1459
+ mandatory: !0,
1460
+ maxItems: 1,
1461
+ acceptTypes: ["measure"],
1462
+ emptyText: "Drop a measure here"
1463
+ }
1464
+ ],
1465
+ displayOptionsConfig: [
1466
+ {
1467
+ key: "showTotal",
1468
+ label: "Show Total Bar",
1469
+ type: "boolean",
1470
+ defaultValue: !0,
1471
+ description: "Append a final bar showing the running total"
1393
1472
  },
1394
1473
  {
1395
- key: "medianField",
1396
- label: "Median Field (3/5-measure mode)",
1397
- type: "string",
1398
- placeholder: "e.g. Trades.medianPnl",
1399
- description: "Median measure for 3-measure or 5-measure mode"
1474
+ key: "showConnectorLine",
1475
+ label: "Show Connector Line",
1476
+ type: "boolean",
1477
+ defaultValue: !0,
1478
+ description: "Draw a dashed step-line connecting bar tops"
1400
1479
  },
1401
1480
  {
1402
- key: "minField",
1403
- label: "Min Field (5-measure mode)",
1404
- type: "string",
1405
- placeholder: "e.g. Trades.minPnl",
1406
- description: "Minimum measure for 5-measure full box plot"
1481
+ key: "showDataLabels",
1482
+ label: "Show Data Labels",
1483
+ type: "boolean",
1484
+ defaultValue: !1,
1485
+ description: "Display the value above each bar segment"
1407
1486
  },
1408
1487
  {
1409
- key: "q1Field",
1410
- label: "Q1 Field (5-measure mode)",
1411
- type: "string",
1412
- placeholder: "e.g. Trades.q1Pnl",
1413
- description: "First quartile measure for 5-measure full box plot"
1488
+ key: "leftYAxisFormat",
1489
+ label: "Y-Axis Format",
1490
+ type: "axisFormat",
1491
+ description: "Number formatting for the Y-axis"
1492
+ }
1493
+ ]
1494
+ }, ce = {
1495
+ label: "Candlestick Chart",
1496
+ description: "Financial candlestick chart showing open/close body and high/low wicks",
1497
+ useCase: "Best for EOD quotes (bid/ask spread per date/symbol), markout distribution bands, or OHLC price data",
1498
+ clickableElements: { bar: !0 },
1499
+ displayOptions: ["hideHeader"],
1500
+ dropZones: [
1501
+ {
1502
+ key: "xAxis",
1503
+ label: "X-Axis (Time / Category)",
1504
+ description: "Time dimension or category for each candle (e.g. date, symbol)",
1505
+ mandatory: !0,
1506
+ maxItems: 1,
1507
+ acceptTypes: ["timeDimension", "dimension"],
1508
+ emptyText: "Drop a time or dimension here"
1414
1509
  },
1415
1510
  {
1416
- key: "q3Field",
1417
- label: "Q3 Field (5-measure mode)",
1418
- type: "string",
1419
- placeholder: "e.g. Trades.q3Pnl",
1420
- description: "Third quartile measure for 5-measure full box plot"
1511
+ key: "yAxis",
1512
+ label: "OHLC Measures (open, close, high, low)",
1513
+ description: "Drop 2–4 measures in order: open, close, high, low (OHLC mode). For range mode drop 2: high, low.",
1514
+ mandatory: !0,
1515
+ acceptTypes: ["measure"],
1516
+ emptyText: "Drop 2+ measures here"
1517
+ }
1518
+ ],
1519
+ displayOptionsConfig: [
1520
+ {
1521
+ key: "rangeMode",
1522
+ label: "Chart Mode",
1523
+ type: "select",
1524
+ defaultValue: "ohlc",
1525
+ options: [
1526
+ { value: "ohlc", label: "OHLC (open, close, high, low)" },
1527
+ { value: "range", label: "Range (high, low / bid, ask)" }
1528
+ ],
1529
+ description: "OHLC: 4 measures. Range: 2 measures (high + low)."
1421
1530
  },
1422
1531
  {
1423
- key: "maxField",
1424
- label: "Max Field (5-measure mode)",
1425
- type: "string",
1426
- placeholder: "e.g. Trades.maxPnl",
1427
- description: "Maximum measure for 5-measure full box plot"
1532
+ key: "bullColor",
1533
+ label: "Bullish Colour",
1534
+ type: "color",
1535
+ defaultValue: "#22c55e",
1536
+ description: "Candle colour when close open"
1537
+ },
1538
+ {
1539
+ key: "bearColor",
1540
+ label: "Bearish Colour",
1541
+ type: "color",
1542
+ defaultValue: "#ef4444",
1543
+ description: "Candle colour when close < open"
1544
+ },
1545
+ {
1546
+ key: "showWicks",
1547
+ label: "Show Wicks",
1548
+ type: "boolean",
1549
+ defaultValue: !0,
1550
+ description: "Draw high/low wicks above and below the body"
1428
1551
  },
1429
1552
  {
1430
1553
  key: "leftYAxisFormat",
1431
1554
  label: "Y-Axis Format",
1432
1555
  type: "axisFormat",
1433
- description: "Number formatting for the value axis"
1556
+ description: "Number formatting for the price axis"
1434
1557
  }
1435
1558
  ]
1436
- }, _ = {
1437
- bar: H,
1559
+ }, me = {
1560
+ label: "Measure Profile",
1561
+ description: "Plot N measures as sequential X-axis points to visualise a profile or shape across intervals",
1562
+ useCase: "Best for markout interval analysis (e.g. avgMinus2m → avgAtEvent → avgPlus2h), metric profiles, or any pattern across ordered measures",
1563
+ displayOptions: ["showLegend", "showTooltip", "hideHeader"],
1564
+ dropZones: [
1565
+ {
1566
+ key: "yAxis",
1567
+ label: "Measures (X-Axis Order)",
1568
+ description: "Add 2 or more measures — they become the X-axis categories in the order listed",
1569
+ mandatory: !0,
1570
+ acceptTypes: ["measure"],
1571
+ emptyText: "Drop 2+ measures here (displayed left → right)"
1572
+ },
1573
+ {
1574
+ key: "series",
1575
+ label: "Series (Split into Multiple Lines)",
1576
+ description: "Dimension to split data into separate profile lines (e.g. symbol, platform)",
1577
+ mandatory: !1,
1578
+ maxItems: 1,
1579
+ acceptTypes: ["dimension"],
1580
+ emptyText: "Drop a dimension here to create multiple lines"
1581
+ }
1582
+ ],
1583
+ displayOptionsConfig: [
1584
+ {
1585
+ key: "showReferenceLineAtZero",
1586
+ label: "Show Zero Reference Line",
1587
+ type: "boolean",
1588
+ defaultValue: !0,
1589
+ description: "Draw a dashed line at Y = 0"
1590
+ },
1591
+ {
1592
+ key: "showDataLabels",
1593
+ label: "Show Data Labels",
1594
+ type: "boolean",
1595
+ defaultValue: !1,
1596
+ description: "Display value at each data point"
1597
+ },
1598
+ {
1599
+ key: "showLegend",
1600
+ label: "Show Legend",
1601
+ type: "boolean",
1602
+ defaultValue: !0,
1603
+ description: "Show series legend (only visible with a Series dimension)"
1604
+ },
1605
+ {
1606
+ key: "lineType",
1607
+ label: "Line Interpolation",
1608
+ type: "select",
1609
+ defaultValue: "monotone",
1610
+ options: [
1611
+ { value: "monotone", label: "Smooth (monotone)" },
1612
+ { value: "linear", label: "Linear" },
1613
+ { value: "step", label: "Step" }
1614
+ ],
1615
+ description: "How data points are connected"
1616
+ },
1617
+ {
1618
+ key: "leftYAxisFormat",
1619
+ label: "Y-Axis Format",
1620
+ type: "axisFormat",
1621
+ description: "Number formatting for the Y-axis"
1622
+ }
1623
+ ]
1624
+ }, ye = {
1625
+ label: "Gauge Chart",
1626
+ description: "Half-circle arc gauge for a single KPI value versus a maximum target",
1627
+ useCase: "Best for high-water marks vs equity, margin utilisation, or any single value progress toward a goal",
1628
+ clickableElements: {},
1629
+ displayOptions: ["hideHeader"],
1630
+ dropZones: [
1631
+ {
1632
+ key: "yAxis",
1633
+ label: "Value Measure",
1634
+ description: "Current value to display on the gauge (e.g. current equity, margin used)",
1635
+ mandatory: !0,
1636
+ maxItems: 2,
1637
+ acceptTypes: ["measure"],
1638
+ emptyText: "Drop 1 measure here (optional 2nd for dynamic max)"
1639
+ }
1640
+ ],
1641
+ displayOptionsConfig: [
1642
+ {
1643
+ key: "minValue",
1644
+ label: "Minimum Value",
1645
+ type: "number",
1646
+ defaultValue: 0,
1647
+ description: "Lower bound of the gauge arc (default 0)"
1648
+ },
1649
+ {
1650
+ key: "maxValue",
1651
+ label: "Maximum Value (static)",
1652
+ type: "number",
1653
+ description: "Upper bound of the gauge. Leave empty to use yAxis[1] or default 100"
1654
+ },
1655
+ {
1656
+ key: "thresholds",
1657
+ label: "Threshold Bands",
1658
+ type: "string",
1659
+ placeholder: '[{"value":0.33,"color":"#22c55e"},{"value":0.66,"color":"#f59e0b"},{"value":1,"color":"#ef4444"}]',
1660
+ description: "Array of {value (0–1 fraction), color} bands shown as outer arc markers"
1661
+ },
1662
+ {
1663
+ key: "showCenterLabel",
1664
+ label: "Show Centre Label",
1665
+ type: "boolean",
1666
+ defaultValue: !0,
1667
+ description: "Display current value and field name in the centre of the gauge"
1668
+ },
1669
+ {
1670
+ key: "showPercentage",
1671
+ label: "Show as Percentage",
1672
+ type: "boolean",
1673
+ defaultValue: !1,
1674
+ description: "Display value as % of max instead of raw number"
1675
+ },
1676
+ {
1677
+ key: "leftYAxisFormat",
1678
+ label: "Value Format",
1679
+ type: "axisFormat",
1680
+ description: "Number formatting for the displayed value and axis labels"
1681
+ }
1682
+ ]
1683
+ }, q = {
1684
+ bar: B,
1438
1685
  line: $,
1439
- area: B,
1440
- pie: j,
1441
- scatter: G,
1442
- bubble: K,
1443
- radar: Z,
1444
- radialBar: X,
1445
- treemap: U,
1446
- table: W,
1447
- activityGrid: J,
1448
- kpiNumber: Q,
1449
- kpiDelta: ee,
1450
- kpiText: te,
1686
+ area: j,
1687
+ pie: G,
1688
+ scatter: K,
1689
+ bubble: Z,
1690
+ radar: U,
1691
+ radialBar: W,
1692
+ treemap: X,
1693
+ table: J,
1694
+ activityGrid: Q,
1695
+ kpiNumber: ee,
1696
+ kpiDelta: te,
1697
+ kpiText: ae,
1451
1698
  markdown: ie,
1452
1699
  funnel: se,
1453
- sankey: ae,
1454
- sunburst: oe,
1455
- heatmap: re,
1456
- retentionHeatmap: ne,
1457
- retentionCombined: le,
1458
- boxPlot: de
1700
+ sankey: oe,
1701
+ sunburst: re,
1702
+ heatmap: ne,
1703
+ retentionHeatmap: le,
1704
+ retentionCombined: de,
1705
+ boxPlot: pe,
1706
+ waterfall: ue,
1707
+ candlestick: ce,
1708
+ measureProfile: me,
1709
+ gauge: ye
1459
1710
  };
1460
- function pe(o, t, i) {
1461
- const s = _[o];
1462
- if (!s)
1711
+ function he(o, t, a) {
1712
+ const i = q[o];
1713
+ if (!i)
1463
1714
  return { isValid: !0, errors: [] };
1464
- if (s.skipQuery)
1715
+ if (i.skipQuery)
1465
1716
  return { isValid: !0, errors: [] };
1466
1717
  const e = [];
1467
- for (const a of s.dropZones) {
1468
- if (!a.mandatory) continue;
1469
- const n = t?.[a.key];
1470
- if (!(Array.isArray(n) ? n.length > 0 : !!n)) {
1471
- const u = a.acceptTypes?.join("/") ?? "fields";
1718
+ for (const s of i.dropZones) {
1719
+ if (!s.mandatory) continue;
1720
+ const r = t?.[s.key];
1721
+ if (!(Array.isArray(r) ? r.length > 0 : !!r)) {
1722
+ const m = s.acceptTypes?.join("/") ?? "fields";
1472
1723
  e.push(
1473
- `chartConfig.${a.key} is required for ${o} chart (${a.label}). Accepts: ${u}.`
1724
+ `chartConfig.${s.key} is required for ${o} chart (${s.label}). Accepts: ${m}.`
1474
1725
  );
1475
1726
  }
1476
1727
  }
1477
1728
  if (o === "bar") {
1478
- const a = t?.xAxis;
1479
- if (!(Array.isArray(a) ? a.length > 0 : !!a)) {
1480
- const l = i.dimensions ?? [], u = i.timeDimensions ?? [];
1481
- l.length > 0 || u.length > 0 ? e.push(
1729
+ const s = t?.xAxis;
1730
+ if (!(Array.isArray(s) ? s.length > 0 : !!s)) {
1731
+ const p = a.dimensions ?? [], m = a.timeDimensions ?? [];
1732
+ p.length > 0 || m.length > 0 ? e.push(
1482
1733
  "chartConfig.xAxis is required for bar charts. Put a dimension in xAxis so bars have category labels."
1483
1734
  ) : e.push(
1484
1735
  'Bar charts need an xAxis dimension for category labels. Add a dimension to the query or use "table" chart type instead.'
@@ -1486,76 +1737,76 @@ function pe(o, t, i) {
1486
1737
  }
1487
1738
  }
1488
1739
  if (t?.xAxis && t?.series) {
1489
- const a = new Set(
1740
+ const s = new Set(
1490
1741
  Array.isArray(t.xAxis) ? t.xAxis : [t.xAxis]
1491
- ), l = (Array.isArray(t.series) ? t.series : [t.series]).filter((u) => a.has(u));
1492
- l.length > 0 && e.push(
1493
- `chartConfig.series must not contain the same field as xAxis (found: ${l.join(", ")}). The series field is only for splitting into grouped/stacked sub-series by a DIFFERENT dimension. Remove the duplicate from series.`
1742
+ ), p = (Array.isArray(t.series) ? t.series : [t.series]).filter((m) => s.has(m));
1743
+ p.length > 0 && e.push(
1744
+ `chartConfig.series must not contain the same field as xAxis (found: ${p.join(", ")}). The series field is only for splitting into grouped/stacked sub-series by a DIFFERENT dimension. Remove the duplicate from series.`
1494
1745
  );
1495
1746
  }
1496
1747
  return { isValid: e.length === 0, errors: e };
1497
1748
  }
1498
- function ue(o, t, i) {
1499
- const s = _[o];
1500
- if (!s)
1749
+ function fe(o, t, a) {
1750
+ const i = q[o];
1751
+ if (!i)
1501
1752
  return t ?? {};
1502
- const e = { ...t }, a = i.measures ?? [], n = i.dimensions ?? [], u = (i.timeDimensions ?? []).map((d) => d.dimension);
1503
- for (const d of s.dropZones) {
1504
- const p = e[d.key];
1505
- if (Array.isArray(p) ? p.length > 0 : !!p) continue;
1506
- const f = d.acceptTypes ?? [];
1507
- if (d.key === "sizeField" || d.key === "colorField") {
1508
- if (f.includes("measure")) {
1509
- const m = /* @__PURE__ */ new Set();
1510
- for (const y of s.dropZones) {
1511
- if (y.key === d.key) continue;
1512
- const x = e[y.key];
1513
- Array.isArray(x) ? x.forEach((w) => m.add(w)) : typeof x == "string" && m.add(x);
1753
+ const e = { ...t }, s = a.measures ?? [], r = a.dimensions ?? [], m = (a.timeDimensions ?? []).map((c) => c.dimension);
1754
+ for (const c of i.dropZones) {
1755
+ const y = e[c.key];
1756
+ if (Array.isArray(y) ? y.length > 0 : !!y) continue;
1757
+ const g = c.acceptTypes ?? [];
1758
+ if (c.key === "sizeField" || c.key === "colorField") {
1759
+ if (g.includes("measure")) {
1760
+ const h = /* @__PURE__ */ new Set();
1761
+ for (const x of i.dropZones) {
1762
+ if (x.key === c.key) continue;
1763
+ const u = e[x.key];
1764
+ Array.isArray(u) ? u.forEach((A) => h.add(A)) : typeof u == "string" && h.add(u);
1514
1765
  }
1515
- const C = a.filter((y) => !m.has(y));
1516
- C.length > 0 && (e[d.key] = C[0]);
1766
+ const d = s.filter((x) => !h.has(x));
1767
+ d.length > 0 && (e[c.key] = d[0]);
1517
1768
  }
1518
1769
  continue;
1519
1770
  }
1520
- const c = [];
1521
- if (f.includes("dimension") && c.push(...n), f.includes("timeDimension") && c.push(...u), f.includes("measure") && c.push(...a), c.length === 0) continue;
1522
- let g = c;
1523
- if (d.key === "series") {
1524
- const m = new Set(
1771
+ const f = [];
1772
+ if (g.includes("dimension") && f.push(...r), g.includes("timeDimension") && f.push(...m), g.includes("measure") && f.push(...s), f.length === 0) continue;
1773
+ let b = f;
1774
+ if (c.key === "series") {
1775
+ const h = new Set(
1525
1776
  Array.isArray(e.xAxis) ? e.xAxis : e.xAxis ? [e.xAxis] : []
1526
1777
  );
1527
- if (g = c.filter((C) => !m.has(C)), g.length === 0) continue;
1778
+ if (b = f.filter((d) => !h.has(d)), b.length === 0) continue;
1528
1779
  }
1529
- const F = d.maxItems ?? 1 / 0, v = g.slice(0, F);
1530
- v.length > 0 && (e[d.key] = v);
1780
+ const w = c.maxItems ?? 1 / 0, C = b.slice(0, w);
1781
+ C.length > 0 && (e[c.key] = C);
1531
1782
  }
1532
1783
  return e;
1533
1784
  }
1534
- function me(o) {
1785
+ function be(o) {
1535
1786
  const t = [`
1536
1787
  Chart config requirements by type:`];
1537
- for (const i of o) {
1538
- const s = _[i];
1539
- if (!s) continue;
1540
- const e = s.description ?? "", a = s.useCase ?? "", n = [e, a].filter(Boolean).join(". "), l = n ? ` — ${n}.` : "", u = s.dropZones.filter((p) => p.mandatory);
1541
- if (u.length === 0 && !s.skipQuery) {
1542
- t.push(` ${i}${l} chartConfig auto-inferred from query.`);
1788
+ for (const a of o) {
1789
+ const i = q[a];
1790
+ if (!i) continue;
1791
+ const e = i.description ?? "", s = i.useCase ?? "", r = [e, s].filter(Boolean).join(". "), p = r ? ` — ${r}.` : "", m = i.dropZones.filter((y) => y.mandatory);
1792
+ if (m.length === 0 && !i.skipQuery) {
1793
+ t.push(` ${a}${p} chartConfig auto-inferred from query.`);
1543
1794
  continue;
1544
1795
  }
1545
- if (s.skipQuery) {
1546
- t.push(` ${i}${l} No query needed.`);
1796
+ if (i.skipQuery) {
1797
+ t.push(` ${a}${p} No query needed.`);
1547
1798
  continue;
1548
1799
  }
1549
- const d = u.map((p) => {
1550
- const k = p.acceptTypes?.join("/") ?? "any", f = p.maxItems ? ` (max ${p.maxItems})` : "";
1551
- return `${p.key}=[${k}]${f}`;
1800
+ const c = m.map((y) => {
1801
+ const l = y.acceptTypes?.join("/") ?? "any", g = y.maxItems ? ` (max ${y.maxItems})` : "";
1802
+ return `${y.key}=[${l}]${g}`;
1552
1803
  });
1553
- t.push(` ${i}${l} Requires ${d.join(", ")}.`);
1804
+ t.push(` ${a}${p} Requires ${c.join(", ")}.`);
1554
1805
  }
1555
1806
  return t.join(`
1556
1807
  `);
1557
1808
  }
1558
- const q = [
1809
+ const _ = [
1559
1810
  "bar",
1560
1811
  "line",
1561
1812
  "area",
@@ -1572,9 +1823,10 @@ const q = [
1572
1823
  "sunburst",
1573
1824
  "retentionHeatmap",
1574
1825
  "retentionCombined",
1575
- "boxPlot"
1826
+ "boxPlot",
1827
+ "markdown"
1576
1828
  ];
1577
- function ce() {
1829
+ function ge() {
1578
1830
  return [
1579
1831
  // Tool 1: discover_cubes
1580
1832
  {
@@ -1726,7 +1978,7 @@ function ce() {
1726
1978
  {
1727
1979
  name: "add_portlet",
1728
1980
  description: `Add a chart visualization to the notebook.
1729
- ` + me(q) + `
1981
+ ` + be(_) + `
1730
1982
  The query is validated before adding. The portlet fetches its own data.`,
1731
1983
  input_schema: {
1732
1984
  type: "object",
@@ -1738,7 +1990,7 @@ The query is validated before adding. The portlet fetches its own data.`,
1738
1990
  },
1739
1991
  chartType: {
1740
1992
  type: "string",
1741
- enum: q,
1993
+ enum: _,
1742
1994
  description: "Chart type to render"
1743
1995
  },
1744
1996
  chartConfig: {
@@ -1779,26 +2031,113 @@ The query is validated before adding. The portlet fetches its own data.`,
1779
2031
  },
1780
2032
  required: ["content"]
1781
2033
  }
2034
+ },
2035
+ // Tool 6: save_as_dashboard
2036
+ {
2037
+ name: "save_as_dashboard",
2038
+ description: "Convert the current notebook analysis into a persistent dashboard. Constructs a professional DashboardConfig with proper grid layout, section headers (markdown portlets), and dashboard-level filters. Call this when the user asks to save/export the notebook as a dashboard.",
2039
+ input_schema: {
2040
+ type: "object",
2041
+ properties: {
2042
+ title: { type: "string", description: "Dashboard title" },
2043
+ description: { type: "string", description: "Optional dashboard description" },
2044
+ portlets: {
2045
+ type: "array",
2046
+ items: {
2047
+ type: "object",
2048
+ properties: {
2049
+ id: { type: "string", description: "Unique portlet ID" },
2050
+ title: { type: "string", description: "Portlet title" },
2051
+ chartType: {
2052
+ type: "string",
2053
+ enum: _,
2054
+ description: 'Chart type. Use "markdown" for section headers.'
2055
+ },
2056
+ query: {
2057
+ type: "string",
2058
+ description: "JSON string of the query. Omit or leave empty for markdown portlets."
2059
+ },
2060
+ chartConfig: {
2061
+ type: "object",
2062
+ properties: {
2063
+ xAxis: { type: "array", items: { type: "string" } },
2064
+ yAxis: { type: "array", items: { type: "string" } },
2065
+ series: { type: "array", items: { type: "string" } },
2066
+ sizeField: { type: "string" },
2067
+ colorField: { type: "string" }
2068
+ },
2069
+ description: "Chart axis configuration"
2070
+ },
2071
+ displayConfig: {
2072
+ type: "object",
2073
+ description: "Chart display configuration (for markdown: { content, hideHeader, transparentBackground, autoHeight })"
2074
+ },
2075
+ dashboardFilterMapping: {
2076
+ type: "array",
2077
+ items: { type: "string" },
2078
+ description: "Array of dashboard filter IDs that apply to this portlet"
2079
+ },
2080
+ analysisType: {
2081
+ type: "string",
2082
+ enum: ["query", "funnel", "flow", "retention"],
2083
+ description: 'Analysis type (default: "query")'
2084
+ },
2085
+ w: { type: "number", description: "Grid width (1-12)" },
2086
+ h: { type: "number", description: "Grid height in row units" },
2087
+ x: { type: "number", description: "Grid x position (0-11)" },
2088
+ y: { type: "number", description: "Grid y position" }
2089
+ },
2090
+ required: ["id", "title", "chartType", "w", "h", "x", "y"]
2091
+ },
2092
+ description: "Array of portlet configurations for the dashboard"
2093
+ },
2094
+ filters: {
2095
+ type: "array",
2096
+ items: {
2097
+ type: "object",
2098
+ properties: {
2099
+ id: { type: "string", description: "Unique filter ID" },
2100
+ label: { type: "string", description: "Display label for the filter" },
2101
+ filter: {
2102
+ type: "object",
2103
+ properties: {
2104
+ member: { type: "string" },
2105
+ operator: { type: "string" },
2106
+ values: { type: "array", items: {} }
2107
+ },
2108
+ required: ["member", "operator"],
2109
+ description: "The filter definition"
2110
+ },
2111
+ isUniversalTime: { type: "boolean", description: "When true, applies to all time dimensions in portlets" }
2112
+ },
2113
+ required: ["id", "label", "filter"]
2114
+ },
2115
+ description: "Dashboard-level filters"
2116
+ },
2117
+ colorPalette: { type: "string", description: "Color palette name" }
2118
+ },
2119
+ required: ["title", "portlets"]
2120
+ }
1782
2121
  }
1783
2122
  ];
1784
2123
  }
1785
- function ye(o) {
1786
- const { semanticLayer: t, securityContext: i } = o, s = /* @__PURE__ */ new Map();
1787
- return s.set("discover_cubes", async (e) => {
1788
- const a = await Y(t, {
2124
+ function xe(o) {
2125
+ const { semanticLayer: t, securityContext: a } = o, i = /* @__PURE__ */ new Map();
2126
+ return i.set("discover_cubes", async (e) => {
2127
+ const s = await Y(t, {
1789
2128
  topic: e.topic,
1790
2129
  intent: e.intent,
1791
2130
  limit: e.limit,
1792
2131
  minScore: e.minScore
1793
2132
  });
1794
- return { result: JSON.stringify(a, null, 2) };
1795
- }), s.set("get_cube_metadata", async () => {
2133
+ return { result: JSON.stringify(s, null, 2) };
2134
+ }), i.set("get_cube_metadata", async () => {
1796
2135
  const e = t.getMetadata();
1797
2136
  return { result: JSON.stringify(e, null, 2) };
1798
- }), s.set("execute_query", async (e) => {
2137
+ }), i.set("execute_query", async (e) => {
1799
2138
  try {
1800
- let a;
1801
- e.funnel ? a = { funnel: e.funnel } : e.flow ? a = { flow: e.flow } : e.retention ? a = { retention: e.retention } : a = {
2139
+ let s;
2140
+ e.funnel ? s = { funnel: e.funnel } : e.flow ? s = { flow: e.flow } : e.retention ? s = { retention: e.retention } : s = {
1802
2141
  measures: e.measures,
1803
2142
  dimensions: e.dimensions,
1804
2143
  filters: e.filters,
@@ -1806,90 +2145,173 @@ function ye(o) {
1806
2145
  order: e.order,
1807
2146
  limit: e.limit
1808
2147
  };
1809
- const n = await M(t, i, { query: a });
2148
+ const r = await M(t, a, { query: s });
1810
2149
  return {
1811
2150
  result: JSON.stringify({
1812
- rowCount: n.data.length,
1813
- data: n.data,
1814
- annotation: n.annotation
2151
+ rowCount: r.data.length,
2152
+ data: r.data,
2153
+ annotation: r.annotation
1815
2154
  }, null, 2)
1816
2155
  };
1817
- } catch (a) {
2156
+ } catch (s) {
1818
2157
  return {
1819
- result: `Query execution failed: ${a instanceof Error ? a.message : "Unknown error"}`,
2158
+ result: `Query execution failed: ${s instanceof Error ? s.message : "Unknown error"}`,
1820
2159
  isError: !0
1821
2160
  };
1822
2161
  }
1823
- }), s.set("add_portlet", async (e) => {
1824
- const n = {
2162
+ }), i.set("add_portlet", async (e) => {
2163
+ const r = {
1825
2164
  number: "kpiNumber",
1826
2165
  retention: "retentionHeatmap"
1827
2166
  }[e.chartType] ?? e.chartType;
1828
- let l;
2167
+ let p;
1829
2168
  try {
1830
- l = JSON.parse(e.query);
2169
+ p = JSON.parse(e.query);
1831
2170
  } catch {
1832
2171
  return {
1833
2172
  result: "Invalid query: could not parse JSON string. Ensure `query` is a valid JSON string.",
1834
2173
  isError: !0
1835
2174
  };
1836
2175
  }
1837
- const u = t.validateQuery(l);
1838
- if (!u.isValid)
2176
+ const m = t.validateQuery(p);
2177
+ if (!m.isValid)
1839
2178
  return {
1840
2179
  result: `Invalid query — fix these errors and retry:
1841
- ${u.errors.join(`
2180
+ ${m.errors.join(`
1842
2181
  `)}`,
1843
2182
  isError: !0
1844
2183
  };
1845
- const d = !!(l.funnel || l.flow || l.retention);
1846
- let p;
1847
- if (d)
1848
- p = e.chartConfig ?? {};
2184
+ const c = !!(p.funnel || p.flow || p.retention);
2185
+ let y;
2186
+ if (c)
2187
+ y = e.chartConfig ?? {};
1849
2188
  else {
1850
- const c = ue(n, e.chartConfig, l), g = pe(n, c, l);
1851
- if (!g.isValid)
2189
+ const f = fe(r, e.chartConfig, p), b = he(r, f, p);
2190
+ if (!b.isValid)
1852
2191
  return {
1853
2192
  result: `Chart config invalid — fix these errors and retry:
1854
- ${g.errors.join(`
2193
+ ${b.errors.join(`
1855
2194
  `)}`,
1856
2195
  isError: !0
1857
2196
  };
1858
- p = c;
2197
+ y = f;
1859
2198
  }
1860
- const k = `portlet-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`, f = {
1861
- id: k,
2199
+ const l = `portlet-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`, g = {
2200
+ id: l,
1862
2201
  title: e.title,
1863
2202
  query: e.query,
1864
- chartType: n,
1865
- chartConfig: p,
2203
+ chartType: r,
2204
+ chartConfig: y,
1866
2205
  displayConfig: e.displayConfig
1867
2206
  };
1868
2207
  return {
1869
- result: `Portlet "${e.title}" added to notebook (id: ${k}, chart: ${n}). [Reminder: in your next response, start with a brief sentence about what you will do next BEFORE making any tool calls.]`,
1870
- sideEffect: { type: "add_portlet", data: f }
2208
+ result: `Portlet "${e.title}" added to notebook (id: ${l}, chart: ${r}). [Reminder: in your next response, start with a brief sentence about what you will do next BEFORE making any tool calls.]`,
2209
+ sideEffect: { type: "add_portlet", data: g }
1871
2210
  };
1872
- }), s.set("add_markdown", async (e) => {
1873
- const a = `markdown-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`, n = {
1874
- id: a,
2211
+ }), i.set("add_markdown", async (e) => {
2212
+ const s = `markdown-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`, r = {
2213
+ id: s,
1875
2214
  title: e.title,
1876
2215
  content: e.content
1877
2216
  };
1878
2217
  return {
1879
- result: `Markdown block added to notebook (id: ${a}). [Reminder: in your next response, start with a brief sentence about what you will do next BEFORE making any tool calls.]`,
1880
- sideEffect: { type: "add_markdown", data: n }
2218
+ result: `Markdown block added to notebook (id: ${s}). [Reminder: in your next response, start with a brief sentence about what you will do next BEFORE making any tool calls.]`,
2219
+ sideEffect: { type: "add_markdown", data: r }
1881
2220
  };
1882
- }), s;
2221
+ }), i.set("save_as_dashboard", async (e) => {
2222
+ try {
2223
+ const s = e.portlets;
2224
+ if (!s || s.length === 0)
2225
+ return { result: "Dashboard must contain at least one portlet.", isError: !0 };
2226
+ const r = [];
2227
+ for (const l of s) {
2228
+ if (l.chartType === "markdown") continue;
2229
+ const f = l.query;
2230
+ if (!f) {
2231
+ r.push(`Portlet "${l.title}": missing query`);
2232
+ continue;
2233
+ }
2234
+ let b;
2235
+ try {
2236
+ b = JSON.parse(f);
2237
+ } catch {
2238
+ r.push(`Portlet "${l.title}": invalid JSON query`);
2239
+ continue;
2240
+ }
2241
+ const w = t.validateQuery(b);
2242
+ w.isValid || r.push(`Portlet "${l.title}": ${w.errors.join(", ")}`);
2243
+ }
2244
+ if (r.length > 0)
2245
+ return {
2246
+ result: `Dashboard has invalid portlets — fix these errors and retry:
2247
+ ${r.join(`
2248
+ `)}`,
2249
+ isError: !0
2250
+ };
2251
+ const p = {
2252
+ portlets: s.map((l) => {
2253
+ const g = l.chartType, f = g === "markdown", b = f ? "query" : l.analysisType || "query", w = b === "funnel" ? "funnel" : b === "flow" ? "flow" : b === "retention" ? "retention" : "query", C = l.query || "{}";
2254
+ let h;
2255
+ try {
2256
+ h = JSON.parse(C);
2257
+ } catch {
2258
+ h = {};
2259
+ }
2260
+ const d = {
2261
+ version: 1,
2262
+ analysisType: w,
2263
+ activeView: "chart",
2264
+ charts: {
2265
+ [w]: {
2266
+ chartType: g,
2267
+ chartConfig: l.chartConfig || {},
2268
+ displayConfig: l.displayConfig || {}
2269
+ }
2270
+ },
2271
+ query: f ? {} : h
2272
+ };
2273
+ return {
2274
+ id: l.id,
2275
+ title: l.title,
2276
+ analysisConfig: d,
2277
+ dashboardFilterMapping: l.dashboardFilterMapping,
2278
+ w: l.w,
2279
+ h: l.h,
2280
+ x: l.x,
2281
+ y: l.y
2282
+ };
2283
+ }),
2284
+ filters: e.filters,
2285
+ colorPalette: e.colorPalette
2286
+ }, m = e.title, c = p.portlets.length, y = p.filters?.length || 0;
2287
+ return {
2288
+ result: `Dashboard "${m}" created with ${c} portlets and ${y} filters.`,
2289
+ sideEffect: {
2290
+ type: "dashboard_saved",
2291
+ data: {
2292
+ title: m,
2293
+ description: e.description,
2294
+ dashboardConfig: p
2295
+ }
2296
+ }
2297
+ };
2298
+ } catch (s) {
2299
+ return {
2300
+ result: `Failed to save dashboard: ${s instanceof Error ? s.message : "Unknown error"}`,
2301
+ isError: !0
2302
+ };
2303
+ }
2304
+ }), i;
1883
2305
  }
1884
- async function* ge(o) {
1885
- const { message: t, sessionId: i, semanticLayer: s, securityContext: e, agentConfig: a, apiKey: n } = o;
1886
- let l;
2306
+ async function* Ce(o) {
2307
+ const { message: t, sessionId: a, history: i, semanticLayer: e, securityContext: s, agentConfig: r, apiKey: p } = o;
2308
+ let m;
1887
2309
  try {
1888
- const m = await import(
2310
+ const d = await import(
1889
2311
  /* webpackIgnore: true */
1890
2312
  "@anthropic-ai/sdk"
1891
2313
  );
1892
- l = m.default || m.Anthropic || m;
2314
+ m = d.default || d.Anthropic || d;
1893
2315
  } catch {
1894
2316
  yield {
1895
2317
  type: "error",
@@ -1899,134 +2321,159 @@ async function* ge(o) {
1899
2321
  };
1900
2322
  return;
1901
2323
  }
1902
- const u = new l({ apiKey: n }), d = ce(), p = ye({ semanticLayer: s, securityContext: e }), k = s.getMetadata(), f = L(k), c = a.model || "claude-sonnet-4-6", g = a.maxTurns || 25, F = a.maxTokens || 4096, v = [
1903
- { role: "user", content: t }
1904
- ];
2324
+ const c = new m({ apiKey: p }), y = ge(), l = xe({ semanticLayer: e, securityContext: s }), g = e.getMetadata(), f = H(g), b = r.model || "claude-sonnet-4-6", w = r.maxTurns || 25, C = r.maxTokens || 4096, h = [];
2325
+ if (i && i.length > 0) {
2326
+ for (const d of i)
2327
+ if (d.role === "user")
2328
+ h.push({ role: "user", content: d.content });
2329
+ else if (d.role === "assistant") {
2330
+ const x = [];
2331
+ if (d.content && x.push({ type: "text", text: d.content }), d.toolCalls && d.toolCalls.length > 0) {
2332
+ for (const u of d.toolCalls)
2333
+ x.push({
2334
+ type: "tool_use",
2335
+ id: u.id,
2336
+ name: u.name,
2337
+ input: u.input || {}
2338
+ });
2339
+ h.push({ role: "assistant", content: x }), h.push({
2340
+ role: "user",
2341
+ content: d.toolCalls.map((u) => ({
2342
+ type: "tool_result",
2343
+ tool_use_id: u.id,
2344
+ content: typeof u.result == "string" ? u.result : JSON.stringify(u.result ?? ""),
2345
+ ...u.status === "error" ? { is_error: !0 } : {}
2346
+ }))
2347
+ });
2348
+ } else x.length > 0 && h.push({ role: "assistant", content: d.content });
2349
+ }
2350
+ }
2351
+ h.push({ role: "user", content: t });
1905
2352
  try {
1906
- for (let m = 0; m < g; m++) {
1907
- const C = await u.messages.create({
1908
- model: c,
1909
- max_tokens: F,
2353
+ for (let d = 0; d < w; d++) {
2354
+ const x = await c.messages.create({
2355
+ model: b,
2356
+ max_tokens: C,
1910
2357
  system: f,
1911
- tools: d,
1912
- messages: v,
2358
+ tools: y,
2359
+ messages: h,
1913
2360
  stream: !0
1914
- }), y = [];
1915
- let x = -1, w = "", V = "";
1916
- for await (const h of C)
1917
- switch (h.type) {
2361
+ }), u = [];
2362
+ let A = -1, D = "", E = "";
2363
+ for await (const k of x)
2364
+ switch (k.type) {
1918
2365
  case "content_block_start": {
1919
- x++;
1920
- const r = h.content_block;
1921
- r.type === "tool_use" ? (y.push({ type: "tool_use", id: r.id, name: r.name, input: {} }), w = "", yield {
2366
+ A++;
2367
+ const n = k.content_block;
2368
+ n.type === "tool_use" ? (u.push({ type: "tool_use", id: n.id, name: n.name, input: {} }), D = "", yield {
1922
2369
  type: "tool_use_start",
1923
- data: { id: r.id, name: r.name, input: void 0 }
1924
- }) : r.type === "text" && y.push({ type: "text", text: "" });
2370
+ data: { id: n.id, name: n.name, input: void 0 }
2371
+ }) : n.type === "text" && u.push({ type: "text", text: "" });
1925
2372
  break;
1926
2373
  }
1927
2374
  case "content_block_delta": {
1928
- const r = h.delta;
1929
- if (r.type === "text_delta" && r.text) {
1930
- const A = y[x];
1931
- A && (A.text = (A.text || "") + r.text), yield { type: "text_delta", data: r.text };
1932
- } else r.type === "input_json_delta" && r.partial_json && (w += r.partial_json);
2375
+ const n = k.delta;
2376
+ if (n.type === "text_delta" && n.text) {
2377
+ const S = u[A];
2378
+ S && (S.text = (S.text || "") + n.text), yield { type: "text_delta", data: n.text };
2379
+ } else n.type === "input_json_delta" && n.partial_json && (D += n.partial_json);
1933
2380
  break;
1934
2381
  }
1935
2382
  case "content_block_stop": {
1936
- const r = y[x];
1937
- if (r?.type === "tool_use" && w) {
2383
+ const n = u[A];
2384
+ if (n?.type === "tool_use" && D) {
1938
2385
  try {
1939
- r.input = JSON.parse(w);
2386
+ n.input = JSON.parse(D);
1940
2387
  } catch {
1941
- r.input = {};
2388
+ n.input = {};
1942
2389
  }
1943
- w = "";
2390
+ D = "";
1944
2391
  }
1945
2392
  break;
1946
2393
  }
1947
2394
  case "message_delta": {
1948
- const r = h.delta;
1949
- r.stop_reason && (V = r.stop_reason);
2395
+ const n = k.delta;
2396
+ n.stop_reason && (E = n.stop_reason);
1950
2397
  break;
1951
2398
  }
1952
2399
  }
1953
- if (v.push({ role: "assistant", content: y }), V !== "tool_use")
2400
+ if (h.push({ role: "assistant", content: u }), E !== "tool_use")
1954
2401
  break;
1955
- const D = [];
1956
- for (const h of y) {
1957
- if (h.type !== "tool_use") continue;
1958
- const r = h.name, A = h.input || {}, T = h.id, E = p.get(r);
1959
- if (!E) {
1960
- D.push({
2402
+ const F = [];
2403
+ for (const k of u) {
2404
+ if (k.type !== "tool_use") continue;
2405
+ const n = k.name, S = k.input || {}, T = k.id, I = l.get(n);
2406
+ if (!I) {
2407
+ F.push({
1961
2408
  type: "tool_result",
1962
2409
  tool_use_id: T,
1963
- content: `Unknown tool: ${r}`,
2410
+ content: `Unknown tool: ${n}`,
1964
2411
  is_error: !0
1965
2412
  }), yield {
1966
2413
  type: "tool_use_result",
1967
- data: { id: T, name: r, result: `Unknown tool: ${r}`, isError: !0 }
2414
+ data: { id: T, name: n, result: `Unknown tool: ${n}`, isError: !0 }
1968
2415
  };
1969
2416
  continue;
1970
2417
  }
1971
2418
  try {
1972
- const b = await E(A);
1973
- b.sideEffect && (yield b.sideEffect), D.push({
2419
+ const v = await I(S);
2420
+ v.sideEffect && (yield v.sideEffect), F.push({
1974
2421
  type: "tool_result",
1975
2422
  tool_use_id: T,
1976
- content: b.result,
1977
- ...b.isError ? { is_error: !0 } : {}
2423
+ content: v.result,
2424
+ ...v.isError ? { is_error: !0 } : {}
1978
2425
  }), yield {
1979
2426
  type: "tool_use_result",
1980
- data: { id: T, name: r, result: b.result, ...b.isError ? { isError: !0 } : {} }
2427
+ data: { id: T, name: n, result: v.result, ...v.isError ? { isError: !0 } : {} }
1981
2428
  };
1982
- } catch (b) {
1983
- const I = b instanceof Error ? b.message : "Tool execution failed";
1984
- D.push({
2429
+ } catch (v) {
2430
+ const O = v instanceof Error ? v.message : "Tool execution failed";
2431
+ F.push({
1985
2432
  type: "tool_result",
1986
2433
  tool_use_id: T,
1987
- content: I,
2434
+ content: O,
1988
2435
  is_error: !0
1989
2436
  }), yield {
1990
2437
  type: "tool_use_result",
1991
- data: { id: T, name: r, result: I, isError: !0 }
2438
+ data: { id: T, name: n, result: O, isError: !0 }
1992
2439
  };
1993
2440
  }
1994
2441
  }
1995
- yield { type: "turn_complete", data: {} }, v.push({ role: "user", content: D });
2442
+ yield { type: "turn_complete", data: {} }, h.push({ role: "user", content: F });
1996
2443
  }
1997
2444
  yield {
1998
2445
  type: "done",
1999
- data: { sessionId: i || "" }
2446
+ data: { sessionId: a || "" }
2000
2447
  };
2001
- } catch (m) {
2448
+ } catch (d) {
2002
2449
  yield {
2003
2450
  type: "error",
2004
2451
  data: {
2005
- message: fe(m)
2452
+ message: we(d)
2006
2453
  }
2007
2454
  };
2008
2455
  }
2009
2456
  }
2010
- function fe(o) {
2457
+ function we(o) {
2011
2458
  if (!o || !(o instanceof Error))
2012
2459
  return "Something went wrong. Please try again.";
2013
- const t = o.message || "", i = {
2460
+ const t = o.message || "", a = {
2014
2461
  overloaded_error: "The AI service is temporarily overloaded. Please try again in a moment.",
2015
2462
  rate_limit_error: "Too many requests. Please wait a moment and try again.",
2016
2463
  api_error: "The AI service encountered an error. Please try again.",
2017
2464
  authentication_error: "Authentication failed. Please check your API key configuration.",
2018
2465
  invalid_request_error: "There was a problem with the request. Please try again."
2019
- }, s = o;
2020
- if (s.status || s.type) {
2021
- const e = s.error?.type || s.type || "";
2022
- if (i[e])
2023
- return i[e];
2466
+ }, i = o;
2467
+ if (i.status || i.type) {
2468
+ const e = i.error?.type || i.type || "";
2469
+ if (a[e])
2470
+ return a[e];
2024
2471
  }
2025
2472
  if (t.startsWith("{") || t.startsWith("Error: {")) {
2026
2473
  try {
2027
- const e = JSON.parse(t.replace(/^Error:\s*/, "")), a = e.error?.type || e.type || "";
2028
- if (i[a])
2029
- return i[a];
2474
+ const e = JSON.parse(t.replace(/^Error:\s*/, "")), s = e.error?.type || e.type || "";
2475
+ if (a[s])
2476
+ return a[s];
2030
2477
  } catch {
2031
2478
  }
2032
2479
  return "The AI service encountered an error. Please try again.";
@@ -2034,5 +2481,5 @@ function fe(o) {
2034
2481
  return t;
2035
2482
  }
2036
2483
  export {
2037
- ge as handleAgentChat
2484
+ Ce as handleAgentChat
2038
2485
  };