@tangle-network/agent-app 0.42.18 → 0.43.1

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.
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-E7QYOOON.js";
8
8
 
9
9
  // src/web-react/index.tsx
10
- import { useEffect as useEffect6, useMemo as useMemo3, useRef as useRef5, useState as useState7, memo } from "react";
10
+ import { useEffect as useEffect5, useMemo as useMemo3, useRef as useRef4, useState as useState7, memo } from "react";
11
11
 
12
12
  // src/web-react/smooth-text.ts
13
13
  import { useEffect, useRef, useState } from "react";
@@ -490,35 +490,11 @@ async function streamChatTurn(opts) {
490
490
  }
491
491
 
492
492
  // src/web-react/chat-composer.tsx
493
+ import { useCallback, useState as useState3 } from "react";
493
494
  import {
494
- useCallback,
495
- useEffect as useEffect3,
496
- useRef as useRef3,
497
- useState as useState3
498
- } from "react";
499
- import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
500
- function SendGlyph({ className }) {
501
- return /* @__PURE__ */ jsx4("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx4("path", { d: "M22 2 11 13M22 2l-7 20-4-9-9-4 20-7z" }) });
502
- }
503
- function StopGlyph({ className }) {
504
- return /* @__PURE__ */ jsx4("svg", { className, viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": true, children: /* @__PURE__ */ jsx4("rect", { x: "6", y: "6", width: "12", height: "12", rx: "2" }) });
505
- }
506
- function PaperclipGlyph({ className }) {
507
- return /* @__PURE__ */ jsx4("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx4("path", { d: "m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48" }) });
508
- }
509
- function FolderGlyph({ className }) {
510
- return /* @__PURE__ */ jsxs3("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
511
- /* @__PURE__ */ jsx4("path", { d: "M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z" }),
512
- /* @__PURE__ */ jsx4("path", { d: "M12 10v6m-3-3h6" })
513
- ] });
514
- }
515
- function CloseGlyph({ className }) {
516
- return /* @__PURE__ */ jsx4("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx4("path", { d: "M18 6 6 18M6 6l12 12" }) });
517
- }
518
- function UploadGlyph({ className }) {
519
- return /* @__PURE__ */ jsx4("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx4("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12" }) });
520
- }
521
- var MAX_HEIGHT = 168;
495
+ AgentComposer
496
+ } from "@tangle-network/sandbox-ui/chat";
497
+ import { jsx as jsx4 } from "react/jsx-runtime";
522
498
  function ChatComposer({
523
499
  onSend,
524
500
  onCancel,
@@ -529,14 +505,13 @@ function ChatComposer({
529
505
  onValueChange,
530
506
  initialValue,
531
507
  controls,
532
- controlsPlacement = "above",
533
508
  onAttach,
534
509
  onAttachFolder,
535
- pendingFiles = [],
510
+ pendingFiles,
536
511
  onRemoveFile,
537
512
  accept,
538
- dropTitle = "Drop files to add context",
539
- dropDescription = "They attach to your next message.",
513
+ dropTitle,
514
+ dropDescription,
540
515
  focusShortcut = true,
541
516
  sendLabel = "Send",
542
517
  className
@@ -544,11 +519,6 @@ function ChatComposer({
544
519
  const isControlled = value !== void 0;
545
520
  const [internal, setInternal] = useState3(initialValue ?? "");
546
521
  const text = isControlled ? value : internal;
547
- const textareaRef = useRef3(null);
548
- const fileInputRef = useRef3(null);
549
- const folderInputRef = useRef3(null);
550
- const [dragOver, setDragOver] = useState3(false);
551
- const dragDepth = useRef3(0);
552
522
  const setText = useCallback(
553
523
  (next) => {
554
524
  if (!isControlled) setInternal(next);
@@ -556,218 +526,40 @@ function ChatComposer({
556
526
  },
557
527
  [isControlled, onValueChange]
558
528
  );
559
- useEffect3(() => {
560
- const el = textareaRef.current;
561
- if (!el) return;
562
- el.style.height = "auto";
563
- el.style.height = `${Math.min(el.scrollHeight, MAX_HEIGHT)}px`;
564
- }, [text]);
565
- useEffect3(() => {
566
- if (!focusShortcut || disabled) return;
567
- function onKeyDown(e) {
568
- if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "l") {
569
- e.preventDefault();
570
- textareaRef.current?.focus();
571
- }
572
- }
573
- document.addEventListener("keydown", onKeyDown);
574
- return () => document.removeEventListener("keydown", onKeyDown);
575
- }, [focusShortcut, disabled]);
576
- const canSend = text.trim().length > 0 && !isStreaming && !disabled;
577
- const send = useCallback(() => {
529
+ const handleSubmit = useCallback(() => {
578
530
  const trimmed = text.trim();
579
531
  if (!trimmed || isStreaming || disabled) return;
580
532
  onSend(trimmed);
581
533
  setText("");
582
534
  }, [text, isStreaming, disabled, onSend, setText]);
583
- const handleKeyDown = (e) => {
584
- if (e.nativeEvent.isComposing) return;
585
- if (e.key === "Enter" && !e.shiftKey) {
586
- e.preventDefault();
587
- send();
588
- }
589
- };
590
- const handleFileChange = (e) => {
591
- if (e.target.files?.length) onAttach?.(e.target.files);
592
- e.target.value = "";
593
- };
594
- const handleFolderChange = (e) => {
595
- if (e.target.files?.length) (onAttachFolder ?? onAttach)?.(e.target.files);
596
- e.target.value = "";
597
- };
598
- const handleDragEnter = useCallback((e) => {
599
- e.preventDefault();
600
- e.stopPropagation();
601
- dragDepth.current++;
602
- if (e.dataTransfer?.types.includes("Files")) setDragOver(true);
603
- }, []);
604
- const handleDragLeave = useCallback((e) => {
605
- e.preventDefault();
606
- e.stopPropagation();
607
- dragDepth.current--;
608
- if (dragDepth.current <= 0) {
609
- dragDepth.current = 0;
610
- setDragOver(false);
611
- }
612
- }, []);
613
- const handleDragOver = useCallback((e) => {
614
- e.preventDefault();
615
- e.stopPropagation();
616
- if (e.dataTransfer) e.dataTransfer.dropEffect = "copy";
617
- }, []);
618
- const handleDrop = useCallback(
619
- (e) => {
620
- e.preventDefault();
621
- e.stopPropagation();
622
- dragDepth.current = 0;
623
- setDragOver(false);
624
- const files = e.dataTransfer?.files;
625
- if (files?.length) onAttach?.(files);
626
- },
627
- [onAttach]
628
- );
629
- const folderChips = pendingFiles.filter((f) => f.kind === "folder");
630
- const fileChips = pendingFiles.filter((f) => f.kind !== "folder");
631
- const showFooter = controls != null && controlsPlacement === "footer";
632
- const showAbove = controls != null && controlsPlacement === "above";
633
- return /* @__PURE__ */ jsxs3(
634
- "div",
535
+ return /* @__PURE__ */ jsx4(
536
+ AgentComposer,
635
537
  {
636
- className: `relative ${className ?? ""}`,
637
- onDragEnter: onAttach ? handleDragEnter : void 0,
638
- onDragLeave: onAttach ? handleDragLeave : void 0,
639
- onDragOver: onAttach ? handleDragOver : void 0,
640
- onDrop: onAttach ? handleDrop : void 0,
641
- children: [
642
- dragOver && /* @__PURE__ */ jsx4("div", { className: "pointer-events-none absolute inset-0 z-10 flex items-center justify-center rounded-2xl border-2 border-dashed border-primary/50 bg-card/95", children: /* @__PURE__ */ jsxs3("div", { className: "text-center", children: [
643
- /* @__PURE__ */ jsx4("span", { className: "mx-auto mb-2 flex h-11 w-11 items-center justify-center rounded-xl bg-primary/10 text-primary", children: /* @__PURE__ */ jsx4(UploadGlyph, { className: "h-5 w-5" }) }),
644
- /* @__PURE__ */ jsx4("p", { className: "text-sm font-semibold text-foreground", children: dropTitle }),
645
- /* @__PURE__ */ jsx4("p", { className: "mt-0.5 text-xs text-muted-foreground", children: dropDescription })
646
- ] }) }),
647
- showAbove && /* @__PURE__ */ jsx4("div", { className: "mb-1.5 flex flex-wrap items-center gap-1.5 px-1", children: controls }),
648
- pendingFiles.length > 0 && /* @__PURE__ */ jsx4("div", { className: "mb-2 flex flex-wrap gap-1.5", children: [...folderChips, ...fileChips].map((f) => /* @__PURE__ */ jsxs3(
649
- "span",
650
- {
651
- className: `inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs ${f.status === "error" ? "border-destructive/40 text-destructive" : "border-border bg-muted/50 text-foreground"}`,
652
- children: [
653
- f.kind === "folder" ? /* @__PURE__ */ jsx4(FolderGlyph, { className: "h-3 w-3 shrink-0" }) : /* @__PURE__ */ jsx4(PaperclipGlyph, { className: "h-3 w-3 shrink-0" }),
654
- /* @__PURE__ */ jsx4("span", { className: "max-w-[150px] truncate", children: f.name }),
655
- f.fileCount !== void 0 && /* @__PURE__ */ jsxs3("span", { className: "text-muted-foreground", children: [
656
- "(",
657
- f.fileCount,
658
- ")"
659
- ] }),
660
- f.status === "uploading" && /* @__PURE__ */ jsx4("span", { className: "h-3 w-3 animate-spin rounded-full border-2 border-primary border-t-transparent" }),
661
- onRemoveFile && /* @__PURE__ */ jsx4(
662
- "button",
663
- {
664
- type: "button",
665
- "aria-label": `Remove ${f.name}`,
666
- onClick: () => onRemoveFile(f.id),
667
- className: "rounded p-0.5 text-muted-foreground transition hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
668
- children: /* @__PURE__ */ jsx4(CloseGlyph, { className: "h-3 w-3" })
669
- }
670
- )
671
- ]
672
- },
673
- f.id
674
- )) }),
675
- /* @__PURE__ */ jsxs3("div", { className: "flex items-end gap-2 rounded-2xl border border-border bg-card px-2.5 py-2 transition focus-within:border-primary/40 focus-within:ring-2 focus-within:ring-primary/15", children: [
676
- onAttach && /* @__PURE__ */ jsxs3(Fragment2, { children: [
677
- /* @__PURE__ */ jsx4(
678
- "button",
679
- {
680
- type: "button",
681
- onClick: () => fileInputRef.current?.click(),
682
- disabled,
683
- "aria-label": "Attach files",
684
- title: "Attach files",
685
- className: "mb-0.5 shrink-0 rounded-lg p-2 text-muted-foreground transition hover:bg-accent/40 hover:text-foreground disabled:opacity-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
686
- children: /* @__PURE__ */ jsx4(PaperclipGlyph, { className: "h-4 w-4" })
687
- }
688
- ),
689
- /* @__PURE__ */ jsx4("input", { ref: fileInputRef, type: "file", multiple: true, className: "hidden", accept, onChange: handleFileChange })
690
- ] }),
691
- onAttachFolder && /* @__PURE__ */ jsxs3(Fragment2, { children: [
692
- /* @__PURE__ */ jsx4(
693
- "button",
694
- {
695
- type: "button",
696
- onClick: () => folderInputRef.current?.click(),
697
- disabled,
698
- "aria-label": "Attach folder",
699
- title: "Attach folder",
700
- className: "mb-0.5 shrink-0 rounded-lg p-2 text-muted-foreground transition hover:bg-accent/40 hover:text-foreground disabled:opacity-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
701
- children: /* @__PURE__ */ jsx4(FolderGlyph, { className: "h-4 w-4" })
702
- }
703
- ),
704
- /* @__PURE__ */ jsx4(
705
- "input",
706
- {
707
- ref: folderInputRef,
708
- type: "file",
709
- multiple: true,
710
- className: "hidden",
711
- onChange: handleFolderChange,
712
- ...{ webkitdirectory: "" }
713
- }
714
- )
715
- ] }),
716
- /* @__PURE__ */ jsx4(
717
- "textarea",
718
- {
719
- ref: textareaRef,
720
- value: text,
721
- onChange: (e) => setText(e.target.value),
722
- onKeyDown: handleKeyDown,
723
- placeholder,
724
- disabled,
725
- rows: 1,
726
- "aria-label": "Message input",
727
- className: "max-h-[168px] min-h-[40px] flex-1 resize-none bg-transparent px-1.5 py-2 text-[15px] leading-6 text-foreground outline-none placeholder:text-muted-foreground disabled:opacity-50"
728
- }
729
- ),
730
- showFooter && /* @__PURE__ */ jsx4("div", { className: "mb-0.5 flex shrink-0 items-center gap-1.5", children: controls }),
731
- isStreaming ? /* @__PURE__ */ jsxs3(
732
- "button",
733
- {
734
- type: "button",
735
- onClick: onCancel,
736
- "aria-label": "Stop response",
737
- className: "mb-0.5 inline-flex shrink-0 items-center gap-1.5 rounded-full bg-destructive/15 px-3.5 py-2 text-sm font-medium text-destructive transition hover:bg-destructive/25 focus:outline-none focus-visible:ring-2 focus-visible:ring-destructive/50",
738
- children: [
739
- /* @__PURE__ */ jsx4(StopGlyph, { className: "h-3.5 w-3.5" }),
740
- /* @__PURE__ */ jsx4("span", { children: "Stop" })
741
- ]
742
- }
743
- ) : /* @__PURE__ */ jsxs3(
744
- "button",
745
- {
746
- type: "button",
747
- onClick: send,
748
- disabled: !canSend,
749
- "aria-label": "Send message",
750
- className: "mb-0.5 inline-flex shrink-0 items-center gap-1.5 rounded-full bg-primary px-3.5 py-2 text-sm font-medium text-primary-foreground shadow-sm transition hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-40 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-card",
751
- children: [
752
- /* @__PURE__ */ jsx4(SendGlyph, { className: "h-3.5 w-3.5" }),
753
- /* @__PURE__ */ jsx4("span", { children: sendLabel })
754
- ]
755
- }
756
- )
757
- ] }),
758
- focusShortcut && /* @__PURE__ */ jsx4("div", { className: "mt-1.5 flex justify-end px-1", children: /* @__PURE__ */ jsxs3("span", { className: "text-xs text-muted-foreground", children: [
759
- /* @__PURE__ */ jsx4("kbd", { className: "rounded border border-border bg-background px-1 py-0.5 text-[10px]", children: "Cmd" }),
760
- /* @__PURE__ */ jsx4("kbd", { className: "ml-0.5 rounded border border-border bg-background px-1 py-0.5 text-[10px]", children: "L" }),
761
- /* @__PURE__ */ jsx4("span", { className: "ml-1", children: "to focus" })
762
- ] }) })
763
- ]
538
+ value: text,
539
+ onChange: setText,
540
+ onSubmit: handleSubmit,
541
+ placeholder,
542
+ disabled,
543
+ busy: isStreaming,
544
+ onCancel,
545
+ controls,
546
+ onAttach,
547
+ onAttachFolder,
548
+ attachments: pendingFiles,
549
+ onRemoveFile,
550
+ accept,
551
+ dropTitle,
552
+ dropDescription,
553
+ focusShortcut,
554
+ sendLabel,
555
+ className
764
556
  }
765
557
  );
766
558
  }
767
559
 
768
560
  // src/web-react/mission-activity.tsx
769
- import { useCallback as useCallback2, useEffect as useEffect4, useState as useState4 } from "react";
770
- import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
561
+ import { useCallback as useCallback2, useEffect as useEffect3, useState as useState4 } from "react";
562
+ import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
771
563
  var LIVE_STATUSES = /* @__PURE__ */ new Set(["pending", "running"]);
772
564
  var OK_STATUSES = /* @__PURE__ */ new Set(["completed", "done", "succeeded"]);
773
565
  var ERROR_STATUSES = /* @__PURE__ */ new Set(["failed", "error", "cancelled", "aborted"]);
@@ -820,7 +612,7 @@ function RefreshGlyph({ className }) {
820
612
  return /* @__PURE__ */ jsx5("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx5("path", { d: "M21 12a9 9 0 1 1-2.64-6.36M21 3v6h-6" }) });
821
613
  }
822
614
  function CopyGlyph({ className }) {
823
- return /* @__PURE__ */ jsxs4("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
615
+ return /* @__PURE__ */ jsxs3("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
824
616
  /* @__PURE__ */ jsx5("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
825
617
  /* @__PURE__ */ jsx5("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
826
618
  ] });
@@ -837,7 +629,7 @@ function TraceIdCopy({ traceId }) {
837
629
  }
838
630
  );
839
631
  }, [traceId]);
840
- return /* @__PURE__ */ jsxs4(
632
+ return /* @__PURE__ */ jsxs3(
841
633
  "button",
842
634
  {
843
635
  type: "button",
@@ -854,7 +646,7 @@ function TraceIdCopy({ traceId }) {
854
646
  );
855
647
  }
856
648
  function StatusDot({ tone }) {
857
- return /* @__PURE__ */ jsxs4("span", { className: "inline-flex items-center", children: [
649
+ return /* @__PURE__ */ jsxs3("span", { className: "inline-flex items-center", children: [
858
650
  /* @__PURE__ */ jsx5(
859
651
  "span",
860
652
  {
@@ -874,8 +666,8 @@ function FlowWaterfall({ trace }) {
874
666
  const rows = waterfallLayout(trace);
875
667
  if (rows.length === 0) return null;
876
668
  const cost = formatActivityCost(trace.costUsd);
877
- return /* @__PURE__ */ jsxs4("div", { className: "space-y-1", children: [
878
- rows.map((row, i) => /* @__PURE__ */ jsxs4("div", { className: "grid grid-cols-[minmax(0,2fr)_minmax(0,3fr)_auto] items-center gap-2", children: [
669
+ return /* @__PURE__ */ jsxs3("div", { className: "space-y-1", children: [
670
+ rows.map((row, i) => /* @__PURE__ */ jsxs3("div", { className: "grid grid-cols-[minmax(0,2fr)_minmax(0,3fr)_auto] items-center gap-2", children: [
879
671
  /* @__PURE__ */ jsx5("span", { className: "truncate font-mono text-[11px] text-muted-foreground", title: row.name, children: row.name }),
880
672
  /* @__PURE__ */ jsx5("div", { className: "relative h-2 rounded-sm bg-muted/40", children: /* @__PURE__ */ jsx5(
881
673
  "div",
@@ -886,7 +678,7 @@ function FlowWaterfall({ trace }) {
886
678
  ) }),
887
679
  /* @__PURE__ */ jsx5("span", { className: "shrink-0 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: row.durationLabel })
888
680
  ] }, i)),
889
- /* @__PURE__ */ jsxs4("p", { className: "pt-0.5 text-right font-mono text-[10px] tabular-nums text-muted-foreground/60", children: [
681
+ /* @__PURE__ */ jsxs3("p", { className: "pt-0.5 text-right font-mono text-[10px] tabular-nums text-muted-foreground/60", children: [
890
682
  (trace.totalMs / 1e3).toFixed(1),
891
683
  "s",
892
684
  cost ? ` \xB7 ${cost}` : ""
@@ -896,29 +688,29 @@ function FlowWaterfall({ trace }) {
896
688
  function MissionActivityLane({ activity, startedAt, nowMs }) {
897
689
  const [expanded, setExpanded] = useState4(false);
898
690
  if (activity.length === 0) return null;
899
- return /* @__PURE__ */ jsxs4("div", { className: "mt-1 border-l border-border/50 pl-3", children: [
691
+ return /* @__PURE__ */ jsxs3("div", { className: "mt-1 border-l border-border/50 pl-3", children: [
900
692
  activity.map((run) => {
901
693
  const tone = activityTone(run.status);
902
694
  const cost = formatActivityCost(run.costUsd);
903
695
  const duration = formatActivityDuration(run.durationMs);
904
- return /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2 py-1 text-xs", children: [
696
+ return /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 py-1 text-xs", children: [
905
697
  /* @__PURE__ */ jsx5(StatusDot, { tone }),
906
- /* @__PURE__ */ jsxs4("span", { className: "min-w-0 flex-1 truncate", children: [
698
+ /* @__PURE__ */ jsxs3("span", { className: "min-w-0 flex-1 truncate", children: [
907
699
  /* @__PURE__ */ jsx5("span", { className: "font-medium", children: run.tool }),
908
- /* @__PURE__ */ jsxs4("span", { className: "text-muted-foreground", children: [
700
+ /* @__PURE__ */ jsxs3("span", { className: "text-muted-foreground", children: [
909
701
  " \u2014 ",
910
702
  run.detail
911
703
  ] })
912
704
  ] }),
913
705
  tone === "live" && (run.iteration !== void 0 || run.phase !== void 0) && /* @__PURE__ */ jsx5("span", { className: "shrink-0 rounded-full bg-warning/10 px-1.5 py-0.5 font-mono text-[10px] text-warning", children: [run.iteration !== void 0 ? `iter ${run.iteration}` : null, run.phase ?? null].filter(Boolean).join(" \xB7 ") }),
914
- /* @__PURE__ */ jsxs4("span", { className: "flex shrink-0 items-center gap-1.5 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: [
706
+ /* @__PURE__ */ jsxs3("span", { className: "flex shrink-0 items-center gap-1.5 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: [
915
707
  tone !== "live" && tone !== "ok" && /* @__PURE__ */ jsx5("span", { children: run.status }),
916
708
  cost && /* @__PURE__ */ jsx5("span", { children: cost }),
917
709
  duration && /* @__PURE__ */ jsx5("span", { children: duration })
918
710
  ] })
919
711
  ] }, run.taskId);
920
712
  }),
921
- /* @__PURE__ */ jsxs4(
713
+ /* @__PURE__ */ jsxs3(
922
714
  "button",
923
715
  {
924
716
  type: "button",
@@ -949,12 +741,12 @@ function ActivityRow({
949
741
  const tone = activityTone(record.status);
950
742
  const cost = formatActivityCost(record.costUsd);
951
743
  const duration = formatActivityDuration(record.durationMs);
952
- return /* @__PURE__ */ jsxs4("div", { className: "rounded-lg border border-border/60 bg-card", children: [
953
- /* @__PURE__ */ jsxs4("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm", children: [
744
+ return /* @__PURE__ */ jsxs3("div", { className: "rounded-lg border border-border/60 bg-card", children: [
745
+ /* @__PURE__ */ jsxs3("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm", children: [
954
746
  /* @__PURE__ */ jsx5(StatusDot, { tone }),
955
- /* @__PURE__ */ jsxs4("span", { className: "min-w-0 flex-1 truncate", children: [
747
+ /* @__PURE__ */ jsxs3("span", { className: "min-w-0 flex-1 truncate", children: [
956
748
  /* @__PURE__ */ jsx5("span", { className: "font-medium", children: record.tool }),
957
- /* @__PURE__ */ jsxs4("span", { className: "text-muted-foreground", children: [
749
+ /* @__PURE__ */ jsxs3("span", { className: "text-muted-foreground", children: [
958
750
  " \u2014 ",
959
751
  record.detail
960
752
  ] })
@@ -970,18 +762,18 @@ function ActivityRow({
970
762
  cost && /* @__PURE__ */ jsx5("span", { className: "shrink-0 font-mono text-[11px] tabular-nums text-muted-foreground", children: cost }),
971
763
  /* @__PURE__ */ jsx5(ChevronGlyph, { className: `h-3 w-3 shrink-0 text-muted-foreground transition-transform ${open ? "rotate-180" : ""}` })
972
764
  ] }),
973
- open && /* @__PURE__ */ jsxs4("div", { className: "space-y-2.5 border-t border-border/40 px-3 py-2.5", children: [
765
+ open && /* @__PURE__ */ jsxs3("div", { className: "space-y-2.5 border-t border-border/40 px-3 py-2.5", children: [
974
766
  record.durationMs !== void 0 && /* @__PURE__ */ jsx5("div", { className: "rounded-md border border-border/50 bg-muted/10 p-2", children: /* @__PURE__ */ jsx5(FlowWaterfall, { trace: stepActivityFlowTrace([record]) }) }),
975
- /* @__PURE__ */ jsxs4("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 font-mono text-[11px]", children: [
767
+ /* @__PURE__ */ jsxs3("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 font-mono text-[11px]", children: [
976
768
  /* @__PURE__ */ jsx5("dt", { className: "text-muted-foreground/60", children: "task" }),
977
769
  /* @__PURE__ */ jsx5("dd", { className: "truncate text-muted-foreground", children: record.taskId }),
978
770
  /* @__PURE__ */ jsx5("dt", { className: "text-muted-foreground/60", children: "started" }),
979
771
  /* @__PURE__ */ jsx5("dd", { className: "text-muted-foreground", children: new Date(record.startedAt).toLocaleString() }),
980
- duration && /* @__PURE__ */ jsxs4(Fragment3, { children: [
772
+ duration && /* @__PURE__ */ jsxs3(Fragment2, { children: [
981
773
  /* @__PURE__ */ jsx5("dt", { className: "text-muted-foreground/60", children: "duration" }),
982
774
  /* @__PURE__ */ jsx5("dd", { className: "text-muted-foreground", children: duration })
983
775
  ] }),
984
- record.traceId && /* @__PURE__ */ jsxs4(Fragment3, { children: [
776
+ record.traceId && /* @__PURE__ */ jsxs3(Fragment2, { children: [
985
777
  /* @__PURE__ */ jsx5("dt", { className: "text-muted-foreground/60", children: "trace" }),
986
778
  /* @__PURE__ */ jsx5("dd", { className: "min-w-0", children: /* @__PURE__ */ jsx5(TraceIdCopy, { traceId: record.traceId }) })
987
779
  ] })
@@ -1011,11 +803,11 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
1011
803
  },
1012
804
  [fetchActivity]
1013
805
  );
1014
- useEffect4(() => {
806
+ useEffect3(() => {
1015
807
  void load();
1016
808
  }, [load]);
1017
- return /* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
1018
- /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
809
+ return /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
810
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
1019
811
  /* @__PURE__ */ jsx5("h2", { className: "flex-1 text-sm font-semibold", children: title }),
1020
812
  /* @__PURE__ */ jsx5(
1021
813
  "button",
@@ -1046,7 +838,7 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
1046
838
  }
1047
839
 
1048
840
  // src/web-react/sandbox-terminal.ts
1049
- import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef4, useState as useState5 } from "react";
841
+ import { useCallback as useCallback3, useEffect as useEffect4, useRef as useRef3, useState as useState5 } from "react";
1050
842
  var DEFAULT_PROVISION_POLL_INTERVAL_MS = 2e3;
1051
843
  var DEFAULT_PROVISION_POLL_TIMEOUT_MS = 9e4;
1052
844
  var DEFAULT_TOKEN_REFRESH_SKEW_MS = 12e4;
@@ -1061,8 +853,8 @@ var EMPTY_CONNECTION = {
1061
853
  };
1062
854
  function useSandboxTerminalConnection(opts) {
1063
855
  const [conn, setConn] = useState5(EMPTY_CONNECTION);
1064
- const mountedRef = useRef4(false);
1065
- const generationRef = useRef4(0);
856
+ const mountedRef = useRef3(false);
857
+ const generationRef = useRef3(0);
1066
858
  const fetcher = opts.fetcher ?? fetch;
1067
859
  const pollIntervalMs = opts.provisionPollIntervalMs ?? DEFAULT_PROVISION_POLL_INTERVAL_MS;
1068
860
  const pollTimeoutMs = opts.provisionPollTimeoutMs ?? DEFAULT_PROVISION_POLL_TIMEOUT_MS;
@@ -1153,17 +945,17 @@ function useSandboxTerminalConnection(opts) {
1153
945
  }
1154
946
  }
1155
947
  }, [connectionUrl, fetcher, pollIntervalMs, pollTimeoutMs]);
1156
- useEffect5(() => {
948
+ useEffect4(() => {
1157
949
  mountedRef.current = true;
1158
950
  return () => {
1159
951
  mountedRef.current = false;
1160
952
  generationRef.current += 1;
1161
953
  };
1162
954
  }, []);
1163
- useEffect5(() => {
955
+ useEffect4(() => {
1164
956
  void connect();
1165
957
  }, [connect]);
1166
- useEffect5(() => {
958
+ useEffect4(() => {
1167
959
  if (!conn.runtimeUrl || !conn.token || !conn.expiresAt) return;
1168
960
  const refreshAt = Date.parse(conn.expiresAt) - Date.now() - refreshSkewMs;
1169
961
  if (!Number.isFinite(refreshAt)) {
@@ -1208,7 +1000,7 @@ function tabTerminalConnectionId(storageKey = DEFAULT_TERMINAL_CID_KEY) {
1208
1000
 
1209
1001
  // src/web-react/workspace-terminal-panel.tsx
1210
1002
  import { lazy as lazy2, Suspense as Suspense2 } from "react";
1211
- import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1003
+ import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
1212
1004
  var TerminalView = lazy2(
1213
1005
  () => import("@tangle-network/sandbox-ui/terminal").then((m) => ({ default: m.TerminalView }))
1214
1006
  );
@@ -1238,14 +1030,14 @@ function WorkspaceTerminalPanel({
1238
1030
  const status = (statusDisplay ?? defaultStatusDisplay)(connection);
1239
1031
  const apiUrl = connection.runtimeUrl ?? connection.sidecarUrl;
1240
1032
  const ready = Boolean(apiUrl && connection.token);
1241
- return /* @__PURE__ */ jsxs5("div", { className: `flex h-full min-h-0 flex-col overflow-hidden rounded-xl border border-border bg-card ${className ?? ""}`, children: [
1242
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between gap-3 border-b border-border px-4 py-2.5", children: [
1243
- /* @__PURE__ */ jsxs5("div", { className: "min-w-0", children: [
1033
+ return /* @__PURE__ */ jsxs4("div", { className: `flex h-full min-h-0 flex-col overflow-hidden rounded-xl border border-border bg-card ${className ?? ""}`, children: [
1034
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between gap-3 border-b border-border px-4 py-2.5", children: [
1035
+ /* @__PURE__ */ jsxs4("div", { className: "min-w-0", children: [
1244
1036
  /* @__PURE__ */ jsx6("p", { className: "truncate text-sm font-medium text-foreground", children: title }),
1245
1037
  subtitle && /* @__PURE__ */ jsx6("p", { className: "truncate text-xs text-muted-foreground", children: subtitle })
1246
1038
  ] }),
1247
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
1248
- /* @__PURE__ */ jsxs5("span", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
1039
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
1040
+ /* @__PURE__ */ jsxs4("span", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
1249
1041
  /* @__PURE__ */ jsx6("span", { className: `h-1.5 w-1.5 rounded-full ${TONE_DOT[status.tone]}`, "aria-hidden": true }),
1250
1042
  status.label
1251
1043
  ] }),
@@ -1262,7 +1054,7 @@ function WorkspaceTerminalPanel({
1262
1054
  subtitle,
1263
1055
  isActive
1264
1056
  }
1265
- ) }) : /* @__PURE__ */ jsx6(TerminalMessage, { children: connection.error ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
1057
+ ) }) : /* @__PURE__ */ jsx6(TerminalMessage, { children: connection.error ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
1266
1058
  /* @__PURE__ */ jsx6("p", { className: "text-sm text-destructive", children: connection.error }),
1267
1059
  onRetry && /* @__PURE__ */ jsx6(
1268
1060
  "button",
@@ -1273,7 +1065,7 @@ function WorkspaceTerminalPanel({
1273
1065
  children: "Reconnect"
1274
1066
  }
1275
1067
  )
1276
- ] }) : connection.loading ? /* @__PURE__ */ jsx6("p", { className: "text-sm text-muted-foreground", children: connection.status === "provisioning" ? "Provisioning sandbox\u2026" : "Connecting\u2026" }) : /* @__PURE__ */ jsxs5(Fragment4, { children: [
1068
+ ] }) : connection.loading ? /* @__PURE__ */ jsx6("p", { className: "text-sm text-muted-foreground", children: connection.status === "provisioning" ? "Provisioning sandbox\u2026" : "Connecting\u2026" }) : /* @__PURE__ */ jsxs4(Fragment3, { children: [
1277
1069
  /* @__PURE__ */ jsx6("p", { className: "text-sm text-muted-foreground", children: "Terminal not connected." }),
1278
1070
  onRetry && /* @__PURE__ */ jsx6(
1279
1071
  "button",
@@ -1292,7 +1084,7 @@ function TerminalMessage({ children }) {
1292
1084
  }
1293
1085
 
1294
1086
  // src/web-react/seat-paywall.tsx
1295
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1087
+ import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1296
1088
  function CheckGlyph() {
1297
1089
  return /* @__PURE__ */ jsx7(
1298
1090
  "svg",
@@ -1310,7 +1102,7 @@ function CheckGlyph() {
1310
1102
  );
1311
1103
  }
1312
1104
  function Benefit({ children }) {
1313
- return /* @__PURE__ */ jsxs6("li", { className: "flex items-start gap-2.5 text-sm text-foreground", children: [
1105
+ return /* @__PURE__ */ jsxs5("li", { className: "flex items-start gap-2.5 text-sm text-foreground", children: [
1314
1106
  /* @__PURE__ */ jsx7("span", { className: "mt-0.5", children: /* @__PURE__ */ jsx7(CheckGlyph, {}) }),
1315
1107
  /* @__PURE__ */ jsx7("span", { children })
1316
1108
  ] });
@@ -1326,21 +1118,21 @@ function SeatPaywall({
1326
1118
  footnote
1327
1119
  }) {
1328
1120
  const { pending, run } = usePending();
1329
- return /* @__PURE__ */ jsx7("div", { className: "flex min-h-[60vh] w-full items-center justify-center p-6", children: /* @__PURE__ */ jsxs6("div", { className: "w-full max-w-md rounded-2xl border border-border bg-card p-8 shadow-sm", children: [
1121
+ return /* @__PURE__ */ jsx7("div", { className: "flex min-h-[60vh] w-full items-center justify-center p-6", children: /* @__PURE__ */ jsxs5("div", { className: "w-full max-w-md rounded-2xl border border-border bg-card p-8 shadow-sm", children: [
1330
1122
  /* @__PURE__ */ jsx7("p", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: product }),
1331
- /* @__PURE__ */ jsxs6("h1", { className: "mt-2 text-2xl font-semibold tracking-tight text-foreground", children: [
1123
+ /* @__PURE__ */ jsxs5("h1", { className: "mt-2 text-2xl font-semibold tracking-tight text-foreground", children: [
1332
1124
  "Unlock ",
1333
1125
  product
1334
1126
  ] }),
1335
1127
  tagline && /* @__PURE__ */ jsx7("p", { className: "mt-2 text-sm text-muted-foreground", children: tagline }),
1336
- /* @__PURE__ */ jsxs6("div", { className: "mt-6 flex items-baseline gap-1.5", children: [
1337
- /* @__PURE__ */ jsxs6("span", { className: "text-3xl font-semibold text-foreground", children: [
1128
+ /* @__PURE__ */ jsxs5("div", { className: "mt-6 flex items-baseline gap-1.5", children: [
1129
+ /* @__PURE__ */ jsxs5("span", { className: "text-3xl font-semibold text-foreground", children: [
1338
1130
  "$",
1339
1131
  priceUsd
1340
1132
  ] }),
1341
1133
  /* @__PURE__ */ jsx7("span", { className: "text-sm text-muted-foreground", children: "/mo" })
1342
1134
  ] }),
1343
- /* @__PURE__ */ jsxs6("p", { className: "mt-1 text-sm text-muted-foreground", children: [
1135
+ /* @__PURE__ */ jsxs5("p", { className: "mt-1 text-sm text-muted-foreground", children: [
1344
1136
  "Includes $",
1345
1137
  includedUsageUsd,
1346
1138
  "/mo of AI usage"
@@ -1365,7 +1157,7 @@ function SeatPaywall({
1365
1157
 
1366
1158
  // src/web-react/agent-session-controls.tsx
1367
1159
  import { useMemo as useMemo2, useState as useState6 } from "react";
1368
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1160
+ import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
1369
1161
  var HARNESS_LABELS = {
1370
1162
  opencode: "OpenCode (any model)",
1371
1163
  "claude-code": "Claude Code (Anthropic)",
@@ -1388,7 +1180,7 @@ function ChevronDown2({ className }) {
1388
1180
  return /* @__PURE__ */ jsx8("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx8("path", { d: "m6 9 6 6 6-6" }) });
1389
1181
  }
1390
1182
  function GearGlyph({ className }) {
1391
- return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1183
+ return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1392
1184
  /* @__PURE__ */ jsx8("circle", { cx: "12", cy: "12", r: "3" }),
1393
1185
  /* @__PURE__ */ jsx8("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" })
1394
1186
  ] });
@@ -1402,8 +1194,8 @@ function HarnessPicker({
1402
1194
  const [open, setOpen] = useState6(false);
1403
1195
  const { containerRef, triggerProps } = usePopover(open, setOpen);
1404
1196
  const options = available ?? Object.keys(HARNESS_LABELS);
1405
- return /* @__PURE__ */ jsxs7("div", { ref: containerRef, className: "relative inline-flex", children: [
1406
- /* @__PURE__ */ jsxs7(
1197
+ return /* @__PURE__ */ jsxs6("div", { ref: containerRef, className: "relative inline-flex", children: [
1198
+ /* @__PURE__ */ jsxs6(
1407
1199
  "button",
1408
1200
  {
1409
1201
  type: "button",
@@ -1479,16 +1271,16 @@ function AgentSessionControls(props) {
1479
1271
  }
1480
1272
  );
1481
1273
  if (layout === "inline") {
1482
- return /* @__PURE__ */ jsxs7("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
1274
+ return /* @__PURE__ */ jsxs6("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
1483
1275
  modelPicker,
1484
1276
  showHarness && /* @__PURE__ */ jsx8(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
1485
1277
  showEffort && /* @__PURE__ */ jsx8(EffortPicker, { value: effort, onChange: onEffortChange })
1486
1278
  ] });
1487
1279
  }
1488
1280
  const hasAdvanced = showHarness || showEffort;
1489
- return /* @__PURE__ */ jsxs7("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
1281
+ return /* @__PURE__ */ jsxs6("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
1490
1282
  modelPicker,
1491
- hasAdvanced && /* @__PURE__ */ jsxs7("div", { ref: popoverRef, className: "relative inline-flex", children: [
1283
+ hasAdvanced && /* @__PURE__ */ jsxs6("div", { ref: popoverRef, className: "relative inline-flex", children: [
1492
1284
  /* @__PURE__ */ jsx8(
1493
1285
  "button",
1494
1286
  {
@@ -1501,13 +1293,13 @@ function AgentSessionControls(props) {
1501
1293
  children: /* @__PURE__ */ jsx8(GearGlyph, { className: "h-4 w-4" })
1502
1294
  }
1503
1295
  ),
1504
- open && /* @__PURE__ */ jsxs7("div", { className: "absolute bottom-full left-0 z-50 mb-2 w-72 space-y-3 rounded-xl border border-border bg-card p-3 shadow-lg", children: [
1505
- showHarness && /* @__PURE__ */ jsxs7("div", { className: "space-y-1.5", children: [
1296
+ open && /* @__PURE__ */ jsxs6("div", { className: "absolute bottom-full left-0 z-50 mb-2 w-72 space-y-3 rounded-xl border border-border bg-card p-3 shadow-lg", children: [
1297
+ showHarness && /* @__PURE__ */ jsxs6("div", { className: "space-y-1.5", children: [
1506
1298
  /* @__PURE__ */ jsx8("p", { className: "text-xs font-medium text-foreground", children: "Agent backend" }),
1507
1299
  /* @__PURE__ */ jsx8(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
1508
1300
  /* @__PURE__ */ jsx8("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "The engine that runs the agent. Switching it keeps your model choice compatible." })
1509
1301
  ] }),
1510
- showEffort && /* @__PURE__ */ jsxs7("div", { className: "space-y-1.5", children: [
1302
+ showEffort && /* @__PURE__ */ jsxs6("div", { className: "space-y-1.5", children: [
1511
1303
  /* @__PURE__ */ jsx8("p", { className: "text-xs font-medium text-foreground", children: "Thinking" }),
1512
1304
  /* @__PURE__ */ jsx8(EffortPicker, { value: effort, onChange: onEffortChange, label: "" }),
1513
1305
  /* @__PURE__ */ jsx8("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "How hard the agent thinks before answering. Higher is slower but more thorough." })
@@ -1518,7 +1310,7 @@ function AgentSessionControls(props) {
1518
1310
  }
1519
1311
 
1520
1312
  // src/web-react/index.tsx
1521
- import { Fragment as Fragment5, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1313
+ import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
1522
1314
  function formatModelCost(msg, models) {
1523
1315
  if (msg.promptTokens == null && msg.completionTokens == null) return null;
1524
1316
  const pricing = models.find((m) => m.id === msg.modelUsed)?.pricing;
@@ -1532,15 +1324,15 @@ function formatTokensPerSecond(msg) {
1532
1324
  return `${Math.round(msg.completionTokens / (msg.durationMs / 1e3))} tok/s`;
1533
1325
  }
1534
1326
  function RunDrillIn({ run, onClose }) {
1535
- return /* @__PURE__ */ jsxs8("div", { className: "fixed inset-y-0 right-0 z-50 flex w-[480px] max-w-full flex-col border-l border-border bg-card shadow-xl", children: [
1536
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2 border-b border-border px-4 py-3", children: [
1327
+ return /* @__PURE__ */ jsxs7("div", { className: "fixed inset-y-0 right-0 z-50 flex w-[480px] max-w-full flex-col border-l border-border bg-card shadow-xl", children: [
1328
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 border-b border-border px-4 py-3", children: [
1537
1329
  /* @__PURE__ */ jsx9(
1538
1330
  "span",
1539
1331
  {
1540
1332
  className: `h-2 w-2 shrink-0 rounded-full ${run.status === "running" ? "bg-warning" : run.status === "error" ? "bg-destructive" : "bg-success"}`
1541
1333
  }
1542
1334
  ),
1543
- /* @__PURE__ */ jsxs8("div", { className: "min-w-0 flex-1", children: [
1335
+ /* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
1544
1336
  /* @__PURE__ */ jsx9("p", { className: "truncate text-sm font-semibold", children: run.title }),
1545
1337
  /* @__PURE__ */ jsx9("p", { className: "truncate font-mono text-[11px] text-muted-foreground", children: run.toolName })
1546
1338
  ] }),
@@ -1555,10 +1347,10 @@ function RunDrillIn({ run, onClose }) {
1555
1347
  }
1556
1348
  )
1557
1349
  ] }),
1558
- /* @__PURE__ */ jsxs8("div", { className: "flex-1 space-y-3 overflow-y-auto p-4", children: [
1350
+ /* @__PURE__ */ jsxs7("div", { className: "flex-1 space-y-3 overflow-y-auto p-4", children: [
1559
1351
  run.steps.length === 0 && /* @__PURE__ */ jsx9("p", { className: "text-sm text-muted-foreground", children: "No steps recorded yet." }),
1560
- run.steps.map((step, i) => /* @__PURE__ */ jsxs8("div", { className: "rounded-lg border border-border/60 bg-background", children: [
1561
- /* @__PURE__ */ jsxs8("div", { className: "flex items-baseline gap-2 border-b border-border/40 px-3 py-1.5", children: [
1352
+ run.steps.map((step, i) => /* @__PURE__ */ jsxs7("div", { className: "rounded-lg border border-border/60 bg-background", children: [
1353
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-baseline gap-2 border-b border-border/40 px-3 py-1.5", children: [
1562
1354
  /* @__PURE__ */ jsx9("span", { className: `font-mono text-[11px] ${step.status === "error" ? "text-destructive" : "text-muted-foreground"}`, children: step.status === "error" ? "\u2717" : "$" }),
1563
1355
  /* @__PURE__ */ jsx9("code", { className: "min-w-0 flex-1 truncate font-mono text-xs", children: step.label }),
1564
1356
  /* @__PURE__ */ jsx9("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: new Date(step.at).toLocaleTimeString() })
@@ -1580,12 +1372,12 @@ function ChatEmptyState({
1580
1372
  subline = "Describe the outcome you want. The agent works through it step by step, and pauses for your approval before anything irreversible.",
1581
1373
  doors
1582
1374
  }) {
1583
- return /* @__PURE__ */ jsxs8("div", { className: "mx-auto flex w-full max-w-2xl flex-col items-center px-6 py-12 text-center sm:py-20", children: [
1375
+ return /* @__PURE__ */ jsxs7("div", { className: "mx-auto flex w-full max-w-2xl flex-col items-center px-6 py-12 text-center sm:py-20", children: [
1584
1376
  /* @__PURE__ */ jsx9("span", { className: "mb-5 inline-flex h-14 w-14 items-center justify-center rounded-2xl bg-primary/10 ring-1 ring-primary/15", children: /* @__PURE__ */ jsx9(BrandMark, { size: 32, className: "shrink-0" }) }),
1585
1377
  /* @__PURE__ */ jsx9("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-muted-foreground", children: productName }),
1586
1378
  /* @__PURE__ */ jsx9("h2", { className: "mt-1.5 text-balance text-2xl font-semibold leading-tight text-foreground sm:text-[28px]", children: headline }),
1587
1379
  subline && /* @__PURE__ */ jsx9("p", { className: "mt-3 max-w-md text-[15px] leading-relaxed text-muted-foreground", children: subline }),
1588
- doors && doors.length > 0 && /* @__PURE__ */ jsx9("div", { className: "mt-7 grid w-full gap-2.5 sm:grid-cols-3", children: doors.slice(0, 3).map((door, i) => /* @__PURE__ */ jsxs8(
1380
+ doors && doors.length > 0 && /* @__PURE__ */ jsx9("div", { className: "mt-7 grid w-full gap-2.5 sm:grid-cols-3", children: doors.slice(0, 3).map((door, i) => /* @__PURE__ */ jsxs7(
1589
1381
  "button",
1590
1382
  {
1591
1383
  type: "button",
@@ -1602,24 +1394,24 @@ function ChatEmptyState({
1602
1394
  }
1603
1395
  function ToolGlyph({ name, className }) {
1604
1396
  if (name.startsWith("sandbox_")) {
1605
- return /* @__PURE__ */ jsxs8("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1397
+ return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1606
1398
  /* @__PURE__ */ jsx9("polyline", { points: "4 17 10 11 4 5" }),
1607
1399
  /* @__PURE__ */ jsx9("line", { x1: "12", y1: "19", x2: "20", y2: "19" })
1608
1400
  ] });
1609
1401
  }
1610
1402
  if (name === "submit_proposal") {
1611
- return /* @__PURE__ */ jsxs8("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1403
+ return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1612
1404
  /* @__PURE__ */ jsx9("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1613
1405
  /* @__PURE__ */ jsx9("path", { d: "M14 2v6h6M9 15l2 2 4-4" })
1614
1406
  ] });
1615
1407
  }
1616
1408
  if (name === "schedule_followup") {
1617
- return /* @__PURE__ */ jsxs8("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: [
1409
+ return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: [
1618
1410
  /* @__PURE__ */ jsx9("circle", { cx: "12", cy: "12", r: "9" }),
1619
1411
  /* @__PURE__ */ jsx9("path", { d: "M12 7v5l3 3" })
1620
1412
  ] });
1621
1413
  }
1622
- return /* @__PURE__ */ jsxs8("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1414
+ return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1623
1415
  /* @__PURE__ */ jsx9("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3" }),
1624
1416
  /* @__PURE__ */ jsx9("circle", { cx: "12", cy: "12", r: "4" })
1625
1417
  ] });
@@ -1688,7 +1480,7 @@ function truncate(v, max = 240) {
1688
1480
  function KvRows({ data }) {
1689
1481
  const entries = Object.entries(data).filter(([, v]) => v !== void 0 && v !== null && v !== "");
1690
1482
  if (!entries.length) return null;
1691
- return /* @__PURE__ */ jsx9("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1", children: entries.map(([k, v]) => /* @__PURE__ */ jsxs8("div", { className: "contents", children: [
1483
+ return /* @__PURE__ */ jsx9("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1", children: entries.map(([k, v]) => /* @__PURE__ */ jsxs7("div", { className: "contents", children: [
1692
1484
  /* @__PURE__ */ jsx9("dt", { className: "font-mono text-[11px] text-muted-foreground", children: k }),
1693
1485
  /* @__PURE__ */ jsx9("dd", { className: "min-w-0 whitespace-pre-wrap break-words font-mono text-[11px] text-muted-foreground", children: truncate(v) })
1694
1486
  ] }, k)) });
@@ -1696,11 +1488,11 @@ function KvRows({ data }) {
1696
1488
  function ShellDetail({ call }) {
1697
1489
  const outcome = toolOutcomeOf(call);
1698
1490
  const r = outcome?.result ?? {};
1699
- return /* @__PURE__ */ jsxs8("div", { className: "overflow-hidden rounded-md bg-zinc-900 font-mono text-[11px] leading-relaxed", children: [
1700
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2 px-3 pt-2 text-zinc-400", children: [
1491
+ return /* @__PURE__ */ jsxs7("div", { className: "overflow-hidden rounded-md bg-zinc-900 font-mono text-[11px] leading-relaxed", children: [
1492
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 px-3 pt-2 text-zinc-400", children: [
1701
1493
  /* @__PURE__ */ jsx9("span", { className: "select-none text-zinc-500", children: "$" }),
1702
1494
  /* @__PURE__ */ jsx9("span", { className: "min-w-0 flex-1 truncate text-zinc-200", children: String(call.args?.command ?? "") }),
1703
- r.exitCode != null && /* @__PURE__ */ jsxs8("span", { className: r.exitCode === 0 ? "text-success" : "text-destructive", children: [
1495
+ r.exitCode != null && /* @__PURE__ */ jsxs7("span", { className: r.exitCode === 0 ? "text-success" : "text-destructive", children: [
1704
1496
  "exit ",
1705
1497
  r.exitCode
1706
1498
  ] })
@@ -1710,12 +1502,12 @@ function ShellDetail({ call }) {
1710
1502
  }
1711
1503
  function DefaultToolDetail({ call }) {
1712
1504
  const outcome = toolOutcomeOf(call);
1713
- return /* @__PURE__ */ jsxs8("div", { className: "space-y-2", children: [
1714
- call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */ jsxs8("div", { children: [
1505
+ return /* @__PURE__ */ jsxs7("div", { className: "space-y-2", children: [
1506
+ call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */ jsxs7("div", { children: [
1715
1507
  /* @__PURE__ */ jsx9("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Called with" }),
1716
1508
  /* @__PURE__ */ jsx9(KvRows, { data: call.args })
1717
1509
  ] }),
1718
- outcome && /* @__PURE__ */ jsxs8("div", { children: [
1510
+ outcome && /* @__PURE__ */ jsxs7("div", { children: [
1719
1511
  /* @__PURE__ */ jsx9("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: outcome.ok === false ? "Failed" : "Result" }),
1720
1512
  outcome.ok === false ? /* @__PURE__ */ jsx9("p", { className: "text-xs text-destructive", children: outcome.message ?? "Tool failed" }) : outcome.result && typeof outcome.result === "object" ? /* @__PURE__ */ jsx9(KvRows, { data: outcome.result }) : /* @__PURE__ */ jsx9("p", { className: "font-mono text-[11px] text-muted-foreground", children: truncate(outcome.result) })
1721
1513
  ] })
@@ -1732,18 +1524,18 @@ function ProposalCard({
1732
1524
  const { summary, meta } = proposalPreview(call);
1733
1525
  const custom = renderers?.[call.name]?.(call, message);
1734
1526
  const { pending: deciding, run: decide } = usePending();
1735
- return /* @__PURE__ */ jsxs8("div", { className: "w-full max-w-full rounded-xl border border-warning/50 bg-warning/[0.06] text-sm shadow-sm ring-1 ring-warning/10", children: [
1736
- /* @__PURE__ */ jsxs8("div", { className: "flex items-start gap-2.5 px-4 pt-3.5", children: [
1527
+ return /* @__PURE__ */ jsxs7("div", { className: "w-full max-w-full rounded-xl border border-warning/50 bg-warning/[0.06] text-sm shadow-sm ring-1 ring-warning/10", children: [
1528
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-start gap-2.5 px-4 pt-3.5", children: [
1737
1529
  /* @__PURE__ */ jsx9("span", { className: "mt-0.5 inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-warning/15 text-warning", children: /* @__PURE__ */ jsx9(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5" }) }),
1738
- /* @__PURE__ */ jsxs8("div", { className: "min-w-0 flex-1", children: [
1530
+ /* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
1739
1531
  /* @__PURE__ */ jsx9("p", { className: "text-[10px] font-semibold uppercase tracking-wider text-warning-foreground", children: "Needs your approval" }),
1740
1532
  /* @__PURE__ */ jsx9("p", { className: "mt-0.5 text-[15px] font-semibold leading-snug text-foreground", children: friendlyToolTitle(call) }),
1741
1533
  summary && /* @__PURE__ */ jsx9("p", { className: "mt-1 text-[13px] leading-relaxed text-muted-foreground", children: summary }),
1742
1534
  meta.length > 0 && /* @__PURE__ */ jsx9("div", { className: "mt-1.5 flex flex-wrap items-center gap-1.5", children: meta.map((m, i) => /* @__PURE__ */ jsx9("span", { className: "rounded-full bg-muted/60 px-2 py-0.5 text-[11px] font-medium text-muted-foreground", children: m }, i)) })
1743
1535
  ] })
1744
1536
  ] }),
1745
- /* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap items-center gap-2 px-4 pb-3.5 pt-3", children: [
1746
- approval ? /* @__PURE__ */ jsxs8(Fragment5, { children: [
1537
+ /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap items-center gap-2 px-4 pb-3.5 pt-3", children: [
1538
+ approval ? /* @__PURE__ */ jsxs7(Fragment4, { children: [
1747
1539
  /* @__PURE__ */ jsx9(
1748
1540
  "button",
1749
1541
  {
@@ -1765,7 +1557,7 @@ function ProposalCard({
1765
1557
  }
1766
1558
  )
1767
1559
  ] }) : /* @__PURE__ */ jsx9("span", { className: "text-[12px] font-medium text-muted-foreground", children: "Awaiting approval\u2026" }),
1768
- /* @__PURE__ */ jsxs8(
1560
+ /* @__PURE__ */ jsxs7(
1769
1561
  "button",
1770
1562
  {
1771
1563
  type: "button",
@@ -1785,8 +1577,8 @@ function ProposalCard({
1785
1577
  function FollowupCard({ call }) {
1786
1578
  const a = call.args ?? {};
1787
1579
  const when = typeof a.when === "string" ? a.when : typeof a.at === "string" ? a.at : typeof a.schedule === "string" ? a.schedule : null;
1788
- return /* @__PURE__ */ jsxs8("div", { className: "w-fit min-w-[260px] max-w-full rounded-lg border border-border/60 border-l-2 border-l-primary/60 bg-muted/20 px-3 py-2 text-sm", children: [
1789
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
1580
+ return /* @__PURE__ */ jsxs7("div", { className: "w-fit min-w-[260px] max-w-full rounded-lg border border-border/60 border-l-2 border-l-primary/60 bg-muted/20 px-3 py-2 text-sm", children: [
1581
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
1790
1582
  /* @__PURE__ */ jsx9(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-primary/80" }),
1791
1583
  /* @__PURE__ */ jsx9("span", { className: "min-w-0 flex-1 truncate font-medium text-foreground", children: friendlyToolTitle(call) })
1792
1584
  ] }),
@@ -1821,13 +1613,13 @@ function ToolCallCard({
1821
1613
  return /* @__PURE__ */ jsx9(FollowupCard, { call });
1822
1614
  }
1823
1615
  const isCommand = kind === "command";
1824
- return /* @__PURE__ */ jsxs8(
1616
+ return /* @__PURE__ */ jsxs7(
1825
1617
  "div",
1826
1618
  {
1827
1619
  className: `w-fit min-w-[280px] max-w-full rounded-lg border text-xs transition ${failed ? "border-destructive/40 bg-destructive/5" : "border-border/60 bg-muted/20"}`,
1828
1620
  children: [
1829
- /* @__PURE__ */ jsxs8("div", { className: "flex w-full items-center gap-2 px-3 py-2", children: [
1830
- /* @__PURE__ */ jsxs8(
1621
+ /* @__PURE__ */ jsxs7("div", { className: "flex w-full items-center gap-2 px-3 py-2", children: [
1622
+ /* @__PURE__ */ jsxs7(
1831
1623
  "button",
1832
1624
  {
1833
1625
  type: "button",
@@ -1865,7 +1657,7 @@ function ToolCallCard({
1865
1657
  }
1866
1658
  )
1867
1659
  ] }),
1868
- expanded && /* @__PURE__ */ jsxs8("div", { className: "border-t border-border/40 px-3 py-2.5", children: [
1660
+ expanded && /* @__PURE__ */ jsxs7("div", { className: "border-t border-border/40 px-3 py-2.5", children: [
1869
1661
  custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */ jsx9(ShellDetail, { call }) : /* @__PURE__ */ jsx9(DefaultToolDetail, { call })),
1870
1662
  onOpenRun && call.name.startsWith("sandbox_") && /* @__PURE__ */ jsx9(
1871
1663
  "button",
@@ -1899,7 +1691,7 @@ function SegmentText({
1899
1691
  const text = useSmoothText(content, streaming);
1900
1692
  const body = useMemo3(() => renderBody(text), [renderBody, text]);
1901
1693
  if (!content.trim() && !showCaret) return null;
1902
- return /* @__PURE__ */ jsxs8("div", { className: "text-base leading-[1.75]", children: [
1694
+ return /* @__PURE__ */ jsxs7("div", { className: "text-base leading-[1.75]", children: [
1903
1695
  body,
1904
1696
  showCaret && /* @__PURE__ */ jsx9(StreamingCaret, {})
1905
1697
  ] });
@@ -1931,7 +1723,7 @@ function SegmentedBody({
1931
1723
  },
1932
1724
  `tool-${call.id}`
1933
1725
  );
1934
- return /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-2", children: [
1726
+ return /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-2", children: [
1935
1727
  segments.map(
1936
1728
  (seg, i) => seg.kind === "text" ? /* @__PURE__ */ jsx9(
1937
1729
  SegmentText,
@@ -1964,31 +1756,31 @@ function AssistantMessageImpl({
1964
1756
  const body = useMemo3(() => renderBody(content), [renderBody, content]);
1965
1757
  const segments = msg.segments;
1966
1758
  const hasAnswerText = content !== "" || (segments?.some((s) => s.kind === "text" && s.content.trim() !== "") ?? false);
1967
- const reasoningScrollRef = useRef5(null);
1968
- const thinkStartRef = useRef5(null);
1969
- const thinkMsRef = useRef5(null);
1759
+ const reasoningScrollRef = useRef4(null);
1760
+ const thinkStartRef = useRef4(null);
1761
+ const thinkMsRef = useRef4(null);
1970
1762
  if (streaming && reasoning && !hasAnswerText && thinkStartRef.current === null) {
1971
1763
  thinkStartRef.current = performance.now();
1972
1764
  }
1973
1765
  if (hasAnswerText && thinkStartRef.current !== null && thinkMsRef.current === null) {
1974
1766
  thinkMsRef.current = performance.now() - thinkStartRef.current;
1975
1767
  }
1976
- useEffect6(() => {
1768
+ useEffect5(() => {
1977
1769
  const el = reasoningScrollRef.current;
1978
1770
  if (el && streaming && !hasAnswerText) el.scrollTop = el.scrollHeight;
1979
1771
  }, [reasoning, streaming, hasAnswerText]);
1980
1772
  const thinkingSeconds = useThinkingSeconds(
1981
1773
  streaming && !!reasoning && !hasAnswerText
1982
1774
  );
1983
- return /* @__PURE__ */ jsxs8("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
1984
- /* @__PURE__ */ jsxs8("div", { className: "mb-1 flex items-baseline gap-2 text-[11px] tracking-wide text-muted-foreground", children: [
1775
+ return /* @__PURE__ */ jsxs7("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
1776
+ /* @__PURE__ */ jsxs7("div", { className: "mb-1 flex items-baseline gap-2 text-[11px] tracking-wide text-muted-foreground", children: [
1985
1777
  /* @__PURE__ */ jsx9("span", { className: "font-semibold uppercase", children: agentLabel }),
1986
1778
  msg.modelUsed && /* @__PURE__ */ jsx9("span", { className: "font-mono normal-case", children: msg.modelUsed }),
1987
1779
  formatTokensPerSecond(msg) && /* @__PURE__ */ jsx9("span", { children: formatTokensPerSecond(msg) }),
1988
1780
  formatModelCost(msg, models) && /* @__PURE__ */ jsx9("span", { children: formatModelCost(msg, models) })
1989
1781
  ] }),
1990
- reasoning && /* @__PURE__ */ jsxs8("details", { className: "mb-2 rounded-lg border-l-2 border-border/70 bg-muted/20 px-3 py-2", open: !hasAnswerText, children: [
1991
- /* @__PURE__ */ jsx9("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: !hasAnswerText ? /* @__PURE__ */ jsxs8("span", { className: "animate-pulse", children: [
1782
+ reasoning && /* @__PURE__ */ jsxs7("details", { className: "mb-2 rounded-lg border-l-2 border-border/70 bg-muted/20 px-3 py-2", open: !hasAnswerText, children: [
1783
+ /* @__PURE__ */ jsx9("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: !hasAnswerText ? /* @__PURE__ */ jsxs7("span", { className: "animate-pulse", children: [
1992
1784
  "Thinking",
1993
1785
  thinkingSeconds >= 3 ? ` \xB7 ${thinkingSeconds}s` : "\u2026"
1994
1786
  ] }) : thinkMsRef.current != null ? `Thought for ${Math.max(1, Math.round(thinkMsRef.current / 1e3))}s` : "Thought process" }),
@@ -2005,8 +1797,8 @@ function AssistantMessageImpl({
2005
1797
  onToolCallClick,
2006
1798
  toolRenderers
2007
1799
  }
2008
- ) : /* @__PURE__ */ jsxs8(Fragment5, { children: [
2009
- /* @__PURE__ */ jsxs8("div", { className: "text-base leading-[1.75]", children: [
1800
+ ) : /* @__PURE__ */ jsxs7(Fragment4, { children: [
1801
+ /* @__PURE__ */ jsxs7("div", { className: "text-base leading-[1.75]", children: [
2010
1802
  body,
2011
1803
  streaming && content && !msg.toolCalls?.length && /* @__PURE__ */ jsx9(StreamingCaret, {})
2012
1804
  ] }),
@@ -2028,7 +1820,7 @@ function AssistantMessageImpl({
2028
1820
  var AssistantMessage = memo(AssistantMessageImpl);
2029
1821
  function useThinkingSeconds(active) {
2030
1822
  const [seconds, setSeconds] = useState7(0);
2031
- useEffect6(() => {
1823
+ useEffect5(() => {
2032
1824
  if (!active) return;
2033
1825
  setSeconds(0);
2034
1826
  const id = setInterval(() => setSeconds((s) => s + 1), 1e3);
@@ -2038,9 +1830,9 @@ function useThinkingSeconds(active) {
2038
1830
  }
2039
1831
  function ThinkingRow({ agentLabel }) {
2040
1832
  const seconds = useThinkingSeconds(true);
2041
- return /* @__PURE__ */ jsxs8("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
1833
+ return /* @__PURE__ */ jsxs7("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
2042
1834
  /* @__PURE__ */ jsx9("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: agentLabel }),
2043
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2 text-base text-muted-foreground", children: [
1835
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 text-base text-muted-foreground", children: [
2044
1836
  /* @__PURE__ */ jsx9("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": true, children: /* @__PURE__ */ jsx9("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", strokeLinecap: "round" }) }),
2045
1837
  "Thinking",
2046
1838
  seconds >= 3 ? ` \xB7 ${seconds}s` : "..."
@@ -2048,8 +1840,8 @@ function ThinkingRow({ agentLabel }) {
2048
1840
  ] });
2049
1841
  }
2050
1842
  function StreamErrorRow({ message, onRetry }) {
2051
- return /* @__PURE__ */ jsx9("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs8("div", { role: "alert", className: "flex items-start gap-2.5 rounded-lg border border-destructive/40 bg-destructive/5 px-3 py-2.5 text-sm text-destructive", children: [
2052
- /* @__PURE__ */ jsxs8("svg", { className: "mt-0.5 h-4 w-4 shrink-0", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1843
+ return /* @__PURE__ */ jsx9("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs7("div", { role: "alert", className: "flex items-start gap-2.5 rounded-lg border border-destructive/40 bg-destructive/5 px-3 py-2.5 text-sm text-destructive", children: [
1844
+ /* @__PURE__ */ jsxs7("svg", { className: "mt-0.5 h-4 w-4 shrink-0", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
2053
1845
  /* @__PURE__ */ jsx9("circle", { cx: "12", cy: "12", r: "9" }),
2054
1846
  /* @__PURE__ */ jsx9("path", { d: "M12 8v4m0 4h.01" })
2055
1847
  ] }),
@@ -2089,15 +1881,15 @@ function ChatMessages({
2089
1881
  const lastIsUser = messages[messages.length - 1]?.role === "user";
2090
1882
  if (messages.length === 0 && !loading && !error) {
2091
1883
  const empty = renderEmpty ? renderEmpty() : /* @__PURE__ */ jsx9(ChatEmptyState, { ...emptyState });
2092
- return /* @__PURE__ */ jsxs8(Fragment5, { children: [
1884
+ return /* @__PURE__ */ jsxs7(Fragment4, { children: [
2093
1885
  header,
2094
1886
  empty
2095
1887
  ] });
2096
1888
  }
2097
- return /* @__PURE__ */ jsxs8(Fragment5, { children: [
1889
+ return /* @__PURE__ */ jsxs7(Fragment4, { children: [
2098
1890
  header,
2099
1891
  messages.map(
2100
- (msg) => msg.role === "user" ? /* @__PURE__ */ jsx9("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs8("div", { className: "ml-auto w-fit max-w-[85%]", children: [
1892
+ (msg) => msg.role === "user" ? /* @__PURE__ */ jsx9("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs7("div", { className: "ml-auto w-fit max-w-[85%]", children: [
2101
1893
  /* @__PURE__ */ jsx9("p", { className: "mb-1 text-right text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: userLabel }),
2102
1894
  /* @__PURE__ */ jsx9("div", { className: "rounded-2xl rounded-tr-md bg-primary/10 px-4 py-2.5 text-base leading-relaxed", children: /* @__PURE__ */ jsx9("p", { className: "whitespace-pre-wrap", children: msg.content }) })
2103
1895
  ] }) }, msg.id) : /* @__PURE__ */ jsx9(
@@ -2155,4 +1947,4 @@ export {
2155
1947
  useThinkingSeconds,
2156
1948
  ChatMessages
2157
1949
  };
2158
- //# sourceMappingURL=chunk-WV2U5UIB.js.map
1950
+ //# sourceMappingURL=chunk-7DPQ5VWR.js.map