@invergent/agent-chat-react 2.0.2 → 2.0.7

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.
package/dist/index.cjs CHANGED
@@ -794,29 +794,6 @@ var ConversationScrollButton = ({
794
794
  );
795
795
  };
796
796
 
797
- // src/components/ui/separator.tsx
798
- init_utils();
799
- function Separator({
800
- className,
801
- orientation = "horizontal",
802
- decorative = true,
803
- ...props
804
- }) {
805
- return /* @__PURE__ */ jsxRuntime.jsx(
806
- radixUi.Separator.Root,
807
- {
808
- "data-slot": "separator",
809
- decorative,
810
- orientation,
811
- className: cn(
812
- "shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
813
- className
814
- ),
815
- ...props
816
- }
817
- );
818
- }
819
-
820
797
  // src/components/ai-elements/message.tsx
821
798
  init_utils();
822
799
  var Message = ({ className, from, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
@@ -10771,42 +10748,6 @@ function Card({
10771
10748
  }
10772
10749
  );
10773
10750
  }
10774
- function CardHeader({ className, ...props }) {
10775
- return /* @__PURE__ */ jsxRuntime.jsx(
10776
- "div",
10777
- {
10778
- "data-slot": "card-header",
10779
- className: cn(
10780
- "group/card-header @container/card-header grid auto-rows-min items-start gap-1.5 rounded-none px-8 group-data-[size=sm]/card:px-5 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-8 group-data-[size=sm]/card:[.border-b]:pb-5",
10781
- className
10782
- ),
10783
- ...props
10784
- }
10785
- );
10786
- }
10787
- function CardTitle({ className, ...props }) {
10788
- return /* @__PURE__ */ jsxRuntime.jsx(
10789
- "div",
10790
- {
10791
- "data-slot": "card-title",
10792
- className: cn(
10793
- "font-heading text-lg font-semibold tracking-wider uppercase",
10794
- className
10795
- ),
10796
- ...props
10797
- }
10798
- );
10799
- }
10800
- function CardDescription({ className, ...props }) {
10801
- return /* @__PURE__ */ jsxRuntime.jsx(
10802
- "div",
10803
- {
10804
- "data-slot": "card-description",
10805
- className: cn("text-sm leading-relaxed text-muted-foreground", className),
10806
- ...props
10807
- }
10808
- );
10809
- }
10810
10751
  function CardContent({ className, ...props }) {
10811
10752
  return /* @__PURE__ */ jsxRuntime.jsx(
10812
10753
  "div",
@@ -10874,6 +10815,97 @@ var MISSION_WORKER_KIND_TOOLTIP = {
10874
10815
  worker: "Async one-shot session spawned by spawn_worker. Durable session, no retry/DAG.",
10875
10816
  delegation: "Sync fork-join child spawned by delegate_task. Coordinator's wake blocked until it finished."
10876
10817
  };
10818
+ function CountBadge({ n }) {
10819
+ if (n === 0) return null;
10820
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 rounded bg-muted px-1 py-px text-[9px] text-muted-foreground/70", children: n });
10821
+ }
10822
+ function firstLine3(text, max = 140) {
10823
+ const trimmed = text.replace(/\s+/g, " ").trim();
10824
+ if (trimmed.length <= max) return trimmed;
10825
+ return `${trimmed.slice(0, max).trimEnd()}\u2026`;
10826
+ }
10827
+ var ACTIVITY_KIND_TONE = {
10828
+ "mission.defined": "bg-primary/10 text-primary border-primary/30",
10829
+ "mission.paused": "bg-amber-500/10 text-amber-600 border-amber-500/30",
10830
+ "mission.cancelled": "bg-destructive/10 text-destructive border-destructive/30",
10831
+ "task.spawned": "bg-foreground/5 text-foreground/80 border-foreground/20",
10832
+ "task.completed": "bg-emerald-500/10 text-emerald-600 border-emerald-500/30",
10833
+ "task.failed": "bg-destructive/10 text-destructive border-destructive/30",
10834
+ "task.cancelled": "bg-muted text-muted-foreground border-border",
10835
+ "worker.latest": "bg-foreground/5 text-foreground/70 border-foreground/15",
10836
+ "evaluator.verdict": "bg-primary/10 text-primary border-primary/30"
10837
+ };
10838
+ function buildMissionActivity(mission, tasks, workers) {
10839
+ const entries = [];
10840
+ entries.push({
10841
+ at: mission.createdAt,
10842
+ kind: "mission.defined",
10843
+ label: "Mission defined",
10844
+ detail: mission.description
10845
+ });
10846
+ if (mission.status === "paused" && mission.pausedReason) {
10847
+ entries.push({
10848
+ at: mission.updatedAt,
10849
+ kind: "mission.paused",
10850
+ label: "Paused",
10851
+ detail: mission.pausedReason
10852
+ });
10853
+ }
10854
+ if (mission.status === "cancelled" && mission.cancelledReason) {
10855
+ entries.push({
10856
+ at: mission.updatedAt,
10857
+ kind: "mission.cancelled",
10858
+ label: "Cancelled",
10859
+ detail: mission.cancelledReason
10860
+ });
10861
+ }
10862
+ for (const task of tasks) {
10863
+ if (task.createdAt) {
10864
+ entries.push({
10865
+ at: task.createdAt,
10866
+ kind: "task.spawned",
10867
+ label: `Spawn \xB7 ${task.agentDefName ?? "task"}`,
10868
+ detail: firstLine3(task.goal, 200)
10869
+ });
10870
+ }
10871
+ if (task.completedAt) {
10872
+ const kind = task.status === "done" ? "task.completed" : task.status === "failed" ? "task.failed" : task.status === "cancelled" ? "task.cancelled" : "task.completed";
10873
+ entries.push({
10874
+ at: task.completedAt,
10875
+ kind,
10876
+ label: `${task.status} \xB7 ${task.agentDefName ?? "task"}`,
10877
+ detail: task.result ? firstLine3(task.result, 200) : void 0
10878
+ });
10879
+ }
10880
+ }
10881
+ for (const worker of workers) {
10882
+ if (worker.latestEventAt && worker.latestEventKind) {
10883
+ entries.push({
10884
+ at: worker.latestEventAt,
10885
+ kind: "worker.latest",
10886
+ label: `${worker.kind} \xB7 ${worker.latestEventKind}`,
10887
+ detail: deriveMissionWorkerActivityLabel(worker)
10888
+ });
10889
+ }
10890
+ }
10891
+ if (mission.lastEvaluationAt && mission.lastEvaluationResult) {
10892
+ entries.push({
10893
+ at: mission.lastEvaluationAt,
10894
+ kind: "evaluator.verdict",
10895
+ label: `Verdict \xB7 ${mission.lastEvaluationResult}`,
10896
+ detail: mission.lastEvaluationFeedback ?? void 0
10897
+ });
10898
+ }
10899
+ entries.sort((a, b) => b.at.localeCompare(a.at));
10900
+ return entries;
10901
+ }
10902
+ function formatTimestamp(iso) {
10903
+ try {
10904
+ return new Date(iso).toLocaleTimeString();
10905
+ } catch {
10906
+ return iso;
10907
+ }
10908
+ }
10877
10909
  var INITIAL_STATE = {
10878
10910
  mission: null,
10879
10911
  tasks: [],
@@ -11026,210 +11058,153 @@ function MissionDashboard({
11026
11058
  setBusy(false);
11027
11059
  }
11028
11060
  };
11029
- const statusVariant = mission.status === "satisfied" ? "default" : mission.status === "failed" || mission.status === "cancelled" ? "destructive" : "secondary";
11030
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 p-4 sm:gap-6 sm:p-6", children: [
11031
- /* @__PURE__ */ jsxRuntime.jsxs(Card, { children: [
11032
- /* @__PURE__ */ jsxRuntime.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-stretch gap-4 sm:flex-row sm:items-start sm:justify-between", children: [
11033
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1 min-w-0 flex-1", children: [
11034
- /* @__PURE__ */ jsxRuntime.jsx(CardTitle, { className: "wrap-break-word -uppercase text-sm", children: mission.description }),
11035
- /* @__PURE__ */ jsxRuntime.jsxs(CardDescription, { className: "wrap-break-word text-foreground/70", children: [
11036
- "Rubric: ",
11037
- mission.rubric
11038
- ] }),
11039
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1 pt-2 text-xs text-foreground/70", children: [
11040
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant, className: "font-mono text-foreground", children: mission.status }),
11041
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono text-primary", children: [
11042
- "Iteration ",
11043
- mission.iteration,
11044
- "/",
11045
- mission.maxIterations
11046
- ] }),
11047
- mission.lastEvaluationResult ? /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
11048
- "Last verdict:",
11049
- " ",
11050
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-primary", children: mission.lastEvaluationResult })
11051
- ] }) : null
11052
- ] })
11053
- ] }),
11054
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-2 shrink-0", children: ACTIVE_MISSION_STATUSES.has(mission.status) ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11055
- mission.status === "active" ? /* @__PURE__ */ jsxRuntime.jsxs(
11056
- Button,
11057
- {
11058
- size: "sm",
11059
- variant: "outline",
11060
- onClick: doPause,
11061
- disabled: busy,
11062
- children: [
11063
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pause, { className: "size-4" }),
11064
- " Pause"
11065
- ]
11066
- }
11067
- ) : /* @__PURE__ */ jsxRuntime.jsxs(
11068
- Button,
11061
+ const statusTone = mission.status === "satisfied" ? "border-emerald-500/40 bg-emerald-500/10 text-emerald-700 dark:text-emerald-400" : mission.status === "failed" || mission.status === "cancelled" ? "border-destructive/40 bg-destructive/10 text-destructive" : mission.status === "paused" ? "border-amber-500/40 bg-amber-500/10 text-amber-700 dark:text-amber-400" : "border-primary/40 bg-primary/10 text-primary";
11062
+ const activity = buildMissionActivity(mission, state.tasks, state.workers);
11063
+ const isActive = ACTIVE_MISSION_STATUSES.has(mission.status);
11064
+ const iterationPct = mission.maxIterations > 0 ? Math.min(100, mission.iteration / mission.maxIterations * 100) : 0;
11065
+ return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { delayDuration: 300, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-1 flex-col overflow-hidden bg-muted/30", children: [
11066
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 px-5 pt-5 sm:px-6 sm:pt-6", children: /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "border-border/60 bg-card shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: "space-y-4 p-5 sm:p-6", children: [
11067
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [
11068
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
11069
+ /* @__PURE__ */ jsxRuntime.jsx(
11070
+ "span",
11069
11071
  {
11070
- size: "sm",
11071
- variant: "outline",
11072
- onClick: doResume,
11073
- disabled: busy,
11074
- children: [
11075
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Play, { className: "size-4" }),
11076
- " Resume"
11077
- ]
11072
+ className: `rounded-md border px-2 py-0.5 font-mono text-[10px] font-semibold uppercase tracking-wider ${statusTone}`,
11073
+ children: mission.status
11078
11074
  }
11079
11075
  ),
11080
- /* @__PURE__ */ jsxRuntime.jsxs(
11076
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-1.5", children: [
11077
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-display text-2xl font-bold tracking-tight tabular-nums text-foreground", children: mission.iteration }),
11078
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-muted-foreground/70", children: [
11079
+ "/ ",
11080
+ mission.maxIterations
11081
+ ] }),
11082
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-[10px] uppercase tracking-wider text-muted-foreground/60", children: "iterations" })
11083
+ ] }),
11084
+ mission.lastEvaluationResult ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-[11px] text-muted-foreground/70", children: [
11085
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "opacity-70", children: "last verdict" }),
11086
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded border border-primary/30 bg-primary/10 px-1.5 py-0.5 font-mono text-[10px] uppercase tracking-wider text-primary", children: mission.lastEvaluationResult })
11087
+ ] }) : null
11088
+ ] }),
11089
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 flex-wrap items-center gap-2", children: [
11090
+ isActive ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11091
+ mission.status === "active" ? /* @__PURE__ */ jsxRuntime.jsxs(
11092
+ Button,
11093
+ {
11094
+ size: "sm",
11095
+ variant: "outline",
11096
+ onClick: doPause,
11097
+ disabled: busy,
11098
+ children: [
11099
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pause, { className: "size-4" }),
11100
+ " Pause"
11101
+ ]
11102
+ }
11103
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(
11104
+ Button,
11105
+ {
11106
+ size: "sm",
11107
+ variant: "outline",
11108
+ onClick: doResume,
11109
+ disabled: busy,
11110
+ children: [
11111
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Play, { className: "size-4" }),
11112
+ " Resume"
11113
+ ]
11114
+ }
11115
+ ),
11116
+ /* @__PURE__ */ jsxRuntime.jsxs(
11117
+ Button,
11118
+ {
11119
+ size: "sm",
11120
+ variant: "destructive",
11121
+ onClick: () => {
11122
+ setCancelCascade(false);
11123
+ setCancelOpen(true);
11124
+ },
11125
+ disabled: busy,
11126
+ children: [
11127
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Ban, { className: "size-4" }),
11128
+ " Cancel"
11129
+ ]
11130
+ }
11131
+ )
11132
+ ] }) : onNavigateBack ? /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", variant: "outline", onClick: onNavigateBack, children: "Back" }) : null,
11133
+ /* @__PURE__ */ jsxRuntime.jsx(
11081
11134
  Button,
11082
11135
  {
11136
+ variant: "ghost",
11083
11137
  size: "sm",
11084
- variant: "destructive",
11085
- onClick: () => {
11086
- setCancelCascade(false);
11087
- setCancelOpen(true);
11088
- },
11138
+ onClick: () => void refresh(),
11089
11139
  disabled: busy,
11090
- children: [
11091
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Ban, { className: "size-4" }),
11092
- " Cancel"
11093
- ]
11140
+ "aria-label": "Refresh",
11141
+ title: "Refresh",
11142
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "size-4" })
11094
11143
  }
11095
11144
  )
11096
- ] }) : onNavigateBack ? /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", variant: "outline", onClick: onNavigateBack, children: "Back" }) : null })
11097
- ] }) }),
11098
- mission.lastEvaluationFeedback ? /* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: "space-y-2", children: [
11099
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-semibold uppercase tracking-widest text-foreground/70", children: "Evaluator feedback" }),
11100
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm whitespace-pre-wrap wrap-break-word", children: mission.lastEvaluationFeedback }),
11101
- mission.lastEvaluationExplanation ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-foreground/70 whitespace-pre-wrap wrap-break-word", children: mission.lastEvaluationExplanation }) : null
11102
- ] }) : null
11103
- ] }),
11104
- /* @__PURE__ */ jsxRuntime.jsxs(Card, { children: [
11105
- /* @__PURE__ */ jsxRuntime.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(CardTitle, { children: [
11106
- "Tasks (",
11107
- state.tasks.length,
11108
- ")"
11109
- ] }) }),
11110
- /* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: "space-y-4", children: [
11111
- ["in_flight", "blocked", "done", "failed_or_cancelled"].map((bucket) => {
11112
- const rows = taskBuckets[bucket];
11113
- if (rows.length === 0) return null;
11114
- const heading = {
11115
- in_flight: "In flight",
11116
- blocked: "Blocked",
11117
- done: "Done",
11118
- failed_or_cancelled: "Failed / cancelled"
11119
- }[bucket];
11120
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
11121
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs font-semibold uppercase tracking-widest text-foreground/70", children: [
11122
- heading,
11123
- " (",
11124
- rows.length,
11125
- ")"
11126
- ] }),
11127
- /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-1.5", children: rows.map((task) => /* @__PURE__ */ jsxRuntime.jsx(
11128
- "li",
11129
- {
11130
- className: "flex items-start justify-between gap-3 rounded border border-border/40 px-3 py-2 text-sm",
11131
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 space-y-1", children: [
11132
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
11133
- task.agentDefName ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-foreground/70", children: task.agentDefName }) : null,
11134
- task.attemptCount > 1 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-foreground/70", children: [
11135
- "attempt ",
11136
- task.attemptCount,
11137
- "/",
11138
- task.maxAttempts
11139
- ] }) : null
11140
- ] }),
11141
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm wrap-break-word", children: task.goal }),
11142
- task.parentIds.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-foreground/70", children: [
11143
- "after:",
11144
- " ",
11145
- task.parentIds.map((p) => p.slice(0, 8)).join(", ")
11146
- ] }) : null,
11147
- task.result ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs whitespace-pre-wrap bg-muted/30 rounded px-2 py-1 max-h-32 overflow-auto", children: task.result }) : null,
11148
- task.resultMetadata ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs whitespace-pre-wrap bg-muted/30 rounded px-2 py-1 max-h-32 overflow-auto", children: JSON.stringify(task.resultMetadata, null, 2) }) : null
11149
- ] })
11150
- },
11151
- task.id
11152
- )) })
11153
- ] }, bucket);
11154
- }),
11155
- state.tasks.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-foreground/70", children: "No tasks spawned yet." }) : null
11156
- ] })
11157
- ] }),
11158
- /* @__PURE__ */ jsxRuntime.jsxs(Card, { children: [
11159
- /* @__PURE__ */ jsxRuntime.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(CardTitle, { children: [
11160
- "Live workers (",
11161
- state.workers.length,
11162
- ")"
11163
- ] }) }),
11164
- /* @__PURE__ */ jsxRuntime.jsx(CardContent, { children: state.workers.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-foreground/70", children: "No workers attached to this mission right now." }) : /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-1.5", children: state.workers.map((w) => {
11165
- const onTranscriptClick = (e) => {
11166
- if (onOpenTranscript) {
11167
- e.preventDefault();
11168
- onOpenTranscript(w.workerSessionId);
11169
- }
11170
- };
11171
- return /* @__PURE__ */ jsxRuntime.jsxs(
11172
- "li",
11173
- {
11174
- className: "flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between rounded border border-border/40 px-3 py-2 text-sm",
11175
- children: [
11176
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 space-y-1", children: [
11177
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
11178
- /* @__PURE__ */ jsxRuntime.jsx(
11179
- Badge,
11180
- {
11181
- variant: "outline",
11182
- className: MISSION_WORKER_KIND_BADGE_CLASS[w.kind],
11183
- title: MISSION_WORKER_KIND_TOOLTIP[w.kind],
11184
- children: w.kind
11185
- }
11186
- ),
11187
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "text-foreground/70", children: w.kind === "task" ? w.taskStatus ?? "\u2014" : w.sessionStatus }),
11188
- w.agentDefName ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-foreground/70", children: w.agentDefName }) : null
11189
- ] }),
11190
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm wrap-break-word", children: deriveMissionWorkerActivityLabel(w) }),
11191
- w.latestEventAt ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-foreground/70", children: new Date(w.latestEventAt).toLocaleTimeString() }) : null
11192
- ] }),
11193
- /* @__PURE__ */ jsxRuntime.jsx(
11194
- "a",
11195
- {
11196
- href: w.transcriptUrl,
11197
- target: "_blank",
11198
- rel: "noreferrer",
11199
- onClick: onTranscriptClick,
11200
- className: "text-xs text-primary hover:underline self-start",
11201
- children: "View session"
11202
- }
11203
- )
11204
- ]
11205
- },
11206
- w.workerSessionId
11207
- );
11208
- }) }) })
11209
- ] }),
11210
- /* @__PURE__ */ jsxRuntime.jsx(Separator, {}),
11211
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center text-xs text-foreground/70", children: [
11212
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
11213
- "Auto-refresh every ",
11214
- pollIntervalMs / 1e3,
11215
- "s while mission is active."
11145
+ ] })
11216
11146
  ] }),
11217
- /* @__PURE__ */ jsxRuntime.jsxs(
11218
- Button,
11147
+ /* @__PURE__ */ jsxRuntime.jsx(
11148
+ Progress,
11219
11149
  {
11220
- variant: "ghost",
11221
- size: "sm",
11222
- onClick: () => {
11223
- void refresh();
11224
- },
11225
- disabled: busy,
11226
- children: [
11227
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "size-4" }),
11228
- " Refresh"
11229
- ]
11150
+ value: iterationPct,
11151
+ className: `h-1 ${isActive ? "" : "opacity-40"}`
11230
11152
  }
11231
- )
11232
- ] }),
11153
+ ),
11154
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
11155
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "line-clamp-4 cursor-default font-display text-lg font-semibold leading-snug text-foreground wrap-break-word", children: mission.description }) }),
11156
+ mission.description.length > 240 ? /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { className: "max-w-lg", side: "bottom", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap text-xs", children: mission.description }) }) : null
11157
+ ] }) }),
11158
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-md border border-border/60 bg-muted/40 px-3 py-2", children: [
11159
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-0.5 font-mono text-[9px] uppercase tracking-widest text-muted-foreground/70", children: "Rubric" }),
11160
+ /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
11161
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "line-clamp-3 cursor-default text-sm leading-relaxed text-foreground/90 wrap-break-word", children: mission.rubric }) }),
11162
+ mission.rubric.length > 200 ? /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { className: "max-w-lg", side: "bottom", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap text-xs", children: mission.rubric }) }) : null
11163
+ ] })
11164
+ ] })
11165
+ ] }) }) }),
11166
+ /* @__PURE__ */ jsxRuntime.jsxs(
11167
+ Tabs,
11168
+ {
11169
+ defaultValue: "activity",
11170
+ className: "mt-5 flex flex-1 flex-col overflow-hidden sm:mt-6",
11171
+ children: [
11172
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 border-b border-border bg-background px-5 sm:px-6", children: /* @__PURE__ */ jsxRuntime.jsxs(TabsList, { variant: "line", children: [
11173
+ /* @__PURE__ */ jsxRuntime.jsxs(TabsTrigger, { value: "activity", children: [
11174
+ "Activity",
11175
+ /* @__PURE__ */ jsxRuntime.jsx(CountBadge, { n: activity.length })
11176
+ ] }),
11177
+ /* @__PURE__ */ jsxRuntime.jsxs(TabsTrigger, { value: "tasks", children: [
11178
+ "Tasks",
11179
+ /* @__PURE__ */ jsxRuntime.jsx(CountBadge, { n: state.tasks.length })
11180
+ ] }),
11181
+ /* @__PURE__ */ jsxRuntime.jsxs(TabsTrigger, { value: "workers", children: [
11182
+ "Workers",
11183
+ /* @__PURE__ */ jsxRuntime.jsx(CountBadge, { n: state.workers.length })
11184
+ ] }),
11185
+ /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: "metadata", children: "Metadata" })
11186
+ ] }) }),
11187
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto bg-background px-5 py-4 sm:px-6", children: [
11188
+ /* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value: "activity", className: "mt-0", children: /* @__PURE__ */ jsxRuntime.jsx(ActivityTimeline, { entries: activity }) }),
11189
+ /* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value: "tasks", className: "mt-0", children: /* @__PURE__ */ jsxRuntime.jsx(
11190
+ TasksList,
11191
+ {
11192
+ taskBuckets,
11193
+ totalTasks: state.tasks.length
11194
+ }
11195
+ ) }),
11196
+ /* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value: "workers", className: "mt-0", children: /* @__PURE__ */ jsxRuntime.jsx(
11197
+ WorkersList,
11198
+ {
11199
+ workers: state.workers,
11200
+ onOpenTranscript
11201
+ }
11202
+ ) }),
11203
+ /* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value: "metadata", className: "mt-0", children: /* @__PURE__ */ jsxRuntime.jsx(MetadataPane, { mission }) })
11204
+ ] })
11205
+ ]
11206
+ }
11207
+ ),
11233
11208
  /* @__PURE__ */ jsxRuntime.jsx(
11234
11209
  Dialog,
11235
11210
  {
@@ -11287,6 +11262,234 @@ function MissionDashboard({
11287
11262
  ] })
11288
11263
  }
11289
11264
  )
11265
+ ] }) });
11266
+ }
11267
+ function ActivityTimeline({ entries }) {
11268
+ if (entries.length === 0) {
11269
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-8 text-center text-sm text-muted-foreground/60", children: "No mission activity yet." });
11270
+ }
11271
+ return /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "space-y-1", children: entries.map((e, i) => /* @__PURE__ */ jsxRuntime.jsxs(
11272
+ "li",
11273
+ {
11274
+ className: "flex items-start gap-3 rounded px-2 py-1.5 text-sm hover:bg-muted/30",
11275
+ children: [
11276
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-20 shrink-0 font-mono text-[10px] text-muted-foreground/60", children: formatTimestamp(e.at) }),
11277
+ /* @__PURE__ */ jsxRuntime.jsx(
11278
+ "span",
11279
+ {
11280
+ className: `shrink-0 rounded border px-1.5 py-0.5 font-mono text-[9px] uppercase tracking-wide ${ACTIVITY_KIND_TONE[e.kind]}`,
11281
+ children: e.label
11282
+ }
11283
+ ),
11284
+ e.detail ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate text-foreground/80", children: e.detail }) : null
11285
+ ]
11286
+ },
11287
+ `${e.kind}-${e.at}-${i}`
11288
+ )) });
11289
+ }
11290
+ function TaskRow({ task }) {
11291
+ const [open, setOpen] = react.useState(false);
11292
+ const goalPreview = firstLine3(task.goal, 160);
11293
+ const hasMore = task.goal.length > 160 || Boolean(task.result) || Boolean(task.resultMetadata);
11294
+ const statusTone = task.status === "done" ? "border-emerald-500/30 bg-emerald-500/10 text-emerald-600" : task.status === "failed" ? "border-destructive/30 bg-destructive/10 text-destructive" : task.status === "cancelled" ? "border-border bg-muted text-muted-foreground" : task.status === "running" ? "border-primary/30 bg-primary/10 text-primary" : "border-foreground/20 bg-foreground/5 text-foreground/70";
11295
+ return /* @__PURE__ */ jsxRuntime.jsx(Collapsible, { open, onOpenChange: setOpen, asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "rounded border border-border/40 text-sm", children: [
11296
+ /* @__PURE__ */ jsxRuntime.jsx(
11297
+ CollapsibleTrigger,
11298
+ {
11299
+ asChild: true,
11300
+ disabled: !hasMore,
11301
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
11302
+ "button",
11303
+ {
11304
+ type: "button",
11305
+ className: "flex w-full items-start gap-3 px-3 py-2 text-left hover:bg-muted/30 disabled:hover:bg-transparent",
11306
+ children: [
11307
+ /* @__PURE__ */ jsxRuntime.jsx(
11308
+ lucideReact.ChevronRight,
11309
+ {
11310
+ className: `mt-0.5 size-3.5 shrink-0 text-muted-foreground/60 transition-transform ${open ? "rotate-90" : ""} ${hasMore ? "" : "opacity-0"}`
11311
+ }
11312
+ ),
11313
+ /* @__PURE__ */ jsxRuntime.jsx(
11314
+ "span",
11315
+ {
11316
+ className: `shrink-0 rounded border px-1.5 py-0.5 font-mono text-[9px] uppercase tracking-wide ${statusTone}`,
11317
+ children: task.status
11318
+ }
11319
+ ),
11320
+ task.agentDefName ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-[10px] text-muted-foreground/70", children: task.agentDefName }) : null,
11321
+ task.attemptCount > 1 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "shrink-0 text-[10px] text-muted-foreground/60", children: [
11322
+ "(",
11323
+ task.attemptCount,
11324
+ "/",
11325
+ task.maxAttempts,
11326
+ ")"
11327
+ ] }) : null,
11328
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate text-foreground/80", children: goalPreview })
11329
+ ]
11330
+ }
11331
+ )
11332
+ }
11333
+ ),
11334
+ /* @__PURE__ */ jsxRuntime.jsxs(CollapsibleContent, { className: "border-t border-border/40 px-3 py-2 text-xs", children: [
11335
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-2", children: [
11336
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-1 font-mono text-[9px] uppercase tracking-wide text-muted-foreground/60", children: "Goal" }),
11337
+ /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "max-h-64 overflow-auto whitespace-pre-wrap rounded bg-muted/30 px-2 py-1.5 text-[11px] text-foreground/90", children: task.goal })
11338
+ ] }),
11339
+ task.parentIds.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-2 text-[10px] text-muted-foreground/70", children: [
11340
+ "after: ",
11341
+ task.parentIds.map((p) => p.slice(0, 8)).join(", ")
11342
+ ] }) : null,
11343
+ task.result ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-2", children: [
11344
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-1 font-mono text-[9px] uppercase tracking-wide text-muted-foreground/60", children: "Result" }),
11345
+ /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "max-h-64 overflow-auto whitespace-pre-wrap rounded bg-muted/30 px-2 py-1.5 text-[11px] text-foreground/90", children: task.result })
11346
+ ] }) : null,
11347
+ task.resultMetadata ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11348
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-1 font-mono text-[9px] uppercase tracking-wide text-muted-foreground/60", children: "Result metadata" }),
11349
+ /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "max-h-64 overflow-auto whitespace-pre-wrap rounded bg-muted/30 px-2 py-1.5 text-[11px] text-foreground/90", children: JSON.stringify(task.resultMetadata, null, 2) })
11350
+ ] }) : null
11351
+ ] })
11352
+ ] }) });
11353
+ }
11354
+ function TasksList({
11355
+ taskBuckets,
11356
+ totalTasks
11357
+ }) {
11358
+ if (totalTasks === 0) {
11359
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-8 text-center text-sm text-muted-foreground/60", children: "No tasks spawned yet." });
11360
+ }
11361
+ const headings = {
11362
+ in_flight: "In flight",
11363
+ blocked: "Blocked",
11364
+ done: "Done",
11365
+ failed_or_cancelled: "Failed / cancelled"
11366
+ };
11367
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4", children: Object.keys(headings).map((bucket) => {
11368
+ const rows = taskBuckets[bucket];
11369
+ if (rows.length === 0) return null;
11370
+ return /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
11371
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: [
11372
+ headings[bucket],
11373
+ " (",
11374
+ rows.length,
11375
+ ")"
11376
+ ] }),
11377
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-1", children: rows.map((task) => /* @__PURE__ */ jsxRuntime.jsx(TaskRow, { task }, task.id)) })
11378
+ ] }, bucket);
11379
+ }) });
11380
+ }
11381
+ function WorkersList({
11382
+ workers,
11383
+ onOpenTranscript
11384
+ }) {
11385
+ if (workers.length === 0) {
11386
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-8 text-center text-sm text-muted-foreground/60", children: "No workers attached to this mission right now." });
11387
+ }
11388
+ return /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-1", children: workers.map((w) => {
11389
+ const onTranscriptClick = (e) => {
11390
+ if (onOpenTranscript) {
11391
+ e.preventDefault();
11392
+ onOpenTranscript(w.workerSessionId);
11393
+ }
11394
+ };
11395
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11396
+ "li",
11397
+ {
11398
+ className: "flex flex-col gap-2 rounded border border-border/40 px-3 py-2 text-sm sm:flex-row sm:items-start sm:justify-between",
11399
+ children: [
11400
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 space-y-1", children: [
11401
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
11402
+ /* @__PURE__ */ jsxRuntime.jsx(
11403
+ Badge,
11404
+ {
11405
+ variant: "outline",
11406
+ className: MISSION_WORKER_KIND_BADGE_CLASS[w.kind],
11407
+ title: MISSION_WORKER_KIND_TOOLTIP[w.kind],
11408
+ children: w.kind
11409
+ }
11410
+ ),
11411
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "text-foreground/70", children: w.kind === "task" ? w.taskStatus ?? "\u2014" : w.sessionStatus }),
11412
+ w.agentDefName ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground/70", children: w.agentDefName }) : null,
11413
+ w.latestEventAt ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto font-mono text-[10px] text-muted-foreground/60", children: formatTimestamp(w.latestEventAt) }) : null
11414
+ ] }),
11415
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-sm text-foreground/80", children: deriveMissionWorkerActivityLabel(w) })
11416
+ ] }),
11417
+ /* @__PURE__ */ jsxRuntime.jsx(
11418
+ "a",
11419
+ {
11420
+ href: w.transcriptUrl,
11421
+ target: "_blank",
11422
+ rel: "noreferrer",
11423
+ onClick: onTranscriptClick,
11424
+ className: "self-start text-xs text-primary hover:underline",
11425
+ children: "View session"
11426
+ }
11427
+ )
11428
+ ]
11429
+ },
11430
+ w.workerSessionId
11431
+ );
11432
+ }) });
11433
+ }
11434
+ function MetadataPane({ mission }) {
11435
+ const rows = [];
11436
+ rows.push({
11437
+ label: "Mission ID",
11438
+ value: /* @__PURE__ */ jsxRuntime.jsx("code", { className: "text-[11px]", children: mission.id })
11439
+ });
11440
+ rows.push({
11441
+ label: "Session ID",
11442
+ value: /* @__PURE__ */ jsxRuntime.jsx("code", { className: "text-[11px]", children: mission.sessionId })
11443
+ });
11444
+ rows.push({
11445
+ label: "Agent ID",
11446
+ value: /* @__PURE__ */ jsxRuntime.jsx("code", { className: "text-[11px]", children: mission.agentId })
11447
+ });
11448
+ rows.push({ label: "Status", value: mission.status });
11449
+ rows.push({
11450
+ label: "Iteration",
11451
+ value: `${mission.iteration} / ${mission.maxIterations}`
11452
+ });
11453
+ rows.push({
11454
+ label: "Owner",
11455
+ value: mission.userId ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11456
+ "user ",
11457
+ /* @__PURE__ */ jsxRuntime.jsx("code", { className: "text-[11px]", children: mission.userId })
11458
+ ] }) : mission.serviceAccountId ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11459
+ "service account ",
11460
+ /* @__PURE__ */ jsxRuntime.jsx("code", { className: "text-[11px]", children: mission.serviceAccountId })
11461
+ ] }) : "\u2014"
11462
+ });
11463
+ rows.push({
11464
+ label: "Created",
11465
+ value: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[11px]", children: new Date(mission.createdAt).toLocaleString() })
11466
+ });
11467
+ rows.push({
11468
+ label: "Updated",
11469
+ value: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[11px]", children: new Date(mission.updatedAt).toLocaleString() })
11470
+ });
11471
+ if (mission.pausedReason) {
11472
+ rows.push({ label: "Paused reason", value: mission.pausedReason });
11473
+ }
11474
+ if (mission.cancelledReason) {
11475
+ rows.push({ label: "Cancelled reason", value: mission.cancelledReason });
11476
+ }
11477
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
11478
+ mission.lastEvaluationResult ? /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-2", children: [
11479
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: [
11480
+ "Last verdict \u2014 ",
11481
+ mission.lastEvaluationResult
11482
+ ] }),
11483
+ mission.lastEvaluationFeedback ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap text-sm text-foreground/90", children: mission.lastEvaluationFeedback }) : null,
11484
+ mission.lastEvaluationExplanation ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap text-xs text-muted-foreground/70", children: mission.lastEvaluationExplanation }) : null
11485
+ ] }) : null,
11486
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { children: [
11487
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2 font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: "Identifiers" }),
11488
+ /* @__PURE__ */ jsxRuntime.jsx("dl", { className: "grid grid-cols-[max-content_1fr] gap-x-4 gap-y-1 text-xs", children: rows.map((r) => /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
11489
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-muted-foreground/70", children: r.label }),
11490
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { className: "break-all text-foreground/90", children: r.value })
11491
+ ] }, r.label)) })
11492
+ ] })
11290
11493
  ] });
11291
11494
  }
11292
11495
  init_utils();