@timbal-ai/timbal-react 1.0.0 → 1.2.0

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 (42) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +55 -8
  3. package/dist/app.cjs +2369 -1189
  4. package/dist/app.d.cts +8 -4
  5. package/dist/app.d.ts +8 -4
  6. package/dist/app.esm.js +32 -7
  7. package/dist/{chart-artifact-DOkwSTjQ.d.cts → chart-artifact-E58ve76I.d.cts} +279 -12
  8. package/dist/{chart-artifact-CBo9x8Ch.d.ts → chart-artifact-_PEJgCpQ.d.ts} +279 -12
  9. package/dist/{chat-Bed4FQSl.d.cts → chat-ClmzWzCX.d.cts} +33 -4
  10. package/dist/{chat-Bed4FQSl.d.ts → chat-ClmzWzCX.d.ts} +33 -4
  11. package/dist/chat.cjs +1446 -776
  12. package/dist/chat.d.cts +1 -1
  13. package/dist/chat.d.ts +1 -1
  14. package/dist/chat.esm.js +3 -3
  15. package/dist/{chunk-YEFBANNF.esm.js → chunk-4VULP3CJ.esm.js} +242 -288
  16. package/dist/{chunk-RZ6QC6RG.esm.js → chunk-AGJKK6R7.esm.js} +2 -2
  17. package/dist/{chunk-FOD67Z6G.esm.js → chunk-BMXFXLVV.esm.js} +341 -12
  18. package/dist/chunk-FEYZUVBM.esm.js +52 -0
  19. package/dist/{chunk-C6IXFM4T.esm.js → chunk-MTYXREHK.esm.js} +4 -4
  20. package/dist/{chunk-AYHOVAMI.esm.js → chunk-NAMKO2MU.esm.js} +1 -1
  21. package/dist/{chunk-SNLXVG7H.esm.js → chunk-UY7AKWJL.esm.js} +1108 -656
  22. package/dist/{chunk-GLPOVYEA.esm.js → chunk-XDIY2WSL.esm.js} +669 -279
  23. package/dist/index.cjs +2967 -1824
  24. package/dist/index.d.cts +5 -5
  25. package/dist/index.d.ts +5 -5
  26. package/dist/index.esm.js +41 -11
  27. package/dist/pill-segmented-tabs-BsIOW1Lo.d.cts +528 -0
  28. package/dist/pill-segmented-tabs-BsIOW1Lo.d.ts +528 -0
  29. package/dist/studio.cjs +1685 -1015
  30. package/dist/studio.d.cts +2 -2
  31. package/dist/studio.d.ts +2 -2
  32. package/dist/studio.esm.js +5 -5
  33. package/dist/styles.css +24 -0
  34. package/dist/ui.cjs +387 -49
  35. package/dist/ui.d.cts +71 -491
  36. package/dist/ui.d.ts +71 -491
  37. package/dist/ui.esm.js +26 -6
  38. package/dist/{welcome-COOb05a5.d.cts → welcome-BFGRoNfK.d.cts} +1 -1
  39. package/dist/{welcome-DE08m9ca.d.ts → welcome-DXqsGTwH.d.ts} +1 -1
  40. package/package.json +7 -3
  41. package/vite/local-dev.d.ts +5 -1
  42. package/vite/local-dev.mjs +17 -13
@@ -3,6 +3,11 @@ import {
3
3
  AvatarFallback,
4
4
  AvatarImage,
5
5
  Button,
6
+ ChartContainer,
7
+ ChartLegend,
8
+ ChartLegendContent,
9
+ ChartTooltip,
10
+ ChartTooltipContent,
6
11
  Dialog,
7
12
  DialogContent,
8
13
  DialogTitle,
@@ -18,7 +23,7 @@ import {
18
23
  TooltipProvider,
19
24
  TooltipTrigger,
20
25
  cn
21
- } from "./chunk-FOD67Z6G.esm.js";
26
+ } from "./chunk-BMXFXLVV.esm.js";
22
27
 
23
28
  // src/chat/tooltip-icon-button.tsx
24
29
  import { forwardRef } from "react";
@@ -202,27 +207,133 @@ var ComposerAddAttachment = () => {
202
207
  ) });
203
208
  };
204
209
 
210
+ // src/charts/line-area-chart-utils.ts
211
+ function resolveChartMargin(options) {
212
+ const { flush, showXAxis, showYAxis } = options;
213
+ if (!flush) {
214
+ return { top: 8, right: 12, bottom: 0, left: 0 };
215
+ }
216
+ const anyAxis = showXAxis || showYAxis;
217
+ if (!anyAxis) {
218
+ return { top: 8, right: 12, bottom: 8, left: 12 };
219
+ }
220
+ return {
221
+ top: 8,
222
+ right: 12,
223
+ bottom: showXAxis ? 24 : 8,
224
+ left: showYAxis ? 8 : 12
225
+ };
226
+ }
227
+ function flushBarCategoryGap(flush, showCategoryAxis) {
228
+ return flush && showCategoryAxis ? "0%" : void 0;
229
+ }
230
+ function flushLineAreaEdgeToEdge(flush, variant, showXAxis, showYAxis) {
231
+ return flush && (variant === "line" || variant === "area") && showXAxis && !showYAxis;
232
+ }
233
+ function resolveTooltipCategory(label, payload, xKey, data, formatX) {
234
+ const row = payload?.[0]?.payload;
235
+ if (row && xKey in row) {
236
+ const idx = data.indexOf(row);
237
+ return formatX(row[xKey], idx >= 0 ? idx : 0);
238
+ }
239
+ if (label != null && label !== "") {
240
+ const idx = typeof label === "number" ? label : data.findIndex((r) => r[xKey] === label || String(r[xKey]) === String(label));
241
+ return formatX(label, idx >= 0 ? idx : 0);
242
+ }
243
+ return "";
244
+ }
245
+
205
246
  // src/charts/line-area-chart.tsx
206
- import { useEffect as useEffect3, useId, useMemo, useState as useState3 } from "react";
247
+ import { useId } from "react";
248
+ import {
249
+ Area,
250
+ AreaChart,
251
+ Bar,
252
+ BarChart,
253
+ CartesianGrid,
254
+ Line,
255
+ LineChart,
256
+ XAxis,
257
+ YAxis
258
+ } from "recharts";
207
259
 
208
- // src/charts/use-chart-width.ts
209
- import { useEffect as useEffect2, useRef, useState as useState2 } from "react";
210
- function useChartWidth(initial = 640) {
211
- const ref = useRef(null);
212
- const [width, setWidth] = useState2(initial);
213
- useEffect2(() => {
214
- const el = ref.current;
215
- if (!el || typeof ResizeObserver === "undefined") return;
216
- const ro = new ResizeObserver((entries) => {
217
- const w = entries[0]?.contentRect.width;
218
- if (w && w > 0) setWidth(w);
219
- });
220
- ro.observe(el);
221
- return () => ro.disconnect();
222
- }, []);
223
- return { ref, width };
260
+ // src/charts/chart-gradient-utils.ts
261
+ function barGradientId(scopeId, dataKey) {
262
+ return `bar-${scopeId}-${sanitizeId(dataKey)}`;
263
+ }
264
+ function pieGradientId(scopeId, key) {
265
+ return `pie-${scopeId}-${sanitizeId(key)}`;
266
+ }
267
+ function sanitizeId(key) {
268
+ return key.replace(/[^a-zA-Z0-9_-]/g, "_");
269
+ }
270
+ function truncateLabel(text, maxChars = 14) {
271
+ const s = String(text ?? "");
272
+ if (s.length <= maxChars) return s;
273
+ if (maxChars <= 1) return "\u2026";
274
+ return `${s.slice(0, maxChars - 1)}\u2026`;
275
+ }
276
+ function estimateYAxisWidth(labels, { min = 48, max = 112, charWidth = 6.5 } = {}) {
277
+ if (labels.length === 0) return min;
278
+ const longest = labels.reduce((a, b) => a.length >= b.length ? a : b, "");
279
+ return Math.min(max, Math.max(min, Math.ceil(longest.length * charWidth) + 12));
224
280
  }
225
281
 
282
+ // src/charts/chart-axis-tick.tsx
283
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
284
+ var ChartAxisTick = ({
285
+ x = 0,
286
+ y = 0,
287
+ payload,
288
+ textAnchor = "end",
289
+ maxChars = 14,
290
+ clipTicks = true
291
+ }) => {
292
+ const raw = String(payload?.value ?? "");
293
+ const label = clipTicks ? truncateLabel(raw, maxChars) : raw;
294
+ return /* @__PURE__ */ jsxs3("g", { transform: `translate(${x},${y})`, children: [
295
+ /* @__PURE__ */ jsx3("title", { children: raw }),
296
+ /* @__PURE__ */ jsx3(
297
+ "text",
298
+ {
299
+ textAnchor,
300
+ fill: "currentColor",
301
+ className: "fill-muted-foreground",
302
+ dominantBaseline: "middle",
303
+ children: label
304
+ }
305
+ )
306
+ ] });
307
+ };
308
+
309
+ // src/charts/chart-gradients.tsx
310
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
311
+ var BarGradientDefs = ({
312
+ scopeId,
313
+ dataKeys,
314
+ horizontal
315
+ }) => /* @__PURE__ */ jsx4("defs", { children: dataKeys.map((dataKey) => {
316
+ const id = barGradientId(scopeId, dataKey);
317
+ const color = `var(--color-${dataKey})`;
318
+ if (horizontal) {
319
+ return /* @__PURE__ */ jsxs4("linearGradient", { id, x1: "0", y1: "0", x2: "1", y2: "0", children: [
320
+ /* @__PURE__ */ jsx4("stop", { offset: "0%", stopColor: color, stopOpacity: 1 }),
321
+ /* @__PURE__ */ jsx4("stop", { offset: "100%", stopColor: color, stopOpacity: 0.55 })
322
+ ] }, dataKey);
323
+ }
324
+ return /* @__PURE__ */ jsxs4("linearGradient", { id, x1: "0", y1: "0", x2: "0", y2: "1", children: [
325
+ /* @__PURE__ */ jsx4("stop", { offset: "0%", stopColor: color, stopOpacity: 1 }),
326
+ /* @__PURE__ */ jsx4("stop", { offset: "100%", stopColor: color, stopOpacity: 0.55 })
327
+ ] }, dataKey);
328
+ }) });
329
+ var PieGradientDefs = ({ scopeId, slices }) => /* @__PURE__ */ jsx4("defs", { children: slices.map(({ key, color }) => {
330
+ const id = pieGradientId(scopeId, key);
331
+ return /* @__PURE__ */ jsxs4("linearGradient", { id, x1: "0", y1: "0", x2: "1", y2: "1", children: [
332
+ /* @__PURE__ */ jsx4("stop", { offset: "0%", stopColor: color, stopOpacity: 1 }),
333
+ /* @__PURE__ */ jsx4("stop", { offset: "100%", stopColor: color, stopOpacity: 0.65 })
334
+ ] }, key);
335
+ }) });
336
+
226
337
  // src/charts/geometry.ts
227
338
  function toNum(value) {
228
339
  const n = typeof value === "number" ? value : Number(value);
@@ -293,27 +404,6 @@ function monotoneTangents(points) {
293
404
  }
294
405
  return tangents;
295
406
  }
296
- function niceTicks(min, max, count = 4) {
297
- if (!Number.isFinite(min) || !Number.isFinite(max) || max === min) {
298
- return [min || 0];
299
- }
300
- const step = niceStep((max - min) / count);
301
- const start = Math.floor(min / step) * step;
302
- const out = [];
303
- for (let v = start; v <= max + step / 2; v += step) {
304
- out.push(round(v));
305
- }
306
- return out;
307
- }
308
- function niceStep(raw) {
309
- const exp = Math.floor(Math.log10(Math.abs(raw) || 1));
310
- const base = Math.pow(10, exp);
311
- const norm = raw / base;
312
- let nice = 1;
313
- if (norm >= 5) nice = 5;
314
- else if (norm >= 2) nice = 2;
315
- return nice * base;
316
- }
317
407
  function round(v) {
318
408
  return Math.round(v * 1e6) / 1e6;
319
409
  }
@@ -327,17 +417,16 @@ function formatCompact(value, unit) {
327
417
  }
328
418
 
329
419
  // src/charts/line-area-chart.tsx
330
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
420
+ import { Fragment, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
421
+ var INDEX_X_KEY = "__index";
331
422
  var CHART_PALETTE = [
332
- "var(--primary, #6366f1)",
333
- "#10b981",
334
- "#f59e0b",
335
- "#06b6d4",
336
- "#a855f7",
337
- "#ef4444"
423
+ "var(--chart-1, #4f46e5)",
424
+ "var(--chart-2, #3b82f6)",
425
+ "var(--chart-3, #0ea5e9)",
426
+ "var(--chart-4, #6366f1)",
427
+ "var(--chart-5, #60a5fa)",
428
+ "var(--chart-6, #2563eb)"
338
429
  ];
339
- var PAD_DEFAULT = { top: 12, right: 16, bottom: 26, left: 44 };
340
- var PAD_FLUSH = { top: 20, right: 0, bottom: 8, left: 0 };
341
430
  var LineAreaChart = ({
342
431
  data = [],
343
432
  xKey: xKeyProp,
@@ -346,308 +435,314 @@ var LineAreaChart = ({
346
435
  height = 240,
347
436
  unit,
348
437
  yMax,
438
+ curve = "monotone",
439
+ stacked = false,
440
+ dots = false,
441
+ orientation = "vertical",
442
+ barRadius = 4,
443
+ gridLines,
349
444
  layout = "default",
350
445
  showGrid = true,
351
446
  showXAxis: showXAxisProp,
352
447
  showYAxis: showYAxisProp,
353
448
  showLegend: showLegendProp,
354
449
  showTooltip = true,
450
+ tooltipIndicator = "dot",
355
451
  formatValue,
356
452
  formatX,
453
+ clipTicks = true,
357
454
  className,
358
455
  ariaLabel = "Chart"
359
456
  }) => {
360
- const uid = useId();
361
- const { ref, width } = useChartWidth();
362
- const [active, setActive] = useState3(null);
363
- const [grown, setGrown] = useState3(false);
457
+ const gradientScopeId = useId().replace(/:/g, "");
364
458
  const xKey = xKeyProp ?? inferXKey(data);
365
- const series = useMemo(
366
- () => resolveSeries(seriesProp, data, xKey),
367
- [seriesProp, data, xKey]
368
- );
369
- const pad = layout === "flush" ? PAD_FLUSH : PAD_DEFAULT;
370
- const showXAxis = showXAxisProp ?? layout !== "flush";
371
- const showYAxis = showYAxisProp ?? layout !== "flush";
372
- const showLegend = showLegendProp ?? (layout !== "flush" && series.length > 1);
373
- useEffect3(() => {
374
- const t = requestAnimationFrame(() => setGrown(true));
375
- return () => cancelAnimationFrame(t);
376
- }, []);
377
- const innerW = Math.max(0, width - pad.left - pad.right);
378
- const innerH = Math.max(0, height - pad.top - pad.bottom);
379
- const { minV, maxV } = useMemo(() => {
380
- let lo = 0;
381
- let hi = yMax ?? 0;
382
- for (const s of series) {
383
- for (const d of data) {
384
- const v = toNum(d[s.dataKey]);
385
- if (v > hi && yMax == null) hi = v;
386
- if (v < lo) lo = v;
387
- }
388
- }
389
- if (hi === lo) hi = lo + 1;
390
- return { minV: lo, maxV: yMax != null ? yMax : hi * 1.08 };
391
- }, [series, data, yMax]);
392
- const ticks = useMemo(() => niceTicks(minV, maxV, 4), [minV, maxV]);
459
+ const series = resolveSeries(seriesProp, data, xKey);
460
+ const flush = layout === "flush";
461
+ const horizontal = orientation === "horizontal" && variant === "bar";
462
+ const showXAxis = showXAxisProp ?? !flush;
463
+ const showYAxis = showYAxisProp ?? !flush;
464
+ const showLegend = showLegendProp ?? (!flush && series.length > 1);
465
+ const grid = gridLines ?? (horizontal ? "vertical" : "horizontal");
393
466
  if (data.length === 0 || series.length === 0) {
394
- return /* @__PURE__ */ jsx3(ChartEmpty, { className, height });
395
- }
396
- const yScale = (v) => pad.top + innerH - (v - minV) / (maxV - minV || 1) * innerH;
397
- const xCount = data.length;
398
- const xStep = xCount > 1 ? innerW / (xCount - 1) : innerW;
399
- const xPos = (i) => variant === "bar" ? pad.left + innerW * (i + 0.5) / xCount : pad.left + i * xStep;
400
- const baseY = yScale(Math.max(0, minV));
401
- const fmtV = (v) => formatValue ? formatValue(v) : formatCompact(v, unit);
402
- const fmtX = (i) => formatX ? formatX(data[i]?.[xKey], i) : String(data[i]?.[xKey] ?? i);
403
- const onMove = (event) => {
404
- const rect = event.currentTarget.getBoundingClientRect();
405
- const px = event.clientX - rect.left - pad.left;
406
- const i = Math.round(px / (xStep || 1));
407
- setActive(Math.max(0, Math.min(xCount - 1, i)));
408
- };
409
- const labelIdx = pickXLabels(xCount, innerW);
410
- return /* @__PURE__ */ jsxs3("div", { ref, className: cn("relative w-full", className), style: { height }, children: [
411
- /* @__PURE__ */ jsxs3(
412
- "svg",
467
+ return /* @__PURE__ */ jsx5(ChartEmpty, { className, height, ariaLabel });
468
+ }
469
+ const config = {};
470
+ series.forEach((s, i) => {
471
+ config[s.dataKey] = {
472
+ label: s.label ?? s.dataKey,
473
+ color: s.color ?? CHART_PALETTE[i % CHART_PALETTE.length]
474
+ };
475
+ });
476
+ const valueFmt = (v) => formatValue ? formatValue(toNum(v)) : formatCompact(toNum(v), unit);
477
+ const xFmt = (v, i) => formatX ? formatX(v, i) : String(v ?? "");
478
+ const margin = resolveChartMargin({ flush, showXAxis, showYAxis });
479
+ const flushCategoryXAxisProps = flush && showXAxis && flushLineAreaEdgeToEdge(flush, variant, showXAxis, showYAxis) ? { scale: "point", padding: "no-gap", interval: 0 } : flush && showXAxis && variant === "bar" ? { interval: 0 } : {};
480
+ const useIndexX = flushLineAreaEdgeToEdge(flush, variant, showXAxis, showYAxis);
481
+ const chartData = useIndexX ? data.map((row, i) => ({ ...row, [INDEX_X_KEY]: i })) : data;
482
+ const chartXKey = useIndexX ? INDEX_X_KEY : xKey;
483
+ const categoryTick = (textAnchor) => /* @__PURE__ */ jsx5(ChartAxisTick, { textAnchor, clipTicks });
484
+ const showVGrid = showGrid && (grid === "vertical" || grid === "both");
485
+ const showHGrid = showGrid && (grid === "horizontal" || grid === "both");
486
+ const tooltipEl = showTooltip ? /* @__PURE__ */ jsx5(
487
+ ChartTooltip,
488
+ {
489
+ cursor: variant === "bar",
490
+ content: ({ active, payload, label }) => /* @__PURE__ */ jsx5(
491
+ ChartTooltipContent,
492
+ {
493
+ active,
494
+ payload,
495
+ label,
496
+ indicator: tooltipIndicator,
497
+ labelFormatter: (_value, items) => {
498
+ const category = resolveTooltipCategory(label, items, xKey, data, xFmt);
499
+ return category || null;
500
+ },
501
+ formatter: (value, name, item) => {
502
+ const key = String(item.dataKey ?? name ?? "value");
503
+ const seriesLabel = config[key]?.label ?? name;
504
+ return /* @__PURE__ */ jsxs5("div", { className: "flex flex-1 items-center justify-between leading-none", children: [
505
+ /* @__PURE__ */ jsx5("span", { className: "text-muted-foreground", children: seriesLabel }),
506
+ value != null ? /* @__PURE__ */ jsx5("span", { className: "text-foreground font-mono font-medium tabular-nums", children: valueFmt(value) }) : null
507
+ ] });
508
+ }
509
+ }
510
+ )
511
+ }
512
+ ) : null;
513
+ const legendEl = showLegend ? /* @__PURE__ */ jsx5(ChartLegend, { content: /* @__PURE__ */ jsx5(ChartLegendContent, {}) }) : null;
514
+ const gridEl = showGrid && grid !== "none" ? /* @__PURE__ */ jsx5(CartesianGrid, { vertical: showVGrid, horizontal: showHGrid, strokeDasharray: "4 4" }) : null;
515
+ const yDomain = yMax != null ? [0, yMax] : void 0;
516
+ if (variant === "bar") {
517
+ const dataKeys = series.map((s) => s.dataKey);
518
+ const barDefs = /* @__PURE__ */ jsx5(BarGradientDefs, { scopeId: gradientScopeId, dataKeys, horizontal });
519
+ const bars = series.map((s) => /* @__PURE__ */ jsx5(
520
+ Bar,
413
521
  {
414
- width,
415
- height,
416
- role: "img",
417
- "aria-label": ariaLabel,
418
- className: "block overflow-visible",
419
- children: [
420
- /* @__PURE__ */ jsxs3("defs", { children: [
421
- /* @__PURE__ */ jsx3("clipPath", { id: `${uid}-grow`, children: /* @__PURE__ */ jsx3(
422
- "rect",
522
+ dataKey: s.dataKey,
523
+ fill: `url(#${barGradientId(gradientScopeId, s.dataKey)})`,
524
+ radius: barCornerRadius(barRadius, horizontal, stacked),
525
+ stackId: stacked ? "stack" : void 0,
526
+ isAnimationActive: true
527
+ },
528
+ s.dataKey
529
+ ));
530
+ if (horizontal) {
531
+ const categoryLabels = data.map((row, i) => xFmt(row[xKey], i));
532
+ const yAxisWidth = showYAxis ? estimateYAxisWidth(
533
+ clipTicks ? categoryLabels.map((l) => l.slice(0, 14)) : categoryLabels
534
+ ) : 0;
535
+ return /* @__PURE__ */ jsx5(ChartShell, { config, height, className, ariaLabel, children: /* @__PURE__ */ jsxs5(
536
+ BarChart,
537
+ {
538
+ accessibilityLayer: true,
539
+ data,
540
+ layout: "vertical",
541
+ margin,
542
+ barCategoryGap: flushBarCategoryGap(flush, showYAxis),
543
+ children: [
544
+ barDefs,
545
+ gridEl,
546
+ showXAxis ? /* @__PURE__ */ jsx5(
547
+ XAxis,
423
548
  {
424
- x: pad.left,
425
- y: 0,
426
- height,
427
- width: grown ? innerW : 0,
428
- style: { transition: "width 900ms cubic-bezier(0.22,1,0.36,1)" }
549
+ type: "number",
550
+ tickLine: false,
551
+ axisLine: false,
552
+ tickMargin: 8,
553
+ tickFormatter: (v) => valueFmt(v),
554
+ domain: yDomain
429
555
  }
430
- ) }),
431
- /* @__PURE__ */ jsxs3("linearGradient", { id: `${uid}-gridfade`, x1: "0%", x2: "100%", y1: "0", y2: "0", children: [
432
- /* @__PURE__ */ jsx3("stop", { offset: "0%", stopColor: "white", stopOpacity: 0 }),
433
- /* @__PURE__ */ jsx3("stop", { offset: "8%", stopColor: "white", stopOpacity: 1 }),
434
- /* @__PURE__ */ jsx3("stop", { offset: "92%", stopColor: "white", stopOpacity: 1 }),
435
- /* @__PURE__ */ jsx3("stop", { offset: "100%", stopColor: "white", stopOpacity: 0 })
436
- ] }),
437
- /* @__PURE__ */ jsx3("mask", { id: `${uid}-gridmask`, children: /* @__PURE__ */ jsx3(
438
- "rect",
556
+ ) : null,
557
+ showYAxis ? /* @__PURE__ */ jsx5(
558
+ YAxis,
439
559
  {
440
- x: pad.left,
441
- y: pad.top,
442
- width: innerW,
443
- height: innerH,
444
- fill: `url(#${uid}-gridfade)`
560
+ type: "category",
561
+ dataKey: xKey,
562
+ tickLine: false,
563
+ axisLine: false,
564
+ tickMargin: 8,
565
+ width: yAxisWidth,
566
+ minTickGap: 16,
567
+ tick: categoryTick("end")
445
568
  }
446
- ) }),
447
- series.map((s, i) => {
448
- const color = s.color ?? CHART_PALETTE[i % CHART_PALETTE.length];
449
- return /* @__PURE__ */ jsxs3(
450
- "linearGradient",
451
- {
452
- id: `${uid}-fill-${i}`,
453
- x1: "0",
454
- x2: "0",
455
- y1: "0",
456
- y2: "1",
457
- children: [
458
- /* @__PURE__ */ jsx3("stop", { offset: "0%", style: { stopColor: color, stopOpacity: 0.28 } }),
459
- /* @__PURE__ */ jsx3("stop", { offset: "100%", style: { stopColor: color, stopOpacity: 0 } })
460
- ]
461
- },
462
- s.dataKey
463
- );
464
- })
465
- ] }),
466
- showGrid && /* @__PURE__ */ jsx3("g", { mask: `url(#${uid}-gridmask)`, children: ticks.map((t, i) => /* @__PURE__ */ jsx3(
467
- "line",
468
- {
469
- x1: pad.left,
470
- x2: width - pad.right,
471
- y1: yScale(t),
472
- y2: yScale(t),
473
- stroke: "currentColor",
474
- strokeOpacity: 0.14,
475
- strokeDasharray: "4 4",
476
- className: "text-muted-foreground"
477
- },
478
- i
479
- )) }),
480
- showYAxis && ticks.map((t, i) => /* @__PURE__ */ jsx3(
481
- "text",
482
- {
483
- x: pad.left - 8,
484
- y: yScale(t),
485
- textAnchor: "end",
486
- dominantBaseline: "middle",
487
- className: "fill-muted-foreground text-[10px] tabular-nums",
488
- children: fmtV(t)
489
- },
490
- i
491
- )),
492
- showXAxis && labelIdx.map((i) => /* @__PURE__ */ jsx3(
493
- "text",
569
+ ) : /* @__PURE__ */ jsx5(YAxis, { type: "category", dataKey: xKey, hide: true, width: 0 }),
570
+ tooltipEl,
571
+ legendEl,
572
+ bars
573
+ ]
574
+ }
575
+ ) });
576
+ }
577
+ return /* @__PURE__ */ jsx5(ChartShell, { config, height, className, ariaLabel, children: /* @__PURE__ */ jsxs5(
578
+ BarChart,
579
+ {
580
+ accessibilityLayer: true,
581
+ data,
582
+ margin,
583
+ barCategoryGap: flushBarCategoryGap(flush, showXAxis),
584
+ children: [
585
+ barDefs,
586
+ gridEl,
587
+ showXAxis ? /* @__PURE__ */ jsx5(
588
+ XAxis,
494
589
  {
495
- x: xPos(i),
496
- y: height - pad.bottom + 16,
497
- textAnchor: i === 0 ? "start" : i === xCount - 1 ? "end" : "middle",
498
- className: "fill-muted-foreground text-[10px] tabular-nums",
499
- children: fmtX(i)
500
- },
501
- i
502
- )),
503
- /* @__PURE__ */ jsx3("g", { clipPath: `url(#${uid}-grow)`, children: variant === "bar" ? renderBars({ data, series, xCount, xPos, yScale, baseY, innerW, uid }) : series.map((s, si) => {
504
- const color = s.color ?? CHART_PALETTE[si % CHART_PALETTE.length];
505
- const pts = data.map((d, i) => ({
506
- x: xPos(i),
507
- y: yScale(toNum(d[s.dataKey]))
508
- }));
509
- return /* @__PURE__ */ jsxs3("g", { children: [
510
- variant === "area" && /* @__PURE__ */ jsx3("path", { d: monotoneAreaPath(pts, baseY), fill: `url(#${uid}-fill-${si})` }),
511
- /* @__PURE__ */ jsx3(
512
- "path",
513
- {
514
- d: monotoneLinePath(pts),
515
- fill: "none",
516
- stroke: color,
517
- strokeWidth: 2,
518
- strokeLinecap: "round",
519
- strokeLinejoin: "round"
520
- }
521
- )
522
- ] }, s.dataKey);
523
- }) }),
524
- showTooltip && active != null && variant !== "bar" && /* @__PURE__ */ jsxs3("g", { pointerEvents: "none", children: [
525
- /* @__PURE__ */ jsx3(
526
- "line",
527
- {
528
- x1: xPos(active),
529
- x2: xPos(active),
530
- y1: pad.top,
531
- y2: pad.top + innerH,
532
- stroke: "currentColor",
533
- strokeOpacity: 0.25,
534
- className: "text-foreground"
535
- }
536
- ),
537
- series.map((s, si) => {
538
- const color = s.color ?? CHART_PALETTE[si % CHART_PALETTE.length];
539
- return /* @__PURE__ */ jsx3(
540
- "circle",
541
- {
542
- cx: xPos(active),
543
- cy: yScale(toNum(data[active]?.[s.dataKey])),
544
- r: 4,
545
- fill: color,
546
- stroke: "var(--background, #fff)",
547
- strokeWidth: 2
548
- },
549
- s.dataKey
550
- );
551
- })
552
- ] }),
553
- showTooltip && /* @__PURE__ */ jsx3(
554
- "rect",
590
+ dataKey: xKey,
591
+ tickLine: false,
592
+ axisLine: false,
593
+ tickMargin: 8,
594
+ minTickGap: 16,
595
+ tick: categoryTick("middle"),
596
+ ...flushCategoryXAxisProps
597
+ }
598
+ ) : /* @__PURE__ */ jsx5(XAxis, { dataKey: xKey, hide: true }),
599
+ showYAxis ? /* @__PURE__ */ jsx5(
600
+ YAxis,
555
601
  {
556
- x: pad.left,
557
- y: pad.top,
558
- width: innerW,
559
- height: innerH,
560
- fill: "transparent",
561
- style: { cursor: "crosshair" },
562
- onMouseMove: onMove,
563
- onMouseLeave: () => setActive(null)
602
+ tickLine: false,
603
+ axisLine: false,
604
+ tickMargin: 8,
605
+ width: 44,
606
+ tickFormatter: (v) => valueFmt(v),
607
+ domain: yDomain
564
608
  }
565
- )
609
+ ) : null,
610
+ tooltipEl,
611
+ legendEl,
612
+ bars
566
613
  ]
567
614
  }
568
- ),
569
- showTooltip && active != null && /* @__PURE__ */ jsx3(
570
- ChartTooltip,
615
+ ) });
616
+ }
617
+ const lineAreaAxes = /* @__PURE__ */ jsxs5(Fragment, { children: [
618
+ showXAxis && useIndexX ? /* @__PURE__ */ jsx5(
619
+ XAxis,
571
620
  {
572
- x: xPos(active),
573
- width,
574
- title: fmtX(active),
575
- rows: series.map((s, si) => ({
576
- color: s.color ?? CHART_PALETTE[si % CHART_PALETTE.length],
577
- label: s.label ?? s.dataKey,
578
- value: fmtV(toNum(data[active]?.[s.dataKey]))
579
- }))
621
+ type: "number",
622
+ dataKey: INDEX_X_KEY,
623
+ domain: [0, Math.max(0, chartData.length - 1)],
624
+ allowDecimals: false,
625
+ ticks: chartData.map((_, i) => i),
626
+ tickLine: false,
627
+ axisLine: false,
628
+ tickMargin: 8,
629
+ tickFormatter: (i) => {
630
+ const row = chartData[Number(i)];
631
+ return row ? xFmt(row[xKey], Number(i)) : "";
632
+ }
580
633
  }
581
- ),
582
- showLegend ? /* @__PURE__ */ jsx3(ChartLegend, { series }) : null
634
+ ) : showXAxis ? /* @__PURE__ */ jsx5(
635
+ XAxis,
636
+ {
637
+ dataKey: xKey,
638
+ tickLine: false,
639
+ axisLine: false,
640
+ tickMargin: 8,
641
+ minTickGap: flush ? 8 : 24,
642
+ tickFormatter: (v, i) => xFmt(v, i),
643
+ ...flushCategoryXAxisProps
644
+ }
645
+ ) : /* @__PURE__ */ jsx5(XAxis, { dataKey: chartXKey, hide: true }),
646
+ showYAxis ? /* @__PURE__ */ jsx5(
647
+ YAxis,
648
+ {
649
+ tickLine: false,
650
+ axisLine: false,
651
+ tickMargin: 8,
652
+ width: 44,
653
+ tickFormatter: (v) => valueFmt(v),
654
+ domain: yDomain
655
+ }
656
+ ) : null
583
657
  ] });
584
- };
585
- function renderBars(args) {
586
- const { data, series, xCount, xPos, yScale, baseY, innerW } = args;
587
- const groupWidth = innerW / xCount * 0.66;
588
- const barWidth = groupWidth / series.length;
589
- return series.flatMap(
590
- (s, si) => data.map((d, i) => {
591
- const color = s.color ?? CHART_PALETTE[si % CHART_PALETTE.length];
592
- const y = yScale(toNum(d[s.dataKey]));
593
- const x = xPos(i) - groupWidth / 2 + si * barWidth;
594
- const top = Math.min(y, baseY);
595
- const h = Math.max(1, Math.abs(y - baseY));
596
- return /* @__PURE__ */ jsx3(
597
- "rect",
598
- {
599
- x,
600
- y: top,
601
- width: Math.max(1, barWidth - 2),
602
- height: h,
603
- rx: 3,
604
- fill: color
605
- },
606
- `${s.dataKey}-${i}`
607
- );
608
- })
609
- );
610
- }
611
- var ChartTooltip = ({ x, width, title, rows }) => {
612
- const flip = x > width - 160;
613
- return /* @__PURE__ */ jsxs3(
614
- "div",
658
+ const chartA11y = flush ? {} : { accessibilityLayer: true };
659
+ if (variant === "area") {
660
+ return /* @__PURE__ */ jsx5(
661
+ ChartShell,
662
+ {
663
+ config,
664
+ height,
665
+ className,
666
+ ariaLabel,
667
+ flush,
668
+ children: /* @__PURE__ */ jsxs5(AreaChart, { ...chartA11y, data: chartData, margin, children: [
669
+ /* @__PURE__ */ jsx5("defs", { children: series.map((s) => /* @__PURE__ */ jsxs5("linearGradient", { id: `fill-${s.dataKey}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
670
+ /* @__PURE__ */ jsx5("stop", { offset: "5%", stopColor: `var(--color-${s.dataKey})`, stopOpacity: 0.3 }),
671
+ /* @__PURE__ */ jsx5("stop", { offset: "95%", stopColor: `var(--color-${s.dataKey})`, stopOpacity: 0.04 })
672
+ ] }, s.dataKey)) }),
673
+ gridEl,
674
+ lineAreaAxes,
675
+ tooltipEl,
676
+ legendEl,
677
+ series.map((s) => /* @__PURE__ */ jsx5(
678
+ Area,
679
+ {
680
+ dataKey: s.dataKey,
681
+ type: curve,
682
+ stackId: stacked ? "stack" : void 0,
683
+ stroke: `var(--color-${s.dataKey})`,
684
+ strokeWidth: 2,
685
+ fill: `url(#fill-${s.dataKey})`,
686
+ dot: dots === true ? { r: 3 } : false,
687
+ activeDot: { r: 4 },
688
+ isAnimationActive: true
689
+ },
690
+ s.dataKey
691
+ ))
692
+ ] })
693
+ }
694
+ );
695
+ }
696
+ return /* @__PURE__ */ jsx5(
697
+ ChartShell,
615
698
  {
616
- className: "pointer-events-none absolute top-2 z-10 min-w-[8rem] rounded-lg border border-border bg-popover/95 px-2.5 py-2 text-popover-foreground shadow-card-elevated backdrop-blur-sm",
617
- style: {
618
- left: flip ? void 0 : Math.min(x + 12, width - 8),
619
- right: flip ? Math.max(width - x + 12, 8) : void 0
620
- },
621
- children: [
622
- /* @__PURE__ */ jsx3("div", { className: "mb-1.5 text-[11px] text-muted-foreground", children: title }),
623
- /* @__PURE__ */ jsx3("div", { className: "flex flex-col gap-1", children: rows.map((r) => /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between gap-4", children: [
624
- /* @__PURE__ */ jsxs3("span", { className: "inline-flex items-center gap-1.5 text-xs text-muted-foreground", children: [
625
- /* @__PURE__ */ jsx3(
626
- "span",
627
- {
628
- className: "inline-block size-2 rounded-full",
629
- style: { background: r.color }
630
- }
631
- ),
632
- r.label
633
- ] }),
634
- /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium tabular-nums text-foreground", children: r.value })
635
- ] }, r.label)) })
636
- ]
699
+ config,
700
+ height,
701
+ className,
702
+ ariaLabel,
703
+ flush,
704
+ children: /* @__PURE__ */ jsxs5(LineChart, { ...chartA11y, data: chartData, margin, children: [
705
+ gridEl,
706
+ lineAreaAxes,
707
+ tooltipEl,
708
+ legendEl,
709
+ series.map((s) => /* @__PURE__ */ jsx5(
710
+ Line,
711
+ {
712
+ dataKey: s.dataKey,
713
+ type: curve,
714
+ stroke: `var(--color-${s.dataKey})`,
715
+ strokeWidth: 2,
716
+ dot: dots === true ? { r: 3 } : false,
717
+ activeDot: { r: 4 },
718
+ isAnimationActive: true
719
+ },
720
+ s.dataKey
721
+ ))
722
+ ] })
637
723
  }
638
724
  );
639
725
  };
640
- var ChartLegend = ({ series }) => /* @__PURE__ */ jsx3("div", { className: "mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 pl-10 text-xs text-muted-foreground", children: series.map((s, i) => /* @__PURE__ */ jsxs3("span", { className: "inline-flex items-center gap-1.5", children: [
641
- /* @__PURE__ */ jsx3(
642
- "span",
643
- {
644
- className: "inline-block size-2 rounded-sm",
645
- style: { background: s.color ?? CHART_PALETTE[i % CHART_PALETTE.length] }
646
- }
647
- ),
648
- s.label ?? s.dataKey
649
- ] }, s.dataKey)) });
650
- var ChartEmpty = ({ className, height }) => /* @__PURE__ */ jsx3(
726
+ var ChartShell = ({ config, height, className, ariaLabel, flush = false, children }) => /* @__PURE__ */ jsx5(
727
+ ChartContainer,
728
+ {
729
+ config,
730
+ role: "img",
731
+ "aria-label": ariaLabel,
732
+ className: cn(
733
+ "aspect-auto w-full",
734
+ flush && "justify-start [&_.recharts-responsive-container]:!mx-0 [&_.recharts-responsive-container]:w-full",
735
+ className
736
+ ),
737
+ style: { height },
738
+ children
739
+ }
740
+ );
741
+ var ChartEmpty = ({
742
+ className,
743
+ height,
744
+ ariaLabel
745
+ }) => /* @__PURE__ */ jsx5(
651
746
  "div",
652
747
  {
653
748
  className: cn(
@@ -655,9 +750,15 @@ var ChartEmpty = ({ className, height }) => /* @__PURE__ */ jsx3(
655
750
  className
656
751
  ),
657
752
  style: { height },
753
+ role: "img",
754
+ "aria-label": ariaLabel,
658
755
  children: "No data yet"
659
756
  }
660
757
  );
758
+ function barCornerRadius(r, horizontal, stacked) {
759
+ if (stacked) return r;
760
+ return horizontal ? [0, r, r, 0] : [r, r, 0, 0];
761
+ }
661
762
  function inferXKey(data) {
662
763
  if (data.length === 0) return "x";
663
764
  for (const k of Object.keys(data[0])) {
@@ -672,21 +773,372 @@ function resolveSeries(seriesProp, data, xKey) {
672
773
  if (data.length === 0) return [];
673
774
  return Object.keys(data[0]).filter((k) => k !== xKey && typeof data[0][k] === "number").map((dataKey) => ({ dataKey }));
674
775
  }
675
- function pickXLabels(count, innerW) {
676
- if (count <= 1) return [0];
677
- const maxLabels = Math.max(2, Math.min(count, Math.floor(innerW / 64) + 1));
678
- if (maxLabels >= count) return Array.from({ length: count }, (_, i) => i);
679
- const out = /* @__PURE__ */ new Set([0, count - 1]);
680
- const step = (count - 1) / (maxLabels - 1);
681
- for (let i = 1; i < maxLabels - 1; i++) out.add(Math.round(i * step));
682
- return [...out].sort((a, b) => a - b);
776
+
777
+ // src/charts/pie-chart.tsx
778
+ import { useId as useId2 } from "react";
779
+ import { Cell, Label, Pie, PieChart as RePieChart } from "recharts";
780
+
781
+ // src/charts/chart-center-label.tsx
782
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
783
+ var CENTER_BOX_W = 96;
784
+ var CENTER_BOX_H = 52;
785
+ var ChartCenterLabel = ({ cx, cy, value, label }) => {
786
+ const hasValue = value != null && value !== "";
787
+ const hasLabel = label != null && label !== "";
788
+ if (!hasValue && !hasLabel) return null;
789
+ return /* @__PURE__ */ jsx6(
790
+ "foreignObject",
791
+ {
792
+ x: cx - CENTER_BOX_W / 2,
793
+ y: cy - CENTER_BOX_H / 2,
794
+ width: CENTER_BOX_W,
795
+ height: CENTER_BOX_H,
796
+ className: "overflow-visible",
797
+ children: /* @__PURE__ */ jsxs6("div", { className: "pointer-events-none flex h-full flex-col items-center justify-center gap-0.5 text-center", children: [
798
+ hasValue ? /* @__PURE__ */ jsx6("div", { className: "text-2xl font-normal leading-none tabular-nums text-foreground", children: value }) : null,
799
+ hasLabel ? /* @__PURE__ */ jsx6("div", { className: "text-[11px] leading-none text-muted-foreground", children: label }) : null
800
+ ] })
801
+ }
802
+ );
803
+ };
804
+
805
+ // src/charts/pie-chart.tsx
806
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
807
+ var PieChart = ({
808
+ data,
809
+ nameKey: nameKeyProp,
810
+ dataKey = "value",
811
+ innerRadius = 0,
812
+ colors,
813
+ height = 260,
814
+ showLegend = true,
815
+ showLabels = false,
816
+ showTooltip = true,
817
+ tooltipIndicator = "dot",
818
+ centerValue,
819
+ centerLabel,
820
+ className,
821
+ ariaLabel = "Pie chart"
822
+ }) => {
823
+ const gradientScopeId = useId2().replace(/:/g, "");
824
+ const nameKey = nameKeyProp ?? inferNameKey(data, dataKey);
825
+ const palette = colors ?? CHART_PALETTE;
826
+ if (data.length === 0) {
827
+ return /* @__PURE__ */ jsx7(PieEmpty, { className, height, ariaLabel });
828
+ }
829
+ const slices = data.map((d, i) => ({
830
+ name: String(d[nameKey] ?? i),
831
+ value: toNum(d[dataKey]),
832
+ fill: palette[i % palette.length]
833
+ }));
834
+ const config = {};
835
+ for (const s of slices) config[s.name] = { label: s.name };
836
+ const innerPct = innerRadius > 0 ? `${Math.round(innerRadius * 75)}%` : 0;
837
+ const hasCenter = innerRadius > 0 && (centerValue != null || centerLabel != null);
838
+ return /* @__PURE__ */ jsx7(
839
+ ChartContainer,
840
+ {
841
+ config,
842
+ role: "img",
843
+ "aria-label": ariaLabel,
844
+ className: cn("aspect-auto w-full", className),
845
+ style: { height },
846
+ children: /* @__PURE__ */ jsxs7(RePieChart, { children: [
847
+ /* @__PURE__ */ jsx7(
848
+ PieGradientDefs,
849
+ {
850
+ scopeId: gradientScopeId,
851
+ slices: slices.map((s) => ({ key: s.name, color: s.fill }))
852
+ }
853
+ ),
854
+ showTooltip && /* @__PURE__ */ jsx7(
855
+ ChartTooltip,
856
+ {
857
+ content: /* @__PURE__ */ jsx7(ChartTooltipContent, { nameKey: "name", indicator: tooltipIndicator, hideLabel: true })
858
+ }
859
+ ),
860
+ /* @__PURE__ */ jsxs7(
861
+ Pie,
862
+ {
863
+ data: slices,
864
+ dataKey: "value",
865
+ nameKey: "name",
866
+ innerRadius: innerPct,
867
+ outerRadius: "75%",
868
+ paddingAngle: innerRadius > 0 ? 2 : 0,
869
+ strokeWidth: 2,
870
+ label: showLabels,
871
+ isAnimationActive: true,
872
+ children: [
873
+ slices.map((s) => /* @__PURE__ */ jsx7(Cell, { fill: `url(#${pieGradientId(gradientScopeId, s.name)})` }, s.name)),
874
+ hasCenter && /* @__PURE__ */ jsx7(
875
+ Label,
876
+ {
877
+ position: "center",
878
+ content: ({ viewBox }) => {
879
+ if (!viewBox || !("cx" in viewBox)) return null;
880
+ const { cx, cy } = viewBox;
881
+ return /* @__PURE__ */ jsx7(
882
+ ChartCenterLabel,
883
+ {
884
+ cx,
885
+ cy,
886
+ value: centerValue,
887
+ label: centerLabel
888
+ }
889
+ );
890
+ }
891
+ }
892
+ )
893
+ ]
894
+ }
895
+ ),
896
+ showLegend && /* @__PURE__ */ jsx7(ChartLegend, { content: /* @__PURE__ */ jsx7(ChartLegendContent, { nameKey: "name" }) })
897
+ ] })
898
+ }
899
+ );
900
+ };
901
+ var PieEmpty = ({
902
+ className,
903
+ height,
904
+ ariaLabel
905
+ }) => /* @__PURE__ */ jsx7(
906
+ "div",
907
+ {
908
+ className: cn("flex w-full items-center justify-center text-xs text-muted-foreground", className),
909
+ style: { height },
910
+ role: "img",
911
+ "aria-label": ariaLabel,
912
+ children: "No data yet"
913
+ }
914
+ );
915
+ function inferNameKey(data, dataKey) {
916
+ if (data.length === 0) return "name";
917
+ for (const k of Object.keys(data[0])) {
918
+ if (k !== dataKey && typeof data[0][k] !== "number") return k;
919
+ }
920
+ return Object.keys(data[0]).find((k) => k !== dataKey) ?? "name";
921
+ }
922
+
923
+ // src/charts/radial-chart.tsx
924
+ import { useId as useId3 } from "react";
925
+ import {
926
+ Cell as Cell2,
927
+ Label as Label2,
928
+ PolarAngleAxis,
929
+ PolarRadiusAxis,
930
+ RadialBar,
931
+ RadialBarChart
932
+ } from "recharts";
933
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
934
+ var RadialChart = ({
935
+ data,
936
+ nameKey: nameKeyProp,
937
+ dataKey = "value",
938
+ maxValue,
939
+ colors,
940
+ height = 260,
941
+ ringWidth = 16,
942
+ ringGap = 4,
943
+ showLegend = true,
944
+ centerValue,
945
+ centerLabel,
946
+ className,
947
+ ariaLabel = "Radial chart"
948
+ }) => {
949
+ const gradientScopeId = useId3().replace(/:/g, "");
950
+ const nameKey = nameKeyProp ?? inferNameKey2(data, dataKey);
951
+ const palette = colors ?? CHART_PALETTE;
952
+ if (data.length === 0) {
953
+ return /* @__PURE__ */ jsx8(RadialEmpty, { className, height, ariaLabel });
954
+ }
955
+ const rows = data.map((d, i) => ({
956
+ name: String(d[nameKey] ?? i),
957
+ value: toNum(d[dataKey]),
958
+ fill: palette[i % palette.length]
959
+ }));
960
+ const max = maxValue ?? Math.max(...rows.map((r) => r.value), 1);
961
+ const config = {};
962
+ for (const r of rows) config[r.name] = { label: r.name };
963
+ const hasCenter = centerValue != null || centerLabel != null;
964
+ return /* @__PURE__ */ jsxs8("div", { className: cn("flex w-full flex-col items-center gap-3", className), children: [
965
+ /* @__PURE__ */ jsx8(
966
+ ChartContainer,
967
+ {
968
+ config,
969
+ role: "img",
970
+ "aria-label": ariaLabel,
971
+ className: "aspect-auto w-full",
972
+ style: { height: height - (showLegend ? 32 : 0) },
973
+ children: /* @__PURE__ */ jsxs8(
974
+ RadialBarChart,
975
+ {
976
+ data: rows,
977
+ startAngle: 90,
978
+ endAngle: -270,
979
+ innerRadius: "30%",
980
+ outerRadius: "100%",
981
+ barSize: ringWidth,
982
+ barGap: ringGap,
983
+ children: [
984
+ /* @__PURE__ */ jsx8(
985
+ PieGradientDefs,
986
+ {
987
+ scopeId: gradientScopeId,
988
+ slices: rows.map((r) => ({ key: r.name, color: r.fill }))
989
+ }
990
+ ),
991
+ /* @__PURE__ */ jsx8(PolarAngleAxis, { type: "number", domain: [0, max], tick: false, axisLine: false }),
992
+ /* @__PURE__ */ jsx8(ChartTooltip, { content: /* @__PURE__ */ jsx8(ChartTooltipContent, { nameKey: "name", hideLabel: true }) }),
993
+ /* @__PURE__ */ jsx8(RadialBar, { dataKey: "value", background: true, cornerRadius: ringWidth / 2, isAnimationActive: true, children: rows.map((r) => /* @__PURE__ */ jsx8(Cell2, { fill: `url(#${pieGradientId(gradientScopeId, r.name)})` }, r.name)) }),
994
+ hasCenter && /* @__PURE__ */ jsx8(PolarRadiusAxis, { tick: false, tickLine: false, axisLine: false, children: /* @__PURE__ */ jsx8(
995
+ Label2,
996
+ {
997
+ position: "center",
998
+ content: ({ viewBox }) => {
999
+ if (!viewBox || !("cx" in viewBox)) return null;
1000
+ const { cx, cy } = viewBox;
1001
+ return /* @__PURE__ */ jsx8(
1002
+ ChartCenterLabel,
1003
+ {
1004
+ cx,
1005
+ cy,
1006
+ value: centerValue,
1007
+ label: centerLabel
1008
+ }
1009
+ );
1010
+ }
1011
+ }
1012
+ ) })
1013
+ ]
1014
+ }
1015
+ )
1016
+ }
1017
+ ),
1018
+ showLegend && /* @__PURE__ */ jsx8("div", { className: "flex flex-wrap items-center justify-center gap-x-4 gap-y-1 text-xs text-muted-foreground", children: rows.map((r) => /* @__PURE__ */ jsxs8("span", { className: "inline-flex items-center gap-1.5", children: [
1019
+ /* @__PURE__ */ jsx8("span", { className: "inline-block size-2.5 rounded-[3px]", style: { background: r.fill } }),
1020
+ r.name
1021
+ ] }, r.name)) })
1022
+ ] });
1023
+ };
1024
+ var RadialEmpty = ({
1025
+ className,
1026
+ height,
1027
+ ariaLabel
1028
+ }) => /* @__PURE__ */ jsx8(
1029
+ "div",
1030
+ {
1031
+ className: cn("flex w-full items-center justify-center text-xs text-muted-foreground", className),
1032
+ style: { height },
1033
+ role: "img",
1034
+ "aria-label": ariaLabel,
1035
+ children: "No data yet"
1036
+ }
1037
+ );
1038
+ function inferNameKey2(data, dataKey) {
1039
+ if (data.length === 0) return "name";
1040
+ for (const k of Object.keys(data[0])) {
1041
+ if (k !== dataKey && typeof data[0][k] !== "number") return k;
1042
+ }
1043
+ return Object.keys(data[0]).find((k) => k !== dataKey) ?? "name";
1044
+ }
1045
+
1046
+ // src/charts/radar-chart.tsx
1047
+ import {
1048
+ PolarAngleAxis as PolarAngleAxis2,
1049
+ PolarGrid,
1050
+ Radar,
1051
+ RadarChart as ReRadarChart
1052
+ } from "recharts";
1053
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1054
+ var RadarChart = ({
1055
+ data,
1056
+ nameKey: nameKeyProp,
1057
+ series: seriesProp,
1058
+ maxValue,
1059
+ height = 280,
1060
+ showLegend = true,
1061
+ fill = true,
1062
+ className,
1063
+ ariaLabel = "Radar chart"
1064
+ }) => {
1065
+ const nameKey = nameKeyProp ?? inferNameKey3(data);
1066
+ const series = resolveSeries2(seriesProp, data, nameKey);
1067
+ if (data.length < 3 || series.length === 0) {
1068
+ return /* @__PURE__ */ jsx9(
1069
+ "div",
1070
+ {
1071
+ className: cn("flex items-center justify-center text-xs text-muted-foreground", className),
1072
+ style: { height },
1073
+ role: "img",
1074
+ "aria-label": ariaLabel,
1075
+ children: "Radar needs at least 3 axes"
1076
+ }
1077
+ );
1078
+ }
1079
+ const config = {};
1080
+ series.forEach((s, i) => {
1081
+ config[s.dataKey] = {
1082
+ label: s.label ?? s.dataKey,
1083
+ color: s.color ?? CHART_PALETTE[i % CHART_PALETTE.length]
1084
+ };
1085
+ });
1086
+ return /* @__PURE__ */ jsx9(
1087
+ ChartContainer,
1088
+ {
1089
+ config,
1090
+ role: "img",
1091
+ "aria-label": ariaLabel,
1092
+ className: cn("mx-auto aspect-square", className),
1093
+ style: { height },
1094
+ children: /* @__PURE__ */ jsxs9(ReRadarChart, { data, outerRadius: "70%", children: [
1095
+ /* @__PURE__ */ jsx9(ChartTooltip, { content: /* @__PURE__ */ jsx9(ChartTooltipContent, { indicator: "line" }) }),
1096
+ /* @__PURE__ */ jsx9(PolarGrid, {}),
1097
+ /* @__PURE__ */ jsx9(
1098
+ PolarAngleAxis2,
1099
+ {
1100
+ dataKey: nameKey,
1101
+ tick: { fontSize: 10, fill: "var(--color-muted-foreground)" }
1102
+ }
1103
+ ),
1104
+ series.map((s) => /* @__PURE__ */ jsx9(
1105
+ Radar,
1106
+ {
1107
+ dataKey: s.dataKey,
1108
+ stroke: `var(--color-${s.dataKey})`,
1109
+ fill: `var(--color-${s.dataKey})`,
1110
+ fillOpacity: fill ? 0.18 : 0,
1111
+ strokeWidth: 2,
1112
+ dot: { r: 2.5, fillOpacity: 1 },
1113
+ isAnimationActive: true
1114
+ },
1115
+ s.dataKey
1116
+ )),
1117
+ showLegend && series.length > 1 && /* @__PURE__ */ jsx9(ChartLegend, { content: /* @__PURE__ */ jsx9(ChartLegendContent, {}) })
1118
+ ] })
1119
+ }
1120
+ );
1121
+ };
1122
+ function inferNameKey3(data) {
1123
+ if (data.length === 0) return "name";
1124
+ for (const k of Object.keys(data[0])) {
1125
+ if (typeof data[0][k] !== "number") return k;
1126
+ }
1127
+ return Object.keys(data[0])[0] ?? "name";
1128
+ }
1129
+ function resolveSeries2(seriesProp, data, nameKey) {
1130
+ if (seriesProp && seriesProp.length > 0) {
1131
+ return seriesProp.map((s) => typeof s === "string" ? { dataKey: s } : s);
1132
+ }
1133
+ if (data.length === 0) return [];
1134
+ return Object.keys(data[0]).filter((k) => k !== nameKey && typeof data[0][k] === "number").map((dataKey) => ({ dataKey }));
683
1135
  }
684
1136
 
685
1137
  // src/artifacts/artifact-card.tsx
686
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1138
+ import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
687
1139
  var ArtifactCard = ({ title, kind, className, bodyClassName, toolbar, children }) => {
688
1140
  const hasHeader = Boolean(title || toolbar);
689
- return /* @__PURE__ */ jsxs4(
1141
+ return /* @__PURE__ */ jsxs10(
690
1142
  "div",
691
1143
  {
692
1144
  className: cn(
@@ -695,30 +1147,30 @@ var ArtifactCard = ({ title, kind, className, bodyClassName, toolbar, children }
695
1147
  ),
696
1148
  "data-artifact-kind": kind,
697
1149
  children: [
698
- hasHeader && /* @__PURE__ */ jsxs4("div", { className: "aui-artifact-header flex items-center gap-2 border-b border-border/40 bg-muted/30 px-3 py-1.5", children: [
699
- title && /* @__PURE__ */ jsx4("span", { className: "aui-artifact-title flex-1 truncate text-xs font-semibold text-foreground/80", children: title }),
700
- !title && /* @__PURE__ */ jsx4("span", { className: "flex-1" }),
1150
+ hasHeader && /* @__PURE__ */ jsxs10("div", { className: "aui-artifact-header flex items-center gap-2 border-b border-border/40 bg-muted/30 px-3 py-1.5", children: [
1151
+ title && /* @__PURE__ */ jsx10("span", { className: "aui-artifact-title flex-1 truncate text-xs font-semibold text-foreground/80", children: title }),
1152
+ !title && /* @__PURE__ */ jsx10("span", { className: "flex-1" }),
701
1153
  toolbar
702
1154
  ] }),
703
- /* @__PURE__ */ jsx4("div", { className: cn("aui-artifact-body", bodyClassName), children })
1155
+ /* @__PURE__ */ jsx10("div", { className: cn("aui-artifact-body", bodyClassName), children })
704
1156
  ]
705
1157
  }
706
1158
  );
707
1159
  };
708
1160
 
709
1161
  // src/artifacts/chart-artifact.tsx
710
- import { useMemo as useMemo2 } from "react";
711
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1162
+ import { useMemo } from "react";
1163
+ import { jsx as jsx11 } from "react/jsx-runtime";
712
1164
  var ChartArtifactView = ({
713
1165
  artifact,
714
1166
  embedded = false,
715
1167
  height = 300
716
1168
  }) => {
717
- const plot = /* @__PURE__ */ jsx5(ChartArtifactPlot, { artifact, height });
1169
+ const plot = /* @__PURE__ */ jsx11(ChartArtifactPlot, { artifact, height });
718
1170
  if (embedded) {
719
- return /* @__PURE__ */ jsx5("div", { className: "aui-artifact-chart w-full", children: plot });
1171
+ return /* @__PURE__ */ jsx11("div", { className: "aui-artifact-chart w-full", children: plot });
720
1172
  }
721
- return /* @__PURE__ */ jsx5(ArtifactCard, { title: artifact.title, kind: "chart", children: /* @__PURE__ */ jsx5("div", { className: "aui-artifact-chart pt-2", children: plot }) });
1173
+ return /* @__PURE__ */ jsx11(ArtifactCard, { title: artifact.title, kind: "chart", children: /* @__PURE__ */ jsx11("div", { className: "aui-artifact-chart pt-2", children: plot }) });
722
1174
  };
723
1175
  function ChartArtifactPlot({
724
1176
  artifact,
@@ -726,14 +1178,59 @@ function ChartArtifactPlot({
726
1178
  }) {
727
1179
  const { chartType = "bar", data = [] } = artifact;
728
1180
  const xKey = artifact.xKey ?? inferXKey2(data);
729
- const series = useMemo2(() => {
1181
+ const series = useMemo(() => {
1182
+ if (artifact.series && artifact.series.length > 0) {
1183
+ return artifact.series.map((s) => ({
1184
+ dataKey: s.dataKey,
1185
+ label: s.label,
1186
+ color: s.color
1187
+ }));
1188
+ }
730
1189
  const keys = Array.isArray(artifact.dataKey) ? artifact.dataKey : typeof artifact.dataKey === "string" ? [artifact.dataKey] : inferDataKeys(data, xKey);
731
- return keys.map((dataKey) => ({ dataKey }));
732
- }, [artifact.dataKey, data, xKey]);
733
- if (chartType === "pie") {
734
- return /* @__PURE__ */ jsx5("div", { className: "px-3 pb-3 pt-2", children: /* @__PURE__ */ jsx5(PieChart, { data, xKey, dataKey: series[0]?.dataKey ?? "value" }) });
1190
+ const colors = artifact.colors;
1191
+ return keys.map((dataKey, i) => ({
1192
+ dataKey,
1193
+ color: colors?.[i]
1194
+ }));
1195
+ }, [artifact.series, artifact.dataKey, artifact.colors, data, xKey]);
1196
+ const aria = typeof artifact.title === "string" ? artifact.title : "Chart";
1197
+ if (chartType === "pie" || chartType === "donut") {
1198
+ const total = data.reduce((sum, d) => sum + toNum(d[series[0]?.dataKey ?? "value"]), 0);
1199
+ return /* @__PURE__ */ jsx11("div", { className: "px-3 pb-3 pt-2", children: /* @__PURE__ */ jsx11(
1200
+ PieChart,
1201
+ {
1202
+ data,
1203
+ nameKey: xKey,
1204
+ dataKey: series[0]?.dataKey ?? "value",
1205
+ innerRadius: chartType === "donut" ? 0.6 : 0,
1206
+ colors: artifact.colors,
1207
+ height,
1208
+ unit: artifact.unit,
1209
+ centerValue: chartType === "donut" ? formatCompact(total, artifact.unit) : void 0,
1210
+ centerLabel: chartType === "donut" ? "Total" : void 0,
1211
+ ariaLabel: aria
1212
+ }
1213
+ ) });
735
1214
  }
736
- return /* @__PURE__ */ jsx5(
1215
+ if (chartType === "radial") {
1216
+ return /* @__PURE__ */ jsx11("div", { className: "px-3 pb-3 pt-2", children: /* @__PURE__ */ jsx11(
1217
+ RadialChart,
1218
+ {
1219
+ data,
1220
+ nameKey: xKey,
1221
+ dataKey: series[0]?.dataKey ?? "value",
1222
+ colors: artifact.colors,
1223
+ height,
1224
+ ariaLabel: aria
1225
+ }
1226
+ ) });
1227
+ }
1228
+ if (chartType === "radar") {
1229
+ return /* @__PURE__ */ jsx11("div", { className: "px-3 pb-3 pt-2", children: /* @__PURE__ */ jsx11(RadarChart, { data, nameKey: xKey, series, height, ariaLabel: aria }) });
1230
+ }
1231
+ const horizontal = chartType === "horizontalBar";
1232
+ const showAxes = artifact.showAxes === true;
1233
+ return /* @__PURE__ */ jsx11(
737
1234
  LineAreaChart,
738
1235
  {
739
1236
  data,
@@ -742,71 +1239,19 @@ function ChartArtifactPlot({
742
1239
  layout: "flush",
743
1240
  height,
744
1241
  variant: chartType === "line" ? "line" : chartType === "area" ? "area" : "bar",
1242
+ orientation: horizontal ? "horizontal" : "vertical",
1243
+ stacked: artifact.stacked,
1244
+ curve: artifact.curve,
1245
+ dots: artifact.dots,
1246
+ tooltipIndicator: artifact.tooltipIndicator,
1247
+ showXAxis: showAxes,
1248
+ showYAxis: showAxes && horizontal,
1249
+ showLegend: artifact.legend ?? series.length > 1,
745
1250
  unit: artifact.unit,
746
- ariaLabel: typeof artifact.title === "string" ? artifact.title : "Chart"
1251
+ ariaLabel: aria
747
1252
  }
748
1253
  );
749
1254
  }
750
- var PIE_W = 320;
751
- var PIE_H = 220;
752
- var PieChart = ({ data, xKey, dataKey }) => {
753
- if (data.length === 0) {
754
- return /* @__PURE__ */ jsx5("div", { className: "flex h-32 items-center justify-center text-xs text-muted-foreground", children: "No data" });
755
- }
756
- const cx = PIE_W / 2;
757
- const cy = PIE_H / 2;
758
- const r = Math.min(PIE_W, PIE_H) / 2 - 16;
759
- const total = data.reduce((sum, d) => sum + toNum(d[dataKey]), 0) || 1;
760
- let acc = 0;
761
- return /* @__PURE__ */ jsxs5("div", { className: "flex flex-col items-center gap-3", children: [
762
- /* @__PURE__ */ jsx5(
763
- "svg",
764
- {
765
- viewBox: `0 0 ${PIE_W} ${PIE_H}`,
766
- className: "w-full max-w-[20rem]",
767
- role: "img",
768
- "aria-label": "Pie chart",
769
- children: data.map((d, i) => {
770
- const value = toNum(d[dataKey]);
771
- const start = acc / total * Math.PI * 2;
772
- acc += value;
773
- const end = acc / total * Math.PI * 2;
774
- return /* @__PURE__ */ jsx5(
775
- PieSlice,
776
- {
777
- cx,
778
- cy,
779
- r,
780
- start,
781
- end,
782
- color: CHART_PALETTE[i % CHART_PALETTE.length]
783
- },
784
- i
785
- );
786
- })
787
- }
788
- ),
789
- /* @__PURE__ */ jsx5("div", { className: "flex flex-wrap items-center justify-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: data.map((d, i) => /* @__PURE__ */ jsxs5("span", { className: "inline-flex items-center gap-1.5", children: [
790
- /* @__PURE__ */ jsx5(
791
- "span",
792
- {
793
- className: "inline-block size-2 rounded-sm",
794
- style: { background: CHART_PALETTE[i % CHART_PALETTE.length] }
795
- }
796
- ),
797
- String(d[xKey] ?? i)
798
- ] }, i)) })
799
- ] });
800
- };
801
- var PieSlice = ({ cx, cy, r, start, end, color }) => {
802
- const x1 = cx + Math.sin(start) * r;
803
- const y1 = cy - Math.cos(start) * r;
804
- const x2 = cx + Math.sin(end) * r;
805
- const y2 = cy - Math.cos(end) * r;
806
- const large = end - start > Math.PI ? 1 : 0;
807
- const path = `M ${cx} ${cy} L ${x1} ${y1} A ${r} ${r} 0 ${large} 1 ${x2} ${y2} Z`;
808
- return /* @__PURE__ */ jsx5("path", { d: path, fill: color, stroke: "var(--background, #fff)", strokeWidth: 1.5 });
809
- };
810
1255
  function inferXKey2(data) {
811
1256
  if (data.length === 0) return "x";
812
1257
  for (const k of Object.keys(data[0])) {
@@ -822,7 +1267,7 @@ function inferDataKeys(data, xKey) {
822
1267
  }
823
1268
 
824
1269
  // src/artifacts/question-artifact.tsx
825
- import { useCallback, useState as useState4 } from "react";
1270
+ import { useCallback, useState as useState2 } from "react";
826
1271
  import { useThreadRuntime } from "@assistant-ui/react";
827
1272
  import { CheckIcon } from "lucide-react";
828
1273
 
@@ -938,12 +1383,12 @@ var studioQuestionOptionSelectedClass = cn(
938
1383
  );
939
1384
 
940
1385
  // src/artifacts/question-artifact.tsx
941
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1386
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
942
1387
  function optionKey(option, index) {
943
1388
  const id = option.id?.trim();
944
1389
  return id ? id : `__option-${index}`;
945
1390
  }
946
- var OptionRadio = ({ selected }) => /* @__PURE__ */ jsx6(
1391
+ var OptionRadio = ({ selected }) => /* @__PURE__ */ jsx12(
947
1392
  "span",
948
1393
  {
949
1394
  className: cn(
@@ -951,15 +1396,15 @@ var OptionRadio = ({ selected }) => /* @__PURE__ */ jsx6(
951
1396
  selected ? "border-foreground bg-foreground text-background" : "border-border bg-background"
952
1397
  ),
953
1398
  "aria-hidden": true,
954
- children: selected ? /* @__PURE__ */ jsx6(CheckIcon, { className: "size-2.5 stroke-[3]" }) : null
1399
+ children: selected ? /* @__PURE__ */ jsx12(CheckIcon, { className: "size-2.5 stroke-[3]" }) : null
955
1400
  }
956
1401
  );
957
1402
  var QuestionArtifactView = ({
958
1403
  artifact
959
1404
  }) => {
960
1405
  const runtime = useThreadRuntime();
961
- const [selected, setSelected] = useState4([]);
962
- const [submittedIds, setSubmittedIds] = useState4(null);
1406
+ const [selected, setSelected] = useState2([]);
1407
+ const [submittedIds, setSubmittedIds] = useState2(null);
963
1408
  const isMulti = artifact.multi === true;
964
1409
  const isDisabled = submittedIds !== null;
965
1410
  const send = useCallback(
@@ -990,12 +1435,12 @@ var QuestionArtifactView = ({
990
1435
  const onConfirm = useCallback(() => {
991
1436
  send(selected);
992
1437
  }, [selected, send]);
993
- return /* @__PURE__ */ jsx6("div", { className: studioArtifactShellClass, "data-artifact-kind": "question", children: /* @__PURE__ */ jsxs6("div", { className: "px-2.5 py-2", children: [
994
- artifact.prompt ? /* @__PURE__ */ jsx6("p", { className: "mb-2 text-sm font-normal leading-snug text-foreground", children: artifact.prompt }) : null,
995
- /* @__PURE__ */ jsx6("div", { className: "flex flex-col gap-0.5", role: "list", children: artifact.options.map((option, index) => {
1438
+ return /* @__PURE__ */ jsx12("div", { className: studioArtifactShellClass, "data-artifact-kind": "question", children: /* @__PURE__ */ jsxs11("div", { className: "px-2.5 py-2", children: [
1439
+ artifact.prompt ? /* @__PURE__ */ jsx12("p", { className: "mb-2 text-sm font-normal leading-snug text-foreground", children: artifact.prompt }) : null,
1440
+ /* @__PURE__ */ jsx12("div", { className: "flex flex-col gap-0.5", role: "list", children: artifact.options.map((option, index) => {
996
1441
  const key = optionKey(option, index);
997
1442
  const isSelected = submittedIds ? submittedIds.includes(key) : isMulti && selected.includes(key);
998
- return /* @__PURE__ */ jsxs6(
1443
+ return /* @__PURE__ */ jsxs11(
999
1444
  "button",
1000
1445
  {
1001
1446
  type: "button",
@@ -1007,17 +1452,17 @@ var QuestionArtifactView = ({
1007
1452
  isDisabled && (isSelected ? "cursor-default" : "cursor-not-allowed opacity-50")
1008
1453
  ),
1009
1454
  children: [
1010
- /* @__PURE__ */ jsx6(OptionRadio, { selected: isSelected }),
1011
- /* @__PURE__ */ jsxs6("span", { className: "min-w-0 flex-1 text-left", children: [
1012
- /* @__PURE__ */ jsx6("span", { className: "block font-normal text-foreground", children: option.label }),
1013
- option.description ? /* @__PURE__ */ jsx6("span", { className: "mt-0.5 block text-xs text-muted-foreground", children: option.description }) : null
1455
+ /* @__PURE__ */ jsx12(OptionRadio, { selected: isSelected }),
1456
+ /* @__PURE__ */ jsxs11("span", { className: "min-w-0 flex-1 text-left", children: [
1457
+ /* @__PURE__ */ jsx12("span", { className: "block font-normal text-foreground", children: option.label }),
1458
+ option.description ? /* @__PURE__ */ jsx12("span", { className: "mt-0.5 block text-xs text-muted-foreground", children: option.description }) : null
1014
1459
  ] })
1015
1460
  ]
1016
1461
  },
1017
1462
  key
1018
1463
  );
1019
1464
  }) }),
1020
- isMulti && !submittedIds ? /* @__PURE__ */ jsx6("div", { className: "mt-2 flex justify-end", children: /* @__PURE__ */ jsx6(
1465
+ isMulti && !submittedIds ? /* @__PURE__ */ jsx12("div", { className: "mt-2 flex justify-end", children: /* @__PURE__ */ jsx12(
1021
1466
  TimbalV2Button,
1022
1467
  {
1023
1468
  type: "button",
@@ -1032,12 +1477,12 @@ var QuestionArtifactView = ({
1032
1477
  };
1033
1478
 
1034
1479
  // src/artifacts/html-artifact.tsx
1035
- import { jsx as jsx7 } from "react/jsx-runtime";
1480
+ import { jsx as jsx13 } from "react/jsx-runtime";
1036
1481
  var HtmlArtifactView = ({ artifact }) => {
1037
1482
  const sandboxed = artifact.sandboxed !== false;
1038
1483
  const sandbox = sandboxed ? "allow-scripts allow-same-origin allow-forms allow-modals allow-popups allow-pointer-lock" : void 0;
1039
1484
  const height = artifact.height ?? "320px";
1040
- return /* @__PURE__ */ jsx7(ArtifactCard, { title: artifact.title, kind: "html", children: /* @__PURE__ */ jsx7(
1485
+ return /* @__PURE__ */ jsx13(ArtifactCard, { title: artifact.title, kind: "html", children: /* @__PURE__ */ jsx13(
1041
1486
  "iframe",
1042
1487
  {
1043
1488
  title: artifact.title ?? "HTML artifact",
@@ -1050,7 +1495,7 @@ var HtmlArtifactView = ({ artifact }) => {
1050
1495
  };
1051
1496
 
1052
1497
  // src/artifacts/json-artifact.tsx
1053
- import { jsx as jsx8 } from "react/jsx-runtime";
1498
+ import { jsx as jsx14 } from "react/jsx-runtime";
1054
1499
  var JsonArtifactView = ({
1055
1500
  artifact
1056
1501
  }) => {
@@ -1062,16 +1507,16 @@ var JsonArtifactView = ({
1062
1507
  } catch {
1063
1508
  body = String(data);
1064
1509
  }
1065
- return /* @__PURE__ */ jsx8(ArtifactCard, { title, kind: "json", children: /* @__PURE__ */ jsx8("pre", { className: "aui-artifact-json m-0 max-h-[420px] overflow-auto p-3 font-mono text-[12px] leading-relaxed text-foreground/85", children: body }) });
1510
+ return /* @__PURE__ */ jsx14(ArtifactCard, { title, kind: "json", children: /* @__PURE__ */ jsx14("pre", { className: "aui-artifact-json m-0 max-h-[420px] overflow-auto p-3 font-mono text-[12px] leading-relaxed text-foreground/85", children: body }) });
1066
1511
  };
1067
1512
 
1068
1513
  // src/artifacts/table-artifact.tsx
1069
- import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
1514
+ import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
1070
1515
  var TableArtifactView = ({ artifact }) => {
1071
1516
  const rows = artifact.rows ?? [];
1072
1517
  const columns = artifact.columns ?? deriveColumns(rows);
1073
- return /* @__PURE__ */ jsx9(ArtifactCard, { title: artifact.title, kind: "table", children: /* @__PURE__ */ jsx9("div", { className: "aui-artifact-table-wrap overflow-x-auto", children: /* @__PURE__ */ jsxs7("table", { className: "aui-artifact-table w-full border-collapse text-sm", children: [
1074
- /* @__PURE__ */ jsx9("thead", { children: /* @__PURE__ */ jsx9("tr", { className: "border-b border-border/40 bg-muted/20", children: columns.map((col) => /* @__PURE__ */ jsx9(
1518
+ return /* @__PURE__ */ jsx15(ArtifactCard, { title: artifact.title, kind: "table", children: /* @__PURE__ */ jsx15("div", { className: "aui-artifact-table-wrap overflow-x-auto", children: /* @__PURE__ */ jsxs12("table", { className: "aui-artifact-table w-full border-collapse text-sm", children: [
1519
+ /* @__PURE__ */ jsx15("thead", { children: /* @__PURE__ */ jsx15("tr", { className: "border-b border-border/40 bg-muted/20", children: columns.map((col) => /* @__PURE__ */ jsx15(
1075
1520
  "th",
1076
1521
  {
1077
1522
  className: "px-3 py-2 text-left text-xs font-semibold uppercase tracking-wider text-muted-foreground",
@@ -1079,11 +1524,11 @@ var TableArtifactView = ({ artifact }) => {
1079
1524
  },
1080
1525
  col.key
1081
1526
  )) }) }),
1082
- /* @__PURE__ */ jsx9("tbody", { children: rows.map((row, i) => /* @__PURE__ */ jsx9(
1527
+ /* @__PURE__ */ jsx15("tbody", { children: rows.map((row, i) => /* @__PURE__ */ jsx15(
1083
1528
  "tr",
1084
1529
  {
1085
1530
  className: "border-b border-border/30 transition-colors last:border-b-0 hover:bg-muted/20",
1086
- children: columns.map((col) => /* @__PURE__ */ jsx9(
1531
+ children: columns.map((col) => /* @__PURE__ */ jsx15(
1087
1532
  "td",
1088
1533
  {
1089
1534
  className: "px-3 py-2 align-top text-foreground/85",
@@ -1170,11 +1615,11 @@ import {
1170
1615
  createContext,
1171
1616
  useContext
1172
1617
  } from "react";
1173
- import { jsx as jsx10 } from "react/jsx-runtime";
1618
+ import { jsx as jsx16 } from "react/jsx-runtime";
1174
1619
  var UiStateContext = createContext({});
1175
1620
  var UiDispatchContext = createContext(() => {
1176
1621
  });
1177
- var UiStateProvider = ({ state, dispatch, children }) => /* @__PURE__ */ jsx10(UiStateContext.Provider, { value: state, children: /* @__PURE__ */ jsx10(UiDispatchContext.Provider, { value: dispatch, children }) });
1622
+ var UiStateProvider = ({ state, dispatch, children }) => /* @__PURE__ */ jsx16(UiStateContext.Provider, { value: state, children: /* @__PURE__ */ jsx16(UiDispatchContext.Provider, { value: dispatch, children }) });
1178
1623
  function useUiState() {
1179
1624
  return useContext(UiStateContext);
1180
1625
  }
@@ -1184,12 +1629,12 @@ function useUiDispatch() {
1184
1629
  var UiEventContext = createContext(
1185
1630
  null
1186
1631
  );
1187
- var UiEventProvider = ({ onEvent, children }) => /* @__PURE__ */ jsx10(UiEventContext.Provider, { value: onEvent, children });
1632
+ var UiEventProvider = ({ onEvent, children }) => /* @__PURE__ */ jsx16(UiEventContext.Provider, { value: onEvent, children });
1188
1633
  function useUiEventEmitter() {
1189
1634
  return useContext(UiEventContext);
1190
1635
  }
1191
1636
  var UiCustomNodeRegistryContext = createContext({});
1192
- var UiCustomNodeRegistryProvider = ({ renderers, children }) => /* @__PURE__ */ jsx10(UiCustomNodeRegistryContext.Provider, { value: renderers, children });
1637
+ var UiCustomNodeRegistryProvider = ({ renderers, children }) => /* @__PURE__ */ jsx16(UiCustomNodeRegistryContext.Provider, { value: renderers, children });
1193
1638
  function useUiCustomNodeRegistry() {
1194
1639
  return useContext(UiCustomNodeRegistryContext);
1195
1640
  }
@@ -1198,29 +1643,29 @@ function useUiCustomNodeRegistry() {
1198
1643
  import { useCallback as useCallback2 } from "react";
1199
1644
  import { motion } from "motion/react";
1200
1645
  import { useThreadRuntime as useThreadRuntime2 } from "@assistant-ui/react";
1201
- import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
1646
+ import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
1202
1647
  var UiNodeView = ({ node }) => {
1203
1648
  switch (node.kind) {
1204
1649
  case "box":
1205
- return /* @__PURE__ */ jsx11(BoxNode, { node });
1650
+ return /* @__PURE__ */ jsx17(BoxNode, { node });
1206
1651
  case "text":
1207
- return /* @__PURE__ */ jsx11(TextNode, { node });
1652
+ return /* @__PURE__ */ jsx17(TextNode, { node });
1208
1653
  case "heading":
1209
- return /* @__PURE__ */ jsx11(HeadingNode, { node });
1654
+ return /* @__PURE__ */ jsx17(HeadingNode, { node });
1210
1655
  case "badge":
1211
- return /* @__PURE__ */ jsx11(BadgeNode, { node });
1656
+ return /* @__PURE__ */ jsx17(BadgeNode, { node });
1212
1657
  case "button":
1213
- return /* @__PURE__ */ jsx11(ButtonNode, { node });
1658
+ return /* @__PURE__ */ jsx17(ButtonNode, { node });
1214
1659
  case "toggle":
1215
- return /* @__PURE__ */ jsx11(ToggleNode, { node });
1660
+ return /* @__PURE__ */ jsx17(ToggleNode, { node });
1216
1661
  case "slider":
1217
- return /* @__PURE__ */ jsx11(SliderNode, { node });
1662
+ return /* @__PURE__ */ jsx17(SliderNode, { node });
1218
1663
  case "tooltip":
1219
- return /* @__PURE__ */ jsx11(TooltipNode, { node });
1664
+ return /* @__PURE__ */ jsx17(TooltipNode, { node });
1220
1665
  case "draggable":
1221
- return /* @__PURE__ */ jsx11(DraggableNode, { node });
1666
+ return /* @__PURE__ */ jsx17(DraggableNode, { node });
1222
1667
  case "custom":
1223
- return /* @__PURE__ */ jsx11(CustomNode, { node });
1668
+ return /* @__PURE__ */ jsx17(CustomNode, { node });
1224
1669
  default:
1225
1670
  return null;
1226
1671
  }
@@ -1280,7 +1725,7 @@ var JUSTIFY_CLS = {
1280
1725
  };
1281
1726
  var BoxNode = ({ node }) => {
1282
1727
  const dir = node.direction ?? "col";
1283
- return /* @__PURE__ */ jsx11(
1728
+ return /* @__PURE__ */ jsx17(
1284
1729
  "div",
1285
1730
  {
1286
1731
  className: cn(
@@ -1295,7 +1740,7 @@ var BoxNode = ({ node }) => {
1295
1740
  gap: node.gap !== void 0 ? `${node.gap * 0.25}rem` : void 0,
1296
1741
  padding: node.padding !== void 0 ? `${node.padding * 0.25}rem` : void 0
1297
1742
  },
1298
- children: node.children?.map((child, i) => /* @__PURE__ */ jsx11(UiNodeView, { node: child }, child.id ?? i))
1743
+ children: node.children?.map((child, i) => /* @__PURE__ */ jsx17(UiNodeView, { node: child }, child.id ?? i))
1299
1744
  }
1300
1745
  );
1301
1746
  };
@@ -1314,7 +1759,7 @@ var TEXT_WEIGHT = {
1314
1759
  var TextNode = ({ node }) => {
1315
1760
  const state = useUiState();
1316
1761
  const value = resolveBindable(node.value, state);
1317
- return /* @__PURE__ */ jsx11(
1762
+ return /* @__PURE__ */ jsx17(
1318
1763
  "span",
1319
1764
  {
1320
1765
  className: cn(
@@ -1345,13 +1790,13 @@ var HeadingNode = ({ node }) => {
1345
1790
  );
1346
1791
  switch (level) {
1347
1792
  case 1:
1348
- return /* @__PURE__ */ jsx11("h1", { className: cls, children: value });
1793
+ return /* @__PURE__ */ jsx17("h1", { className: cls, children: value });
1349
1794
  case 2:
1350
- return /* @__PURE__ */ jsx11("h2", { className: cls, children: value });
1795
+ return /* @__PURE__ */ jsx17("h2", { className: cls, children: value });
1351
1796
  case 3:
1352
- return /* @__PURE__ */ jsx11("h3", { className: cls, children: value });
1797
+ return /* @__PURE__ */ jsx17("h3", { className: cls, children: value });
1353
1798
  case 4:
1354
- return /* @__PURE__ */ jsx11("h4", { className: cls, children: value });
1799
+ return /* @__PURE__ */ jsx17("h4", { className: cls, children: value });
1355
1800
  }
1356
1801
  };
1357
1802
  var BADGE_TONE = {
@@ -1364,7 +1809,7 @@ var BADGE_TONE = {
1364
1809
  var BadgeNode = ({ node }) => {
1365
1810
  const state = useUiState();
1366
1811
  const value = String(resolveBindable(node.value, state) ?? "");
1367
- return /* @__PURE__ */ jsx11(
1812
+ return /* @__PURE__ */ jsx17(
1368
1813
  "span",
1369
1814
  {
1370
1815
  className: cn(
@@ -1381,7 +1826,7 @@ var ButtonNode = ({ node }) => {
1381
1826
  const run = useActionRunner();
1382
1827
  const label = String(resolveBindable(node.label, state) ?? "");
1383
1828
  const disabled = node.disabled !== void 0 ? Boolean(resolveBindable(node.disabled, state)) : false;
1384
- return /* @__PURE__ */ jsx11(
1829
+ return /* @__PURE__ */ jsx17(
1385
1830
  Button,
1386
1831
  {
1387
1832
  variant: node.variant ?? "default",
@@ -1403,7 +1848,7 @@ var ToggleNode = ({ node }) => {
1403
1848
  dispatch({ type: "toggle", path: node.binding });
1404
1849
  run(node.onChange);
1405
1850
  };
1406
- return /* @__PURE__ */ jsxs8(
1851
+ return /* @__PURE__ */ jsxs13(
1407
1852
  "label",
1408
1853
  {
1409
1854
  className: cn(
@@ -1411,7 +1856,7 @@ var ToggleNode = ({ node }) => {
1411
1856
  node.className
1412
1857
  ),
1413
1858
  children: [
1414
- /* @__PURE__ */ jsx11(
1859
+ /* @__PURE__ */ jsx17(
1415
1860
  "button",
1416
1861
  {
1417
1862
  type: "button",
@@ -1422,7 +1867,7 @@ var ToggleNode = ({ node }) => {
1422
1867
  "relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-[background,box-shadow,border-color] duration-200",
1423
1868
  value ? "border-foreground/15 bg-gradient-to-b from-primary-fill-from to-primary-fill-to shadow-card" : cn(TIMBAL_V2_SWITCH_TRACK_OFF, "hover:from-secondary-fill-hover-from hover:to-secondary-fill-hover-to")
1424
1869
  ),
1425
- children: /* @__PURE__ */ jsx11(
1870
+ children: /* @__PURE__ */ jsx17(
1426
1871
  "span",
1427
1872
  {
1428
1873
  className: cn(
@@ -1435,7 +1880,7 @@ var ToggleNode = ({ node }) => {
1435
1880
  )
1436
1881
  }
1437
1882
  ),
1438
- label && /* @__PURE__ */ jsx11("span", { className: "text-foreground/85", children: label })
1883
+ label && /* @__PURE__ */ jsx17("span", { className: "text-foreground/85", children: label })
1439
1884
  ]
1440
1885
  }
1441
1886
  );
@@ -1455,12 +1900,12 @@ var SliderNode = ({ node }) => {
1455
1900
  const next = Number(e.target.value);
1456
1901
  dispatch({ type: "set", path: node.binding, value: next });
1457
1902
  };
1458
- return /* @__PURE__ */ jsxs8("div", { className: cn("aui-ui-slider flex flex-col gap-1", node.className), children: [
1459
- (label || showValue) && /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between text-xs text-muted-foreground", children: [
1460
- label && /* @__PURE__ */ jsx11("span", { children: label }),
1461
- showValue && /* @__PURE__ */ jsx11("span", { className: "font-mono", children: value })
1903
+ return /* @__PURE__ */ jsxs13("div", { className: cn("aui-ui-slider flex flex-col gap-1", node.className), children: [
1904
+ (label || showValue) && /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between text-xs text-muted-foreground", children: [
1905
+ label && /* @__PURE__ */ jsx17("span", { children: label }),
1906
+ showValue && /* @__PURE__ */ jsx17("span", { className: "font-mono", children: value })
1462
1907
  ] }),
1463
- /* @__PURE__ */ jsx11(
1908
+ /* @__PURE__ */ jsx17(
1464
1909
  "input",
1465
1910
  {
1466
1911
  type: "range",
@@ -1482,9 +1927,9 @@ var SliderNode = ({ node }) => {
1482
1927
  var TooltipNode = ({ node }) => {
1483
1928
  const state = useUiState();
1484
1929
  const content = String(resolveBindable(node.content, state) ?? "");
1485
- return /* @__PURE__ */ jsx11(TooltipProvider, { children: /* @__PURE__ */ jsxs8(Tooltip, { children: [
1486
- /* @__PURE__ */ jsx11(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx11("span", { className: cn("aui-ui-tooltip-trigger inline-flex", node.className), children: /* @__PURE__ */ jsx11(UiNodeView, { node: node.child }) }) }),
1487
- /* @__PURE__ */ jsx11(TooltipContent, { side: node.side ?? "top", children: content })
1930
+ return /* @__PURE__ */ jsx17(TooltipProvider, { children: /* @__PURE__ */ jsxs13(Tooltip, { children: [
1931
+ /* @__PURE__ */ jsx17(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx17("span", { className: cn("aui-ui-tooltip-trigger inline-flex", node.className), children: /* @__PURE__ */ jsx17(UiNodeView, { node: node.child }) }) }),
1932
+ /* @__PURE__ */ jsx17(TooltipContent, { side: node.side ?? "top", children: content })
1488
1933
  ] }) });
1489
1934
  };
1490
1935
  var DraggableNode = ({ node }) => {
@@ -1492,7 +1937,7 @@ var DraggableNode = ({ node }) => {
1492
1937
  const snapBack = node.snapBack ?? true;
1493
1938
  const axis = node.axis ?? "both";
1494
1939
  const dragProp = axis === "both" ? true : axis;
1495
- return /* @__PURE__ */ jsx11(
1940
+ return /* @__PURE__ */ jsx17(
1496
1941
  motion.div,
1497
1942
  {
1498
1943
  drag: dragProp,
@@ -1504,7 +1949,7 @@ var DraggableNode = ({ node }) => {
1504
1949
  "aui-ui-draggable inline-block cursor-grab touch-none",
1505
1950
  node.className
1506
1951
  ),
1507
- children: /* @__PURE__ */ jsx11(UiNodeView, { node: node.child })
1952
+ children: /* @__PURE__ */ jsx17(UiNodeView, { node: node.child })
1508
1953
  }
1509
1954
  );
1510
1955
  };
@@ -1514,8 +1959,8 @@ var CustomNode = ({ node }) => {
1514
1959
  const Renderer = registry[node.name];
1515
1960
  if (!Renderer) return null;
1516
1961
  const resolvedProps = resolveProps(node.props ?? {}, state);
1517
- const children = node.children?.map((child, i) => /* @__PURE__ */ jsx11(UiNodeView, { node: child }, child.id ?? i));
1518
- return /* @__PURE__ */ jsx11(Renderer, { props: resolvedProps, children });
1962
+ const children = node.children?.map((child, i) => /* @__PURE__ */ jsx17(UiNodeView, { node: child }, child.id ?? i));
1963
+ return /* @__PURE__ */ jsx17(Renderer, { props: resolvedProps, children });
1519
1964
  };
1520
1965
  function resolveProps(props, state) {
1521
1966
  const out = {};
@@ -1527,18 +1972,18 @@ function resolveProps(props, state) {
1527
1972
 
1528
1973
  // src/artifacts/ui/ui-artifact.tsx
1529
1974
  import { useReducer } from "react";
1530
- import { jsx as jsx12 } from "react/jsx-runtime";
1975
+ import { jsx as jsx18 } from "react/jsx-runtime";
1531
1976
  var UiArtifactView = ({ artifact }) => {
1532
1977
  const [state, dispatch] = useReducer(
1533
1978
  uiStateReducer,
1534
1979
  artifact.initialState ?? {}
1535
1980
  );
1536
- return /* @__PURE__ */ jsx12(ArtifactCard, { title: artifact.title, kind: "ui", children: /* @__PURE__ */ jsx12(UiStateProvider, { state, dispatch, children: /* @__PURE__ */ jsx12("div", { className: "aui-ui-root p-3", children: /* @__PURE__ */ jsx12(UiNodeView, { node: artifact.root }) }) }) });
1981
+ return /* @__PURE__ */ jsx18(ArtifactCard, { title: artifact.title, kind: "ui", children: /* @__PURE__ */ jsx18(UiStateProvider, { state, dispatch, children: /* @__PURE__ */ jsx18("div", { className: "aui-ui-root p-3", children: /* @__PURE__ */ jsx18(UiNodeView, { node: artifact.root }) }) }) });
1537
1982
  };
1538
1983
 
1539
1984
  // src/artifacts/registry.tsx
1540
- import { createContext as createContext2, useContext as useContext2, useMemo as useMemo3 } from "react";
1541
- import { jsx as jsx13 } from "react/jsx-runtime";
1985
+ import { createContext as createContext2, useContext as useContext2, useMemo as useMemo2 } from "react";
1986
+ import { jsx as jsx19 } from "react/jsx-runtime";
1542
1987
  var defaultArtifactRenderers = {
1543
1988
  chart: ChartArtifactView,
1544
1989
  question: QuestionArtifactView,
@@ -1551,12 +1996,12 @@ var ArtifactRegistryContext = createContext2(
1551
1996
  defaultArtifactRenderers
1552
1997
  );
1553
1998
  var ArtifactRegistryProvider = ({ renderers, override, children }) => {
1554
- const merged = useMemo3(() => {
1999
+ const merged = useMemo2(() => {
1555
2000
  if (!renderers) return defaultArtifactRenderers;
1556
2001
  if (override) return renderers;
1557
2002
  return { ...defaultArtifactRenderers, ...renderers };
1558
2003
  }, [renderers, override]);
1559
- return /* @__PURE__ */ jsx13(ArtifactRegistryContext.Provider, { value: merged, children });
2004
+ return /* @__PURE__ */ jsx19(ArtifactRegistryContext.Provider, { value: merged, children });
1560
2005
  };
1561
2006
  function useArtifactRegistry() {
1562
2007
  return useContext2(ArtifactRegistryContext);
@@ -1565,7 +2010,7 @@ var ArtifactView = ({ artifact }) => {
1565
2010
  const registry = useArtifactRegistry();
1566
2011
  const Renderer = registry[artifact.type] ?? registry.json;
1567
2012
  if (!Renderer) return null;
1568
- return /* @__PURE__ */ jsx13(Renderer, { artifact });
2013
+ return /* @__PURE__ */ jsx19(Renderer, { artifact });
1569
2014
  };
1570
2015
 
1571
2016
  // src/artifacts/types.ts
@@ -1677,11 +2122,11 @@ import {
1677
2122
  import remarkGfm from "remark-gfm";
1678
2123
  import remarkMath from "remark-math";
1679
2124
  import rehypeKatex from "rehype-katex";
1680
- import { memo, useState as useState6 } from "react";
2125
+ import { memo, useState as useState4 } from "react";
1681
2126
  import { CheckIcon as CheckIcon2, CopyIcon } from "lucide-react";
1682
2127
 
1683
2128
  // src/chat/syntax-highlighter.tsx
1684
- import { useEffect as useEffect4, useState as useState5 } from "react";
2129
+ import { useEffect as useEffect2, useState as useState3 } from "react";
1685
2130
  import { createHighlighterCore } from "shiki/core";
1686
2131
  import { createJavaScriptRegexEngine } from "shiki/engine/javascript";
1687
2132
  import langJavascript from "shiki/langs/javascript.mjs";
@@ -1703,7 +2148,7 @@ import langC from "shiki/langs/c.mjs";
1703
2148
  import langCpp from "shiki/langs/cpp.mjs";
1704
2149
  import themeVitesseDark from "shiki/themes/vitesse-dark.mjs";
1705
2150
  import themeVitesseLight from "shiki/themes/vitesse-light.mjs";
1706
- import { jsx as jsx14 } from "react/jsx-runtime";
2151
+ import { jsx as jsx20 } from "react/jsx-runtime";
1707
2152
  var SHIKI_THEME_DARK = "vitesse-dark";
1708
2153
  var SHIKI_THEME_LIGHT = "vitesse-light";
1709
2154
  var highlighterPromise = null;
@@ -1741,8 +2186,8 @@ var ShikiSyntaxHighlighter = ({
1741
2186
  language,
1742
2187
  code
1743
2188
  }) => {
1744
- const [html, setHtml] = useState5(null);
1745
- useEffect4(() => {
2189
+ const [html, setHtml] = useState3(null);
2190
+ useEffect2(() => {
1746
2191
  let cancelled = false;
1747
2192
  (async () => {
1748
2193
  try {
@@ -1772,13 +2217,13 @@ var ShikiSyntaxHighlighter = ({
1772
2217
  try {
1773
2218
  const parsed = JSON.parse(code);
1774
2219
  if (isArtifact(parsed)) {
1775
- return /* @__PURE__ */ jsx14(ArtifactView, { artifact: parsed });
2220
+ return /* @__PURE__ */ jsx20(ArtifactView, { artifact: parsed });
1776
2221
  }
1777
2222
  } catch {
1778
2223
  }
1779
2224
  }
1780
2225
  if (html) {
1781
- return /* @__PURE__ */ jsx14(
2226
+ return /* @__PURE__ */ jsx20(
1782
2227
  "div",
1783
2228
  {
1784
2229
  className: "shiki-wrapper [&>pre]:!m-0 [&>pre]:!rounded-t-none [&>pre]:!rounded-b-lg [&>pre]:!border [&>pre]:!border-t-0 [&>pre]:!border-border/50 [&>pre]:!p-3 [&>pre]:!text-xs [&>pre]:!leading-relaxed [&>pre]:overflow-x-auto",
@@ -1786,14 +2231,14 @@ var ShikiSyntaxHighlighter = ({
1786
2231
  }
1787
2232
  );
1788
2233
  }
1789
- return /* @__PURE__ */ jsx14(Pre, { children: /* @__PURE__ */ jsx14(Code2, { children: code }) });
2234
+ return /* @__PURE__ */ jsx20(Pre, { children: /* @__PURE__ */ jsx20(Code2, { children: code }) });
1790
2235
  };
1791
2236
  var syntax_highlighter_default = ShikiSyntaxHighlighter;
1792
2237
 
1793
2238
  // src/chat/markdown-text.tsx
1794
- import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
2239
+ import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
1795
2240
  var MarkdownTextImpl = () => {
1796
- return /* @__PURE__ */ jsx15(
2241
+ return /* @__PURE__ */ jsx21(
1797
2242
  MarkdownTextPrimitive,
1798
2243
  {
1799
2244
  remarkPlugins: [remarkGfm, remarkMath],
@@ -1814,20 +2259,20 @@ var CodeHeader = ({ language, code }) => {
1814
2259
  if (!code || isCopied) return;
1815
2260
  copyToClipboard(code);
1816
2261
  };
1817
- return /* @__PURE__ */ jsxs9("div", { className: "aui-code-header flex items-center justify-between rounded-t-lg border border-b-0 border-border/50 bg-code-header-bg px-4 py-2", children: [
1818
- /* @__PURE__ */ jsxs9("span", { className: "flex items-center gap-2 text-xs font-semibold tracking-wide text-muted-foreground/80 uppercase", children: [
1819
- /* @__PURE__ */ jsx15("span", { className: "inline-block h-2 w-2 rounded-full bg-primary/40" }),
2262
+ return /* @__PURE__ */ jsxs14("div", { className: "aui-code-header flex items-center justify-between rounded-t-lg border border-b-0 border-border/50 bg-code-header-bg px-4 py-2", children: [
2263
+ /* @__PURE__ */ jsxs14("span", { className: "flex items-center gap-2 text-xs font-semibold tracking-wide text-muted-foreground/80 uppercase", children: [
2264
+ /* @__PURE__ */ jsx21("span", { className: "inline-block h-2 w-2 rounded-full bg-primary/40" }),
1820
2265
  language
1821
2266
  ] }),
1822
- /* @__PURE__ */ jsxs9(
2267
+ /* @__PURE__ */ jsxs14(
1823
2268
  TooltipIconButton,
1824
2269
  {
1825
2270
  tooltip: isCopied ? "Copied!" : "Copy",
1826
2271
  onClick: onCopy,
1827
2272
  className: "transition-colors hover:text-foreground",
1828
2273
  children: [
1829
- !isCopied && /* @__PURE__ */ jsx15(CopyIcon, { className: "h-3.5 w-3.5" }),
1830
- isCopied && /* @__PURE__ */ jsx15(CheckIcon2, { className: "h-3.5 w-3.5 text-emerald-500" })
2274
+ !isCopied && /* @__PURE__ */ jsx21(CopyIcon, { className: "h-3.5 w-3.5" }),
2275
+ isCopied && /* @__PURE__ */ jsx21(CheckIcon2, { className: "h-3.5 w-3.5 text-emerald-500" })
1831
2276
  ]
1832
2277
  }
1833
2278
  )
@@ -1836,7 +2281,7 @@ var CodeHeader = ({ language, code }) => {
1836
2281
  var useCopyToClipboard = ({
1837
2282
  copiedDuration = 3e3
1838
2283
  } = {}) => {
1839
- const [isCopied, setIsCopied] = useState6(false);
2284
+ const [isCopied, setIsCopied] = useState4(false);
1840
2285
  const copyToClipboard = (value) => {
1841
2286
  if (!value) return;
1842
2287
  navigator.clipboard.writeText(value).then(() => {
@@ -1847,7 +2292,7 @@ var useCopyToClipboard = ({
1847
2292
  return { isCopied, copyToClipboard };
1848
2293
  };
1849
2294
  var defaultComponents = memoizeMarkdownComponents({
1850
- h1: ({ className, ...props }) => /* @__PURE__ */ jsx15(
2295
+ h1: ({ className, ...props }) => /* @__PURE__ */ jsx21(
1851
2296
  "h1",
1852
2297
  {
1853
2298
  className: cn(
@@ -1857,7 +2302,7 @@ var defaultComponents = memoizeMarkdownComponents({
1857
2302
  ...props
1858
2303
  }
1859
2304
  ),
1860
- h2: ({ className, ...props }) => /* @__PURE__ */ jsx15(
2305
+ h2: ({ className, ...props }) => /* @__PURE__ */ jsx21(
1861
2306
  "h2",
1862
2307
  {
1863
2308
  className: cn(
@@ -1867,7 +2312,7 @@ var defaultComponents = memoizeMarkdownComponents({
1867
2312
  ...props
1868
2313
  }
1869
2314
  ),
1870
- h3: ({ className, ...props }) => /* @__PURE__ */ jsx15(
2315
+ h3: ({ className, ...props }) => /* @__PURE__ */ jsx21(
1871
2316
  "h3",
1872
2317
  {
1873
2318
  className: cn(
@@ -1877,7 +2322,7 @@ var defaultComponents = memoizeMarkdownComponents({
1877
2322
  ...props
1878
2323
  }
1879
2324
  ),
1880
- h4: ({ className, ...props }) => /* @__PURE__ */ jsx15(
2325
+ h4: ({ className, ...props }) => /* @__PURE__ */ jsx21(
1881
2326
  "h4",
1882
2327
  {
1883
2328
  className: cn(
@@ -1887,7 +2332,7 @@ var defaultComponents = memoizeMarkdownComponents({
1887
2332
  ...props
1888
2333
  }
1889
2334
  ),
1890
- h5: ({ className, ...props }) => /* @__PURE__ */ jsx15(
2335
+ h5: ({ className, ...props }) => /* @__PURE__ */ jsx21(
1891
2336
  "h5",
1892
2337
  {
1893
2338
  className: cn(
@@ -1897,7 +2342,7 @@ var defaultComponents = memoizeMarkdownComponents({
1897
2342
  ...props
1898
2343
  }
1899
2344
  ),
1900
- h6: ({ className, ...props }) => /* @__PURE__ */ jsx15(
2345
+ h6: ({ className, ...props }) => /* @__PURE__ */ jsx21(
1901
2346
  "h6",
1902
2347
  {
1903
2348
  className: cn(
@@ -1907,7 +2352,7 @@ var defaultComponents = memoizeMarkdownComponents({
1907
2352
  ...props
1908
2353
  }
1909
2354
  ),
1910
- p: ({ className, ...props }) => /* @__PURE__ */ jsx15(
2355
+ p: ({ className, ...props }) => /* @__PURE__ */ jsx21(
1911
2356
  "p",
1912
2357
  {
1913
2358
  className: cn(
@@ -1917,7 +2362,7 @@ var defaultComponents = memoizeMarkdownComponents({
1917
2362
  ...props
1918
2363
  }
1919
2364
  ),
1920
- a: ({ className, ...props }) => /* @__PURE__ */ jsx15(
2365
+ a: ({ className, ...props }) => /* @__PURE__ */ jsx21(
1921
2366
  "a",
1922
2367
  {
1923
2368
  className: cn(
@@ -1929,7 +2374,7 @@ var defaultComponents = memoizeMarkdownComponents({
1929
2374
  ...props
1930
2375
  }
1931
2376
  ),
1932
- blockquote: ({ className, ...props }) => /* @__PURE__ */ jsx15(
2377
+ blockquote: ({ className, ...props }) => /* @__PURE__ */ jsx21(
1933
2378
  "blockquote",
1934
2379
  {
1935
2380
  className: cn(
@@ -1939,7 +2384,7 @@ var defaultComponents = memoizeMarkdownComponents({
1939
2384
  ...props
1940
2385
  }
1941
2386
  ),
1942
- ul: ({ className, ...props }) => /* @__PURE__ */ jsx15(
2387
+ ul: ({ className, ...props }) => /* @__PURE__ */ jsx21(
1943
2388
  "ul",
1944
2389
  {
1945
2390
  className: cn(
@@ -1949,7 +2394,7 @@ var defaultComponents = memoizeMarkdownComponents({
1949
2394
  ...props
1950
2395
  }
1951
2396
  ),
1952
- ol: ({ className, ...props }) => /* @__PURE__ */ jsx15(
2397
+ ol: ({ className, ...props }) => /* @__PURE__ */ jsx21(
1953
2398
  "ol",
1954
2399
  {
1955
2400
  className: cn(
@@ -1959,7 +2404,7 @@ var defaultComponents = memoizeMarkdownComponents({
1959
2404
  ...props
1960
2405
  }
1961
2406
  ),
1962
- hr: ({ className, ...props }) => /* @__PURE__ */ jsx15(
2407
+ hr: ({ className, ...props }) => /* @__PURE__ */ jsx21(
1963
2408
  "hr",
1964
2409
  {
1965
2410
  className: cn(
@@ -1969,14 +2414,14 @@ var defaultComponents = memoizeMarkdownComponents({
1969
2414
  ...props
1970
2415
  }
1971
2416
  ),
1972
- table: ({ className, ...props }) => /* @__PURE__ */ jsx15("div", { className: "my-4 w-full overflow-x-auto rounded-lg border border-border/50", children: /* @__PURE__ */ jsx15(
2417
+ table: ({ className, ...props }) => /* @__PURE__ */ jsx21("div", { className: "my-4 w-full overflow-x-auto rounded-lg border border-border/50", children: /* @__PURE__ */ jsx21(
1973
2418
  "table",
1974
2419
  {
1975
2420
  className: cn("aui-md-table w-full border-collapse text-sm", className),
1976
2421
  ...props
1977
2422
  }
1978
2423
  ) }),
1979
- th: ({ className, ...props }) => /* @__PURE__ */ jsx15(
2424
+ th: ({ className, ...props }) => /* @__PURE__ */ jsx21(
1980
2425
  "th",
1981
2426
  {
1982
2427
  className: cn(
@@ -1986,7 +2431,7 @@ var defaultComponents = memoizeMarkdownComponents({
1986
2431
  ...props
1987
2432
  }
1988
2433
  ),
1989
- td: ({ className, ...props }) => /* @__PURE__ */ jsx15(
2434
+ td: ({ className, ...props }) => /* @__PURE__ */ jsx21(
1990
2435
  "td",
1991
2436
  {
1992
2437
  className: cn(
@@ -1996,7 +2441,7 @@ var defaultComponents = memoizeMarkdownComponents({
1996
2441
  ...props
1997
2442
  }
1998
2443
  ),
1999
- tr: ({ className, ...props }) => /* @__PURE__ */ jsx15(
2444
+ tr: ({ className, ...props }) => /* @__PURE__ */ jsx21(
2000
2445
  "tr",
2001
2446
  {
2002
2447
  className: cn(
@@ -2006,8 +2451,8 @@ var defaultComponents = memoizeMarkdownComponents({
2006
2451
  ...props
2007
2452
  }
2008
2453
  ),
2009
- li: ({ className, ...props }) => /* @__PURE__ */ jsx15("li", { className: cn("aui-md-li leading-[1.7]", className), ...props }),
2010
- sup: ({ className, ...props }) => /* @__PURE__ */ jsx15(
2454
+ li: ({ className, ...props }) => /* @__PURE__ */ jsx21("li", { className: cn("aui-md-li leading-[1.7]", className), ...props }),
2455
+ sup: ({ className, ...props }) => /* @__PURE__ */ jsx21(
2011
2456
  "sup",
2012
2457
  {
2013
2458
  className: cn(
@@ -2017,7 +2462,7 @@ var defaultComponents = memoizeMarkdownComponents({
2017
2462
  ...props
2018
2463
  }
2019
2464
  ),
2020
- pre: ({ className, ...props }) => /* @__PURE__ */ jsx15(
2465
+ pre: ({ className, ...props }) => /* @__PURE__ */ jsx21(
2021
2466
  "pre",
2022
2467
  {
2023
2468
  className: cn(
@@ -2029,7 +2474,7 @@ var defaultComponents = memoizeMarkdownComponents({
2029
2474
  ),
2030
2475
  code: function Code({ className, ...props }) {
2031
2476
  const isCodeBlock = useIsMarkdownCodeBlock();
2032
- return /* @__PURE__ */ jsx15(
2477
+ return /* @__PURE__ */ jsx21(
2033
2478
  "code",
2034
2479
  {
2035
2480
  className: cn(
@@ -2040,8 +2485,8 @@ var defaultComponents = memoizeMarkdownComponents({
2040
2485
  }
2041
2486
  );
2042
2487
  },
2043
- strong: ({ className, ...props }) => /* @__PURE__ */ jsx15("strong", { className: cn("font-semibold text-foreground", className), ...props }),
2044
- em: ({ className, ...props }) => /* @__PURE__ */ jsx15("em", { className: cn("italic", className), ...props }),
2488
+ strong: ({ className, ...props }) => /* @__PURE__ */ jsx21("strong", { className: cn("font-semibold text-foreground", className), ...props }),
2489
+ em: ({ className, ...props }) => /* @__PURE__ */ jsx21("em", { className: cn("italic", className), ...props }),
2045
2490
  CodeHeader
2046
2491
  });
2047
2492
 
@@ -2237,10 +2682,10 @@ import {
2237
2682
  createContext as createContext4,
2238
2683
  useCallback as useCallback3,
2239
2684
  useContext as useContext4,
2240
- useEffect as useEffect5,
2241
- useMemo as useMemo4,
2242
- useRef as useRef2,
2243
- useState as useState7
2685
+ useEffect as useEffect3,
2686
+ useMemo as useMemo3,
2687
+ useRef,
2688
+ useState as useState5
2244
2689
  } from "react";
2245
2690
  import {
2246
2691
  useExternalStoreRuntime,
@@ -2594,20 +3039,20 @@ function buildPromptBody({
2594
3039
 
2595
3040
  // src/runtime/attachments-context.tsx
2596
3041
  import { createContext as createContext3, useContext as useContext3 } from "react";
2597
- import { jsx as jsx16 } from "react/jsx-runtime";
3042
+ import { jsx as jsx22 } from "react/jsx-runtime";
2598
3043
  var TimbalAttachmentsEnabledContext = createContext3(false);
2599
3044
  function TimbalAttachmentsEnabledProvider({
2600
3045
  enabled,
2601
3046
  children
2602
3047
  }) {
2603
- return /* @__PURE__ */ jsx16(TimbalAttachmentsEnabledContext.Provider, { value: enabled, children });
3048
+ return /* @__PURE__ */ jsx22(TimbalAttachmentsEnabledContext.Provider, { value: enabled, children });
2604
3049
  }
2605
3050
  function useTimbalAttachmentsEnabled() {
2606
3051
  return useContext3(TimbalAttachmentsEnabledContext);
2607
3052
  }
2608
3053
 
2609
3054
  // src/runtime/provider.tsx
2610
- import { jsx as jsx17 } from "react/jsx-runtime";
3055
+ import { jsx as jsx23 } from "react/jsx-runtime";
2611
3056
  function projectAttachment(attachment) {
2612
3057
  const filename = attachment.name ?? "attachment";
2613
3058
  const mimeType = attachment.contentType ?? "application/octet-stream";
@@ -2672,19 +3117,19 @@ function useTimbalStream({
2672
3117
  fetch: fetchFn,
2673
3118
  debug = false
2674
3119
  }) {
2675
- const [messages, setMessages] = useState7([]);
2676
- const [isRunning, setIsRunning] = useState7(false);
2677
- const abortRef = useRef2(null);
2678
- const messagesRef = useRef2([]);
2679
- const fetchFnRef = useRef2(fetchFn ?? authFetch);
2680
- useEffect5(() => {
3120
+ const [messages, setMessages] = useState5([]);
3121
+ const [isRunning, setIsRunning] = useState5(false);
3122
+ const abortRef = useRef(null);
3123
+ const messagesRef = useRef([]);
3124
+ const fetchFnRef = useRef(fetchFn ?? authFetch);
3125
+ useEffect3(() => {
2681
3126
  fetchFnRef.current = fetchFn ?? authFetch;
2682
3127
  }, [fetchFn]);
2683
- const debugRef = useRef2(debug);
2684
- useEffect5(() => {
3128
+ const debugRef = useRef(debug);
3129
+ useEffect3(() => {
2685
3130
  debugRef.current = debug;
2686
3131
  }, [debug]);
2687
- useEffect5(() => {
3132
+ useEffect3(() => {
2688
3133
  messagesRef.current = messages;
2689
3134
  }, [messages]);
2690
3135
  const streamAssistantResponse = useCallback3(
@@ -2833,7 +3278,7 @@ function useTimbalStream({
2833
3278
  abortRef.current?.abort();
2834
3279
  setMessages([]);
2835
3280
  }, []);
2836
- return useMemo4(
3281
+ return useMemo3(
2837
3282
  () => ({ messages, isRunning, send, reload, cancel, clear }),
2838
3283
  [messages, isRunning, send, reload, cancel, clear]
2839
3284
  );
@@ -2870,7 +3315,7 @@ function TimbalRuntimeProvider({
2870
3315
  fetch: fetchFn,
2871
3316
  debug
2872
3317
  });
2873
- const attachmentAdapter = useMemo4(
3318
+ const attachmentAdapter = useMemo3(
2874
3319
  () => resolveAttachmentAdapter(attachments, {
2875
3320
  baseUrl,
2876
3321
  fetch: fetchFn,
@@ -2913,7 +3358,7 @@ function TimbalRuntimeProvider({
2913
3358
  onCancel,
2914
3359
  ...attachmentAdapter ? { adapters: { attachments: attachmentAdapter } } : {}
2915
3360
  });
2916
- return /* @__PURE__ */ jsx17(TimbalStreamContext.Provider, { value: stream, children: /* @__PURE__ */ jsx17(TimbalAttachmentsEnabledProvider, { enabled: attachmentAdapter !== void 0, children: /* @__PURE__ */ jsx17(AssistantRuntimeProvider, { runtime, children }) }) });
3361
+ return /* @__PURE__ */ jsx23(TimbalStreamContext.Provider, { value: stream, children: /* @__PURE__ */ jsx23(TimbalAttachmentsEnabledProvider, { enabled: attachmentAdapter !== void 0, children: /* @__PURE__ */ jsx23(AssistantRuntimeProvider, { runtime, children }) }) });
2917
3362
  }
2918
3363
  function findParentIdFromAuiParent(messages, auiParentId) {
2919
3364
  const idx = messages.findIndex((m) => m.id === auiParentId);
@@ -2922,7 +3367,7 @@ function findParentIdFromAuiParent(messages, auiParentId) {
2922
3367
  }
2923
3368
 
2924
3369
  // src/chat/tool-fallback.tsx
2925
- import { memo as memo2, useMemo as useMemo5, useState as useState8 } from "react";
3370
+ import { memo as memo2, useMemo as useMemo4, useState as useState6 } from "react";
2926
3371
  import { ChevronRightIcon } from "lucide-react";
2927
3372
  import {
2928
3373
  useAuiState as useAuiState2
@@ -2930,7 +3375,7 @@ import {
2930
3375
 
2931
3376
  // src/chat/motion.tsx
2932
3377
  import { AnimatePresence, motion as motion2, useReducedMotion } from "motion/react";
2933
- import { jsx as jsx18 } from "react/jsx-runtime";
3378
+ import { jsx as jsx24 } from "react/jsx-runtime";
2934
3379
  var luxuryEase = [0.16, 1, 0.3, 1];
2935
3380
  var TOOL_ENTER_MS = 0.78;
2936
3381
  var TOOL_EXIT_MS = 0.28;
@@ -2958,7 +3403,7 @@ function toolMotionState(reduced, entering, variant) {
2958
3403
  function ToolMotion({ children, className, motionKey }) {
2959
3404
  const reduced = useReducedMotion() ?? false;
2960
3405
  const { enter, exit } = toolPresenceTransition(reduced);
2961
- return /* @__PURE__ */ jsx18(
3406
+ return /* @__PURE__ */ jsx24(
2962
3407
  motion2.div,
2963
3408
  {
2964
3409
  className: cn("aui-tool-motion w-full min-w-0", className),
@@ -2981,7 +3426,7 @@ function ToolPresence({
2981
3426
  const reduced = useReducedMotion() ?? false;
2982
3427
  const { enter, exit } = toolPresenceTransition(reduced);
2983
3428
  const enterTransition = variant === "executing" ? { duration: reduced ? 0.3 : 0.52, ease: luxuryEase } : enter;
2984
- return /* @__PURE__ */ jsx18(AnimatePresence, { mode: "wait", initial: true, children: /* @__PURE__ */ jsx18(
3429
+ return /* @__PURE__ */ jsx24(AnimatePresence, { mode: "wait", initial: true, children: /* @__PURE__ */ jsx24(
2985
3430
  motion2.div,
2986
3431
  {
2987
3432
  className: cn("aui-tool-presence w-full min-w-0", className),
@@ -3003,7 +3448,7 @@ function ToolBodyPresence({
3003
3448
  className
3004
3449
  }) {
3005
3450
  const reduced = useReducedMotion() ?? false;
3006
- return /* @__PURE__ */ jsx18(
3451
+ return /* @__PURE__ */ jsx24(
3007
3452
  "div",
3008
3453
  {
3009
3454
  className: cn(
@@ -3011,7 +3456,7 @@ function ToolBodyPresence({
3011
3456
  open ? reduced ? "duration-200 ease-out" : "duration-[340ms] ease-[cubic-bezier(0.16,1,0.3,1)]" : reduced ? "duration-150 ease-[cubic-bezier(0.4,0,0.2,1)]" : "duration-200 ease-[cubic-bezier(0.4,0,0.2,1)]"
3012
3457
  ),
3013
3458
  style: { gridTemplateRows: open ? "1fr" : "0fr" },
3014
- children: /* @__PURE__ */ jsx18("div", { className: "min-h-0 overflow-hidden", children: /* @__PURE__ */ jsx18(
3459
+ children: /* @__PURE__ */ jsx24("div", { className: "min-h-0 overflow-hidden", children: /* @__PURE__ */ jsx24(
3015
3460
  "div",
3016
3461
  {
3017
3462
  className: cn(
@@ -3027,7 +3472,7 @@ function ToolBodyPresence({
3027
3472
  }
3028
3473
 
3029
3474
  // src/chat/tool-fallback.tsx
3030
- import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
3475
+ import { jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
3031
3476
  function detectRunning({
3032
3477
  status,
3033
3478
  result,
@@ -3059,8 +3504,8 @@ function formatToolResult(result) {
3059
3504
  return String(result);
3060
3505
  }
3061
3506
  }
3062
- var TimelineActionLabel = ({ action, detail, shimmer = false }) => /* @__PURE__ */ jsxs10("span", { className: "inline-flex min-w-0 max-w-full items-baseline gap-1", children: [
3063
- action ? shimmer ? /* @__PURE__ */ jsx19(
3507
+ var TimelineActionLabel = ({ action, detail, shimmer = false }) => /* @__PURE__ */ jsxs15("span", { className: "inline-flex min-w-0 max-w-full items-baseline gap-1", children: [
3508
+ action ? shimmer ? /* @__PURE__ */ jsx25(
3064
3509
  Shimmer,
3065
3510
  {
3066
3511
  as: "span",
@@ -3069,10 +3514,10 @@ var TimelineActionLabel = ({ action, detail, shimmer = false }) => /* @__PURE__
3069
3514
  spread: 2.5,
3070
3515
  children: action
3071
3516
  }
3072
- ) : /* @__PURE__ */ jsx19("span", { className: studioTimelineActionClass, children: action }) : null,
3073
- detail ? /* @__PURE__ */ jsx19("span", { className: studioTimelineDetailClass, children: detail }) : null
3517
+ ) : /* @__PURE__ */ jsx25("span", { className: studioTimelineActionClass, children: action }) : null,
3518
+ detail ? /* @__PURE__ */ jsx25("span", { className: studioTimelineDetailClass, children: detail }) : null
3074
3519
  ] });
3075
- var TimelineHoverChevron = ({ expanded }) => /* @__PURE__ */ jsx19(
3520
+ var TimelineHoverChevron = ({ expanded }) => /* @__PURE__ */ jsx25(
3076
3521
  ChevronRightIcon,
3077
3522
  {
3078
3523
  className: studioTimelineChevronClass(expanded),
@@ -3080,9 +3525,9 @@ var TimelineHoverChevron = ({ expanded }) => /* @__PURE__ */ jsx19(
3080
3525
  }
3081
3526
  );
3082
3527
  var ToolPanel = ({ toolName, argsText, result, isError }) => {
3083
- const [open, setOpen] = useState8(false);
3528
+ const [open, setOpen] = useState6(false);
3084
3529
  const detail = formatToolLabel(toolName);
3085
- const formattedArgs = useMemo5(() => {
3530
+ const formattedArgs = useMemo4(() => {
3086
3531
  if (!argsText || argsText === "{}") return null;
3087
3532
  try {
3088
3533
  return JSON.stringify(JSON.parse(argsText), null, 2);
@@ -3090,17 +3535,17 @@ var ToolPanel = ({ toolName, argsText, result, isError }) => {
3090
3535
  return argsText;
3091
3536
  }
3092
3537
  }, [argsText]);
3093
- const formattedResult = useMemo5(() => {
3538
+ const formattedResult = useMemo4(() => {
3094
3539
  if (result === void 0 || result === null) return null;
3095
3540
  return formatToolResult(result);
3096
3541
  }, [result]);
3097
3542
  const hasBody = Boolean(formattedArgs || formattedResult);
3098
3543
  const action = isError ? "Failed" : "Used";
3099
3544
  if (!hasBody) {
3100
- return /* @__PURE__ */ jsx19("div", { className: "aui-tool-row w-full min-w-0", children: /* @__PURE__ */ jsx19(TimelineActionLabel, { action, detail }) });
3545
+ return /* @__PURE__ */ jsx25("div", { className: "aui-tool-row w-full min-w-0", children: /* @__PURE__ */ jsx25(TimelineActionLabel, { action, detail }) });
3101
3546
  }
3102
- return /* @__PURE__ */ jsxs10("div", { className: "aui-tool-row w-full min-w-0", children: [
3103
- /* @__PURE__ */ jsx19(
3547
+ return /* @__PURE__ */ jsxs15("div", { className: "aui-tool-row w-full min-w-0", children: [
3548
+ /* @__PURE__ */ jsx25(
3104
3549
  "button",
3105
3550
  {
3106
3551
  type: "button",
@@ -3108,7 +3553,7 @@ var ToolPanel = ({ toolName, argsText, result, isError }) => {
3108
3553
  "aria-expanded": open,
3109
3554
  "aria-label": `${action} ${detail}`,
3110
3555
  className: studioTimelineRowButtonClass,
3111
- children: /* @__PURE__ */ jsxs10(
3556
+ children: /* @__PURE__ */ jsxs15(
3112
3557
  "span",
3113
3558
  {
3114
3559
  className: cn(
@@ -3117,37 +3562,37 @@ var ToolPanel = ({ toolName, argsText, result, isError }) => {
3117
3562
  "text-foreground"
3118
3563
  ),
3119
3564
  children: [
3120
- /* @__PURE__ */ jsx19(TimelineActionLabel, { action, detail }),
3121
- /* @__PURE__ */ jsx19(TimelineHoverChevron, { expanded: open })
3565
+ /* @__PURE__ */ jsx25(TimelineActionLabel, { action, detail }),
3566
+ /* @__PURE__ */ jsx25(TimelineHoverChevron, { expanded: open })
3122
3567
  ]
3123
3568
  }
3124
3569
  )
3125
3570
  }
3126
3571
  ),
3127
- /* @__PURE__ */ jsxs10(
3572
+ /* @__PURE__ */ jsxs15(
3128
3573
  ToolBodyPresence,
3129
3574
  {
3130
3575
  open,
3131
3576
  className: cn(studioTimelineBodyPadClass, "gap-2"),
3132
3577
  children: [
3133
- formattedArgs ? /* @__PURE__ */ jsx19(
3578
+ formattedArgs ? /* @__PURE__ */ jsx25(
3134
3579
  "div",
3135
3580
  {
3136
3581
  className: cn(
3137
3582
  studioComposerIoWellClass,
3138
3583
  "max-h-48 overflow-auto px-2.5 py-2"
3139
3584
  ),
3140
- children: /* @__PURE__ */ jsx19("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] font-normal leading-relaxed text-foreground", children: formattedArgs })
3585
+ children: /* @__PURE__ */ jsx25("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] font-normal leading-relaxed text-foreground", children: formattedArgs })
3141
3586
  }
3142
3587
  ) : null,
3143
- formattedResult ? /* @__PURE__ */ jsx19(
3588
+ formattedResult ? /* @__PURE__ */ jsx25(
3144
3589
  "div",
3145
3590
  {
3146
3591
  className: cn(
3147
3592
  studioComposerIoWellClass,
3148
3593
  "max-h-48 overflow-auto px-2.5 py-2"
3149
3594
  ),
3150
- children: /* @__PURE__ */ jsx19("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] font-normal leading-relaxed text-foreground", children: formattedResult })
3595
+ children: /* @__PURE__ */ jsx25("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] font-normal leading-relaxed text-foreground", children: formattedResult })
3151
3596
  }
3152
3597
  ) : null
3153
3598
  ]
@@ -3164,20 +3609,20 @@ var ToolFallbackImpl = ({
3164
3609
  const isRunning = useToolRunning({ status, result });
3165
3610
  const isError = status?.type === "incomplete" && status.reason !== "cancelled";
3166
3611
  const presenceKey = isRunning ? "running" : isError ? "error" : "complete";
3167
- return /* @__PURE__ */ jsx19(
3612
+ return /* @__PURE__ */ jsx25(
3168
3613
  ToolPresence,
3169
3614
  {
3170
3615
  presenceKey,
3171
3616
  variant: isRunning ? "executing" : "settled",
3172
3617
  className: "py-0.5",
3173
- children: isRunning ? /* @__PURE__ */ jsx19("div", { className: "aui-tool-running", children: /* @__PURE__ */ jsx19(
3618
+ children: isRunning ? /* @__PURE__ */ jsx25("div", { className: "aui-tool-running", children: /* @__PURE__ */ jsx25(
3174
3619
  TimelineActionLabel,
3175
3620
  {
3176
3621
  action: "Using",
3177
3622
  detail: formatToolLabel(toolName),
3178
3623
  shimmer: true
3179
3624
  }
3180
- ) }) : /* @__PURE__ */ jsx19(
3625
+ ) }) : /* @__PURE__ */ jsx25(
3181
3626
  ToolPanel,
3182
3627
  {
3183
3628
  toolName,
@@ -3195,7 +3640,7 @@ var ToolFallback = memo2(
3195
3640
  ToolFallback.displayName = "ToolFallback";
3196
3641
 
3197
3642
  // src/artifacts/tool-artifact.tsx
3198
- import { jsx as jsx20 } from "react/jsx-runtime";
3643
+ import { jsx as jsx26 } from "react/jsx-runtime";
3199
3644
  var ToolArtifactFallback = (props) => {
3200
3645
  const registry = useArtifactRegistry();
3201
3646
  const isRunning = useToolRunning({
@@ -3207,18 +3652,18 @@ var ToolArtifactFallback = (props) => {
3207
3652
  if (artifact) {
3208
3653
  const Renderer = registry[artifact.type];
3209
3654
  if (Renderer) {
3210
- return /* @__PURE__ */ jsx20(
3655
+ return /* @__PURE__ */ jsx26(
3211
3656
  ToolMotion,
3212
3657
  {
3213
3658
  motionKey: `artifact-${artifact.type}`,
3214
3659
  className: "aui-tool-artifact",
3215
- children: /* @__PURE__ */ jsx20(Renderer, { artifact })
3660
+ children: /* @__PURE__ */ jsx26(Renderer, { artifact })
3216
3661
  }
3217
3662
  );
3218
3663
  }
3219
3664
  }
3220
3665
  }
3221
- return /* @__PURE__ */ jsx20(ToolFallback, { ...props });
3666
+ return /* @__PURE__ */ jsx26(ToolFallback, { ...props });
3222
3667
  };
3223
3668
 
3224
3669
  // src/chat/composer.tsx
@@ -3228,7 +3673,7 @@ import {
3228
3673
  useComposerRuntime
3229
3674
  } from "@assistant-ui/react";
3230
3675
  import { ArrowUpIcon, SquareIcon } from "lucide-react";
3231
- import { Fragment, jsx as jsx21, jsxs as jsxs11 } from "react/jsx-runtime";
3676
+ import { Fragment as Fragment2, jsx as jsx27, jsxs as jsxs16 } from "react/jsx-runtime";
3232
3677
  var Composer = ({
3233
3678
  placeholder = "Send a message...",
3234
3679
  showAttachments,
@@ -3239,10 +3684,10 @@ var Composer = ({
3239
3684
  }) => {
3240
3685
  const attachmentsEnabled = useTimbalAttachmentsEnabled();
3241
3686
  const attachUi = showAttachments !== false && attachmentsEnabled;
3242
- const shell = /* @__PURE__ */ jsxs11(Fragment, { children: [
3243
- attachUi && /* @__PURE__ */ jsx21(ComposerAttachments, {}),
3244
- /* @__PURE__ */ jsx21(ComposerInput, { placeholder, autoFocus: !noAutoFocus }),
3245
- /* @__PURE__ */ jsx21(
3687
+ const shell = /* @__PURE__ */ jsxs16(Fragment2, { children: [
3688
+ attachUi && /* @__PURE__ */ jsx27(ComposerAttachments, {}),
3689
+ /* @__PURE__ */ jsx27(ComposerInput, { placeholder, autoFocus: !noAutoFocus }),
3690
+ /* @__PURE__ */ jsx27(
3246
3691
  ComposerToolbar,
3247
3692
  {
3248
3693
  showAttachments: attachUi,
@@ -3251,14 +3696,14 @@ var Composer = ({
3251
3696
  }
3252
3697
  )
3253
3698
  ] });
3254
- return /* @__PURE__ */ jsx21(
3699
+ return /* @__PURE__ */ jsx27(
3255
3700
  ComposerPrimitive2.Root,
3256
3701
  {
3257
3702
  className: cn(
3258
3703
  "aui-composer-root relative flex w-full flex-col",
3259
3704
  className
3260
3705
  ),
3261
- children: attachUi ? /* @__PURE__ */ jsx21(
3706
+ children: attachUi ? /* @__PURE__ */ jsx27(
3262
3707
  ComposerPrimitive2.AttachmentDropzone,
3263
3708
  {
3264
3709
  className: cn(
@@ -3267,7 +3712,7 @@ var Composer = ({
3267
3712
  ),
3268
3713
  children: shell
3269
3714
  }
3270
- ) : /* @__PURE__ */ jsx21("div", { className: studioComposeInputShellClass, children: shell })
3715
+ ) : /* @__PURE__ */ jsx27("div", { className: studioComposeInputShellClass, children: shell })
3271
3716
  }
3272
3717
  );
3273
3718
  };
@@ -3287,7 +3732,7 @@ var ComposerInput = ({
3287
3732
  el.style.height = "auto";
3288
3733
  el.style.height = `${Math.min(el.scrollHeight, 240)}px`;
3289
3734
  };
3290
- return /* @__PURE__ */ jsx21(
3735
+ return /* @__PURE__ */ jsx27(
3291
3736
  ComposerPrimitive2.Input,
3292
3737
  {
3293
3738
  placeholder,
@@ -3301,17 +3746,17 @@ var ComposerInput = ({
3301
3746
  );
3302
3747
  };
3303
3748
  var ComposerToolbar = ({ showAttachments, toolbar, sendTooltip }) => {
3304
- return /* @__PURE__ */ jsxs11("div", { className: "aui-composer-action-wrapper relative z-[1] flex items-center justify-between gap-1 bg-composer-bg px-2.5 pb-2.5", children: [
3305
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1", children: [
3306
- showAttachments && /* @__PURE__ */ jsx21(ComposerAddAttachment, {}),
3749
+ return /* @__PURE__ */ jsxs16("div", { className: "aui-composer-action-wrapper relative z-[1] flex items-center justify-between gap-1 bg-composer-bg px-2.5 pb-2.5", children: [
3750
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-1", children: [
3751
+ showAttachments && /* @__PURE__ */ jsx27(ComposerAddAttachment, {}),
3307
3752
  toolbar
3308
3753
  ] }),
3309
- /* @__PURE__ */ jsx21(ComposerSendOrCancel, { sendTooltip })
3754
+ /* @__PURE__ */ jsx27(ComposerSendOrCancel, { sendTooltip })
3310
3755
  ] });
3311
3756
  };
3312
3757
  var ComposerSendOrCancel = ({ sendTooltip }) => {
3313
- return /* @__PURE__ */ jsxs11(Fragment, { children: [
3314
- /* @__PURE__ */ jsx21(AuiIf, { condition: (s) => !s.thread.isRunning, children: /* @__PURE__ */ jsx21(ComposerPrimitive2.Send, { asChild: true, children: /* @__PURE__ */ jsx21(
3758
+ return /* @__PURE__ */ jsxs16(Fragment2, { children: [
3759
+ /* @__PURE__ */ jsx27(AuiIf, { condition: (s) => !s.thread.isRunning, children: /* @__PURE__ */ jsx27(ComposerPrimitive2.Send, { asChild: true, children: /* @__PURE__ */ jsx27(
3315
3760
  TooltipIconButton,
3316
3761
  {
3317
3762
  tooltip: sendTooltip,
@@ -3319,17 +3764,17 @@ var ComposerSendOrCancel = ({ sendTooltip }) => {
3319
3764
  type: "submit",
3320
3765
  className: "aui-composer-send shrink-0 disabled:opacity-30",
3321
3766
  "aria-label": "Send message",
3322
- children: /* @__PURE__ */ jsx21(ArrowUpIcon, { className: "aui-composer-send-icon size-4" })
3767
+ children: /* @__PURE__ */ jsx27(ArrowUpIcon, { className: "aui-composer-send-icon size-4" })
3323
3768
  }
3324
3769
  ) }) }),
3325
- /* @__PURE__ */ jsx21(AuiIf, { condition: (s) => s.thread.isRunning, children: /* @__PURE__ */ jsx21(ComposerPrimitive2.Cancel, { asChild: true, children: /* @__PURE__ */ jsx21(
3770
+ /* @__PURE__ */ jsx27(AuiIf, { condition: (s) => s.thread.isRunning, children: /* @__PURE__ */ jsx27(ComposerPrimitive2.Cancel, { asChild: true, children: /* @__PURE__ */ jsx27(
3326
3771
  TooltipIconButton,
3327
3772
  {
3328
3773
  tooltip: "Stop generating",
3329
3774
  variant: "primary",
3330
3775
  className: "aui-composer-cancel shrink-0",
3331
3776
  "aria-label": "Stop generating",
3332
- children: /* @__PURE__ */ jsx21(SquareIcon, { className: "aui-composer-cancel-icon size-3 fill-current" })
3777
+ children: /* @__PURE__ */ jsx27(SquareIcon, { className: "aui-composer-cancel-icon size-3 fill-current" })
3333
3778
  }
3334
3779
  ) }) })
3335
3780
  ] });
@@ -3337,20 +3782,20 @@ var ComposerSendOrCancel = ({ sendTooltip }) => {
3337
3782
 
3338
3783
  // src/chat/suggestions.tsx
3339
3784
  import {
3340
- useEffect as useEffect6,
3341
- useMemo as useMemo6,
3342
- useState as useState9
3785
+ useEffect as useEffect4,
3786
+ useMemo as useMemo5,
3787
+ useState as useState7
3343
3788
  } from "react";
3344
3789
  import { useThreadRuntime as useThreadRuntime3 } from "@assistant-ui/react";
3345
3790
  import { ArrowUpIcon as ArrowUpIcon2 } from "lucide-react";
3346
- import { jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
3791
+ import { jsx as jsx28, jsxs as jsxs17 } from "react/jsx-runtime";
3347
3792
  var Suggestions = ({
3348
3793
  suggestions,
3349
3794
  className
3350
3795
  }) => {
3351
3796
  const items = useResolvedSuggestions(suggestions);
3352
3797
  if (!items || items.length === 0) return null;
3353
- return /* @__PURE__ */ jsx22(
3798
+ return /* @__PURE__ */ jsx28(
3354
3799
  "div",
3355
3800
  {
3356
3801
  className: cn(
@@ -3359,7 +3804,7 @@ var Suggestions = ({
3359
3804
  ),
3360
3805
  role: "list",
3361
3806
  "aria-label": "Suggested prompts",
3362
- children: items.map((suggestion, i) => /* @__PURE__ */ jsx22(SuggestionRow, { suggestion }, (suggestion.prompt ?? suggestion.title) + i))
3807
+ children: items.map((suggestion, i) => /* @__PURE__ */ jsx28(SuggestionRow, { suggestion }, (suggestion.prompt ?? suggestion.title) + i))
3363
3808
  }
3364
3809
  );
3365
3810
  };
@@ -3369,7 +3814,7 @@ var SuggestionRow = ({ suggestion }) => {
3369
3814
  const text = suggestion.prompt ?? suggestion.title;
3370
3815
  runtime.append({ role: "user", content: [{ type: "text", text }] });
3371
3816
  };
3372
- return /* @__PURE__ */ jsxs12(
3817
+ return /* @__PURE__ */ jsxs17(
3373
3818
  "button",
3374
3819
  {
3375
3820
  type: "button",
@@ -3377,20 +3822,20 @@ var SuggestionRow = ({ suggestion }) => {
3377
3822
  onClick,
3378
3823
  className: cn("aui-thread-suggestion", studioListRowButtonClass),
3379
3824
  children: [
3380
- /* @__PURE__ */ jsx22("span", { className: "aui-thread-suggestion-icon shrink-0 text-muted-foreground", children: suggestion.icon ?? /* @__PURE__ */ jsx22(ArrowUpIcon2, { className: "size-4", strokeWidth: 1.75, "aria-hidden": true }) }),
3381
- /* @__PURE__ */ jsxs12("span", { className: "aui-thread-suggestion-text min-w-0 flex-1 text-left", children: [
3382
- /* @__PURE__ */ jsx22("span", { className: "aui-thread-suggestion-text-1 block truncate text-sm font-normal text-foreground", children: suggestion.title }),
3383
- suggestion.description && /* @__PURE__ */ jsx22("span", { className: "aui-thread-suggestion-text-2 mt-0.5 block truncate text-xs text-muted-foreground", children: suggestion.description })
3825
+ /* @__PURE__ */ jsx28("span", { className: "aui-thread-suggestion-icon shrink-0 text-muted-foreground", children: suggestion.icon ?? /* @__PURE__ */ jsx28(ArrowUpIcon2, { className: "size-4", strokeWidth: 1.75, "aria-hidden": true }) }),
3826
+ /* @__PURE__ */ jsxs17("span", { className: "aui-thread-suggestion-text min-w-0 flex-1 text-left", children: [
3827
+ /* @__PURE__ */ jsx28("span", { className: "aui-thread-suggestion-text-1 block truncate text-sm font-normal text-foreground", children: suggestion.title }),
3828
+ suggestion.description && /* @__PURE__ */ jsx28("span", { className: "aui-thread-suggestion-text-2 mt-0.5 block truncate text-xs text-muted-foreground", children: suggestion.description })
3384
3829
  ] })
3385
3830
  ]
3386
3831
  }
3387
3832
  );
3388
3833
  };
3389
3834
  function useResolvedSuggestions(source) {
3390
- const [resolved, setResolved] = useState9(
3835
+ const [resolved, setResolved] = useState7(
3391
3836
  () => Array.isArray(source) ? source : void 0
3392
3837
  );
3393
- useEffect6(() => {
3838
+ useEffect4(() => {
3394
3839
  if (!source) {
3395
3840
  setResolved(void 0);
3396
3841
  return;
@@ -3409,11 +3854,11 @@ function useResolvedSuggestions(source) {
3409
3854
  cancelled = true;
3410
3855
  };
3411
3856
  }, [source]);
3412
- return useMemo6(() => resolved, [resolved]);
3857
+ return useMemo5(() => resolved, [resolved]);
3413
3858
  }
3414
3859
 
3415
3860
  // src/chat/thread.tsx
3416
- import { useEffect as useEffect7 } from "react";
3861
+ import { useEffect as useEffect5 } from "react";
3417
3862
  import {
3418
3863
  ActionBarMorePrimitive,
3419
3864
  ActionBarPrimitive,
@@ -3514,7 +3959,7 @@ function useThreadVariant() {
3514
3959
  }
3515
3960
 
3516
3961
  // src/chat/thread.tsx
3517
- import { jsx as jsx23, jsxs as jsxs13 } from "react/jsx-runtime";
3962
+ import { jsx as jsx29, jsxs as jsxs18 } from "react/jsx-runtime";
3518
3963
  var Thread = ({
3519
3964
  className,
3520
3965
  variant = "default",
@@ -3537,16 +3982,16 @@ var Thread = ({
3537
3982
  const EditComposerSlot = components?.EditComposer ?? EditComposer;
3538
3983
  const ScrollToBottomSlot = components?.ScrollToBottom ?? ThreadScrollToBottom;
3539
3984
  const SuggestionsSlot = components?.Suggestions ?? Suggestions;
3540
- useEffect7(() => {
3985
+ useEffect5(() => {
3541
3986
  scheduleThemeSanityCheck();
3542
3987
  }, []);
3543
- return /* @__PURE__ */ jsx23(ThreadVariantProvider, { value: variant, children: /* @__PURE__ */ jsx23(
3988
+ return /* @__PURE__ */ jsx29(ThreadVariantProvider, { value: variant, children: /* @__PURE__ */ jsx29(
3544
3989
  ArtifactRegistryProvider,
3545
3990
  {
3546
3991
  renderers: artifacts?.renderers,
3547
3992
  override: artifacts?.override,
3548
- children: /* @__PURE__ */ jsx23(UiEventProvider, { onEvent: onArtifactEvent ?? (() => {
3549
- }), children: /* @__PURE__ */ jsx23(
3993
+ children: /* @__PURE__ */ jsx29(UiEventProvider, { onEvent: onArtifactEvent ?? (() => {
3994
+ }), children: /* @__PURE__ */ jsx29(
3550
3995
  ThreadPrimitive.Root,
3551
3996
  {
3552
3997
  className: cn(
@@ -3556,7 +4001,7 @@ var Thread = ({
3556
4001
  ),
3557
4002
  style: { ["--thread-max-width"]: maxWidth },
3558
4003
  "data-thread-variant": variant,
3559
- children: /* @__PURE__ */ jsxs13(
4004
+ children: /* @__PURE__ */ jsxs18(
3560
4005
  ThreadPrimitive.Viewport,
3561
4006
  {
3562
4007
  turnAnchor: "bottom",
@@ -3565,7 +4010,7 @@ var Thread = ({
3565
4010
  isPanel ? "px-2 pt-2" : "px-4 pt-4"
3566
4011
  ),
3567
4012
  children: [
3568
- /* @__PURE__ */ jsx23(
4013
+ /* @__PURE__ */ jsx29(
3569
4014
  WelcomeSlot,
3570
4015
  {
3571
4016
  config: welcome,
@@ -3574,7 +4019,7 @@ var Thread = ({
3574
4019
  Suggestions: SuggestionsSlot
3575
4020
  }
3576
4021
  ),
3577
- /* @__PURE__ */ jsx23(
4022
+ /* @__PURE__ */ jsx29(
3578
4023
  ThreadPrimitive.Messages,
3579
4024
  {
3580
4025
  components: {
@@ -3584,14 +4029,14 @@ var Thread = ({
3584
4029
  }
3585
4030
  }
3586
4031
  ),
3587
- /* @__PURE__ */ jsx23(
4032
+ /* @__PURE__ */ jsx29(
3588
4033
  ThreadPrimitive.ViewportFooter,
3589
4034
  {
3590
4035
  className: cn(
3591
4036
  "aui-thread-viewport-footer sticky bottom-0 z-10 mt-auto w-full isolate pt-2",
3592
4037
  isPanel ? "bg-card pb-2" : "bg-background pb-4 md:pb-6"
3593
4038
  ),
3594
- children: /* @__PURE__ */ jsxs13(
4039
+ children: /* @__PURE__ */ jsxs18(
3595
4040
  "div",
3596
4041
  {
3597
4042
  className: cn(
@@ -3599,8 +4044,8 @@ var Thread = ({
3599
4044
  isPanel ? "gap-2" : "gap-4"
3600
4045
  ),
3601
4046
  children: [
3602
- /* @__PURE__ */ jsx23(ScrollToBottomSlot, {}),
3603
- /* @__PURE__ */ jsx23(ComposerSlot, { placeholder })
4047
+ /* @__PURE__ */ jsx29(ScrollToBottomSlot, {}),
4048
+ /* @__PURE__ */ jsx29(ComposerSlot, { placeholder })
3604
4049
  ]
3605
4050
  }
3606
4051
  )
@@ -3615,13 +4060,13 @@ var Thread = ({
3615
4060
  ) });
3616
4061
  };
3617
4062
  var ThreadScrollToBottom = () => {
3618
- return /* @__PURE__ */ jsx23(ThreadPrimitive.ScrollToBottom, { asChild: true, children: /* @__PURE__ */ jsx23(
4063
+ return /* @__PURE__ */ jsx29(ThreadPrimitive.ScrollToBottom, { asChild: true, children: /* @__PURE__ */ jsx29(
3619
4064
  TooltipIconButton,
3620
4065
  {
3621
4066
  tooltip: "Scroll to bottom",
3622
4067
  variant: "secondary",
3623
4068
  className: "aui-thread-scroll-to-bottom absolute -top-12 z-10 self-center disabled:invisible",
3624
- children: /* @__PURE__ */ jsx23(ArrowDownIcon, { className: "size-4" })
4069
+ children: /* @__PURE__ */ jsx29(ArrowDownIcon, { className: "size-4" })
3625
4070
  }
3626
4071
  ) });
3627
4072
  };
@@ -3660,8 +4105,8 @@ var ThreadWelcome = ({
3660
4105
  if (!isEmpty) return null;
3661
4106
  const defaultHeading = isPanel ? "Ask about this page" : "How can I help you today?";
3662
4107
  const defaultSubheading = isPanel ? "The assistant can use dashboard context from your app." : "Send a message to start a conversation.";
3663
- return /* @__PURE__ */ jsxs13("div", { className: "aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col", children: [
3664
- /* @__PURE__ */ jsx23("div", { className: "aui-thread-welcome-center flex w-full grow flex-col items-center justify-center", children: /* @__PURE__ */ jsxs13(
4108
+ return /* @__PURE__ */ jsxs18("div", { className: "aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col", children: [
4109
+ /* @__PURE__ */ jsx29("div", { className: "aui-thread-welcome-center flex w-full grow flex-col items-center justify-center", children: /* @__PURE__ */ jsxs18(
3665
4110
  motion3.div,
3666
4111
  {
3667
4112
  className: cn(
@@ -3672,8 +4117,8 @@ var ThreadWelcome = ({
3672
4117
  initial: "initial",
3673
4118
  animate: "animate",
3674
4119
  children: [
3675
- config?.icon && /* @__PURE__ */ jsx23(motion3.div, { variants: welcomeIcon, className: isPanel ? "mb-3" : "mb-5", children: config.icon }),
3676
- /* @__PURE__ */ jsx23(
4120
+ config?.icon && /* @__PURE__ */ jsx29(motion3.div, { variants: welcomeIcon, className: isPanel ? "mb-3" : "mb-5", children: config.icon }),
4121
+ /* @__PURE__ */ jsx29(
3677
4122
  motion3.h1,
3678
4123
  {
3679
4124
  variants: welcomeItem,
@@ -3684,7 +4129,7 @@ var ThreadWelcome = ({
3684
4129
  children: config?.heading ?? defaultHeading
3685
4130
  }
3686
4131
  ),
3687
- /* @__PURE__ */ jsx23(
4132
+ /* @__PURE__ */ jsx29(
3688
4133
  motion3.p,
3689
4134
  {
3690
4135
  variants: welcomeItem,
@@ -3695,15 +4140,15 @@ var ThreadWelcome = ({
3695
4140
  ]
3696
4141
  }
3697
4142
  ) }),
3698
- showWelcomeSuggestions && suggestions ? /* @__PURE__ */ jsx23("div", { className: "aui-thread-welcome-suggestions mx-auto w-full max-w-(--thread-max-width) px-2", children: /* @__PURE__ */ jsx23(SuggestionsSlot, { suggestions }) }) : null
4143
+ showWelcomeSuggestions && suggestions ? /* @__PURE__ */ jsx29("div", { className: "aui-thread-welcome-suggestions mx-auto w-full max-w-(--thread-max-width) px-2", children: /* @__PURE__ */ jsx29(SuggestionsSlot, { suggestions }) }) : null
3699
4144
  ] });
3700
4145
  };
3701
4146
  var MessageError = () => {
3702
- return /* @__PURE__ */ jsx23(MessagePrimitive2.Error, { children: /* @__PURE__ */ jsx23(ErrorPrimitive.Root, { className: "aui-message-error-root mt-2 rounded-md border border-destructive bg-destructive/10 p-3 text-destructive text-sm", children: /* @__PURE__ */ jsx23(ErrorPrimitive.Message, { className: "aui-message-error-message line-clamp-2" }) }) });
4147
+ return /* @__PURE__ */ jsx29(MessagePrimitive2.Error, { children: /* @__PURE__ */ jsx29(ErrorPrimitive.Root, { className: "aui-message-error-root mt-2 rounded-md border border-destructive bg-destructive/10 p-3 text-destructive text-sm", children: /* @__PURE__ */ jsx29(ErrorPrimitive.Message, { className: "aui-message-error-message line-clamp-2" }) }) });
3703
4148
  };
3704
4149
  var AssistantMessage = () => {
3705
4150
  const isPanel = useThreadVariant() === "panel";
3706
- return /* @__PURE__ */ jsxs13(
4151
+ return /* @__PURE__ */ jsxs18(
3707
4152
  MessagePrimitive2.Root,
3708
4153
  {
3709
4154
  className: cn(
@@ -3712,7 +4157,7 @@ var AssistantMessage = () => {
3712
4157
  ),
3713
4158
  "data-role": "assistant",
3714
4159
  children: [
3715
- /* @__PURE__ */ jsxs13(
4160
+ /* @__PURE__ */ jsxs18(
3716
4161
  "div",
3717
4162
  {
3718
4163
  className: cn(
@@ -3720,7 +4165,7 @@ var AssistantMessage = () => {
3720
4165
  isPanel ? "px-1 text-sm" : "px-2"
3721
4166
  ),
3722
4167
  children: [
3723
- /* @__PURE__ */ jsx23(
4168
+ /* @__PURE__ */ jsx29(
3724
4169
  MessagePrimitive2.Parts,
3725
4170
  {
3726
4171
  components: {
@@ -3731,11 +4176,11 @@ var AssistantMessage = () => {
3731
4176
  }
3732
4177
  }
3733
4178
  ),
3734
- /* @__PURE__ */ jsx23(MessageError, {})
4179
+ /* @__PURE__ */ jsx29(MessageError, {})
3735
4180
  ]
3736
4181
  }
3737
4182
  ),
3738
- /* @__PURE__ */ jsx23("div", { className: "aui-assistant-message-footer mt-1 mb-3 ml-1 flex", children: /* @__PURE__ */ jsx23(AssistantActionBar, {}) })
4183
+ /* @__PURE__ */ jsx29("div", { className: "aui-assistant-message-footer mt-1 mb-3 ml-1 flex", children: /* @__PURE__ */ jsx29(AssistantActionBar, {}) })
3739
4184
  ]
3740
4185
  }
3741
4186
  );
@@ -3748,36 +4193,36 @@ var ASSISTANT_ACTION_ICON_CLASS = cn(
3748
4193
  "[&>span:first-child]:group-hover/tbv2:bg-ghost-fill-hover"
3749
4194
  );
3750
4195
  var AssistantActionBar = () => {
3751
- return /* @__PURE__ */ jsxs13(
4196
+ return /* @__PURE__ */ jsxs18(
3752
4197
  ActionBarPrimitive.Root,
3753
4198
  {
3754
4199
  hideWhenRunning: true,
3755
4200
  autohide: "never",
3756
4201
  className: "aui-assistant-action-bar-root flex items-center gap-0 bg-transparent px-0 py-0.5 text-muted-foreground/60",
3757
4202
  children: [
3758
- /* @__PURE__ */ jsx23(ActionBarPrimitive.Copy, { asChild: true, children: /* @__PURE__ */ jsxs13(
4203
+ /* @__PURE__ */ jsx29(ActionBarPrimitive.Copy, { asChild: true, children: /* @__PURE__ */ jsxs18(
3759
4204
  TooltipIconButton,
3760
4205
  {
3761
4206
  tooltip: "Copy",
3762
4207
  variant: "ghost",
3763
4208
  className: ASSISTANT_ACTION_ICON_CLASS,
3764
4209
  children: [
3765
- /* @__PURE__ */ jsx23(AuiIf2, { condition: (s) => s.message.isCopied, children: /* @__PURE__ */ jsx23(CheckIcon3, { className: "size-3" }) }),
3766
- /* @__PURE__ */ jsx23(AuiIf2, { condition: (s) => !s.message.isCopied, children: /* @__PURE__ */ jsx23(CopyIcon2, { className: "size-3" }) })
4210
+ /* @__PURE__ */ jsx29(AuiIf2, { condition: (s) => s.message.isCopied, children: /* @__PURE__ */ jsx29(CheckIcon3, { className: "size-3" }) }),
4211
+ /* @__PURE__ */ jsx29(AuiIf2, { condition: (s) => !s.message.isCopied, children: /* @__PURE__ */ jsx29(CopyIcon2, { className: "size-3" }) })
3767
4212
  ]
3768
4213
  }
3769
4214
  ) }),
3770
- /* @__PURE__ */ jsx23(ActionBarPrimitive.Reload, { asChild: true, children: /* @__PURE__ */ jsx23(
4215
+ /* @__PURE__ */ jsx29(ActionBarPrimitive.Reload, { asChild: true, children: /* @__PURE__ */ jsx29(
3771
4216
  TooltipIconButton,
3772
4217
  {
3773
4218
  tooltip: "Regenerate",
3774
4219
  variant: "ghost",
3775
4220
  className: ASSISTANT_ACTION_ICON_CLASS,
3776
- children: /* @__PURE__ */ jsx23(RefreshCwIcon, { className: "size-3" })
4221
+ children: /* @__PURE__ */ jsx29(RefreshCwIcon, { className: "size-3" })
3777
4222
  }
3778
4223
  ) }),
3779
- /* @__PURE__ */ jsxs13(ActionBarMorePrimitive.Root, { children: [
3780
- /* @__PURE__ */ jsx23(ActionBarMorePrimitive.Trigger, { asChild: true, children: /* @__PURE__ */ jsx23(
4224
+ /* @__PURE__ */ jsxs18(ActionBarMorePrimitive.Root, { children: [
4225
+ /* @__PURE__ */ jsx29(ActionBarMorePrimitive.Trigger, { asChild: true, children: /* @__PURE__ */ jsx29(
3781
4226
  TooltipIconButton,
3782
4227
  {
3783
4228
  tooltip: "More",
@@ -3786,17 +4231,17 @@ var AssistantActionBar = () => {
3786
4231
  ASSISTANT_ACTION_ICON_CLASS,
3787
4232
  "data-[state=open]:text-muted-foreground/80"
3788
4233
  ),
3789
- children: /* @__PURE__ */ jsx23(MoreHorizontalIcon, { className: "size-3" })
4234
+ children: /* @__PURE__ */ jsx29(MoreHorizontalIcon, { className: "size-3" })
3790
4235
  }
3791
4236
  ) }),
3792
- /* @__PURE__ */ jsx23(
4237
+ /* @__PURE__ */ jsx29(
3793
4238
  ActionBarMorePrimitive.Content,
3794
4239
  {
3795
4240
  side: "bottom",
3796
4241
  align: "start",
3797
4242
  className: "aui-action-bar-more-content z-50 min-w-36 overflow-hidden rounded-lg border border-border bg-popover p-1 text-popover-foreground shadow-card-elevated",
3798
- children: /* @__PURE__ */ jsx23(ActionBarPrimitive.ExportMarkdown, { asChild: true, children: /* @__PURE__ */ jsxs13(ActionBarMorePrimitive.Item, { className: "aui-action-bar-more-item flex cursor-pointer select-none items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-none hover:bg-muted focus:bg-muted", children: [
3799
- /* @__PURE__ */ jsx23(DownloadIcon, { className: "size-4 shrink-0" }),
4243
+ children: /* @__PURE__ */ jsx29(ActionBarPrimitive.ExportMarkdown, { asChild: true, children: /* @__PURE__ */ jsxs18(ActionBarMorePrimitive.Item, { className: "aui-action-bar-more-item flex cursor-pointer select-none items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-none hover:bg-muted focus:bg-muted", children: [
4244
+ /* @__PURE__ */ jsx29(DownloadIcon, { className: "size-4 shrink-0" }),
3800
4245
  "Export as Markdown"
3801
4246
  ] }) })
3802
4247
  }
@@ -3807,11 +4252,11 @@ var AssistantActionBar = () => {
3807
4252
  );
3808
4253
  };
3809
4254
  var UserMessageText = () => {
3810
- return /* @__PURE__ */ jsx23("span", { className: "whitespace-pre-wrap", children: /* @__PURE__ */ jsx23(MessagePartPrimitive.Text, { smooth: false }) });
4255
+ return /* @__PURE__ */ jsx29("span", { className: "whitespace-pre-wrap", children: /* @__PURE__ */ jsx29(MessagePartPrimitive.Text, { smooth: false }) });
3811
4256
  };
3812
4257
  var UserMessage = () => {
3813
4258
  const isPanel = useThreadVariant() === "panel";
3814
- return /* @__PURE__ */ jsxs13(
4259
+ return /* @__PURE__ */ jsxs18(
3815
4260
  MessagePrimitive2.Root,
3816
4261
  {
3817
4262
  className: cn(
@@ -3820,8 +4265,8 @@ var UserMessage = () => {
3820
4265
  ),
3821
4266
  "data-role": "user",
3822
4267
  children: [
3823
- /* @__PURE__ */ jsx23(UserMessageAttachments, {}),
3824
- /* @__PURE__ */ jsxs13(
4268
+ /* @__PURE__ */ jsx29(UserMessageAttachments, {}),
4269
+ /* @__PURE__ */ jsxs18(
3825
4270
  motion3.div,
3826
4271
  {
3827
4272
  className: cn(
@@ -3832,8 +4277,8 @@ var UserMessage = () => {
3832
4277
  animate: { opacity: 1, y: 0, scale: 1 },
3833
4278
  transition: { duration: 0.65, ease: luxuryEase },
3834
4279
  children: [
3835
- /* @__PURE__ */ jsx23(MessagePrimitive2.Parts, { components: { Text: UserMessageText } }),
3836
- /* @__PURE__ */ jsx23("div", { className: "aui-user-action-bar-wrapper absolute top-1/2 left-0 -translate-x-full -translate-y-1/2 pr-2", children: /* @__PURE__ */ jsx23(UserActionBar, {}) })
4280
+ /* @__PURE__ */ jsx29(MessagePrimitive2.Parts, { components: { Text: UserMessageText } }),
4281
+ /* @__PURE__ */ jsx29("div", { className: "aui-user-action-bar-wrapper absolute top-1/2 left-0 -translate-x-full -translate-y-1/2 pr-2", children: /* @__PURE__ */ jsx29(UserActionBar, {}) })
3837
4282
  ]
3838
4283
  }
3839
4284
  )
@@ -3842,42 +4287,42 @@ var UserMessage = () => {
3842
4287
  );
3843
4288
  };
3844
4289
  var UserActionBar = () => {
3845
- return /* @__PURE__ */ jsx23(
4290
+ return /* @__PURE__ */ jsx29(
3846
4291
  ActionBarPrimitive.Root,
3847
4292
  {
3848
4293
  hideWhenRunning: true,
3849
4294
  autohide: "always",
3850
4295
  className: "aui-user-action-bar-root flex flex-col items-end",
3851
- children: /* @__PURE__ */ jsx23(ActionBarPrimitive.Edit, { asChild: true, children: /* @__PURE__ */ jsx23(
4296
+ children: /* @__PURE__ */ jsx29(ActionBarPrimitive.Edit, { asChild: true, children: /* @__PURE__ */ jsx29(
3852
4297
  TooltipIconButton,
3853
4298
  {
3854
4299
  tooltip: "Edit",
3855
4300
  variant: "ghost",
3856
4301
  className: ASSISTANT_ACTION_ICON_CLASS,
3857
- children: /* @__PURE__ */ jsx23(PencilIcon, { className: "size-3" })
4302
+ children: /* @__PURE__ */ jsx29(PencilIcon, { className: "size-3" })
3858
4303
  }
3859
4304
  ) })
3860
4305
  }
3861
4306
  );
3862
4307
  };
3863
4308
  var EditComposer = () => {
3864
- return /* @__PURE__ */ jsx23(MessagePrimitive2.Root, { className: "aui-edit-composer-wrapper mx-auto flex w-full max-w-(--thread-max-width) flex-col px-2 py-3", children: /* @__PURE__ */ jsxs13(ComposerPrimitive3.Root, { className: "aui-edit-composer-root ml-auto flex w-full max-w-[85%] flex-col rounded-2xl bg-muted", children: [
3865
- /* @__PURE__ */ jsx23(
4309
+ return /* @__PURE__ */ jsx29(MessagePrimitive2.Root, { className: "aui-edit-composer-wrapper mx-auto flex w-full max-w-(--thread-max-width) flex-col px-2 py-3", children: /* @__PURE__ */ jsxs18(ComposerPrimitive3.Root, { className: "aui-edit-composer-root ml-auto flex w-full max-w-[85%] flex-col rounded-2xl bg-muted", children: [
4310
+ /* @__PURE__ */ jsx29(
3866
4311
  ComposerPrimitive3.Input,
3867
4312
  {
3868
4313
  className: "aui-edit-composer-input min-h-14 w-full resize-none bg-transparent p-4 text-foreground text-sm outline-none",
3869
4314
  autoFocus: true
3870
4315
  }
3871
4316
  ),
3872
- /* @__PURE__ */ jsxs13("div", { className: "aui-edit-composer-footer mx-3 mb-3 flex items-center gap-2 self-end", children: [
3873
- /* @__PURE__ */ jsx23(ComposerPrimitive3.Cancel, { asChild: true, children: /* @__PURE__ */ jsx23(TimbalV2Button, { variant: "ghost", size: "sm", children: "Cancel" }) }),
3874
- /* @__PURE__ */ jsx23(ComposerPrimitive3.Send, { asChild: true, children: /* @__PURE__ */ jsx23(TimbalV2Button, { variant: "primary", size: "sm", children: "Update" }) })
4317
+ /* @__PURE__ */ jsxs18("div", { className: "aui-edit-composer-footer mx-3 mb-3 flex items-center gap-2 self-end", children: [
4318
+ /* @__PURE__ */ jsx29(ComposerPrimitive3.Cancel, { asChild: true, children: /* @__PURE__ */ jsx29(TimbalV2Button, { variant: "ghost", size: "sm", children: "Cancel" }) }),
4319
+ /* @__PURE__ */ jsx29(ComposerPrimitive3.Send, { asChild: true, children: /* @__PURE__ */ jsx29(TimbalV2Button, { variant: "primary", size: "sm", children: "Update" }) })
3875
4320
  ] })
3876
4321
  ] }) });
3877
4322
  };
3878
4323
 
3879
4324
  // src/chat/chat.tsx
3880
- import { jsx as jsx24 } from "react/jsx-runtime";
4325
+ import { jsx as jsx30 } from "react/jsx-runtime";
3881
4326
  function TimbalChat({
3882
4327
  workforceId,
3883
4328
  baseUrl,
@@ -3888,7 +4333,7 @@ function TimbalChat({
3888
4333
  debug,
3889
4334
  ...threadProps
3890
4335
  }) {
3891
- return /* @__PURE__ */ jsx24(
4336
+ return /* @__PURE__ */ jsx30(
3892
4337
  TimbalRuntimeProvider,
3893
4338
  {
3894
4339
  workforceId,
@@ -3898,7 +4343,7 @@ function TimbalChat({
3898
4343
  attachmentsUploadUrl,
3899
4344
  attachmentsAccept,
3900
4345
  debug,
3901
- children: /* @__PURE__ */ jsx24(Thread, { ...threadProps })
4346
+ children: /* @__PURE__ */ jsx30(Thread, { ...threadProps })
3902
4347
  }
3903
4348
  );
3904
4349
  }
@@ -3922,8 +4367,15 @@ export {
3922
4367
  toNum,
3923
4368
  monotoneLinePath,
3924
4369
  monotoneAreaPath,
4370
+ resolveChartMargin,
4371
+ flushBarCategoryGap,
4372
+ flushLineAreaEdgeToEdge,
4373
+ resolveTooltipCategory,
3925
4374
  CHART_PALETTE,
3926
4375
  LineAreaChart,
4376
+ PieChart,
4377
+ RadialChart,
4378
+ RadarChart,
3927
4379
  ArtifactCard,
3928
4380
  ChartArtifactView,
3929
4381
  QuestionArtifactView,