@timbal-ai/timbal-react 0.6.0 → 0.7.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 (44) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +24 -5
  3. package/dist/app.cjs +2282 -738
  4. package/dist/app.d.cts +4 -1
  5. package/dist/app.d.ts +4 -1
  6. package/dist/app.esm.js +58 -5
  7. package/dist/button-CIKzUrJI.d.cts +18 -0
  8. package/dist/button-CIKzUrJI.d.ts +18 -0
  9. package/dist/chart-artifact-BFDz8Tf9.d.ts +756 -0
  10. package/dist/chart-artifact-bWUa-iSG.d.cts +756 -0
  11. package/dist/chat.cjs +872 -562
  12. package/dist/chat.d.cts +2 -2
  13. package/dist/chat.d.ts +2 -2
  14. package/dist/chat.esm.js +3 -3
  15. package/dist/{chunk-4TCJQSIX.esm.js → chunk-2XZ3S4OP.esm.js} +14 -3
  16. package/dist/chunk-533MK5EA.esm.js +2294 -0
  17. package/dist/{chunk-OVHR7J3J.esm.js → chunk-7O5VY3TP.esm.js} +38 -11
  18. package/dist/{chunk-WLTW56MC.esm.js → chunk-N3PYVTY5.esm.js} +2 -2
  19. package/dist/{chunk-IYENDIRY.esm.js → chunk-TDIJHV4I.esm.js} +1 -1
  20. package/dist/{chunk-YJQLLFKP.esm.js → chunk-TLUF2RUL.esm.js} +813 -507
  21. package/dist/{chunk-OFHLFNJH.esm.js → chunk-Z27GBSOT.esm.js} +3 -1
  22. package/dist/index.cjs +2587 -1016
  23. package/dist/index.d.cts +6 -5
  24. package/dist/index.d.ts +6 -5
  25. package/dist/index.esm.js +57 -7
  26. package/dist/{layout-CQWngNQ7.d.ts → layout-BTJyU8wd.d.ts} +1 -1
  27. package/dist/{layout-B9VayJhZ.d.cts → layout-C2G-FcER.d.cts} +1 -1
  28. package/dist/studio.cjs +1127 -788
  29. package/dist/studio.d.cts +1 -1
  30. package/dist/studio.d.ts +1 -1
  31. package/dist/studio.esm.js +6 -6
  32. package/dist/{timbal-v2-button-F4-z7m33.d.ts → timbal-v2-button-CNfdwGq4.d.cts} +1 -1
  33. package/dist/{timbal-v2-button-F4-z7m33.d.cts → timbal-v2-button-CNfdwGq4.d.ts} +1 -1
  34. package/dist/ui.cjs +12 -3
  35. package/dist/ui.d.cts +5 -16
  36. package/dist/ui.d.ts +5 -16
  37. package/dist/ui.esm.js +2 -2
  38. package/dist/{welcome-BOizSp5h.d.ts → welcome-BBmB3tl7.d.ts} +4 -3
  39. package/dist/{welcome--80i_O0p.d.cts → welcome-C89Mgdaw.d.cts} +4 -3
  40. package/package.json +2 -1
  41. package/vite/local-dev.mjs +91 -5
  42. package/dist/chart-artifact-C71dk4xI.d.ts +0 -329
  43. package/dist/chart-artifact-CPEpOmtV.d.cts +0 -329
  44. package/dist/chunk-M4V6Q6XO.esm.js +0 -1082
@@ -18,7 +18,7 @@ import {
18
18
  TooltipProvider,
19
19
  TooltipTrigger,
20
20
  cn
21
- } from "./chunk-4TCJQSIX.esm.js";
21
+ } from "./chunk-2XZ3S4OP.esm.js";
22
22
 
23
23
  // src/chat/tooltip-icon-button.tsx
24
24
  import { forwardRef } from "react";
@@ -202,280 +202,612 @@ var ComposerAddAttachment = () => {
202
202
  ) });
203
203
  };
204
204
 
205
- // src/artifacts/artifact-card.tsx
206
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
207
- var ArtifactCard = ({ title, kind, className, bodyClassName, toolbar, children }) => {
208
- const hasHeader = Boolean(title || toolbar);
209
- return /* @__PURE__ */ jsxs3(
210
- "div",
211
- {
212
- className: cn(
213
- "aui-artifact-root my-3 overflow-hidden rounded-xl border border-border/60 bg-background shadow-sm",
214
- className
215
- ),
216
- "data-artifact-kind": kind,
217
- children: [
218
- hasHeader && /* @__PURE__ */ jsxs3("div", { className: "aui-artifact-header flex items-center gap-2 border-b border-border/40 bg-muted/30 px-3 py-1.5", children: [
219
- title && /* @__PURE__ */ jsx3("span", { className: "aui-artifact-title flex-1 truncate text-xs font-semibold text-foreground/80", children: title }),
220
- !title && /* @__PURE__ */ jsx3("span", { className: "flex-1" }),
221
- toolbar
222
- ] }),
223
- /* @__PURE__ */ jsx3("div", { className: cn("aui-artifact-body", bodyClassName), children })
224
- ]
225
- }
226
- );
227
- };
205
+ // src/charts/line-area-chart.tsx
206
+ import { useEffect as useEffect3, useId, useMemo, useState as useState3 } from "react";
228
207
 
229
- // src/artifacts/chart-artifact.tsx
230
- import { useMemo } from "react";
231
- import { Fragment, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
232
- var ChartArtifactView = ({
233
- artifact
234
- }) => {
235
- const { type: _t, chartType = "bar", data = [] } = artifact;
236
- const xKey = artifact.xKey ?? inferXKey(data);
237
- const dataKeys = useMemo(() => {
238
- if (Array.isArray(artifact.dataKey)) return artifact.dataKey;
239
- if (typeof artifact.dataKey === "string") return [artifact.dataKey];
240
- return inferDataKeys(data, xKey);
241
- }, [artifact.dataKey, data, xKey]);
242
- return /* @__PURE__ */ jsx4(ArtifactCard, { title: artifact.title, kind: "chart", children: /* @__PURE__ */ jsxs4("div", { className: "aui-artifact-chart p-3", children: [
243
- /* @__PURE__ */ jsx4(
244
- ChartSvg,
245
- {
246
- chartType,
247
- data,
248
- xKey,
249
- dataKeys,
250
- unit: artifact.unit
251
- }
252
- ),
253
- dataKeys.length > 1 && /* @__PURE__ */ jsx4(Legend, { dataKeys })
254
- ] }) });
255
- };
256
- var COLORS = [
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 };
224
+ }
225
+
226
+ // src/charts/geometry.ts
227
+ function toNum(value) {
228
+ const n = typeof value === "number" ? value : Number(value);
229
+ return Number.isFinite(n) ? n : 0;
230
+ }
231
+ function monotoneLinePath(points) {
232
+ const n = points.length;
233
+ if (n === 0) return "";
234
+ if (n === 1) return `M ${points[0].x},${points[0].y}`;
235
+ if (n === 2) {
236
+ return `M ${points[0].x},${points[0].y} L ${points[1].x},${points[1].y}`;
237
+ }
238
+ const tangents = monotoneTangents(points);
239
+ let d = `M ${points[0].x},${points[0].y}`;
240
+ for (let i = 0; i < n - 1; i++) {
241
+ const p0 = points[i];
242
+ const p1 = points[i + 1];
243
+ const dx = (p1.x - p0.x) / 3;
244
+ const c1x = p0.x + dx;
245
+ const c1y = p0.y + dx * tangents[i];
246
+ const c2x = p1.x - dx;
247
+ const c2y = p1.y - dx * tangents[i + 1];
248
+ d += ` C ${c1x},${c1y} ${c2x},${c2y} ${p1.x},${p1.y}`;
249
+ }
250
+ return d;
251
+ }
252
+ function monotoneAreaPath(points, baseY) {
253
+ if (points.length === 0) return "";
254
+ const line = monotoneLinePath(points);
255
+ const last = points[points.length - 1];
256
+ const first = points[0];
257
+ return `${line} L ${last.x},${baseY} L ${first.x},${baseY} Z`;
258
+ }
259
+ function monotoneTangents(points) {
260
+ const n = points.length;
261
+ const slopes = new Array(n - 1);
262
+ for (let i = 0; i < n - 1; i++) {
263
+ const dx = points[i + 1].x - points[i].x || 1;
264
+ slopes[i] = (points[i + 1].y - points[i].y) / dx;
265
+ }
266
+ const tangents = new Array(n);
267
+ tangents[0] = slopes[0];
268
+ tangents[n - 1] = slopes[n - 2];
269
+ for (let i = 1; i < n - 1; i++) {
270
+ const s0 = slopes[i - 1];
271
+ const s1 = slopes[i];
272
+ if (s0 * s1 <= 0) {
273
+ tangents[i] = 0;
274
+ } else {
275
+ tangents[i] = (s0 + s1) / 2;
276
+ }
277
+ }
278
+ for (let i = 0; i < n - 1; i++) {
279
+ const s = slopes[i];
280
+ if (s === 0) {
281
+ tangents[i] = 0;
282
+ tangents[i + 1] = 0;
283
+ continue;
284
+ }
285
+ const a = tangents[i] / s;
286
+ const b = tangents[i + 1] / s;
287
+ const h = Math.hypot(a, b);
288
+ if (h > 3) {
289
+ const t = 3 / h;
290
+ tangents[i] = t * a * s;
291
+ tangents[i + 1] = t * b * s;
292
+ }
293
+ }
294
+ return tangents;
295
+ }
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
+ function round(v) {
318
+ return Math.round(v * 1e6) / 1e6;
319
+ }
320
+ function formatCompact(value, unit) {
321
+ const abs = Math.abs(value);
322
+ let s;
323
+ if (abs >= 1e6) s = `${round(value / 1e6)}M`;
324
+ else if (abs >= 1e3) s = `${round(value / 1e3)}k`;
325
+ else s = String(round(value));
326
+ return unit ? `${s}${unit}` : s;
327
+ }
328
+
329
+ // src/charts/line-area-chart.tsx
330
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
331
+ var CHART_PALETTE = [
257
332
  "var(--primary, #6366f1)",
258
- "#22c55e",
333
+ "#10b981",
259
334
  "#f59e0b",
260
- "#ef4444",
261
335
  "#06b6d4",
262
- "#a855f7"
336
+ "#a855f7",
337
+ "#ef4444"
263
338
  ];
264
- var W = 600;
265
- var H = 240;
266
- var PAD = { top: 12, right: 16, bottom: 28, left: 36 };
267
- var ChartSvg = ({ chartType, data, xKey, dataKeys, unit }) => {
268
- if (data.length === 0 || dataKeys.length === 0) {
269
- return /* @__PURE__ */ jsx4(EmptyState, {});
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
+ var LineAreaChart = ({
342
+ data = [],
343
+ xKey: xKeyProp,
344
+ series: seriesProp,
345
+ variant = "area",
346
+ height = 240,
347
+ unit,
348
+ yMax,
349
+ layout = "default",
350
+ showGrid = true,
351
+ showXAxis: showXAxisProp,
352
+ showYAxis: showYAxisProp,
353
+ showLegend: showLegendProp,
354
+ showTooltip = true,
355
+ formatValue,
356
+ formatX,
357
+ className,
358
+ ariaLabel = "Chart"
359
+ }) => {
360
+ const uid = useId();
361
+ const { ref, width } = useChartWidth();
362
+ const [active, setActive] = useState3(null);
363
+ const [grown, setGrown] = useState3(false);
364
+ 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]);
393
+ if (data.length === 0 || series.length === 0) {
394
+ return /* @__PURE__ */ jsx3(ChartEmpty, { className, height });
270
395
  }
271
- if (chartType === "pie") {
272
- return /* @__PURE__ */ jsx4(PieChart, { data, xKey, dataKey: dataKeys[0] });
273
- }
274
- const innerW = W - PAD.left - PAD.right;
275
- const innerH = H - PAD.top - PAD.bottom;
276
- const all = dataKeys.flatMap((k) => data.map((d) => toNum(d[k])));
277
- const maxV = Math.max(0, ...all);
278
- const minV = Math.min(0, ...all);
279
- const range = maxV - minV || 1;
280
- const yScale = (v) => PAD.top + innerH - (v - minV) / range * innerH;
396
+ const yScale = (v) => pad.top + innerH - (v - minV) / (maxV - minV || 1) * innerH;
281
397
  const xCount = data.length;
282
398
  const xStep = xCount > 1 ? innerW / (xCount - 1) : innerW;
283
- const xPos = (i) => chartType === "bar" ? PAD.left + innerW * (i + 0.5) / xCount : PAD.left + i * xStep;
284
- const ticks = niceTicks(minV, maxV);
285
- return /* @__PURE__ */ jsxs4(
286
- "svg",
287
- {
288
- viewBox: `0 0 ${W} ${H}`,
289
- className: "aui-artifact-chart-svg w-full",
290
- role: "img",
291
- "aria-label": "Chart",
292
- children: [
293
- ticks.map((t, i) => /* @__PURE__ */ jsxs4("g", { children: [
294
- /* @__PURE__ */ jsx4(
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",
413
+ {
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",
423
+ {
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)" }
429
+ }
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",
439
+ {
440
+ x: pad.left,
441
+ y: pad.top,
442
+ width: innerW,
443
+ height: innerH,
444
+ fill: `url(#${uid}-gridfade)`
445
+ }
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(
295
467
  "line",
296
468
  {
297
- x1: PAD.left,
298
- x2: W - PAD.right,
469
+ x1: pad.left,
470
+ x2: width - pad.right,
299
471
  y1: yScale(t),
300
472
  y2: yScale(t),
301
473
  stroke: "currentColor",
302
- strokeOpacity: 0.08
303
- }
304
- ),
305
- /* @__PURE__ */ jsx4(
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(
306
481
  "text",
307
482
  {
308
- x: PAD.left - 6,
483
+ x: pad.left - 8,
309
484
  y: yScale(t),
310
485
  textAnchor: "end",
311
486
  dominantBaseline: "middle",
312
- className: "fill-muted-foreground text-[10px]",
313
- children: formatTick(t, unit)
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",
494
+ {
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",
555
+ {
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)
314
564
  }
315
565
  )
316
- ] }, i)),
317
- data.map((d, i) => /* @__PURE__ */ jsx4(
318
- "text",
319
- {
320
- x: xPos(i),
321
- y: H - PAD.bottom + 14,
322
- textAnchor: "middle",
323
- className: "fill-muted-foreground text-[10px]",
324
- children: String(d[xKey] ?? i)
325
- },
326
- i
327
- )),
328
- chartType === "bar" && renderBars({ data, dataKeys, xCount, xPos, yScale, minV, innerW }),
329
- chartType === "line" && dataKeys.map((k, ki) => /* @__PURE__ */ jsx4(
330
- Polyline,
331
- {
332
- data,
333
- dataKey: k,
334
- xPos,
335
- yScale,
336
- color: COLORS[ki % COLORS.length]
337
- },
338
- k
339
- )),
340
- chartType === "area" && dataKeys.map((k, ki) => /* @__PURE__ */ jsx4(
341
- Area,
342
- {
343
- data,
344
- dataKey: k,
345
- xPos,
346
- yScale,
347
- baseY: yScale(Math.max(0, minV)),
348
- color: COLORS[ki % COLORS.length]
349
- },
350
- k
351
- ))
352
- ]
353
- }
354
- );
566
+ ]
567
+ }
568
+ ),
569
+ showTooltip && active != null && /* @__PURE__ */ jsx3(
570
+ ChartTooltip,
571
+ {
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
+ }))
580
+ }
581
+ ),
582
+ showLegend ? /* @__PURE__ */ jsx3(ChartLegend, { series }) : null
583
+ ] });
355
584
  };
356
585
  function renderBars(args) {
357
- const { data, dataKeys, xCount, xPos, yScale, minV, innerW } = args;
358
- const groupWidth = innerW / xCount * 0.7;
359
- const barWidth = groupWidth / dataKeys.length;
360
- const baseY = yScale(Math.max(0, minV));
361
- return dataKeys.flatMap(
362
- (k, ki) => data.map((d, i) => {
363
- const v = toNum(d[k]);
364
- const y = yScale(v);
365
- const x = xPos(i) - groupWidth / 2 + ki * barWidth;
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;
366
594
  const top = Math.min(y, baseY);
367
- const height = Math.abs(y - baseY);
368
- return /* @__PURE__ */ jsx4(
595
+ const h = Math.max(1, Math.abs(y - baseY));
596
+ return /* @__PURE__ */ jsx3(
369
597
  "rect",
370
598
  {
371
599
  x,
372
600
  y: top,
373
601
  width: Math.max(1, barWidth - 2),
374
- height: Math.max(1, height),
375
- rx: 2,
376
- fill: COLORS[ki % COLORS.length]
602
+ height: h,
603
+ rx: 3,
604
+ fill: color
377
605
  },
378
- `${k}-${i}`
606
+ `${s.dataKey}-${i}`
379
607
  );
380
608
  })
381
609
  );
382
610
  }
383
- var Polyline = ({ data, dataKey, xPos, yScale, color }) => {
384
- const points = data.map((d, i) => `${xPos(i)},${yScale(toNum(d[dataKey]))}`).join(" ");
385
- return /* @__PURE__ */ jsx4(
386
- "polyline",
611
+ var ChartTooltip = ({ x, width, title, rows }) => {
612
+ const flip = x > width - 160;
613
+ return /* @__PURE__ */ jsxs3(
614
+ "div",
387
615
  {
388
- points,
389
- fill: "none",
390
- stroke: color,
391
- strokeWidth: 2,
392
- strokeLinejoin: "round",
393
- strokeLinecap: "round"
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
+ ]
394
637
  }
395
638
  );
396
639
  };
397
- var Area = ({ data, dataKey, xPos, yScale, baseY, color }) => {
398
- if (data.length === 0) return null;
399
- const top = data.map((d, i) => `${xPos(i)},${yScale(toNum(d[dataKey]))}`).join(" ");
400
- const path = `M ${xPos(0)},${baseY} L ${top} L ${xPos(data.length - 1)},${baseY} Z`;
401
- return /* @__PURE__ */ jsxs4(Fragment, { children: [
402
- /* @__PURE__ */ jsx4("path", { d: path, fill: color, fillOpacity: 0.18 }),
403
- /* @__PURE__ */ jsx4(Polyline, { data, dataKey, xPos, yScale, color })
404
- ] });
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(
651
+ "div",
652
+ {
653
+ className: cn(
654
+ "flex w-full items-center justify-center text-xs text-muted-foreground",
655
+ className
656
+ ),
657
+ style: { height },
658
+ children: "No data yet"
659
+ }
660
+ );
661
+ function inferXKey(data) {
662
+ if (data.length === 0) return "x";
663
+ for (const k of Object.keys(data[0])) {
664
+ if (typeof data[0][k] !== "number") return k;
665
+ }
666
+ return Object.keys(data[0])[0] ?? "x";
667
+ }
668
+ function resolveSeries(seriesProp, data, xKey) {
669
+ if (seriesProp && seriesProp.length > 0) {
670
+ return seriesProp.map((s) => typeof s === "string" ? { dataKey: s } : s);
671
+ }
672
+ if (data.length === 0) return [];
673
+ return Object.keys(data[0]).filter((k) => k !== xKey && typeof data[0][k] === "number").map((dataKey) => ({ dataKey }));
674
+ }
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);
683
+ }
684
+
685
+ // src/artifacts/artifact-card.tsx
686
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
687
+ var ArtifactCard = ({ title, kind, className, bodyClassName, toolbar, children }) => {
688
+ const hasHeader = Boolean(title || toolbar);
689
+ return /* @__PURE__ */ jsxs4(
690
+ "div",
691
+ {
692
+ className: cn(
693
+ "aui-artifact-root my-3 overflow-hidden rounded-xl border border-border/60 bg-background shadow-sm",
694
+ className
695
+ ),
696
+ "data-artifact-kind": kind,
697
+ 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" }),
701
+ toolbar
702
+ ] }),
703
+ /* @__PURE__ */ jsx4("div", { className: cn("aui-artifact-body", bodyClassName), children })
704
+ ]
705
+ }
706
+ );
405
707
  };
406
- var PieChart = ({ data, xKey, dataKey }) => {
407
- const cx = W / 2;
408
- const cy = H / 2;
409
- const r = Math.min(W, H) / 2 - 16;
410
- const total = data.reduce((sum, d) => sum + toNum(d[dataKey]), 0) || 1;
411
- let acc = 0;
412
- return /* @__PURE__ */ jsx4(
413
- "svg",
708
+
709
+ // src/artifacts/chart-artifact.tsx
710
+ import { useMemo as useMemo2 } from "react";
711
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
712
+ var ChartArtifactView = ({
713
+ artifact,
714
+ embedded = false,
715
+ height = 300
716
+ }) => {
717
+ const plot = /* @__PURE__ */ jsx5(ChartArtifactPlot, { artifact, height });
718
+ if (embedded) {
719
+ return /* @__PURE__ */ jsx5("div", { className: "aui-artifact-chart w-full", children: plot });
720
+ }
721
+ return /* @__PURE__ */ jsx5(ArtifactCard, { title: artifact.title, kind: "chart", children: /* @__PURE__ */ jsx5("div", { className: "aui-artifact-chart pt-2", children: plot }) });
722
+ };
723
+ function ChartArtifactPlot({
724
+ artifact,
725
+ height
726
+ }) {
727
+ const { chartType = "bar", data = [] } = artifact;
728
+ const xKey = artifact.xKey ?? inferXKey2(data);
729
+ const series = useMemo2(() => {
730
+ 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" }) });
735
+ }
736
+ return /* @__PURE__ */ jsx5(
737
+ LineAreaChart,
414
738
  {
415
- viewBox: `0 0 ${W} ${H}`,
416
- className: "aui-artifact-chart-svg w-full",
417
- role: "img",
418
- "aria-label": "Pie chart",
419
- children: data.map((d, i) => {
420
- const value = toNum(d[dataKey]);
421
- const start = acc / total * Math.PI * 2;
422
- acc += value;
423
- const end = acc / total * Math.PI * 2;
424
- return /* @__PURE__ */ jsx4(
425
- PieSlice,
426
- {
427
- cx,
428
- cy,
429
- r,
430
- start,
431
- end,
432
- color: COLORS[i % COLORS.length],
433
- label: String(d[xKey] ?? i)
434
- },
435
- i
436
- );
437
- })
739
+ data,
740
+ xKey,
741
+ series,
742
+ layout: "flush",
743
+ height,
744
+ variant: chartType === "line" ? "line" : chartType === "area" ? "area" : "bar",
745
+ unit: artifact.unit,
746
+ ariaLabel: typeof artifact.title === "string" ? artifact.title : "Chart"
438
747
  }
439
748
  );
749
+ }
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
+ ] });
440
800
  };
441
- var PieSlice = ({ cx, cy, r, start, end, color, label }) => {
801
+ var PieSlice = ({ cx, cy, r, start, end, color }) => {
442
802
  const x1 = cx + Math.sin(start) * r;
443
803
  const y1 = cy - Math.cos(start) * r;
444
804
  const x2 = cx + Math.sin(end) * r;
445
805
  const y2 = cy - Math.cos(end) * r;
446
806
  const large = end - start > Math.PI ? 1 : 0;
447
807
  const path = `M ${cx} ${cy} L ${x1} ${y1} A ${r} ${r} 0 ${large} 1 ${x2} ${y2} Z`;
448
- const mid = (start + end) / 2;
449
- const lx = cx + Math.sin(mid) * (r * 0.65);
450
- const ly = cy - Math.cos(mid) * (r * 0.65);
451
- return /* @__PURE__ */ jsxs4("g", { children: [
452
- /* @__PURE__ */ jsx4("path", { d: path, fill: color, stroke: "var(--background, #fff)", strokeWidth: 1 }),
453
- /* @__PURE__ */ jsx4(
454
- "text",
455
- {
456
- x: lx,
457
- y: ly,
458
- textAnchor: "middle",
459
- dominantBaseline: "middle",
460
- className: "fill-white text-[10px] font-semibold",
461
- children: label
462
- }
463
- )
464
- ] });
808
+ return /* @__PURE__ */ jsx5("path", { d: path, fill: color, stroke: "var(--background, #fff)", strokeWidth: 1.5 });
465
809
  };
466
- var Legend = ({ dataKeys }) => /* @__PURE__ */ jsx4("div", { className: "aui-artifact-chart-legend mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: dataKeys.map((k, i) => /* @__PURE__ */ jsxs4("span", { className: "inline-flex items-center gap-1.5", children: [
467
- /* @__PURE__ */ jsx4(
468
- "span",
469
- {
470
- className: "inline-block size-2 rounded-sm",
471
- style: { background: COLORS[i % COLORS.length] },
472
- "aria-hidden": true
473
- }
474
- ),
475
- k
476
- ] }, k)) });
477
- var EmptyState = () => /* @__PURE__ */ jsx4("div", { className: "aui-artifact-chart-empty flex h-32 items-center justify-center text-xs text-muted-foreground", children: "No data" });
478
- function inferXKey(data) {
810
+ function inferXKey2(data) {
479
811
  if (data.length === 0) return "x";
480
812
  for (const k of Object.keys(data[0])) {
481
813
  if (typeof data[0][k] !== "number") return k;
@@ -488,40 +820,9 @@ function inferDataKeys(data, xKey) {
488
820
  (k) => k !== xKey && typeof data[0][k] === "number"
489
821
  );
490
822
  }
491
- function toNum(value) {
492
- const n = typeof value === "number" ? value : Number(value);
493
- return Number.isFinite(n) ? n : 0;
494
- }
495
- function niceTicks(min, max, count = 4) {
496
- if (max === min) return [min];
497
- const range = max - min;
498
- const step = niceStep(range / count);
499
- const start = Math.floor(min / step) * step;
500
- const out = [];
501
- for (let v = start; v <= max + step / 2; v += step) {
502
- out.push(round(v));
503
- }
504
- return out;
505
- }
506
- function niceStep(raw) {
507
- const exp = Math.floor(Math.log10(Math.abs(raw))) || 0;
508
- const base = Math.pow(10, exp);
509
- const norm = raw / base;
510
- let nice = 1;
511
- if (norm >= 5) nice = 5;
512
- else if (norm >= 2) nice = 2;
513
- return nice * base;
514
- }
515
- function round(v) {
516
- return Math.round(v * 1e6) / 1e6;
517
- }
518
- function formatTick(v, unit) {
519
- const s = Math.abs(v) >= 1e3 ? `${(v / 1e3).toFixed(1)}k` : String(round(v));
520
- return unit ? `${s}${unit}` : s;
521
- }
522
823
 
523
824
  // src/artifacts/question-artifact.tsx
524
- import { useCallback, useState as useState2 } from "react";
825
+ import { useCallback, useState as useState4 } from "react";
525
826
  import { useThreadRuntime } from "@assistant-ui/react";
526
827
  import { CheckIcon } from "lucide-react";
527
828
 
@@ -637,12 +938,12 @@ var studioQuestionOptionSelectedClass = cn(
637
938
  );
638
939
 
639
940
  // src/artifacts/question-artifact.tsx
640
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
941
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
641
942
  function optionKey(option, index) {
642
943
  const id = option.id?.trim();
643
944
  return id ? id : `__option-${index}`;
644
945
  }
645
- var OptionRadio = ({ selected }) => /* @__PURE__ */ jsx5(
946
+ var OptionRadio = ({ selected }) => /* @__PURE__ */ jsx6(
646
947
  "span",
647
948
  {
648
949
  className: cn(
@@ -650,15 +951,15 @@ var OptionRadio = ({ selected }) => /* @__PURE__ */ jsx5(
650
951
  selected ? "border-foreground bg-foreground text-background" : "border-border bg-background"
651
952
  ),
652
953
  "aria-hidden": true,
653
- children: selected ? /* @__PURE__ */ jsx5(CheckIcon, { className: "size-2.5 stroke-[3]" }) : null
954
+ children: selected ? /* @__PURE__ */ jsx6(CheckIcon, { className: "size-2.5 stroke-[3]" }) : null
654
955
  }
655
956
  );
656
957
  var QuestionArtifactView = ({
657
958
  artifact
658
959
  }) => {
659
960
  const runtime = useThreadRuntime();
660
- const [selected, setSelected] = useState2([]);
661
- const [submittedIds, setSubmittedIds] = useState2(null);
961
+ const [selected, setSelected] = useState4([]);
962
+ const [submittedIds, setSubmittedIds] = useState4(null);
662
963
  const isMulti = artifact.multi === true;
663
964
  const isDisabled = submittedIds !== null;
664
965
  const send = useCallback(
@@ -689,12 +990,12 @@ var QuestionArtifactView = ({
689
990
  const onConfirm = useCallback(() => {
690
991
  send(selected);
691
992
  }, [selected, send]);
692
- return /* @__PURE__ */ jsx5("div", { className: studioArtifactShellClass, "data-artifact-kind": "question", children: /* @__PURE__ */ jsxs5("div", { className: "px-2.5 py-2", children: [
693
- artifact.prompt ? /* @__PURE__ */ jsx5("p", { className: "mb-2 text-sm font-normal leading-snug text-foreground", children: artifact.prompt }) : null,
694
- /* @__PURE__ */ jsx5("div", { className: "flex flex-col gap-0.5", role: "list", children: artifact.options.map((option, index) => {
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) => {
695
996
  const key = optionKey(option, index);
696
997
  const isSelected = submittedIds ? submittedIds.includes(key) : isMulti && selected.includes(key);
697
- return /* @__PURE__ */ jsxs5(
998
+ return /* @__PURE__ */ jsxs6(
698
999
  "button",
699
1000
  {
700
1001
  type: "button",
@@ -706,17 +1007,17 @@ var QuestionArtifactView = ({
706
1007
  isDisabled && (isSelected ? "cursor-default" : "cursor-not-allowed opacity-50")
707
1008
  ),
708
1009
  children: [
709
- /* @__PURE__ */ jsx5(OptionRadio, { selected: isSelected }),
710
- /* @__PURE__ */ jsxs5("span", { className: "min-w-0 flex-1 text-left", children: [
711
- /* @__PURE__ */ jsx5("span", { className: "block font-normal text-foreground", children: option.label }),
712
- option.description ? /* @__PURE__ */ jsx5("span", { className: "mt-0.5 block text-xs text-muted-foreground", children: option.description }) : null
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
713
1014
  ] })
714
1015
  ]
715
1016
  },
716
1017
  key
717
1018
  );
718
1019
  }) }),
719
- isMulti && !submittedIds ? /* @__PURE__ */ jsx5("div", { className: "mt-2 flex justify-end", children: /* @__PURE__ */ jsx5(
1020
+ isMulti && !submittedIds ? /* @__PURE__ */ jsx6("div", { className: "mt-2 flex justify-end", children: /* @__PURE__ */ jsx6(
720
1021
  TimbalV2Button,
721
1022
  {
722
1023
  type: "button",
@@ -731,12 +1032,12 @@ var QuestionArtifactView = ({
731
1032
  };
732
1033
 
733
1034
  // src/artifacts/html-artifact.tsx
734
- import { jsx as jsx6 } from "react/jsx-runtime";
1035
+ import { jsx as jsx7 } from "react/jsx-runtime";
735
1036
  var HtmlArtifactView = ({ artifact }) => {
736
1037
  const sandboxed = artifact.sandboxed !== false;
737
1038
  const sandbox = sandboxed ? "allow-scripts allow-same-origin allow-forms allow-modals allow-popups allow-pointer-lock" : void 0;
738
1039
  const height = artifact.height ?? "320px";
739
- return /* @__PURE__ */ jsx6(ArtifactCard, { title: artifact.title, kind: "html", children: /* @__PURE__ */ jsx6(
1040
+ return /* @__PURE__ */ jsx7(ArtifactCard, { title: artifact.title, kind: "html", children: /* @__PURE__ */ jsx7(
740
1041
  "iframe",
741
1042
  {
742
1043
  title: artifact.title ?? "HTML artifact",
@@ -749,7 +1050,7 @@ var HtmlArtifactView = ({ artifact }) => {
749
1050
  };
750
1051
 
751
1052
  // src/artifacts/json-artifact.tsx
752
- import { jsx as jsx7 } from "react/jsx-runtime";
1053
+ import { jsx as jsx8 } from "react/jsx-runtime";
753
1054
  var JsonArtifactView = ({
754
1055
  artifact
755
1056
  }) => {
@@ -761,16 +1062,16 @@ var JsonArtifactView = ({
761
1062
  } catch {
762
1063
  body = String(data);
763
1064
  }
764
- return /* @__PURE__ */ jsx7(ArtifactCard, { title, kind: "json", children: /* @__PURE__ */ jsx7("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 }) });
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 }) });
765
1066
  };
766
1067
 
767
1068
  // src/artifacts/table-artifact.tsx
768
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
1069
+ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
769
1070
  var TableArtifactView = ({ artifact }) => {
770
1071
  const rows = artifact.rows ?? [];
771
1072
  const columns = artifact.columns ?? deriveColumns(rows);
772
- return /* @__PURE__ */ jsx8(ArtifactCard, { title: artifact.title, kind: "table", children: /* @__PURE__ */ jsx8("div", { className: "aui-artifact-table-wrap overflow-x-auto", children: /* @__PURE__ */ jsxs6("table", { className: "aui-artifact-table w-full border-collapse text-sm", children: [
773
- /* @__PURE__ */ jsx8("thead", { children: /* @__PURE__ */ jsx8("tr", { className: "border-b border-border/40 bg-muted/20", children: columns.map((col) => /* @__PURE__ */ jsx8(
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(
774
1075
  "th",
775
1076
  {
776
1077
  className: "px-3 py-2 text-left text-xs font-semibold uppercase tracking-wider text-muted-foreground",
@@ -778,11 +1079,11 @@ var TableArtifactView = ({ artifact }) => {
778
1079
  },
779
1080
  col.key
780
1081
  )) }) }),
781
- /* @__PURE__ */ jsx8("tbody", { children: rows.map((row, i) => /* @__PURE__ */ jsx8(
1082
+ /* @__PURE__ */ jsx9("tbody", { children: rows.map((row, i) => /* @__PURE__ */ jsx9(
782
1083
  "tr",
783
1084
  {
784
1085
  className: "border-b border-border/30 transition-colors last:border-b-0 hover:bg-muted/20",
785
- children: columns.map((col) => /* @__PURE__ */ jsx8(
1086
+ children: columns.map((col) => /* @__PURE__ */ jsx9(
786
1087
  "td",
787
1088
  {
788
1089
  className: "px-3 py-2 align-top text-foreground/85",
@@ -869,11 +1170,11 @@ import {
869
1170
  createContext,
870
1171
  useContext
871
1172
  } from "react";
872
- import { jsx as jsx9 } from "react/jsx-runtime";
1173
+ import { jsx as jsx10 } from "react/jsx-runtime";
873
1174
  var UiStateContext = createContext({});
874
1175
  var UiDispatchContext = createContext(() => {
875
1176
  });
876
- var UiStateProvider = ({ state, dispatch, children }) => /* @__PURE__ */ jsx9(UiStateContext.Provider, { value: state, children: /* @__PURE__ */ jsx9(UiDispatchContext.Provider, { value: dispatch, children }) });
1177
+ var UiStateProvider = ({ state, dispatch, children }) => /* @__PURE__ */ jsx10(UiStateContext.Provider, { value: state, children: /* @__PURE__ */ jsx10(UiDispatchContext.Provider, { value: dispatch, children }) });
877
1178
  function useUiState() {
878
1179
  return useContext(UiStateContext);
879
1180
  }
@@ -883,12 +1184,12 @@ function useUiDispatch() {
883
1184
  var UiEventContext = createContext(
884
1185
  null
885
1186
  );
886
- var UiEventProvider = ({ onEvent, children }) => /* @__PURE__ */ jsx9(UiEventContext.Provider, { value: onEvent, children });
1187
+ var UiEventProvider = ({ onEvent, children }) => /* @__PURE__ */ jsx10(UiEventContext.Provider, { value: onEvent, children });
887
1188
  function useUiEventEmitter() {
888
1189
  return useContext(UiEventContext);
889
1190
  }
890
1191
  var UiCustomNodeRegistryContext = createContext({});
891
- var UiCustomNodeRegistryProvider = ({ renderers, children }) => /* @__PURE__ */ jsx9(UiCustomNodeRegistryContext.Provider, { value: renderers, children });
1192
+ var UiCustomNodeRegistryProvider = ({ renderers, children }) => /* @__PURE__ */ jsx10(UiCustomNodeRegistryContext.Provider, { value: renderers, children });
892
1193
  function useUiCustomNodeRegistry() {
893
1194
  return useContext(UiCustomNodeRegistryContext);
894
1195
  }
@@ -897,29 +1198,29 @@ function useUiCustomNodeRegistry() {
897
1198
  import { useCallback as useCallback2 } from "react";
898
1199
  import { motion } from "motion/react";
899
1200
  import { useThreadRuntime as useThreadRuntime2 } from "@assistant-ui/react";
900
- import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
1201
+ import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
901
1202
  var UiNodeView = ({ node }) => {
902
1203
  switch (node.kind) {
903
1204
  case "box":
904
- return /* @__PURE__ */ jsx10(BoxNode, { node });
1205
+ return /* @__PURE__ */ jsx11(BoxNode, { node });
905
1206
  case "text":
906
- return /* @__PURE__ */ jsx10(TextNode, { node });
1207
+ return /* @__PURE__ */ jsx11(TextNode, { node });
907
1208
  case "heading":
908
- return /* @__PURE__ */ jsx10(HeadingNode, { node });
1209
+ return /* @__PURE__ */ jsx11(HeadingNode, { node });
909
1210
  case "badge":
910
- return /* @__PURE__ */ jsx10(BadgeNode, { node });
1211
+ return /* @__PURE__ */ jsx11(BadgeNode, { node });
911
1212
  case "button":
912
- return /* @__PURE__ */ jsx10(ButtonNode, { node });
1213
+ return /* @__PURE__ */ jsx11(ButtonNode, { node });
913
1214
  case "toggle":
914
- return /* @__PURE__ */ jsx10(ToggleNode, { node });
1215
+ return /* @__PURE__ */ jsx11(ToggleNode, { node });
915
1216
  case "slider":
916
- return /* @__PURE__ */ jsx10(SliderNode, { node });
1217
+ return /* @__PURE__ */ jsx11(SliderNode, { node });
917
1218
  case "tooltip":
918
- return /* @__PURE__ */ jsx10(TooltipNode, { node });
1219
+ return /* @__PURE__ */ jsx11(TooltipNode, { node });
919
1220
  case "draggable":
920
- return /* @__PURE__ */ jsx10(DraggableNode, { node });
1221
+ return /* @__PURE__ */ jsx11(DraggableNode, { node });
921
1222
  case "custom":
922
- return /* @__PURE__ */ jsx10(CustomNode, { node });
1223
+ return /* @__PURE__ */ jsx11(CustomNode, { node });
923
1224
  default:
924
1225
  return null;
925
1226
  }
@@ -979,7 +1280,7 @@ var JUSTIFY_CLS = {
979
1280
  };
980
1281
  var BoxNode = ({ node }) => {
981
1282
  const dir = node.direction ?? "col";
982
- return /* @__PURE__ */ jsx10(
1283
+ return /* @__PURE__ */ jsx11(
983
1284
  "div",
984
1285
  {
985
1286
  className: cn(
@@ -994,7 +1295,7 @@ var BoxNode = ({ node }) => {
994
1295
  gap: node.gap !== void 0 ? `${node.gap * 0.25}rem` : void 0,
995
1296
  padding: node.padding !== void 0 ? `${node.padding * 0.25}rem` : void 0
996
1297
  },
997
- children: node.children?.map((child, i) => /* @__PURE__ */ jsx10(UiNodeView, { node: child }, child.id ?? i))
1298
+ children: node.children?.map((child, i) => /* @__PURE__ */ jsx11(UiNodeView, { node: child }, child.id ?? i))
998
1299
  }
999
1300
  );
1000
1301
  };
@@ -1013,7 +1314,7 @@ var TEXT_WEIGHT = {
1013
1314
  var TextNode = ({ node }) => {
1014
1315
  const state = useUiState();
1015
1316
  const value = resolveBindable(node.value, state);
1016
- return /* @__PURE__ */ jsx10(
1317
+ return /* @__PURE__ */ jsx11(
1017
1318
  "span",
1018
1319
  {
1019
1320
  className: cn(
@@ -1044,13 +1345,13 @@ var HeadingNode = ({ node }) => {
1044
1345
  );
1045
1346
  switch (level) {
1046
1347
  case 1:
1047
- return /* @__PURE__ */ jsx10("h1", { className: cls, children: value });
1348
+ return /* @__PURE__ */ jsx11("h1", { className: cls, children: value });
1048
1349
  case 2:
1049
- return /* @__PURE__ */ jsx10("h2", { className: cls, children: value });
1350
+ return /* @__PURE__ */ jsx11("h2", { className: cls, children: value });
1050
1351
  case 3:
1051
- return /* @__PURE__ */ jsx10("h3", { className: cls, children: value });
1352
+ return /* @__PURE__ */ jsx11("h3", { className: cls, children: value });
1052
1353
  case 4:
1053
- return /* @__PURE__ */ jsx10("h4", { className: cls, children: value });
1354
+ return /* @__PURE__ */ jsx11("h4", { className: cls, children: value });
1054
1355
  }
1055
1356
  };
1056
1357
  var BADGE_TONE = {
@@ -1063,7 +1364,7 @@ var BADGE_TONE = {
1063
1364
  var BadgeNode = ({ node }) => {
1064
1365
  const state = useUiState();
1065
1366
  const value = String(resolveBindable(node.value, state) ?? "");
1066
- return /* @__PURE__ */ jsx10(
1367
+ return /* @__PURE__ */ jsx11(
1067
1368
  "span",
1068
1369
  {
1069
1370
  className: cn(
@@ -1080,7 +1381,7 @@ var ButtonNode = ({ node }) => {
1080
1381
  const run = useActionRunner();
1081
1382
  const label = String(resolveBindable(node.label, state) ?? "");
1082
1383
  const disabled = node.disabled !== void 0 ? Boolean(resolveBindable(node.disabled, state)) : false;
1083
- return /* @__PURE__ */ jsx10(
1384
+ return /* @__PURE__ */ jsx11(
1084
1385
  Button,
1085
1386
  {
1086
1387
  variant: node.variant ?? "default",
@@ -1102,7 +1403,7 @@ var ToggleNode = ({ node }) => {
1102
1403
  dispatch({ type: "toggle", path: node.binding });
1103
1404
  run(node.onChange);
1104
1405
  };
1105
- return /* @__PURE__ */ jsxs7(
1406
+ return /* @__PURE__ */ jsxs8(
1106
1407
  "label",
1107
1408
  {
1108
1409
  className: cn(
@@ -1110,7 +1411,7 @@ var ToggleNode = ({ node }) => {
1110
1411
  node.className
1111
1412
  ),
1112
1413
  children: [
1113
- /* @__PURE__ */ jsx10(
1414
+ /* @__PURE__ */ jsx11(
1114
1415
  "button",
1115
1416
  {
1116
1417
  type: "button",
@@ -1121,7 +1422,7 @@ var ToggleNode = ({ node }) => {
1121
1422
  "relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-[background,box-shadow,border-color] duration-200",
1122
1423
  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")
1123
1424
  ),
1124
- children: /* @__PURE__ */ jsx10(
1425
+ children: /* @__PURE__ */ jsx11(
1125
1426
  "span",
1126
1427
  {
1127
1428
  className: cn(
@@ -1134,7 +1435,7 @@ var ToggleNode = ({ node }) => {
1134
1435
  )
1135
1436
  }
1136
1437
  ),
1137
- label && /* @__PURE__ */ jsx10("span", { className: "text-foreground/85", children: label })
1438
+ label && /* @__PURE__ */ jsx11("span", { className: "text-foreground/85", children: label })
1138
1439
  ]
1139
1440
  }
1140
1441
  );
@@ -1154,12 +1455,12 @@ var SliderNode = ({ node }) => {
1154
1455
  const next = Number(e.target.value);
1155
1456
  dispatch({ type: "set", path: node.binding, value: next });
1156
1457
  };
1157
- return /* @__PURE__ */ jsxs7("div", { className: cn("aui-ui-slider flex flex-col gap-1", node.className), children: [
1158
- (label || showValue) && /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between text-xs text-muted-foreground", children: [
1159
- label && /* @__PURE__ */ jsx10("span", { children: label }),
1160
- showValue && /* @__PURE__ */ jsx10("span", { className: "font-mono", children: value })
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 })
1161
1462
  ] }),
1162
- /* @__PURE__ */ jsx10(
1463
+ /* @__PURE__ */ jsx11(
1163
1464
  "input",
1164
1465
  {
1165
1466
  type: "range",
@@ -1181,9 +1482,9 @@ var SliderNode = ({ node }) => {
1181
1482
  var TooltipNode = ({ node }) => {
1182
1483
  const state = useUiState();
1183
1484
  const content = String(resolveBindable(node.content, state) ?? "");
1184
- return /* @__PURE__ */ jsx10(TooltipProvider, { children: /* @__PURE__ */ jsxs7(Tooltip, { children: [
1185
- /* @__PURE__ */ jsx10(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx10("span", { className: cn("aui-ui-tooltip-trigger inline-flex", node.className), children: /* @__PURE__ */ jsx10(UiNodeView, { node: node.child }) }) }),
1186
- /* @__PURE__ */ jsx10(TooltipContent, { side: node.side ?? "top", children: content })
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 })
1187
1488
  ] }) });
1188
1489
  };
1189
1490
  var DraggableNode = ({ node }) => {
@@ -1191,7 +1492,7 @@ var DraggableNode = ({ node }) => {
1191
1492
  const snapBack = node.snapBack ?? true;
1192
1493
  const axis = node.axis ?? "both";
1193
1494
  const dragProp = axis === "both" ? true : axis;
1194
- return /* @__PURE__ */ jsx10(
1495
+ return /* @__PURE__ */ jsx11(
1195
1496
  motion.div,
1196
1497
  {
1197
1498
  drag: dragProp,
@@ -1203,7 +1504,7 @@ var DraggableNode = ({ node }) => {
1203
1504
  "aui-ui-draggable inline-block cursor-grab touch-none",
1204
1505
  node.className
1205
1506
  ),
1206
- children: /* @__PURE__ */ jsx10(UiNodeView, { node: node.child })
1507
+ children: /* @__PURE__ */ jsx11(UiNodeView, { node: node.child })
1207
1508
  }
1208
1509
  );
1209
1510
  };
@@ -1213,8 +1514,8 @@ var CustomNode = ({ node }) => {
1213
1514
  const Renderer = registry[node.name];
1214
1515
  if (!Renderer) return null;
1215
1516
  const resolvedProps = resolveProps(node.props ?? {}, state);
1216
- const children = node.children?.map((child, i) => /* @__PURE__ */ jsx10(UiNodeView, { node: child }, child.id ?? i));
1217
- return /* @__PURE__ */ jsx10(Renderer, { props: resolvedProps, children });
1517
+ const children = node.children?.map((child, i) => /* @__PURE__ */ jsx11(UiNodeView, { node: child }, child.id ?? i));
1518
+ return /* @__PURE__ */ jsx11(Renderer, { props: resolvedProps, children });
1218
1519
  };
1219
1520
  function resolveProps(props, state) {
1220
1521
  const out = {};
@@ -1226,18 +1527,18 @@ function resolveProps(props, state) {
1226
1527
 
1227
1528
  // src/artifacts/ui/ui-artifact.tsx
1228
1529
  import { useReducer } from "react";
1229
- import { jsx as jsx11 } from "react/jsx-runtime";
1530
+ import { jsx as jsx12 } from "react/jsx-runtime";
1230
1531
  var UiArtifactView = ({ artifact }) => {
1231
1532
  const [state, dispatch] = useReducer(
1232
1533
  uiStateReducer,
1233
1534
  artifact.initialState ?? {}
1234
1535
  );
1235
- return /* @__PURE__ */ jsx11(ArtifactCard, { title: artifact.title, kind: "ui", children: /* @__PURE__ */ jsx11(UiStateProvider, { state, dispatch, children: /* @__PURE__ */ jsx11("div", { className: "aui-ui-root p-3", children: /* @__PURE__ */ jsx11(UiNodeView, { node: artifact.root }) }) }) });
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 }) }) }) });
1236
1537
  };
1237
1538
 
1238
1539
  // src/artifacts/registry.tsx
1239
- import { createContext as createContext2, useContext as useContext2, useMemo as useMemo2 } from "react";
1240
- import { jsx as jsx12 } from "react/jsx-runtime";
1540
+ import { createContext as createContext2, useContext as useContext2, useMemo as useMemo3 } from "react";
1541
+ import { jsx as jsx13 } from "react/jsx-runtime";
1241
1542
  var defaultArtifactRenderers = {
1242
1543
  chart: ChartArtifactView,
1243
1544
  question: QuestionArtifactView,
@@ -1250,12 +1551,12 @@ var ArtifactRegistryContext = createContext2(
1250
1551
  defaultArtifactRenderers
1251
1552
  );
1252
1553
  var ArtifactRegistryProvider = ({ renderers, override, children }) => {
1253
- const merged = useMemo2(() => {
1554
+ const merged = useMemo3(() => {
1254
1555
  if (!renderers) return defaultArtifactRenderers;
1255
1556
  if (override) return renderers;
1256
1557
  return { ...defaultArtifactRenderers, ...renderers };
1257
1558
  }, [renderers, override]);
1258
- return /* @__PURE__ */ jsx12(ArtifactRegistryContext.Provider, { value: merged, children });
1559
+ return /* @__PURE__ */ jsx13(ArtifactRegistryContext.Provider, { value: merged, children });
1259
1560
  };
1260
1561
  function useArtifactRegistry() {
1261
1562
  return useContext2(ArtifactRegistryContext);
@@ -1264,7 +1565,7 @@ var ArtifactView = ({ artifact }) => {
1264
1565
  const registry = useArtifactRegistry();
1265
1566
  const Renderer = registry[artifact.type] ?? registry.json;
1266
1567
  if (!Renderer) return null;
1267
- return /* @__PURE__ */ jsx12(Renderer, { artifact });
1568
+ return /* @__PURE__ */ jsx13(Renderer, { artifact });
1268
1569
  };
1269
1570
 
1270
1571
  // src/artifacts/types.ts
@@ -1376,11 +1677,11 @@ import {
1376
1677
  import remarkGfm from "remark-gfm";
1377
1678
  import remarkMath from "remark-math";
1378
1679
  import rehypeKatex from "rehype-katex";
1379
- import { memo, useState as useState4 } from "react";
1680
+ import { memo, useState as useState6 } from "react";
1380
1681
  import { CheckIcon as CheckIcon2, CopyIcon } from "lucide-react";
1381
1682
 
1382
1683
  // src/chat/syntax-highlighter.tsx
1383
- import { useEffect as useEffect2, useState as useState3 } from "react";
1684
+ import { useEffect as useEffect4, useState as useState5 } from "react";
1384
1685
  import { createHighlighterCore } from "shiki/core";
1385
1686
  import { createJavaScriptRegexEngine } from "shiki/engine/javascript";
1386
1687
  import langJavascript from "shiki/langs/javascript.mjs";
@@ -1402,7 +1703,7 @@ import langC from "shiki/langs/c.mjs";
1402
1703
  import langCpp from "shiki/langs/cpp.mjs";
1403
1704
  import themeVitesseDark from "shiki/themes/vitesse-dark.mjs";
1404
1705
  import themeVitesseLight from "shiki/themes/vitesse-light.mjs";
1405
- import { jsx as jsx13 } from "react/jsx-runtime";
1706
+ import { jsx as jsx14 } from "react/jsx-runtime";
1406
1707
  var SHIKI_THEME_DARK = "vitesse-dark";
1407
1708
  var SHIKI_THEME_LIGHT = "vitesse-light";
1408
1709
  var highlighterPromise = null;
@@ -1440,8 +1741,8 @@ var ShikiSyntaxHighlighter = ({
1440
1741
  language,
1441
1742
  code
1442
1743
  }) => {
1443
- const [html, setHtml] = useState3(null);
1444
- useEffect2(() => {
1744
+ const [html, setHtml] = useState5(null);
1745
+ useEffect4(() => {
1445
1746
  let cancelled = false;
1446
1747
  (async () => {
1447
1748
  try {
@@ -1471,13 +1772,13 @@ var ShikiSyntaxHighlighter = ({
1471
1772
  try {
1472
1773
  const parsed = JSON.parse(code);
1473
1774
  if (isArtifact(parsed)) {
1474
- return /* @__PURE__ */ jsx13(ArtifactView, { artifact: parsed });
1775
+ return /* @__PURE__ */ jsx14(ArtifactView, { artifact: parsed });
1475
1776
  }
1476
1777
  } catch {
1477
1778
  }
1478
1779
  }
1479
1780
  if (html) {
1480
- return /* @__PURE__ */ jsx13(
1781
+ return /* @__PURE__ */ jsx14(
1481
1782
  "div",
1482
1783
  {
1483
1784
  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",
@@ -1485,14 +1786,14 @@ var ShikiSyntaxHighlighter = ({
1485
1786
  }
1486
1787
  );
1487
1788
  }
1488
- return /* @__PURE__ */ jsx13(Pre, { children: /* @__PURE__ */ jsx13(Code2, { children: code }) });
1789
+ return /* @__PURE__ */ jsx14(Pre, { children: /* @__PURE__ */ jsx14(Code2, { children: code }) });
1489
1790
  };
1490
1791
  var syntax_highlighter_default = ShikiSyntaxHighlighter;
1491
1792
 
1492
1793
  // src/chat/markdown-text.tsx
1493
- import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
1794
+ import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
1494
1795
  var MarkdownTextImpl = () => {
1495
- return /* @__PURE__ */ jsx14(
1796
+ return /* @__PURE__ */ jsx15(
1496
1797
  MarkdownTextPrimitive,
1497
1798
  {
1498
1799
  remarkPlugins: [remarkGfm, remarkMath],
@@ -1513,20 +1814,20 @@ var CodeHeader = ({ language, code }) => {
1513
1814
  if (!code || isCopied) return;
1514
1815
  copyToClipboard(code);
1515
1816
  };
1516
- return /* @__PURE__ */ jsxs8("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: [
1517
- /* @__PURE__ */ jsxs8("span", { className: "flex items-center gap-2 text-xs font-semibold tracking-wide text-muted-foreground/80 uppercase", children: [
1518
- /* @__PURE__ */ jsx14("span", { className: "inline-block h-2 w-2 rounded-full bg-primary/40" }),
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" }),
1519
1820
  language
1520
1821
  ] }),
1521
- /* @__PURE__ */ jsxs8(
1822
+ /* @__PURE__ */ jsxs9(
1522
1823
  TooltipIconButton,
1523
1824
  {
1524
1825
  tooltip: isCopied ? "Copied!" : "Copy",
1525
1826
  onClick: onCopy,
1526
1827
  className: "transition-colors hover:text-foreground",
1527
1828
  children: [
1528
- !isCopied && /* @__PURE__ */ jsx14(CopyIcon, { className: "h-3.5 w-3.5" }),
1529
- isCopied && /* @__PURE__ */ jsx14(CheckIcon2, { className: "h-3.5 w-3.5 text-emerald-500" })
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" })
1530
1831
  ]
1531
1832
  }
1532
1833
  )
@@ -1535,7 +1836,7 @@ var CodeHeader = ({ language, code }) => {
1535
1836
  var useCopyToClipboard = ({
1536
1837
  copiedDuration = 3e3
1537
1838
  } = {}) => {
1538
- const [isCopied, setIsCopied] = useState4(false);
1839
+ const [isCopied, setIsCopied] = useState6(false);
1539
1840
  const copyToClipboard = (value) => {
1540
1841
  if (!value) return;
1541
1842
  navigator.clipboard.writeText(value).then(() => {
@@ -1546,7 +1847,7 @@ var useCopyToClipboard = ({
1546
1847
  return { isCopied, copyToClipboard };
1547
1848
  };
1548
1849
  var defaultComponents = memoizeMarkdownComponents({
1549
- h1: ({ className, ...props }) => /* @__PURE__ */ jsx14(
1850
+ h1: ({ className, ...props }) => /* @__PURE__ */ jsx15(
1550
1851
  "h1",
1551
1852
  {
1552
1853
  className: cn(
@@ -1556,7 +1857,7 @@ var defaultComponents = memoizeMarkdownComponents({
1556
1857
  ...props
1557
1858
  }
1558
1859
  ),
1559
- h2: ({ className, ...props }) => /* @__PURE__ */ jsx14(
1860
+ h2: ({ className, ...props }) => /* @__PURE__ */ jsx15(
1560
1861
  "h2",
1561
1862
  {
1562
1863
  className: cn(
@@ -1566,7 +1867,7 @@ var defaultComponents = memoizeMarkdownComponents({
1566
1867
  ...props
1567
1868
  }
1568
1869
  ),
1569
- h3: ({ className, ...props }) => /* @__PURE__ */ jsx14(
1870
+ h3: ({ className, ...props }) => /* @__PURE__ */ jsx15(
1570
1871
  "h3",
1571
1872
  {
1572
1873
  className: cn(
@@ -1576,7 +1877,7 @@ var defaultComponents = memoizeMarkdownComponents({
1576
1877
  ...props
1577
1878
  }
1578
1879
  ),
1579
- h4: ({ className, ...props }) => /* @__PURE__ */ jsx14(
1880
+ h4: ({ className, ...props }) => /* @__PURE__ */ jsx15(
1580
1881
  "h4",
1581
1882
  {
1582
1883
  className: cn(
@@ -1586,7 +1887,7 @@ var defaultComponents = memoizeMarkdownComponents({
1586
1887
  ...props
1587
1888
  }
1588
1889
  ),
1589
- h5: ({ className, ...props }) => /* @__PURE__ */ jsx14(
1890
+ h5: ({ className, ...props }) => /* @__PURE__ */ jsx15(
1590
1891
  "h5",
1591
1892
  {
1592
1893
  className: cn(
@@ -1596,7 +1897,7 @@ var defaultComponents = memoizeMarkdownComponents({
1596
1897
  ...props
1597
1898
  }
1598
1899
  ),
1599
- h6: ({ className, ...props }) => /* @__PURE__ */ jsx14(
1900
+ h6: ({ className, ...props }) => /* @__PURE__ */ jsx15(
1600
1901
  "h6",
1601
1902
  {
1602
1903
  className: cn(
@@ -1606,7 +1907,7 @@ var defaultComponents = memoizeMarkdownComponents({
1606
1907
  ...props
1607
1908
  }
1608
1909
  ),
1609
- p: ({ className, ...props }) => /* @__PURE__ */ jsx14(
1910
+ p: ({ className, ...props }) => /* @__PURE__ */ jsx15(
1610
1911
  "p",
1611
1912
  {
1612
1913
  className: cn(
@@ -1616,7 +1917,7 @@ var defaultComponents = memoizeMarkdownComponents({
1616
1917
  ...props
1617
1918
  }
1618
1919
  ),
1619
- a: ({ className, ...props }) => /* @__PURE__ */ jsx14(
1920
+ a: ({ className, ...props }) => /* @__PURE__ */ jsx15(
1620
1921
  "a",
1621
1922
  {
1622
1923
  className: cn(
@@ -1628,7 +1929,7 @@ var defaultComponents = memoizeMarkdownComponents({
1628
1929
  ...props
1629
1930
  }
1630
1931
  ),
1631
- blockquote: ({ className, ...props }) => /* @__PURE__ */ jsx14(
1932
+ blockquote: ({ className, ...props }) => /* @__PURE__ */ jsx15(
1632
1933
  "blockquote",
1633
1934
  {
1634
1935
  className: cn(
@@ -1638,7 +1939,7 @@ var defaultComponents = memoizeMarkdownComponents({
1638
1939
  ...props
1639
1940
  }
1640
1941
  ),
1641
- ul: ({ className, ...props }) => /* @__PURE__ */ jsx14(
1942
+ ul: ({ className, ...props }) => /* @__PURE__ */ jsx15(
1642
1943
  "ul",
1643
1944
  {
1644
1945
  className: cn(
@@ -1648,7 +1949,7 @@ var defaultComponents = memoizeMarkdownComponents({
1648
1949
  ...props
1649
1950
  }
1650
1951
  ),
1651
- ol: ({ className, ...props }) => /* @__PURE__ */ jsx14(
1952
+ ol: ({ className, ...props }) => /* @__PURE__ */ jsx15(
1652
1953
  "ol",
1653
1954
  {
1654
1955
  className: cn(
@@ -1658,7 +1959,7 @@ var defaultComponents = memoizeMarkdownComponents({
1658
1959
  ...props
1659
1960
  }
1660
1961
  ),
1661
- hr: ({ className, ...props }) => /* @__PURE__ */ jsx14(
1962
+ hr: ({ className, ...props }) => /* @__PURE__ */ jsx15(
1662
1963
  "hr",
1663
1964
  {
1664
1965
  className: cn(
@@ -1668,14 +1969,14 @@ var defaultComponents = memoizeMarkdownComponents({
1668
1969
  ...props
1669
1970
  }
1670
1971
  ),
1671
- table: ({ className, ...props }) => /* @__PURE__ */ jsx14("div", { className: "my-4 w-full overflow-x-auto rounded-lg border border-border/50", children: /* @__PURE__ */ jsx14(
1972
+ table: ({ className, ...props }) => /* @__PURE__ */ jsx15("div", { className: "my-4 w-full overflow-x-auto rounded-lg border border-border/50", children: /* @__PURE__ */ jsx15(
1672
1973
  "table",
1673
1974
  {
1674
1975
  className: cn("aui-md-table w-full border-collapse text-sm", className),
1675
1976
  ...props
1676
1977
  }
1677
1978
  ) }),
1678
- th: ({ className, ...props }) => /* @__PURE__ */ jsx14(
1979
+ th: ({ className, ...props }) => /* @__PURE__ */ jsx15(
1679
1980
  "th",
1680
1981
  {
1681
1982
  className: cn(
@@ -1685,7 +1986,7 @@ var defaultComponents = memoizeMarkdownComponents({
1685
1986
  ...props
1686
1987
  }
1687
1988
  ),
1688
- td: ({ className, ...props }) => /* @__PURE__ */ jsx14(
1989
+ td: ({ className, ...props }) => /* @__PURE__ */ jsx15(
1689
1990
  "td",
1690
1991
  {
1691
1992
  className: cn(
@@ -1695,7 +1996,7 @@ var defaultComponents = memoizeMarkdownComponents({
1695
1996
  ...props
1696
1997
  }
1697
1998
  ),
1698
- tr: ({ className, ...props }) => /* @__PURE__ */ jsx14(
1999
+ tr: ({ className, ...props }) => /* @__PURE__ */ jsx15(
1699
2000
  "tr",
1700
2001
  {
1701
2002
  className: cn(
@@ -1705,8 +2006,8 @@ var defaultComponents = memoizeMarkdownComponents({
1705
2006
  ...props
1706
2007
  }
1707
2008
  ),
1708
- li: ({ className, ...props }) => /* @__PURE__ */ jsx14("li", { className: cn("aui-md-li leading-[1.7]", className), ...props }),
1709
- sup: ({ className, ...props }) => /* @__PURE__ */ jsx14(
2009
+ li: ({ className, ...props }) => /* @__PURE__ */ jsx15("li", { className: cn("aui-md-li leading-[1.7]", className), ...props }),
2010
+ sup: ({ className, ...props }) => /* @__PURE__ */ jsx15(
1710
2011
  "sup",
1711
2012
  {
1712
2013
  className: cn(
@@ -1716,7 +2017,7 @@ var defaultComponents = memoizeMarkdownComponents({
1716
2017
  ...props
1717
2018
  }
1718
2019
  ),
1719
- pre: ({ className, ...props }) => /* @__PURE__ */ jsx14(
2020
+ pre: ({ className, ...props }) => /* @__PURE__ */ jsx15(
1720
2021
  "pre",
1721
2022
  {
1722
2023
  className: cn(
@@ -1728,7 +2029,7 @@ var defaultComponents = memoizeMarkdownComponents({
1728
2029
  ),
1729
2030
  code: function Code({ className, ...props }) {
1730
2031
  const isCodeBlock = useIsMarkdownCodeBlock();
1731
- return /* @__PURE__ */ jsx14(
2032
+ return /* @__PURE__ */ jsx15(
1732
2033
  "code",
1733
2034
  {
1734
2035
  className: cn(
@@ -1739,8 +2040,8 @@ var defaultComponents = memoizeMarkdownComponents({
1739
2040
  }
1740
2041
  );
1741
2042
  },
1742
- strong: ({ className, ...props }) => /* @__PURE__ */ jsx14("strong", { className: cn("font-semibold text-foreground", className), ...props }),
1743
- em: ({ className, ...props }) => /* @__PURE__ */ jsx14("em", { className: cn("italic", className), ...props }),
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 }),
1744
2045
  CodeHeader
1745
2046
  });
1746
2047
 
@@ -1936,10 +2237,10 @@ import {
1936
2237
  createContext as createContext4,
1937
2238
  useCallback as useCallback3,
1938
2239
  useContext as useContext4,
1939
- useEffect as useEffect3,
1940
- useMemo as useMemo3,
1941
- useRef,
1942
- useState as useState5
2240
+ useEffect as useEffect5,
2241
+ useMemo as useMemo4,
2242
+ useRef as useRef2,
2243
+ useState as useState7
1943
2244
  } from "react";
1944
2245
  import {
1945
2246
  useExternalStoreRuntime,
@@ -2293,20 +2594,20 @@ function buildPromptBody({
2293
2594
 
2294
2595
  // src/runtime/attachments-context.tsx
2295
2596
  import { createContext as createContext3, useContext as useContext3 } from "react";
2296
- import { jsx as jsx15 } from "react/jsx-runtime";
2597
+ import { jsx as jsx16 } from "react/jsx-runtime";
2297
2598
  var TimbalAttachmentsEnabledContext = createContext3(false);
2298
2599
  function TimbalAttachmentsEnabledProvider({
2299
2600
  enabled,
2300
2601
  children
2301
2602
  }) {
2302
- return /* @__PURE__ */ jsx15(TimbalAttachmentsEnabledContext.Provider, { value: enabled, children });
2603
+ return /* @__PURE__ */ jsx16(TimbalAttachmentsEnabledContext.Provider, { value: enabled, children });
2303
2604
  }
2304
2605
  function useTimbalAttachmentsEnabled() {
2305
2606
  return useContext3(TimbalAttachmentsEnabledContext);
2306
2607
  }
2307
2608
 
2308
2609
  // src/runtime/provider.tsx
2309
- import { jsx as jsx16 } from "react/jsx-runtime";
2610
+ import { jsx as jsx17 } from "react/jsx-runtime";
2310
2611
  function projectAttachment(attachment) {
2311
2612
  const filename = attachment.name ?? "attachment";
2312
2613
  const mimeType = attachment.contentType ?? "application/octet-stream";
@@ -2371,19 +2672,19 @@ function useTimbalStream({
2371
2672
  fetch: fetchFn,
2372
2673
  debug = false
2373
2674
  }) {
2374
- const [messages, setMessages] = useState5([]);
2375
- const [isRunning, setIsRunning] = useState5(false);
2376
- const abortRef = useRef(null);
2377
- const messagesRef = useRef([]);
2378
- const fetchFnRef = useRef(fetchFn ?? authFetch);
2379
- useEffect3(() => {
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(() => {
2380
2681
  fetchFnRef.current = fetchFn ?? authFetch;
2381
2682
  }, [fetchFn]);
2382
- const debugRef = useRef(debug);
2383
- useEffect3(() => {
2683
+ const debugRef = useRef2(debug);
2684
+ useEffect5(() => {
2384
2685
  debugRef.current = debug;
2385
2686
  }, [debug]);
2386
- useEffect3(() => {
2687
+ useEffect5(() => {
2387
2688
  messagesRef.current = messages;
2388
2689
  }, [messages]);
2389
2690
  const streamAssistantResponse = useCallback3(
@@ -2532,7 +2833,7 @@ function useTimbalStream({
2532
2833
  abortRef.current?.abort();
2533
2834
  setMessages([]);
2534
2835
  }, []);
2535
- return useMemo3(
2836
+ return useMemo4(
2536
2837
  () => ({ messages, isRunning, send, reload, cancel, clear }),
2537
2838
  [messages, isRunning, send, reload, cancel, clear]
2538
2839
  );
@@ -2569,7 +2870,7 @@ function TimbalRuntimeProvider({
2569
2870
  fetch: fetchFn,
2570
2871
  debug
2571
2872
  });
2572
- const attachmentAdapter = useMemo3(
2873
+ const attachmentAdapter = useMemo4(
2573
2874
  () => resolveAttachmentAdapter(attachments, {
2574
2875
  baseUrl,
2575
2876
  fetch: fetchFn,
@@ -2612,7 +2913,7 @@ function TimbalRuntimeProvider({
2612
2913
  onCancel,
2613
2914
  ...attachmentAdapter ? { adapters: { attachments: attachmentAdapter } } : {}
2614
2915
  });
2615
- return /* @__PURE__ */ jsx16(TimbalStreamContext.Provider, { value: stream, children: /* @__PURE__ */ jsx16(TimbalAttachmentsEnabledProvider, { enabled: attachmentAdapter !== void 0, children: /* @__PURE__ */ jsx16(AssistantRuntimeProvider, { runtime, children }) }) });
2916
+ return /* @__PURE__ */ jsx17(TimbalStreamContext.Provider, { value: stream, children: /* @__PURE__ */ jsx17(TimbalAttachmentsEnabledProvider, { enabled: attachmentAdapter !== void 0, children: /* @__PURE__ */ jsx17(AssistantRuntimeProvider, { runtime, children }) }) });
2616
2917
  }
2617
2918
  function findParentIdFromAuiParent(messages, auiParentId) {
2618
2919
  const idx = messages.findIndex((m) => m.id === auiParentId);
@@ -2621,7 +2922,7 @@ function findParentIdFromAuiParent(messages, auiParentId) {
2621
2922
  }
2622
2923
 
2623
2924
  // src/chat/tool-fallback.tsx
2624
- import { memo as memo2, useMemo as useMemo4, useState as useState6 } from "react";
2925
+ import { memo as memo2, useMemo as useMemo5, useState as useState8 } from "react";
2625
2926
  import { ChevronRightIcon } from "lucide-react";
2626
2927
  import {
2627
2928
  useAuiState as useAuiState2
@@ -2629,7 +2930,7 @@ import {
2629
2930
 
2630
2931
  // src/chat/motion.tsx
2631
2932
  import { AnimatePresence, motion as motion2, useReducedMotion } from "motion/react";
2632
- import { jsx as jsx17 } from "react/jsx-runtime";
2933
+ import { jsx as jsx18 } from "react/jsx-runtime";
2633
2934
  var luxuryEase = [0.16, 1, 0.3, 1];
2634
2935
  var TOOL_ENTER_MS = 0.78;
2635
2936
  var TOOL_EXIT_MS = 0.28;
@@ -2657,7 +2958,7 @@ function toolMotionState(reduced, entering, variant) {
2657
2958
  function ToolMotion({ children, className, motionKey }) {
2658
2959
  const reduced = useReducedMotion() ?? false;
2659
2960
  const { enter, exit } = toolPresenceTransition(reduced);
2660
- return /* @__PURE__ */ jsx17(
2961
+ return /* @__PURE__ */ jsx18(
2661
2962
  motion2.div,
2662
2963
  {
2663
2964
  className: cn("aui-tool-motion w-full min-w-0", className),
@@ -2680,7 +2981,7 @@ function ToolPresence({
2680
2981
  const reduced = useReducedMotion() ?? false;
2681
2982
  const { enter, exit } = toolPresenceTransition(reduced);
2682
2983
  const enterTransition = variant === "executing" ? { duration: reduced ? 0.3 : 0.52, ease: luxuryEase } : enter;
2683
- return /* @__PURE__ */ jsx17(AnimatePresence, { mode: "wait", initial: true, children: /* @__PURE__ */ jsx17(
2984
+ return /* @__PURE__ */ jsx18(AnimatePresence, { mode: "wait", initial: true, children: /* @__PURE__ */ jsx18(
2684
2985
  motion2.div,
2685
2986
  {
2686
2987
  className: cn("aui-tool-presence w-full min-w-0", className),
@@ -2702,7 +3003,7 @@ function ToolBodyPresence({
2702
3003
  className
2703
3004
  }) {
2704
3005
  const reduced = useReducedMotion() ?? false;
2705
- return /* @__PURE__ */ jsx17(
3006
+ return /* @__PURE__ */ jsx18(
2706
3007
  "div",
2707
3008
  {
2708
3009
  className: cn(
@@ -2710,7 +3011,7 @@ function ToolBodyPresence({
2710
3011
  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)]"
2711
3012
  ),
2712
3013
  style: { gridTemplateRows: open ? "1fr" : "0fr" },
2713
- children: /* @__PURE__ */ jsx17("div", { className: "min-h-0 overflow-hidden", children: /* @__PURE__ */ jsx17(
3014
+ children: /* @__PURE__ */ jsx18("div", { className: "min-h-0 overflow-hidden", children: /* @__PURE__ */ jsx18(
2714
3015
  "div",
2715
3016
  {
2716
3017
  className: cn(
@@ -2726,7 +3027,7 @@ function ToolBodyPresence({
2726
3027
  }
2727
3028
 
2728
3029
  // src/chat/tool-fallback.tsx
2729
- import { jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
3030
+ import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
2730
3031
  function detectRunning({
2731
3032
  status,
2732
3033
  result,
@@ -2758,8 +3059,8 @@ function formatToolResult(result) {
2758
3059
  return String(result);
2759
3060
  }
2760
3061
  }
2761
- var TimelineActionLabel = ({ action, detail, shimmer = false }) => /* @__PURE__ */ jsxs9("span", { className: "inline-flex min-w-0 max-w-full items-baseline gap-1", children: [
2762
- action ? shimmer ? /* @__PURE__ */ jsx18(
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(
2763
3064
  Shimmer,
2764
3065
  {
2765
3066
  as: "span",
@@ -2768,10 +3069,10 @@ var TimelineActionLabel = ({ action, detail, shimmer = false }) => /* @__PURE__
2768
3069
  spread: 2.5,
2769
3070
  children: action
2770
3071
  }
2771
- ) : /* @__PURE__ */ jsx18("span", { className: studioTimelineActionClass, children: action }) : null,
2772
- detail ? /* @__PURE__ */ jsx18("span", { className: studioTimelineDetailClass, children: detail }) : null
3072
+ ) : /* @__PURE__ */ jsx19("span", { className: studioTimelineActionClass, children: action }) : null,
3073
+ detail ? /* @__PURE__ */ jsx19("span", { className: studioTimelineDetailClass, children: detail }) : null
2773
3074
  ] });
2774
- var TimelineHoverChevron = ({ expanded }) => /* @__PURE__ */ jsx18(
3075
+ var TimelineHoverChevron = ({ expanded }) => /* @__PURE__ */ jsx19(
2775
3076
  ChevronRightIcon,
2776
3077
  {
2777
3078
  className: studioTimelineChevronClass(expanded),
@@ -2779,9 +3080,9 @@ var TimelineHoverChevron = ({ expanded }) => /* @__PURE__ */ jsx18(
2779
3080
  }
2780
3081
  );
2781
3082
  var ToolPanel = ({ toolName, argsText, result, isError }) => {
2782
- const [open, setOpen] = useState6(false);
3083
+ const [open, setOpen] = useState8(false);
2783
3084
  const detail = formatToolLabel(toolName);
2784
- const formattedArgs = useMemo4(() => {
3085
+ const formattedArgs = useMemo5(() => {
2785
3086
  if (!argsText || argsText === "{}") return null;
2786
3087
  try {
2787
3088
  return JSON.stringify(JSON.parse(argsText), null, 2);
@@ -2789,17 +3090,17 @@ var ToolPanel = ({ toolName, argsText, result, isError }) => {
2789
3090
  return argsText;
2790
3091
  }
2791
3092
  }, [argsText]);
2792
- const formattedResult = useMemo4(() => {
3093
+ const formattedResult = useMemo5(() => {
2793
3094
  if (result === void 0 || result === null) return null;
2794
3095
  return formatToolResult(result);
2795
3096
  }, [result]);
2796
3097
  const hasBody = Boolean(formattedArgs || formattedResult);
2797
3098
  const action = isError ? "Failed" : "Used";
2798
3099
  if (!hasBody) {
2799
- return /* @__PURE__ */ jsx18("div", { className: "aui-tool-row w-full min-w-0", children: /* @__PURE__ */ jsx18(TimelineActionLabel, { action, detail }) });
3100
+ return /* @__PURE__ */ jsx19("div", { className: "aui-tool-row w-full min-w-0", children: /* @__PURE__ */ jsx19(TimelineActionLabel, { action, detail }) });
2800
3101
  }
2801
- return /* @__PURE__ */ jsxs9("div", { className: "aui-tool-row w-full min-w-0", children: [
2802
- /* @__PURE__ */ jsx18(
3102
+ return /* @__PURE__ */ jsxs10("div", { className: "aui-tool-row w-full min-w-0", children: [
3103
+ /* @__PURE__ */ jsx19(
2803
3104
  "button",
2804
3105
  {
2805
3106
  type: "button",
@@ -2807,7 +3108,7 @@ var ToolPanel = ({ toolName, argsText, result, isError }) => {
2807
3108
  "aria-expanded": open,
2808
3109
  "aria-label": `${action} ${detail}`,
2809
3110
  className: studioTimelineRowButtonClass,
2810
- children: /* @__PURE__ */ jsxs9(
3111
+ children: /* @__PURE__ */ jsxs10(
2811
3112
  "span",
2812
3113
  {
2813
3114
  className: cn(
@@ -2816,37 +3117,37 @@ var ToolPanel = ({ toolName, argsText, result, isError }) => {
2816
3117
  "text-foreground"
2817
3118
  ),
2818
3119
  children: [
2819
- /* @__PURE__ */ jsx18(TimelineActionLabel, { action, detail }),
2820
- /* @__PURE__ */ jsx18(TimelineHoverChevron, { expanded: open })
3120
+ /* @__PURE__ */ jsx19(TimelineActionLabel, { action, detail }),
3121
+ /* @__PURE__ */ jsx19(TimelineHoverChevron, { expanded: open })
2821
3122
  ]
2822
3123
  }
2823
3124
  )
2824
3125
  }
2825
3126
  ),
2826
- /* @__PURE__ */ jsxs9(
3127
+ /* @__PURE__ */ jsxs10(
2827
3128
  ToolBodyPresence,
2828
3129
  {
2829
3130
  open,
2830
3131
  className: cn(studioTimelineBodyPadClass, "gap-2"),
2831
3132
  children: [
2832
- formattedArgs ? /* @__PURE__ */ jsx18(
3133
+ formattedArgs ? /* @__PURE__ */ jsx19(
2833
3134
  "div",
2834
3135
  {
2835
3136
  className: cn(
2836
3137
  studioComposerIoWellClass,
2837
3138
  "max-h-48 overflow-auto px-2.5 py-2"
2838
3139
  ),
2839
- children: /* @__PURE__ */ jsx18("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] font-normal leading-relaxed text-foreground", children: formattedArgs })
3140
+ children: /* @__PURE__ */ jsx19("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] font-normal leading-relaxed text-foreground", children: formattedArgs })
2840
3141
  }
2841
3142
  ) : null,
2842
- formattedResult ? /* @__PURE__ */ jsx18(
3143
+ formattedResult ? /* @__PURE__ */ jsx19(
2843
3144
  "div",
2844
3145
  {
2845
3146
  className: cn(
2846
3147
  studioComposerIoWellClass,
2847
3148
  "max-h-48 overflow-auto px-2.5 py-2"
2848
3149
  ),
2849
- children: /* @__PURE__ */ jsx18("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] font-normal leading-relaxed text-foreground", children: formattedResult })
3150
+ children: /* @__PURE__ */ jsx19("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] font-normal leading-relaxed text-foreground", children: formattedResult })
2850
3151
  }
2851
3152
  ) : null
2852
3153
  ]
@@ -2863,20 +3164,20 @@ var ToolFallbackImpl = ({
2863
3164
  const isRunning = useToolRunning({ status, result });
2864
3165
  const isError = status?.type === "incomplete" && status.reason !== "cancelled";
2865
3166
  const presenceKey = isRunning ? "running" : isError ? "error" : "complete";
2866
- return /* @__PURE__ */ jsx18(
3167
+ return /* @__PURE__ */ jsx19(
2867
3168
  ToolPresence,
2868
3169
  {
2869
3170
  presenceKey,
2870
3171
  variant: isRunning ? "executing" : "settled",
2871
3172
  className: "py-0.5",
2872
- children: isRunning ? /* @__PURE__ */ jsx18("div", { className: "aui-tool-running", children: /* @__PURE__ */ jsx18(
3173
+ children: isRunning ? /* @__PURE__ */ jsx19("div", { className: "aui-tool-running", children: /* @__PURE__ */ jsx19(
2873
3174
  TimelineActionLabel,
2874
3175
  {
2875
3176
  action: "Using",
2876
3177
  detail: formatToolLabel(toolName),
2877
3178
  shimmer: true
2878
3179
  }
2879
- ) }) : /* @__PURE__ */ jsx18(
3180
+ ) }) : /* @__PURE__ */ jsx19(
2880
3181
  ToolPanel,
2881
3182
  {
2882
3183
  toolName,
@@ -2894,7 +3195,7 @@ var ToolFallback = memo2(
2894
3195
  ToolFallback.displayName = "ToolFallback";
2895
3196
 
2896
3197
  // src/artifacts/tool-artifact.tsx
2897
- import { jsx as jsx19 } from "react/jsx-runtime";
3198
+ import { jsx as jsx20 } from "react/jsx-runtime";
2898
3199
  var ToolArtifactFallback = (props) => {
2899
3200
  const registry = useArtifactRegistry();
2900
3201
  const isRunning = useToolRunning({
@@ -2906,18 +3207,18 @@ var ToolArtifactFallback = (props) => {
2906
3207
  if (artifact) {
2907
3208
  const Renderer = registry[artifact.type];
2908
3209
  if (Renderer) {
2909
- return /* @__PURE__ */ jsx19(
3210
+ return /* @__PURE__ */ jsx20(
2910
3211
  ToolMotion,
2911
3212
  {
2912
3213
  motionKey: `artifact-${artifact.type}`,
2913
3214
  className: "aui-tool-artifact",
2914
- children: /* @__PURE__ */ jsx19(Renderer, { artifact })
3215
+ children: /* @__PURE__ */ jsx20(Renderer, { artifact })
2915
3216
  }
2916
3217
  );
2917
3218
  }
2918
3219
  }
2919
3220
  }
2920
- return /* @__PURE__ */ jsx19(ToolFallback, { ...props });
3221
+ return /* @__PURE__ */ jsx20(ToolFallback, { ...props });
2921
3222
  };
2922
3223
 
2923
3224
  // src/chat/composer.tsx
@@ -2927,7 +3228,7 @@ import {
2927
3228
  useComposerRuntime
2928
3229
  } from "@assistant-ui/react";
2929
3230
  import { ArrowUpIcon, SquareIcon } from "lucide-react";
2930
- import { Fragment as Fragment2, jsx as jsx20, jsxs as jsxs10 } from "react/jsx-runtime";
3231
+ import { Fragment, jsx as jsx21, jsxs as jsxs11 } from "react/jsx-runtime";
2931
3232
  var Composer = ({
2932
3233
  placeholder = "Send a message...",
2933
3234
  showAttachments,
@@ -2938,10 +3239,10 @@ var Composer = ({
2938
3239
  }) => {
2939
3240
  const attachmentsEnabled = useTimbalAttachmentsEnabled();
2940
3241
  const attachUi = showAttachments !== false && attachmentsEnabled;
2941
- const shell = /* @__PURE__ */ jsxs10(Fragment2, { children: [
2942
- attachUi && /* @__PURE__ */ jsx20(ComposerAttachments, {}),
2943
- /* @__PURE__ */ jsx20(ComposerInput, { placeholder, autoFocus: !noAutoFocus }),
2944
- /* @__PURE__ */ jsx20(
3242
+ const shell = /* @__PURE__ */ jsxs11(Fragment, { children: [
3243
+ attachUi && /* @__PURE__ */ jsx21(ComposerAttachments, {}),
3244
+ /* @__PURE__ */ jsx21(ComposerInput, { placeholder, autoFocus: !noAutoFocus }),
3245
+ /* @__PURE__ */ jsx21(
2945
3246
  ComposerToolbar,
2946
3247
  {
2947
3248
  showAttachments: attachUi,
@@ -2950,14 +3251,14 @@ var Composer = ({
2950
3251
  }
2951
3252
  )
2952
3253
  ] });
2953
- return /* @__PURE__ */ jsx20(
3254
+ return /* @__PURE__ */ jsx21(
2954
3255
  ComposerPrimitive2.Root,
2955
3256
  {
2956
3257
  className: cn(
2957
3258
  "aui-composer-root relative flex w-full flex-col",
2958
3259
  className
2959
3260
  ),
2960
- children: attachUi ? /* @__PURE__ */ jsx20(
3261
+ children: attachUi ? /* @__PURE__ */ jsx21(
2961
3262
  ComposerPrimitive2.AttachmentDropzone,
2962
3263
  {
2963
3264
  className: cn(
@@ -2966,7 +3267,7 @@ var Composer = ({
2966
3267
  ),
2967
3268
  children: shell
2968
3269
  }
2969
- ) : /* @__PURE__ */ jsx20("div", { className: studioComposeInputShellClass, children: shell })
3270
+ ) : /* @__PURE__ */ jsx21("div", { className: studioComposeInputShellClass, children: shell })
2970
3271
  }
2971
3272
  );
2972
3273
  };
@@ -2986,7 +3287,7 @@ var ComposerInput = ({
2986
3287
  el.style.height = "auto";
2987
3288
  el.style.height = `${Math.min(el.scrollHeight, 240)}px`;
2988
3289
  };
2989
- return /* @__PURE__ */ jsx20(
3290
+ return /* @__PURE__ */ jsx21(
2990
3291
  ComposerPrimitive2.Input,
2991
3292
  {
2992
3293
  placeholder,
@@ -3000,17 +3301,17 @@ var ComposerInput = ({
3000
3301
  );
3001
3302
  };
3002
3303
  var ComposerToolbar = ({ showAttachments, toolbar, sendTooltip }) => {
3003
- return /* @__PURE__ */ jsxs10("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: [
3004
- /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1", children: [
3005
- showAttachments && /* @__PURE__ */ jsx20(ComposerAddAttachment, {}),
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, {}),
3006
3307
  toolbar
3007
3308
  ] }),
3008
- /* @__PURE__ */ jsx20(ComposerSendOrCancel, { sendTooltip })
3309
+ /* @__PURE__ */ jsx21(ComposerSendOrCancel, { sendTooltip })
3009
3310
  ] });
3010
3311
  };
3011
3312
  var ComposerSendOrCancel = ({ sendTooltip }) => {
3012
- return /* @__PURE__ */ jsxs10(Fragment2, { children: [
3013
- /* @__PURE__ */ jsx20(AuiIf, { condition: (s) => !s.thread.isRunning, children: /* @__PURE__ */ jsx20(ComposerPrimitive2.Send, { asChild: true, children: /* @__PURE__ */ jsx20(
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(
3014
3315
  TooltipIconButton,
3015
3316
  {
3016
3317
  tooltip: sendTooltip,
@@ -3018,17 +3319,17 @@ var ComposerSendOrCancel = ({ sendTooltip }) => {
3018
3319
  type: "submit",
3019
3320
  className: "aui-composer-send shrink-0 disabled:opacity-30",
3020
3321
  "aria-label": "Send message",
3021
- children: /* @__PURE__ */ jsx20(ArrowUpIcon, { className: "aui-composer-send-icon size-4" })
3322
+ children: /* @__PURE__ */ jsx21(ArrowUpIcon, { className: "aui-composer-send-icon size-4" })
3022
3323
  }
3023
3324
  ) }) }),
3024
- /* @__PURE__ */ jsx20(AuiIf, { condition: (s) => s.thread.isRunning, children: /* @__PURE__ */ jsx20(ComposerPrimitive2.Cancel, { asChild: true, children: /* @__PURE__ */ jsx20(
3325
+ /* @__PURE__ */ jsx21(AuiIf, { condition: (s) => s.thread.isRunning, children: /* @__PURE__ */ jsx21(ComposerPrimitive2.Cancel, { asChild: true, children: /* @__PURE__ */ jsx21(
3025
3326
  TooltipIconButton,
3026
3327
  {
3027
3328
  tooltip: "Stop generating",
3028
3329
  variant: "primary",
3029
3330
  className: "aui-composer-cancel shrink-0",
3030
3331
  "aria-label": "Stop generating",
3031
- children: /* @__PURE__ */ jsx20(SquareIcon, { className: "aui-composer-cancel-icon size-3 fill-current" })
3332
+ children: /* @__PURE__ */ jsx21(SquareIcon, { className: "aui-composer-cancel-icon size-3 fill-current" })
3032
3333
  }
3033
3334
  ) }) })
3034
3335
  ] });
@@ -3036,20 +3337,20 @@ var ComposerSendOrCancel = ({ sendTooltip }) => {
3036
3337
 
3037
3338
  // src/chat/suggestions.tsx
3038
3339
  import {
3039
- useEffect as useEffect4,
3040
- useMemo as useMemo5,
3041
- useState as useState7
3340
+ useEffect as useEffect6,
3341
+ useMemo as useMemo6,
3342
+ useState as useState9
3042
3343
  } from "react";
3043
3344
  import { useThreadRuntime as useThreadRuntime3 } from "@assistant-ui/react";
3044
3345
  import { ArrowUpIcon as ArrowUpIcon2 } from "lucide-react";
3045
- import { jsx as jsx21, jsxs as jsxs11 } from "react/jsx-runtime";
3346
+ import { jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
3046
3347
  var Suggestions = ({
3047
3348
  suggestions,
3048
3349
  className
3049
3350
  }) => {
3050
3351
  const items = useResolvedSuggestions(suggestions);
3051
3352
  if (!items || items.length === 0) return null;
3052
- return /* @__PURE__ */ jsx21(
3353
+ return /* @__PURE__ */ jsx22(
3053
3354
  "div",
3054
3355
  {
3055
3356
  className: cn(
@@ -3058,7 +3359,7 @@ var Suggestions = ({
3058
3359
  ),
3059
3360
  role: "list",
3060
3361
  "aria-label": "Suggested prompts",
3061
- children: items.map((suggestion, i) => /* @__PURE__ */ jsx21(SuggestionRow, { suggestion }, (suggestion.prompt ?? suggestion.title) + i))
3362
+ children: items.map((suggestion, i) => /* @__PURE__ */ jsx22(SuggestionRow, { suggestion }, (suggestion.prompt ?? suggestion.title) + i))
3062
3363
  }
3063
3364
  );
3064
3365
  };
@@ -3068,7 +3369,7 @@ var SuggestionRow = ({ suggestion }) => {
3068
3369
  const text = suggestion.prompt ?? suggestion.title;
3069
3370
  runtime.append({ role: "user", content: [{ type: "text", text }] });
3070
3371
  };
3071
- return /* @__PURE__ */ jsxs11(
3372
+ return /* @__PURE__ */ jsxs12(
3072
3373
  "button",
3073
3374
  {
3074
3375
  type: "button",
@@ -3076,20 +3377,20 @@ var SuggestionRow = ({ suggestion }) => {
3076
3377
  onClick,
3077
3378
  className: cn("aui-thread-suggestion", studioListRowButtonClass),
3078
3379
  children: [
3079
- /* @__PURE__ */ jsx21("span", { className: "aui-thread-suggestion-icon shrink-0 text-muted-foreground", children: suggestion.icon ?? /* @__PURE__ */ jsx21(ArrowUpIcon2, { className: "size-4", strokeWidth: 1.75, "aria-hidden": true }) }),
3080
- /* @__PURE__ */ jsxs11("span", { className: "aui-thread-suggestion-text min-w-0 flex-1 text-left", children: [
3081
- /* @__PURE__ */ jsx21("span", { className: "aui-thread-suggestion-text-1 block truncate text-sm font-normal text-foreground", children: suggestion.title }),
3082
- suggestion.description && /* @__PURE__ */ jsx21("span", { className: "aui-thread-suggestion-text-2 mt-0.5 block truncate text-xs text-muted-foreground", children: suggestion.description })
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 })
3083
3384
  ] })
3084
3385
  ]
3085
3386
  }
3086
3387
  );
3087
3388
  };
3088
3389
  function useResolvedSuggestions(source) {
3089
- const [resolved, setResolved] = useState7(
3390
+ const [resolved, setResolved] = useState9(
3090
3391
  () => Array.isArray(source) ? source : void 0
3091
3392
  );
3092
- useEffect4(() => {
3393
+ useEffect6(() => {
3093
3394
  if (!source) {
3094
3395
  setResolved(void 0);
3095
3396
  return;
@@ -3108,11 +3409,11 @@ function useResolvedSuggestions(source) {
3108
3409
  cancelled = true;
3109
3410
  };
3110
3411
  }, [source]);
3111
- return useMemo5(() => resolved, [resolved]);
3412
+ return useMemo6(() => resolved, [resolved]);
3112
3413
  }
3113
3414
 
3114
3415
  // src/chat/thread.tsx
3115
- import { useEffect as useEffect5 } from "react";
3416
+ import { useEffect as useEffect7 } from "react";
3116
3417
  import {
3117
3418
  ActionBarMorePrimitive,
3118
3419
  ActionBarPrimitive,
@@ -3213,7 +3514,7 @@ function useThreadVariant() {
3213
3514
  }
3214
3515
 
3215
3516
  // src/chat/thread.tsx
3216
- import { jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
3517
+ import { jsx as jsx23, jsxs as jsxs13 } from "react/jsx-runtime";
3217
3518
  var Thread = ({
3218
3519
  className,
3219
3520
  variant = "default",
@@ -3235,16 +3536,16 @@ var Thread = ({
3235
3536
  const EditComposerSlot = components?.EditComposer ?? EditComposer;
3236
3537
  const ScrollToBottomSlot = components?.ScrollToBottom ?? ThreadScrollToBottom;
3237
3538
  const SuggestionsSlot = components?.Suggestions ?? Suggestions;
3238
- useEffect5(() => {
3539
+ useEffect7(() => {
3239
3540
  scheduleThemeSanityCheck();
3240
3541
  }, []);
3241
- return /* @__PURE__ */ jsx22(ThreadVariantProvider, { value: variant, children: /* @__PURE__ */ jsx22(
3542
+ return /* @__PURE__ */ jsx23(ThreadVariantProvider, { value: variant, children: /* @__PURE__ */ jsx23(
3242
3543
  ArtifactRegistryProvider,
3243
3544
  {
3244
3545
  renderers: artifacts?.renderers,
3245
3546
  override: artifacts?.override,
3246
- children: /* @__PURE__ */ jsx22(UiEventProvider, { onEvent: onArtifactEvent ?? (() => {
3247
- }), children: /* @__PURE__ */ jsx22(
3547
+ children: /* @__PURE__ */ jsx23(UiEventProvider, { onEvent: onArtifactEvent ?? (() => {
3548
+ }), children: /* @__PURE__ */ jsx23(
3248
3549
  ThreadPrimitive.Root,
3249
3550
  {
3250
3551
  className: cn(
@@ -3254,7 +3555,7 @@ var Thread = ({
3254
3555
  ),
3255
3556
  style: { ["--thread-max-width"]: maxWidth },
3256
3557
  "data-thread-variant": variant,
3257
- children: /* @__PURE__ */ jsxs12(
3558
+ children: /* @__PURE__ */ jsxs13(
3258
3559
  ThreadPrimitive.Viewport,
3259
3560
  {
3260
3561
  turnAnchor: "bottom",
@@ -3263,7 +3564,7 @@ var Thread = ({
3263
3564
  isPanel ? "px-2 pt-2" : "px-4 pt-4"
3264
3565
  ),
3265
3566
  children: [
3266
- /* @__PURE__ */ jsx22(
3567
+ /* @__PURE__ */ jsx23(
3267
3568
  WelcomeSlot,
3268
3569
  {
3269
3570
  config: welcome,
@@ -3271,7 +3572,7 @@ var Thread = ({
3271
3572
  Suggestions: SuggestionsSlot
3272
3573
  }
3273
3574
  ),
3274
- /* @__PURE__ */ jsx22(
3575
+ /* @__PURE__ */ jsx23(
3275
3576
  ThreadPrimitive.Messages,
3276
3577
  {
3277
3578
  components: {
@@ -3281,14 +3582,14 @@ var Thread = ({
3281
3582
  }
3282
3583
  }
3283
3584
  ),
3284
- /* @__PURE__ */ jsx22(
3585
+ /* @__PURE__ */ jsx23(
3285
3586
  ThreadPrimitive.ViewportFooter,
3286
3587
  {
3287
3588
  className: cn(
3288
3589
  "aui-thread-viewport-footer sticky bottom-0 z-10 mt-auto w-full isolate pt-2",
3289
3590
  isPanel ? "bg-card pb-2" : "bg-background pb-4 md:pb-6"
3290
3591
  ),
3291
- children: /* @__PURE__ */ jsxs12(
3592
+ children: /* @__PURE__ */ jsxs13(
3292
3593
  "div",
3293
3594
  {
3294
3595
  className: cn(
@@ -3296,8 +3597,8 @@ var Thread = ({
3296
3597
  isPanel ? "gap-2" : "gap-4"
3297
3598
  ),
3298
3599
  children: [
3299
- /* @__PURE__ */ jsx22(ScrollToBottomSlot, {}),
3300
- /* @__PURE__ */ jsx22(ComposerSlot, { placeholder })
3600
+ /* @__PURE__ */ jsx23(ScrollToBottomSlot, {}),
3601
+ /* @__PURE__ */ jsx23(ComposerSlot, { placeholder })
3301
3602
  ]
3302
3603
  }
3303
3604
  )
@@ -3312,13 +3613,13 @@ var Thread = ({
3312
3613
  ) });
3313
3614
  };
3314
3615
  var ThreadScrollToBottom = () => {
3315
- return /* @__PURE__ */ jsx22(ThreadPrimitive.ScrollToBottom, { asChild: true, children: /* @__PURE__ */ jsx22(
3616
+ return /* @__PURE__ */ jsx23(ThreadPrimitive.ScrollToBottom, { asChild: true, children: /* @__PURE__ */ jsx23(
3316
3617
  TooltipIconButton,
3317
3618
  {
3318
3619
  tooltip: "Scroll to bottom",
3319
3620
  variant: "secondary",
3320
3621
  className: "aui-thread-scroll-to-bottom absolute -top-12 z-10 self-center disabled:invisible",
3321
- children: /* @__PURE__ */ jsx22(ArrowDownIcon, { className: "size-4" })
3622
+ children: /* @__PURE__ */ jsx23(ArrowDownIcon, { className: "size-4" })
3322
3623
  }
3323
3624
  ) });
3324
3625
  };
@@ -3355,8 +3656,8 @@ var ThreadWelcome = ({
3355
3656
  if (!isEmpty) return null;
3356
3657
  const defaultHeading = isPanel ? "Ask about this page" : "How can I help you today?";
3357
3658
  const defaultSubheading = isPanel ? "The assistant can use dashboard context from your app." : "Send a message to start a conversation.";
3358
- return /* @__PURE__ */ jsxs12("div", { className: "aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col", children: [
3359
- /* @__PURE__ */ jsx22("div", { className: "aui-thread-welcome-center flex w-full grow flex-col items-center justify-center", children: /* @__PURE__ */ jsxs12(
3659
+ 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: [
3660
+ /* @__PURE__ */ jsx23("div", { className: "aui-thread-welcome-center flex w-full grow flex-col items-center justify-center", children: /* @__PURE__ */ jsxs13(
3360
3661
  motion3.div,
3361
3662
  {
3362
3663
  className: cn(
@@ -3367,8 +3668,8 @@ var ThreadWelcome = ({
3367
3668
  initial: "initial",
3368
3669
  animate: "animate",
3369
3670
  children: [
3370
- config?.icon && /* @__PURE__ */ jsx22(motion3.div, { variants: welcomeIcon, className: isPanel ? "mb-3" : "mb-5", children: config.icon }),
3371
- /* @__PURE__ */ jsx22(
3671
+ config?.icon && /* @__PURE__ */ jsx23(motion3.div, { variants: welcomeIcon, className: isPanel ? "mb-3" : "mb-5", children: config.icon }),
3672
+ /* @__PURE__ */ jsx23(
3372
3673
  motion3.h1,
3373
3674
  {
3374
3675
  variants: welcomeItem,
@@ -3379,7 +3680,7 @@ var ThreadWelcome = ({
3379
3680
  children: config?.heading ?? defaultHeading
3380
3681
  }
3381
3682
  ),
3382
- /* @__PURE__ */ jsx22(
3683
+ /* @__PURE__ */ jsx23(
3383
3684
  motion3.p,
3384
3685
  {
3385
3686
  variants: welcomeItem,
@@ -3390,15 +3691,15 @@ var ThreadWelcome = ({
3390
3691
  ]
3391
3692
  }
3392
3693
  ) }),
3393
- suggestions && !isPanel ? /* @__PURE__ */ jsx22("div", { className: "aui-thread-welcome-suggestions mx-auto w-full max-w-(--thread-max-width) px-2", children: /* @__PURE__ */ jsx22(SuggestionsSlot, { suggestions }) }) : null
3694
+ suggestions && !isPanel ? /* @__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
3394
3695
  ] });
3395
3696
  };
3396
3697
  var MessageError = () => {
3397
- return /* @__PURE__ */ jsx22(MessagePrimitive2.Error, { children: /* @__PURE__ */ jsx22(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__ */ jsx22(ErrorPrimitive.Message, { className: "aui-message-error-message line-clamp-2" }) }) });
3698
+ 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" }) }) });
3398
3699
  };
3399
3700
  var AssistantMessage = () => {
3400
3701
  const isPanel = useThreadVariant() === "panel";
3401
- return /* @__PURE__ */ jsxs12(
3702
+ return /* @__PURE__ */ jsxs13(
3402
3703
  MessagePrimitive2.Root,
3403
3704
  {
3404
3705
  className: cn(
@@ -3407,7 +3708,7 @@ var AssistantMessage = () => {
3407
3708
  ),
3408
3709
  "data-role": "assistant",
3409
3710
  children: [
3410
- /* @__PURE__ */ jsxs12(
3711
+ /* @__PURE__ */ jsxs13(
3411
3712
  "div",
3412
3713
  {
3413
3714
  className: cn(
@@ -3415,7 +3716,7 @@ var AssistantMessage = () => {
3415
3716
  isPanel ? "px-1 text-sm" : "px-2"
3416
3717
  ),
3417
3718
  children: [
3418
- /* @__PURE__ */ jsx22(
3719
+ /* @__PURE__ */ jsx23(
3419
3720
  MessagePrimitive2.Parts,
3420
3721
  {
3421
3722
  components: {
@@ -3426,11 +3727,11 @@ var AssistantMessage = () => {
3426
3727
  }
3427
3728
  }
3428
3729
  ),
3429
- /* @__PURE__ */ jsx22(MessageError, {})
3730
+ /* @__PURE__ */ jsx23(MessageError, {})
3430
3731
  ]
3431
3732
  }
3432
3733
  ),
3433
- /* @__PURE__ */ jsx22("div", { className: "aui-assistant-message-footer mt-1 mb-3 ml-1 flex", children: /* @__PURE__ */ jsx22(AssistantActionBar, {}) })
3734
+ /* @__PURE__ */ jsx23("div", { className: "aui-assistant-message-footer mt-1 mb-3 ml-1 flex", children: /* @__PURE__ */ jsx23(AssistantActionBar, {}) })
3434
3735
  ]
3435
3736
  }
3436
3737
  );
@@ -3443,36 +3744,36 @@ var ASSISTANT_ACTION_ICON_CLASS = cn(
3443
3744
  "[&>span:first-child]:group-hover/tbv2:bg-ghost-fill-hover"
3444
3745
  );
3445
3746
  var AssistantActionBar = () => {
3446
- return /* @__PURE__ */ jsxs12(
3747
+ return /* @__PURE__ */ jsxs13(
3447
3748
  ActionBarPrimitive.Root,
3448
3749
  {
3449
3750
  hideWhenRunning: true,
3450
3751
  autohide: "never",
3451
3752
  className: "aui-assistant-action-bar-root flex items-center gap-0 bg-transparent px-0 py-0.5 text-muted-foreground/60",
3452
3753
  children: [
3453
- /* @__PURE__ */ jsx22(ActionBarPrimitive.Copy, { asChild: true, children: /* @__PURE__ */ jsxs12(
3754
+ /* @__PURE__ */ jsx23(ActionBarPrimitive.Copy, { asChild: true, children: /* @__PURE__ */ jsxs13(
3454
3755
  TooltipIconButton,
3455
3756
  {
3456
3757
  tooltip: "Copy",
3457
3758
  variant: "ghost",
3458
3759
  className: ASSISTANT_ACTION_ICON_CLASS,
3459
3760
  children: [
3460
- /* @__PURE__ */ jsx22(AuiIf2, { condition: (s) => s.message.isCopied, children: /* @__PURE__ */ jsx22(CheckIcon3, { className: "size-3" }) }),
3461
- /* @__PURE__ */ jsx22(AuiIf2, { condition: (s) => !s.message.isCopied, children: /* @__PURE__ */ jsx22(CopyIcon2, { className: "size-3" }) })
3761
+ /* @__PURE__ */ jsx23(AuiIf2, { condition: (s) => s.message.isCopied, children: /* @__PURE__ */ jsx23(CheckIcon3, { className: "size-3" }) }),
3762
+ /* @__PURE__ */ jsx23(AuiIf2, { condition: (s) => !s.message.isCopied, children: /* @__PURE__ */ jsx23(CopyIcon2, { className: "size-3" }) })
3462
3763
  ]
3463
3764
  }
3464
3765
  ) }),
3465
- /* @__PURE__ */ jsx22(ActionBarPrimitive.Reload, { asChild: true, children: /* @__PURE__ */ jsx22(
3766
+ /* @__PURE__ */ jsx23(ActionBarPrimitive.Reload, { asChild: true, children: /* @__PURE__ */ jsx23(
3466
3767
  TooltipIconButton,
3467
3768
  {
3468
3769
  tooltip: "Regenerate",
3469
3770
  variant: "ghost",
3470
3771
  className: ASSISTANT_ACTION_ICON_CLASS,
3471
- children: /* @__PURE__ */ jsx22(RefreshCwIcon, { className: "size-3" })
3772
+ children: /* @__PURE__ */ jsx23(RefreshCwIcon, { className: "size-3" })
3472
3773
  }
3473
3774
  ) }),
3474
- /* @__PURE__ */ jsxs12(ActionBarMorePrimitive.Root, { children: [
3475
- /* @__PURE__ */ jsx22(ActionBarMorePrimitive.Trigger, { asChild: true, children: /* @__PURE__ */ jsx22(
3775
+ /* @__PURE__ */ jsxs13(ActionBarMorePrimitive.Root, { children: [
3776
+ /* @__PURE__ */ jsx23(ActionBarMorePrimitive.Trigger, { asChild: true, children: /* @__PURE__ */ jsx23(
3476
3777
  TooltipIconButton,
3477
3778
  {
3478
3779
  tooltip: "More",
@@ -3481,17 +3782,17 @@ var AssistantActionBar = () => {
3481
3782
  ASSISTANT_ACTION_ICON_CLASS,
3482
3783
  "data-[state=open]:text-muted-foreground/80"
3483
3784
  ),
3484
- children: /* @__PURE__ */ jsx22(MoreHorizontalIcon, { className: "size-3" })
3785
+ children: /* @__PURE__ */ jsx23(MoreHorizontalIcon, { className: "size-3" })
3485
3786
  }
3486
3787
  ) }),
3487
- /* @__PURE__ */ jsx22(
3788
+ /* @__PURE__ */ jsx23(
3488
3789
  ActionBarMorePrimitive.Content,
3489
3790
  {
3490
3791
  side: "bottom",
3491
3792
  align: "start",
3492
3793
  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",
3493
- children: /* @__PURE__ */ jsx22(ActionBarPrimitive.ExportMarkdown, { asChild: true, children: /* @__PURE__ */ jsxs12(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: [
3494
- /* @__PURE__ */ jsx22(DownloadIcon, { className: "size-4 shrink-0" }),
3794
+ 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: [
3795
+ /* @__PURE__ */ jsx23(DownloadIcon, { className: "size-4 shrink-0" }),
3495
3796
  "Export as Markdown"
3496
3797
  ] }) })
3497
3798
  }
@@ -3502,11 +3803,11 @@ var AssistantActionBar = () => {
3502
3803
  );
3503
3804
  };
3504
3805
  var UserMessageText = () => {
3505
- return /* @__PURE__ */ jsx22("span", { className: "whitespace-pre-wrap", children: /* @__PURE__ */ jsx22(MessagePartPrimitive.Text, { smooth: false }) });
3806
+ return /* @__PURE__ */ jsx23("span", { className: "whitespace-pre-wrap", children: /* @__PURE__ */ jsx23(MessagePartPrimitive.Text, { smooth: false }) });
3506
3807
  };
3507
3808
  var UserMessage = () => {
3508
3809
  const isPanel = useThreadVariant() === "panel";
3509
- return /* @__PURE__ */ jsxs12(
3810
+ return /* @__PURE__ */ jsxs13(
3510
3811
  MessagePrimitive2.Root,
3511
3812
  {
3512
3813
  className: cn(
@@ -3515,8 +3816,8 @@ var UserMessage = () => {
3515
3816
  ),
3516
3817
  "data-role": "user",
3517
3818
  children: [
3518
- /* @__PURE__ */ jsx22(UserMessageAttachments, {}),
3519
- /* @__PURE__ */ jsxs12(
3819
+ /* @__PURE__ */ jsx23(UserMessageAttachments, {}),
3820
+ /* @__PURE__ */ jsxs13(
3520
3821
  motion3.div,
3521
3822
  {
3522
3823
  className: cn(
@@ -3527,8 +3828,8 @@ var UserMessage = () => {
3527
3828
  animate: { opacity: 1, y: 0, scale: 1 },
3528
3829
  transition: { duration: 0.65, ease: luxuryEase },
3529
3830
  children: [
3530
- /* @__PURE__ */ jsx22(MessagePrimitive2.Parts, { components: { Text: UserMessageText } }),
3531
- /* @__PURE__ */ jsx22("div", { className: "aui-user-action-bar-wrapper absolute top-1/2 left-0 -translate-x-full -translate-y-1/2 pr-2", children: /* @__PURE__ */ jsx22(UserActionBar, {}) })
3831
+ /* @__PURE__ */ jsx23(MessagePrimitive2.Parts, { components: { Text: UserMessageText } }),
3832
+ /* @__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, {}) })
3532
3833
  ]
3533
3834
  }
3534
3835
  )
@@ -3537,42 +3838,42 @@ var UserMessage = () => {
3537
3838
  );
3538
3839
  };
3539
3840
  var UserActionBar = () => {
3540
- return /* @__PURE__ */ jsx22(
3841
+ return /* @__PURE__ */ jsx23(
3541
3842
  ActionBarPrimitive.Root,
3542
3843
  {
3543
3844
  hideWhenRunning: true,
3544
3845
  autohide: "always",
3545
3846
  className: "aui-user-action-bar-root flex flex-col items-end",
3546
- children: /* @__PURE__ */ jsx22(ActionBarPrimitive.Edit, { asChild: true, children: /* @__PURE__ */ jsx22(
3847
+ children: /* @__PURE__ */ jsx23(ActionBarPrimitive.Edit, { asChild: true, children: /* @__PURE__ */ jsx23(
3547
3848
  TooltipIconButton,
3548
3849
  {
3549
3850
  tooltip: "Edit",
3550
3851
  variant: "ghost",
3551
3852
  className: ASSISTANT_ACTION_ICON_CLASS,
3552
- children: /* @__PURE__ */ jsx22(PencilIcon, { className: "size-3" })
3853
+ children: /* @__PURE__ */ jsx23(PencilIcon, { className: "size-3" })
3553
3854
  }
3554
3855
  ) })
3555
3856
  }
3556
3857
  );
3557
3858
  };
3558
3859
  var EditComposer = () => {
3559
- return /* @__PURE__ */ jsx22(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__ */ jsxs12(ComposerPrimitive3.Root, { className: "aui-edit-composer-root ml-auto flex w-full max-w-[85%] flex-col rounded-2xl bg-muted", children: [
3560
- /* @__PURE__ */ jsx22(
3860
+ 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: [
3861
+ /* @__PURE__ */ jsx23(
3561
3862
  ComposerPrimitive3.Input,
3562
3863
  {
3563
3864
  className: "aui-edit-composer-input min-h-14 w-full resize-none bg-transparent p-4 text-foreground text-sm outline-none",
3564
3865
  autoFocus: true
3565
3866
  }
3566
3867
  ),
3567
- /* @__PURE__ */ jsxs12("div", { className: "aui-edit-composer-footer mx-3 mb-3 flex items-center gap-2 self-end", children: [
3568
- /* @__PURE__ */ jsx22(ComposerPrimitive3.Cancel, { asChild: true, children: /* @__PURE__ */ jsx22(TimbalV2Button, { variant: "ghost", size: "sm", children: "Cancel" }) }),
3569
- /* @__PURE__ */ jsx22(ComposerPrimitive3.Send, { asChild: true, children: /* @__PURE__ */ jsx22(TimbalV2Button, { variant: "primary", size: "sm", children: "Update" }) })
3868
+ /* @__PURE__ */ jsxs13("div", { className: "aui-edit-composer-footer mx-3 mb-3 flex items-center gap-2 self-end", children: [
3869
+ /* @__PURE__ */ jsx23(ComposerPrimitive3.Cancel, { asChild: true, children: /* @__PURE__ */ jsx23(TimbalV2Button, { variant: "ghost", size: "sm", children: "Cancel" }) }),
3870
+ /* @__PURE__ */ jsx23(ComposerPrimitive3.Send, { asChild: true, children: /* @__PURE__ */ jsx23(TimbalV2Button, { variant: "primary", size: "sm", children: "Update" }) })
3570
3871
  ] })
3571
3872
  ] }) });
3572
3873
  };
3573
3874
 
3574
3875
  // src/chat/chat.tsx
3575
- import { jsx as jsx23 } from "react/jsx-runtime";
3876
+ import { jsx as jsx24 } from "react/jsx-runtime";
3576
3877
  function TimbalChat({
3577
3878
  workforceId,
3578
3879
  baseUrl,
@@ -3583,7 +3884,7 @@ function TimbalChat({
3583
3884
  debug,
3584
3885
  ...threadProps
3585
3886
  }) {
3586
- return /* @__PURE__ */ jsx23(
3887
+ return /* @__PURE__ */ jsx24(
3587
3888
  TimbalRuntimeProvider,
3588
3889
  {
3589
3890
  workforceId,
@@ -3593,7 +3894,7 @@ function TimbalChat({
3593
3894
  attachmentsUploadUrl,
3594
3895
  attachmentsAccept,
3595
3896
  debug,
3596
- children: /* @__PURE__ */ jsx23(Thread, { ...threadProps })
3897
+ children: /* @__PURE__ */ jsx24(Thread, { ...threadProps })
3597
3898
  }
3598
3899
  );
3599
3900
  }
@@ -3616,6 +3917,11 @@ export {
3616
3917
  UserMessageAttachments,
3617
3918
  ComposerAttachments,
3618
3919
  ComposerAddAttachment,
3920
+ toNum,
3921
+ monotoneLinePath,
3922
+ monotoneAreaPath,
3923
+ CHART_PALETTE,
3924
+ LineAreaChart,
3619
3925
  ArtifactCard,
3620
3926
  ChartArtifactView,
3621
3927
  QuestionArtifactView,