@invergent/agent-chat-react 2.5.8 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1539 -421
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +160 -4
- package/dist/index.d.ts +160 -4
- package/dist/index.js +1522 -422
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cn } from './chunk-QSC4UIVT.js';
|
|
2
2
|
import { createContext, memo, useRef, useEffect, useCallback, useMemo, useState, useLayoutEffect, lazy, useContext, Fragment as Fragment$1, Children, Suspense } from 'react';
|
|
3
|
-
import { ChevronDownIcon, AlertTriangle, ChevronDown, ChevronRight, RefreshCw, File as File$1, FileImage, FileAudio, FileVideo, FileText, FileCode, FileArchive, FileSpreadsheet, PlugZapIcon, ChevronRightIcon, ArrowLeftIcon, Loader2Icon, InboxIcon, Loader2, AlertCircle, Pause, Play, Ban, TargetIcon, CalendarClockIcon, UsersIcon, MessageSquareIcon, ZapIcon, Maximize2Icon, FolderOpenIcon, UploadIcon, RefreshCwIcon, AlertCircleIcon, ExternalLinkIcon, ClipboardCheckIcon, ShieldAlertIcon, TimerIcon, CircleDotIcon, XIcon, Trash2Icon, SquareIcon, ArrowDownIcon, RotateCcwIcon, MousePointer2Icon, DownloadIcon, TrashIcon, ImageIcon, FileTextIcon, CheckIcon, TerminalIcon, SparklesIcon, ClockIcon, PlusIcon, CloudIcon, HardDriveIcon, PaperclipIcon, GlobeIcon, FolderIcon, CopyIcon, FileIcon, ChevronLeftIcon, MinusIcon, SearchIcon, ArrowUpIcon, CircleCheckIcon, ThumbsUpIcon, ThumbsDownIcon, BookOpenIcon, GitBranchIcon, ActivityIcon, EyeIcon, ListTodoIcon, ListIcon, PenLineIcon,
|
|
3
|
+
import { ChevronDownIcon, AlertTriangle, ChevronDown, ChevronRight, RefreshCw, File as File$1, FileImage, FileAudio, FileVideo, FileText, FileCode, FileArchive, FileSpreadsheet, PlugZapIcon, ChevronRightIcon, ArrowLeftIcon, Loader2Icon, InboxIcon, Loader2, AlertCircle, Pause, Play, Ban, TargetIcon, CalendarClockIcon, UsersIcon, MessageSquareIcon, ZapIcon, Maximize2Icon, FolderOpenIcon, UploadIcon, RefreshCwIcon, AlertCircleIcon, ExternalLinkIcon, ClipboardCheckIcon, ShieldAlertIcon, TimerIcon, CircleDotIcon, XIcon, Trash2Icon, SquareIcon, ArrowDownIcon, RotateCcwIcon, MousePointer2Icon, DownloadIcon, TrashIcon, ImageIcon, FileTextIcon, CheckIcon, Clock, ArrowRight, TerminalIcon, SparklesIcon, ClockIcon, PlusIcon, CloudIcon, HardDriveIcon, PaperclipIcon, GlobeIcon, FolderIcon, CopyIcon, FileIcon, ChevronLeftIcon, MinusIcon, SearchIcon, CircleDot, XCircle, CheckCircle2, ArrowUpIcon, CircleCheckIcon, ThumbsUpIcon, ThumbsDownIcon, BookOpenIcon, GitBranchIcon, ActivityIcon, EyeIcon, ListTodoIcon, BotIcon, ListIcon, PenLineIcon, FileEditIcon, WrenchIcon, FileCodeIcon, CodeIcon, FileArchiveIcon, FileVideoIcon, FileAudioIcon, FileImageIcon, FileChartLineIcon, FileSpreadsheetIcon, XCircleIcon, CheckCircle2Icon, Code, CircleXIcon, SkullIcon, CheckCircleIcon, CircleIcon } from 'lucide-react';
|
|
4
4
|
import { cva } from 'class-variance-authority';
|
|
5
5
|
import { Collapsible as Collapsible$1, Slot, Tooltip as Tooltip$1, Progress as Progress$1, Tabs as Tabs$1, Dialog as Dialog$1, ScrollArea as ScrollArea$1, Popover as Popover$1 } from 'radix-ui';
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -13,7 +13,7 @@ import { Streamdown } from 'streamdown';
|
|
|
13
13
|
import { useControllableState } from '@radix-ui/react-use-controllable-state';
|
|
14
14
|
import { createHighlighter } from 'shiki';
|
|
15
15
|
import { diffLines, diffWordsWithSpace } from 'diff';
|
|
16
|
-
import
|
|
16
|
+
import AnsiImport from 'ansi-to-react';
|
|
17
17
|
import { Command as Command$1 } from 'cmdk';
|
|
18
18
|
import { nanoid } from 'nanoid';
|
|
19
19
|
import { getUsage } from 'tokenlens';
|
|
@@ -826,6 +826,11 @@ var MessageResponse = memo(
|
|
|
826
826
|
{
|
|
827
827
|
className: cn(
|
|
828
828
|
"size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0",
|
|
829
|
+
// Streamdown emits ``list-inside`` lists and preflight strips
|
|
830
|
+
// the UA list padding, so bullet markers hug the container
|
|
831
|
+
// edge and wrapped lines slide under them. Hanging-indent
|
|
832
|
+
// lists instead, everywhere markdown renders.
|
|
833
|
+
"[&_ol]:list-outside [&_ol]:pl-5 [&_ul]:list-outside [&_ul]:pl-5",
|
|
829
834
|
className
|
|
830
835
|
),
|
|
831
836
|
plugins: streamdownPlugins,
|
|
@@ -1010,7 +1015,14 @@ var ReasoningContent = memo(
|
|
|
1010
1015
|
className
|
|
1011
1016
|
),
|
|
1012
1017
|
...props,
|
|
1013
|
-
children: /* @__PURE__ */ jsx(
|
|
1018
|
+
children: /* @__PURE__ */ jsx(
|
|
1019
|
+
Streamdown,
|
|
1020
|
+
{
|
|
1021
|
+
className: "[&_ol]:list-outside [&_ol]:pl-5 [&_ul]:list-outside [&_ul]:pl-5",
|
|
1022
|
+
plugins: streamdownPlugins2,
|
|
1023
|
+
children
|
|
1024
|
+
}
|
|
1025
|
+
)
|
|
1014
1026
|
}
|
|
1015
1027
|
)
|
|
1016
1028
|
);
|
|
@@ -3074,7 +3086,7 @@ var TerminalContent = ({
|
|
|
3074
3086
|
ref: containerRef,
|
|
3075
3087
|
...props,
|
|
3076
3088
|
children: children ?? /* @__PURE__ */ jsxs("pre", { className: "whitespace-pre-wrap break-words", children: [
|
|
3077
|
-
/* @__PURE__ */ jsx(
|
|
3089
|
+
/* @__PURE__ */ jsx(AnsiImport, { children: output }),
|
|
3078
3090
|
isStreaming && /* @__PURE__ */ jsx("span", { className: "ml-0.5 inline-block h-4 w-2 animate-pulse bg-foreground" })
|
|
3079
3091
|
] })
|
|
3080
3092
|
}
|
|
@@ -4318,6 +4330,107 @@ function ResearchOutlineBlock({ tc }) {
|
|
|
4318
4330
|
outline ? /* @__PURE__ */ jsx("pre", { className: "max-h-48 overflow-auto whitespace-pre-wrap font-mono text-[11px] leading-snug", children: outline }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "updated" })
|
|
4319
4331
|
] });
|
|
4320
4332
|
}
|
|
4333
|
+
var Ansi2 = AnsiImport.default ?? AnsiImport;
|
|
4334
|
+
function parseCodeRun(result, args) {
|
|
4335
|
+
const fallback = {
|
|
4336
|
+
agent: "",
|
|
4337
|
+
provider: "",
|
|
4338
|
+
prompt: "",
|
|
4339
|
+
output: "",
|
|
4340
|
+
finalMessage: "",
|
|
4341
|
+
error: null,
|
|
4342
|
+
inputTokens: 0,
|
|
4343
|
+
outputTokens: 0
|
|
4344
|
+
};
|
|
4345
|
+
if (result) {
|
|
4346
|
+
try {
|
|
4347
|
+
const parsed = JSON.parse(result);
|
|
4348
|
+
return { ...fallback, ...parsed, error: parsed.error ?? null };
|
|
4349
|
+
} catch {
|
|
4350
|
+
}
|
|
4351
|
+
}
|
|
4352
|
+
try {
|
|
4353
|
+
const parsedArgs = JSON.parse(args);
|
|
4354
|
+
return { ...fallback, ...parsedArgs, error: null };
|
|
4355
|
+
} catch {
|
|
4356
|
+
return fallback;
|
|
4357
|
+
}
|
|
4358
|
+
}
|
|
4359
|
+
function agentLabel(state) {
|
|
4360
|
+
if (state.agent) return state.agent;
|
|
4361
|
+
if (state.provider === "anthropic") return "claude";
|
|
4362
|
+
if (state.provider === "openai") return "codex";
|
|
4363
|
+
return "coding agent";
|
|
4364
|
+
}
|
|
4365
|
+
function CodeRunToolBlock({
|
|
4366
|
+
tc,
|
|
4367
|
+
defaultOpen = false
|
|
4368
|
+
}) {
|
|
4369
|
+
const [isOpen, setIsOpen] = useState(defaultOpen);
|
|
4370
|
+
const isRunning = tc.status === "running";
|
|
4371
|
+
const state = parseCodeRun(tc.result, tc.args);
|
|
4372
|
+
const label = agentLabel(state);
|
|
4373
|
+
const hasError = tc.status === "error" || Boolean(state.error);
|
|
4374
|
+
return /* @__PURE__ */ jsxs(
|
|
4375
|
+
Collapsible,
|
|
4376
|
+
{
|
|
4377
|
+
open: isOpen,
|
|
4378
|
+
onOpenChange: setIsOpen,
|
|
4379
|
+
className: "not-prose w-full",
|
|
4380
|
+
children: [
|
|
4381
|
+
/* @__PURE__ */ jsxs(CollapsibleTrigger, { className: "group/trigger flex w-fit items-center gap-2 text-sm transition-colors", children: [
|
|
4382
|
+
/* @__PURE__ */ jsx("span", { className: "text-left", children: isRunning ? /* @__PURE__ */ jsx(Shimmer, { as: "span", duration: 1, children: `Running ${label}...` }) : hasError ? /* @__PURE__ */ jsx("span", { className: "font-semibold text-destructive", children: `${label} failed` }) : /* @__PURE__ */ jsx("span", { className: "font-semibold text-foreground", children: `Ran ${label}` }) }),
|
|
4383
|
+
/* @__PURE__ */ jsx(
|
|
4384
|
+
ChevronDownIcon,
|
|
4385
|
+
{
|
|
4386
|
+
className: cn(
|
|
4387
|
+
"size-4 shrink-0 transition-transform",
|
|
4388
|
+
isOpen ? "rotate-180" : "rotate-0"
|
|
4389
|
+
)
|
|
4390
|
+
}
|
|
4391
|
+
)
|
|
4392
|
+
] }),
|
|
4393
|
+
/* @__PURE__ */ jsx(
|
|
4394
|
+
CollapsibleContent,
|
|
4395
|
+
{
|
|
4396
|
+
className: cn(
|
|
4397
|
+
"mt-2 overflow-hidden",
|
|
4398
|
+
"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 outline-none data-[state=closed]:animate-out data-[state=open]:animate-in"
|
|
4399
|
+
),
|
|
4400
|
+
children: /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-border overflow-hidden", children: [
|
|
4401
|
+
state.prompt && /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2 bg-background text-muted-foreground px-3 py-2 font-mono text-sm leading-relaxed", children: [
|
|
4402
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 select-none text-emerald-600", children: "IN" }),
|
|
4403
|
+
/* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap wrap-break-word text-foreground/90 flex-1", children: state.prompt })
|
|
4404
|
+
] }),
|
|
4405
|
+
/* @__PURE__ */ jsxs(
|
|
4406
|
+
"div",
|
|
4407
|
+
{
|
|
4408
|
+
className: cn(
|
|
4409
|
+
"px-3 py-2 bg-background font-mono text-sm leading-relaxed max-h-96 overflow-auto",
|
|
4410
|
+
state.prompt && "border-t border-border"
|
|
4411
|
+
),
|
|
4412
|
+
children: [
|
|
4413
|
+
(state.output || !isRunning) && /* @__PURE__ */ jsxs("div", { className: "flex gap-2 text-foreground/90", children: [
|
|
4414
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 select-none text-sky-600", children: "OUT" }),
|
|
4415
|
+
/* @__PURE__ */ jsxs("pre", { className: "whitespace-pre-wrap wrap-break-word flex-1", children: [
|
|
4416
|
+
state.output ? /* @__PURE__ */ jsx(Ansi2, { children: state.output }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground/60", children: "(no output)" }),
|
|
4417
|
+
isRunning && /* @__PURE__ */ jsx("span", { className: "ml-0.5 inline-block h-3.5 w-1.5 animate-pulse bg-foreground" })
|
|
4418
|
+
] })
|
|
4419
|
+
] }),
|
|
4420
|
+
isRunning && !state.output && /* @__PURE__ */ jsx("span", { className: "ml-0.5 inline-block h-3.5 w-1.5 animate-pulse bg-foreground" })
|
|
4421
|
+
]
|
|
4422
|
+
}
|
|
4423
|
+
),
|
|
4424
|
+
!isRunning && hasError && state.error && /* @__PURE__ */ jsx("div", { className: "border-t border-border bg-destructive/5 px-3 py-2 text-sm text-destructive", children: /* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap wrap-break-word", children: state.error }) }),
|
|
4425
|
+
!isRunning && !hasError && state.finalMessage && /* @__PURE__ */ jsx("div", { className: "border-t border-border bg-background px-3 py-2 text-sm text-foreground/90", children: /* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap wrap-break-word", children: state.finalMessage }) }),
|
|
4426
|
+
!isRunning && (state.inputTokens > 0 || state.outputTokens > 0) && /* @__PURE__ */ jsx("div", { className: "border-t border-border bg-background px-3 py-1.5 text-xs text-muted-foreground", children: `${state.inputTokens.toLocaleString()} in \xB7 ${state.outputTokens.toLocaleString()} out tokens` })
|
|
4427
|
+
] })
|
|
4428
|
+
}
|
|
4429
|
+
)
|
|
4430
|
+
]
|
|
4431
|
+
}
|
|
4432
|
+
);
|
|
4433
|
+
}
|
|
4321
4434
|
function ToolCallBlock({
|
|
4322
4435
|
tc,
|
|
4323
4436
|
resolvedArtifactName,
|
|
@@ -4374,6 +4487,8 @@ function ToolCallBlock({
|
|
|
4374
4487
|
return /* @__PURE__ */ jsx(ResearchOutlineBlock, { tc });
|
|
4375
4488
|
case "research_memory":
|
|
4376
4489
|
return /* @__PURE__ */ jsx(ResearchMemoryBlock, { tc });
|
|
4490
|
+
case "code_run":
|
|
4491
|
+
return /* @__PURE__ */ jsx(CodeRunToolBlock, { tc });
|
|
4377
4492
|
case "spawn_worker":
|
|
4378
4493
|
case "send_worker_message":
|
|
4379
4494
|
case "stop_worker":
|
|
@@ -5942,6 +6057,7 @@ function ChatComposerInner({
|
|
|
5942
6057
|
canShowBrowser = false,
|
|
5943
6058
|
canShowWorkspace = false,
|
|
5944
6059
|
deepResearchEnabled = false,
|
|
6060
|
+
codeAgentsEnabled = false,
|
|
5945
6061
|
viewMode = "simple",
|
|
5946
6062
|
onViewModeChange
|
|
5947
6063
|
}) {
|
|
@@ -5996,9 +6112,18 @@ function ChatComposerInner({
|
|
|
5996
6112
|
description: "Delegate a topic to the deep-research workflow"
|
|
5997
6113
|
});
|
|
5998
6114
|
}
|
|
6115
|
+
if (codeAgentsEnabled) {
|
|
6116
|
+
base.push(
|
|
6117
|
+
{ value: "/code claude ", label: "/code claude", description: "Run Claude Code on the workspace (your plan)" },
|
|
6118
|
+
{ value: "/code codex ", label: "/code codex", description: "Run Codex on the workspace (your plan)" },
|
|
6119
|
+
{ value: "/code status", label: "/code status", description: "Show connected coding agents" },
|
|
6120
|
+
{ value: "/code login claude", label: "/code login claude", description: "Connect your Claude plan" },
|
|
6121
|
+
{ value: "/code login codex", label: "/code login codex", description: "Connect your ChatGPT plan" }
|
|
6122
|
+
);
|
|
6123
|
+
}
|
|
5999
6124
|
return base;
|
|
6000
6125
|
},
|
|
6001
|
-
[deepResearchEnabled]
|
|
6126
|
+
[deepResearchEnabled, codeAgentsEnabled]
|
|
6002
6127
|
);
|
|
6003
6128
|
const scheduledExamples = useMemo(
|
|
6004
6129
|
() => [
|
|
@@ -7208,6 +7333,53 @@ function ArtifactSvg({ spec }) {
|
|
|
7208
7333
|
spec.caption && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: spec.caption })
|
|
7209
7334
|
] });
|
|
7210
7335
|
}
|
|
7336
|
+
function useMediaSrc(sessionId, path) {
|
|
7337
|
+
const { adapter } = useAgentChatAdapterContext();
|
|
7338
|
+
return useMemo(
|
|
7339
|
+
() => adapter.getWorkspaceDownloadUrl({ sessionId, path }),
|
|
7340
|
+
[adapter, sessionId, path]
|
|
7341
|
+
);
|
|
7342
|
+
}
|
|
7343
|
+
function MediaCaption({ caption }) {
|
|
7344
|
+
if (!caption) return null;
|
|
7345
|
+
return /* @__PURE__ */ jsx("figcaption", { className: "border-t border-border px-3 py-2 text-xs leading-snug text-muted-foreground", children: caption });
|
|
7346
|
+
}
|
|
7347
|
+
function ArtifactImage({ sessionId, spec, fill = false }) {
|
|
7348
|
+
const src = useMediaSrc(sessionId, spec.path);
|
|
7349
|
+
return /* @__PURE__ */ jsxs("figure", { className: "m-0", children: [
|
|
7350
|
+
/* @__PURE__ */ jsx(
|
|
7351
|
+
"img",
|
|
7352
|
+
{
|
|
7353
|
+
src,
|
|
7354
|
+
alt: spec.caption ?? spec.path,
|
|
7355
|
+
loading: "lazy",
|
|
7356
|
+
className: cn(
|
|
7357
|
+
"block w-full bg-muted/30 object-contain",
|
|
7358
|
+
fill ? "max-h-full" : "max-h-[480px]"
|
|
7359
|
+
)
|
|
7360
|
+
}
|
|
7361
|
+
),
|
|
7362
|
+
/* @__PURE__ */ jsx(MediaCaption, { caption: spec.caption })
|
|
7363
|
+
] });
|
|
7364
|
+
}
|
|
7365
|
+
function ArtifactVideo({ sessionId, spec, fill = false }) {
|
|
7366
|
+
const src = useMediaSrc(sessionId, spec.path);
|
|
7367
|
+
return /* @__PURE__ */ jsxs("figure", { className: "m-0", children: [
|
|
7368
|
+
/* @__PURE__ */ jsx(
|
|
7369
|
+
"video",
|
|
7370
|
+
{
|
|
7371
|
+
src,
|
|
7372
|
+
controls: true,
|
|
7373
|
+
preload: "metadata",
|
|
7374
|
+
className: cn(
|
|
7375
|
+
"block w-full bg-black object-contain",
|
|
7376
|
+
fill ? "max-h-full" : "max-h-[480px]"
|
|
7377
|
+
)
|
|
7378
|
+
}
|
|
7379
|
+
),
|
|
7380
|
+
/* @__PURE__ */ jsx(MediaCaption, { caption: spec.caption })
|
|
7381
|
+
] });
|
|
7382
|
+
}
|
|
7211
7383
|
|
|
7212
7384
|
// src/components/chat/artifacts/artifact-export.ts
|
|
7213
7385
|
function exportArtifact(payload) {
|
|
@@ -7242,6 +7414,17 @@ function exportArtifact(payload) {
|
|
|
7242
7414
|
mime: "image/svg+xml",
|
|
7243
7415
|
extension: "svg"
|
|
7244
7416
|
};
|
|
7417
|
+
// Media artifacts are file references — the bytes live in the
|
|
7418
|
+
// workspace. Copy yields the path; the download action in
|
|
7419
|
+
// ArtifactBlock bypasses this serialisation and uses the
|
|
7420
|
+
// authenticated workspace download URL directly.
|
|
7421
|
+
case "image":
|
|
7422
|
+
case "video":
|
|
7423
|
+
return {
|
|
7424
|
+
text: payload.spec.path,
|
|
7425
|
+
mime: "text/plain",
|
|
7426
|
+
extension: "txt"
|
|
7427
|
+
};
|
|
7245
7428
|
}
|
|
7246
7429
|
}
|
|
7247
7430
|
function tableToCsv(columns, rows) {
|
|
@@ -7294,7 +7477,9 @@ var KIND_LABEL = {
|
|
|
7294
7477
|
table: "Table",
|
|
7295
7478
|
chart: "Chart",
|
|
7296
7479
|
html: "HTML preview",
|
|
7297
|
-
svg: "SVG"
|
|
7480
|
+
svg: "SVG",
|
|
7481
|
+
image: "Generated image",
|
|
7482
|
+
video: "Generated video"
|
|
7298
7483
|
};
|
|
7299
7484
|
var COPY_FEEDBACK_MS = 1500;
|
|
7300
7485
|
function ArtifactBlock({
|
|
@@ -7335,6 +7520,18 @@ function ArtifactBlock({
|
|
|
7335
7520
|
};
|
|
7336
7521
|
const handleDownload = () => {
|
|
7337
7522
|
if (!payload) return;
|
|
7523
|
+
if (payload.kind === "image" || payload.kind === "video") {
|
|
7524
|
+
const a = document.createElement("a");
|
|
7525
|
+
a.href = adapter.getWorkspaceDownloadUrl({
|
|
7526
|
+
sessionId,
|
|
7527
|
+
path: payload.spec.path
|
|
7528
|
+
});
|
|
7529
|
+
a.download = "";
|
|
7530
|
+
document.body.appendChild(a);
|
|
7531
|
+
a.click();
|
|
7532
|
+
document.body.removeChild(a);
|
|
7533
|
+
return;
|
|
7534
|
+
}
|
|
7338
7535
|
const { text, mime, extension } = exportArtifact(payload);
|
|
7339
7536
|
downloadText(`${safeFilename(name)}.${extension}`, text, mime);
|
|
7340
7537
|
};
|
|
@@ -7380,20 +7577,21 @@ function ArtifactBlock({
|
|
|
7380
7577
|
)
|
|
7381
7578
|
] })
|
|
7382
7579
|
] }),
|
|
7383
|
-
/* @__PURE__ */ jsx(ArtifactContent, { className: "p-0 overflow-visible", children: /* @__PURE__ */ jsx(ArtifactBody, { error, payload }) })
|
|
7580
|
+
/* @__PURE__ */ jsx(ArtifactContent, { className: "p-0 overflow-visible", children: /* @__PURE__ */ jsx(ArtifactBody, { error, payload, sessionId }) })
|
|
7384
7581
|
] }),
|
|
7385
7582
|
/* @__PURE__ */ jsx(Dialog, { open: expanded, onOpenChange: setExpanded, children: /* @__PURE__ */ jsxs(DialogContent, { className: "flex h-[95vh] w-[95vw] max-w-[95vw] flex-col gap-4 overflow-hidden p-6 sm:max-w-[95vw]", children: [
|
|
7386
7583
|
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
7387
7584
|
/* @__PURE__ */ jsx(DialogTitle, { className: "truncate pr-10", children: name }),
|
|
7388
7585
|
/* @__PURE__ */ jsx(DialogDescription, { children: description })
|
|
7389
7586
|
] }),
|
|
7390
|
-
/* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-auto", children: /* @__PURE__ */ jsx(ArtifactBody, { error, payload, fill: true }) })
|
|
7587
|
+
/* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-auto", children: /* @__PURE__ */ jsx(ArtifactBody, { error, payload, sessionId, fill: true }) })
|
|
7391
7588
|
] }) })
|
|
7392
7589
|
] });
|
|
7393
7590
|
}
|
|
7394
7591
|
function ArtifactBody({
|
|
7395
7592
|
error,
|
|
7396
7593
|
payload,
|
|
7594
|
+
sessionId,
|
|
7397
7595
|
fill = false
|
|
7398
7596
|
}) {
|
|
7399
7597
|
if (error) {
|
|
@@ -7419,6 +7617,10 @@ function ArtifactBody({
|
|
|
7419
7617
|
return /* @__PURE__ */ jsx(ArtifactHtml, { spec: payload.spec, fill });
|
|
7420
7618
|
case "svg":
|
|
7421
7619
|
return /* @__PURE__ */ jsx(ArtifactSvg, { spec: payload.spec });
|
|
7620
|
+
case "image":
|
|
7621
|
+
return /* @__PURE__ */ jsx(ArtifactImage, { sessionId, spec: payload.spec, fill });
|
|
7622
|
+
case "video":
|
|
7623
|
+
return /* @__PURE__ */ jsx(ArtifactVideo, { sessionId, spec: payload.spec, fill });
|
|
7422
7624
|
}
|
|
7423
7625
|
}
|
|
7424
7626
|
var ErrorMessage = memo(function ErrorMessage2({
|
|
@@ -8517,13 +8719,17 @@ function cancelledToolLabel(toolName) {
|
|
|
8517
8719
|
ask_user_question: "Ask User Question",
|
|
8518
8720
|
process: "Process",
|
|
8519
8721
|
create_artifact: "Create artifact",
|
|
8722
|
+
run_coding_agent: "Coding agent",
|
|
8723
|
+
code_run: "Coding agent",
|
|
8520
8724
|
// ``Research memory`` reads as a noun ("memory of research") and
|
|
8521
8725
|
// makes the shimmer awkward ("Running Research memory…"). The
|
|
8522
8726
|
// one-liner renderer shows just ``Research`` as the label, so
|
|
8523
8727
|
// mirror that here so the live shimmer matches the row that
|
|
8524
8728
|
// replaces it on completion.
|
|
8525
8729
|
research_memory: "Research",
|
|
8526
|
-
research_outline: "Research"
|
|
8730
|
+
research_outline: "Research",
|
|
8731
|
+
generate_image: "image generation",
|
|
8732
|
+
generate_video: "video generation"
|
|
8527
8733
|
};
|
|
8528
8734
|
if (map[toolName]) return map[toolName];
|
|
8529
8735
|
if (toolName.startsWith("mcp__")) return formatMcpToolLabel(toolName);
|
|
@@ -8811,6 +9017,11 @@ function extractToolDetail(tc) {
|
|
|
8811
9017
|
case "consult_expert":
|
|
8812
9018
|
case "delegate_task":
|
|
8813
9019
|
return stringArg("name") ?? stringArg("task") ?? stringArg("title");
|
|
9020
|
+
case "run_coding_agent":
|
|
9021
|
+
case "code_run": {
|
|
9022
|
+
const prompt = stringArg("prompt");
|
|
9023
|
+
return prompt ? truncate3(prompt, 60) : null;
|
|
9024
|
+
}
|
|
8814
9025
|
case "memory":
|
|
8815
9026
|
return stringArg("action") ?? stringArg("key");
|
|
8816
9027
|
case "research_memory": {
|
|
@@ -8934,7 +9145,9 @@ var _TOOL_ROW_ICON = {
|
|
|
8934
9145
|
memory: PenLineIcon,
|
|
8935
9146
|
todo: ListIcon,
|
|
8936
9147
|
research_memory: BookOpenIcon,
|
|
8937
|
-
research_outline: ListIcon
|
|
9148
|
+
research_outline: ListIcon,
|
|
9149
|
+
run_coding_agent: BotIcon,
|
|
9150
|
+
code_run: BotIcon
|
|
8938
9151
|
};
|
|
8939
9152
|
function _toolRowIcon(toolName) {
|
|
8940
9153
|
return _TOOL_ROW_ICON[toolName] ?? WrenchIcon;
|
|
@@ -8980,6 +9193,13 @@ function _toolRowLabel(tc) {
|
|
|
8980
9193
|
return detail ? `Memory ${detail}` : "Updated memory";
|
|
8981
9194
|
case "todo":
|
|
8982
9195
|
return detail ? `Todo ${detail}` : "Updated todo list";
|
|
9196
|
+
case "run_coding_agent":
|
|
9197
|
+
case "code_run": {
|
|
9198
|
+
const a = parseArgs(tc.args);
|
|
9199
|
+
const agent = a?.agent ?? (a?.provider === "openai" ? "codex" : a?.provider === "anthropic" ? "claude" : void 0);
|
|
9200
|
+
const name = agent === "codex" ? "Codex" : agent === "claude" ? "Claude Code" : "coding agent";
|
|
9201
|
+
return detail ? `${name}: ${detail}` : `Ran ${name}`;
|
|
9202
|
+
}
|
|
8983
9203
|
case "research_memory": {
|
|
8984
9204
|
const args = parseArgs(tc.args);
|
|
8985
9205
|
const action = args?.action;
|
|
@@ -9063,6 +9283,9 @@ function IterationExpanded({
|
|
|
9063
9283
|
if (tc.toolName === "todo") {
|
|
9064
9284
|
return /* @__PURE__ */ jsx("div", { className: "pr-1", children: /* @__PURE__ */ jsx(TodoToolBlock, { tc }) }, tc.id);
|
|
9065
9285
|
}
|
|
9286
|
+
if (tc.toolName === "code_run") {
|
|
9287
|
+
return /* @__PURE__ */ jsx("div", { className: "pr-1", children: /* @__PURE__ */ jsx(CodeRunToolBlock, { tc, defaultOpen: true }) }, tc.id);
|
|
9288
|
+
}
|
|
9066
9289
|
return /* @__PURE__ */ jsx(SimpleDetailRow, { icon: _toolRowIcon(tc.toolName), children: /* @__PURE__ */ jsx("span", { children: _toolRowLabel(tc) }) }, tc.id);
|
|
9067
9290
|
}),
|
|
9068
9291
|
showDone && /* @__PURE__ */ jsx(SimpleDetailRow, { icon: CircleCheckIcon, children: /* @__PURE__ */ jsx("span", { className: "text-foreground", children: "Done" }) })
|
|
@@ -9389,6 +9612,7 @@ function ChatThread({
|
|
|
9389
9612
|
viewMode = "simple",
|
|
9390
9613
|
onViewModeChange,
|
|
9391
9614
|
deepResearchEnabled = false,
|
|
9615
|
+
codeAgentsEnabled = false,
|
|
9392
9616
|
researchSources = [],
|
|
9393
9617
|
hideTurnSummary = false,
|
|
9394
9618
|
agentId,
|
|
@@ -9453,7 +9677,8 @@ function ChatThread({
|
|
|
9453
9677
|
canShowWorkspace,
|
|
9454
9678
|
viewMode,
|
|
9455
9679
|
onViewModeChange,
|
|
9456
|
-
deepResearchEnabled
|
|
9680
|
+
deepResearchEnabled,
|
|
9681
|
+
codeAgentsEnabled
|
|
9457
9682
|
}
|
|
9458
9683
|
),
|
|
9459
9684
|
onOpenIntegrations && /* @__PURE__ */ jsx(
|
|
@@ -10273,6 +10498,9 @@ var AGENT_CHAT_LISTENED_EVENTS = [
|
|
|
10273
10498
|
"expert.failure",
|
|
10274
10499
|
"expert.endorse",
|
|
10275
10500
|
"expert.override",
|
|
10501
|
+
"code.run_started",
|
|
10502
|
+
"code.run_progress",
|
|
10503
|
+
"code.run_result",
|
|
10276
10504
|
"user.feedback",
|
|
10277
10505
|
"artifact.created",
|
|
10278
10506
|
"artifact.updated",
|
|
@@ -10452,6 +10680,21 @@ function applyAgentChatEvent(state, event) {
|
|
|
10452
10680
|
nextState,
|
|
10453
10681
|
applyExpertFeedback(nextState.messages, event.type, event.data)
|
|
10454
10682
|
);
|
|
10683
|
+
case "code.run_started":
|
|
10684
|
+
return applyCodeRunStarted(nextState, event);
|
|
10685
|
+
case "code.run_progress":
|
|
10686
|
+
return withMessages(
|
|
10687
|
+
nextState,
|
|
10688
|
+
applyCodeRunProgress(nextState.messages, event.data)
|
|
10689
|
+
);
|
|
10690
|
+
case "code.run_result":
|
|
10691
|
+
return {
|
|
10692
|
+
...withMessages(
|
|
10693
|
+
nextState,
|
|
10694
|
+
applyCodeRunResult(nextState.messages, event.data)
|
|
10695
|
+
),
|
|
10696
|
+
isRunning: false
|
|
10697
|
+
};
|
|
10455
10698
|
case "user.feedback":
|
|
10456
10699
|
return withMessages(
|
|
10457
10700
|
nextState,
|
|
@@ -11002,6 +11245,141 @@ function applyExpertDelegation(state, event) {
|
|
|
11002
11245
|
isRunning: true
|
|
11003
11246
|
};
|
|
11004
11247
|
}
|
|
11248
|
+
var CODE_RUN_TOOL = "code_run";
|
|
11249
|
+
function codeRunFrameId(runId) {
|
|
11250
|
+
return `code-run-${runId}`;
|
|
11251
|
+
}
|
|
11252
|
+
function parseCodeRunState(raw) {
|
|
11253
|
+
if (raw) {
|
|
11254
|
+
try {
|
|
11255
|
+
const parsed = JSON.parse(raw);
|
|
11256
|
+
return {
|
|
11257
|
+
agent: parsed.agent ?? "",
|
|
11258
|
+
provider: parsed.provider ?? "",
|
|
11259
|
+
prompt: parsed.prompt ?? "",
|
|
11260
|
+
output: parsed.output ?? "",
|
|
11261
|
+
finalMessage: parsed.finalMessage ?? "",
|
|
11262
|
+
error: parsed.error ?? null,
|
|
11263
|
+
inputTokens: parsed.inputTokens ?? 0,
|
|
11264
|
+
outputTokens: parsed.outputTokens ?? 0
|
|
11265
|
+
};
|
|
11266
|
+
} catch {
|
|
11267
|
+
}
|
|
11268
|
+
}
|
|
11269
|
+
return {
|
|
11270
|
+
agent: "",
|
|
11271
|
+
provider: "",
|
|
11272
|
+
prompt: "",
|
|
11273
|
+
output: "",
|
|
11274
|
+
finalMessage: "",
|
|
11275
|
+
error: null,
|
|
11276
|
+
inputTokens: 0,
|
|
11277
|
+
outputTokens: 0
|
|
11278
|
+
};
|
|
11279
|
+
}
|
|
11280
|
+
function findCodeRunFrame(messages, runId) {
|
|
11281
|
+
const toolId = codeRunFrameId(runId);
|
|
11282
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
11283
|
+
const tc = messages[i]?.toolCalls?.find((c) => c.id === toolId);
|
|
11284
|
+
if (tc) return { msgIdx: i, toolId };
|
|
11285
|
+
}
|
|
11286
|
+
return null;
|
|
11287
|
+
}
|
|
11288
|
+
function applyCodeRunStarted(state, event) {
|
|
11289
|
+
const runId = stringValue2(event.data.run_id);
|
|
11290
|
+
if (!runId) return state;
|
|
11291
|
+
if (findCodeRunFrame(state.messages, runId)) {
|
|
11292
|
+
return { ...state, terminal: false, isRunning: true };
|
|
11293
|
+
}
|
|
11294
|
+
const agent = stringValue2(event.data.agent);
|
|
11295
|
+
const provider = stringValue2(event.data.provider);
|
|
11296
|
+
const prompt = stringValue2(event.data.prompt);
|
|
11297
|
+
const messages = [...state.messages];
|
|
11298
|
+
const assistantIdx = findLastAssistantIndex(messages);
|
|
11299
|
+
let assistant = assistantIdx >= 0 ? messages[assistantIdx] : null;
|
|
11300
|
+
const userAfterAssistant = assistantIdx >= 0 && hasUserAfterIndex(messages, assistantIdx);
|
|
11301
|
+
if (!assistant || assistant.status === "complete" || userAfterAssistant) {
|
|
11302
|
+
assistant = {
|
|
11303
|
+
id: `evt-${event.eventId}-code-run`,
|
|
11304
|
+
role: "assistant",
|
|
11305
|
+
content: "",
|
|
11306
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
11307
|
+
status: "streaming"
|
|
11308
|
+
};
|
|
11309
|
+
messages.push(assistant);
|
|
11310
|
+
} else {
|
|
11311
|
+
assistant = { ...assistant };
|
|
11312
|
+
messages[assistantIdx] = assistant;
|
|
11313
|
+
}
|
|
11314
|
+
const frameState = {
|
|
11315
|
+
agent,
|
|
11316
|
+
provider,
|
|
11317
|
+
prompt,
|
|
11318
|
+
output: "",
|
|
11319
|
+
finalMessage: "",
|
|
11320
|
+
error: null,
|
|
11321
|
+
inputTokens: 0,
|
|
11322
|
+
outputTokens: 0
|
|
11323
|
+
};
|
|
11324
|
+
const toolCall = {
|
|
11325
|
+
id: codeRunFrameId(runId),
|
|
11326
|
+
toolName: CODE_RUN_TOOL,
|
|
11327
|
+
args: JSON.stringify({ agent, provider, prompt }),
|
|
11328
|
+
status: "running",
|
|
11329
|
+
result: JSON.stringify(frameState)
|
|
11330
|
+
};
|
|
11331
|
+
assistant.toolCalls = [...assistant.toolCalls ?? [], toolCall];
|
|
11332
|
+
return { ...state, messages, terminal: false, isRunning: true };
|
|
11333
|
+
}
|
|
11334
|
+
function applyCodeRunProgress(messages, data) {
|
|
11335
|
+
const runId = stringValue2(data.run_id);
|
|
11336
|
+
if (!runId) return messages;
|
|
11337
|
+
const match = findCodeRunFrame(messages, runId);
|
|
11338
|
+
if (!match) return messages;
|
|
11339
|
+
const chunk = stringValue2(data.chunk);
|
|
11340
|
+
if (!chunk) return messages;
|
|
11341
|
+
const next = [...messages];
|
|
11342
|
+
const msg = next[match.msgIdx];
|
|
11343
|
+
next[match.msgIdx] = {
|
|
11344
|
+
...msg,
|
|
11345
|
+
toolCalls: msg.toolCalls?.map((tc) => {
|
|
11346
|
+
if (tc.id !== match.toolId) return tc;
|
|
11347
|
+
const frame = parseCodeRunState(tc.result);
|
|
11348
|
+
frame.output += chunk;
|
|
11349
|
+
return { ...tc, result: JSON.stringify(frame) };
|
|
11350
|
+
})
|
|
11351
|
+
};
|
|
11352
|
+
return next;
|
|
11353
|
+
}
|
|
11354
|
+
function applyCodeRunResult(messages, data) {
|
|
11355
|
+
const runId = stringValue2(data.run_id);
|
|
11356
|
+
if (!runId) return messages;
|
|
11357
|
+
const match = findCodeRunFrame(messages, runId);
|
|
11358
|
+
if (!match) return messages;
|
|
11359
|
+
const error = optionalStringValue(data.error) ?? null;
|
|
11360
|
+
const finalMessage = stringValue2(data.final_message);
|
|
11361
|
+
const inputTokens = numberValue(data.input_tokens);
|
|
11362
|
+
const outputTokens = numberValue(data.output_tokens);
|
|
11363
|
+
const next = [...messages];
|
|
11364
|
+
const msg = next[match.msgIdx];
|
|
11365
|
+
next[match.msgIdx] = {
|
|
11366
|
+
...msg,
|
|
11367
|
+
toolCalls: msg.toolCalls?.map((tc) => {
|
|
11368
|
+
if (tc.id !== match.toolId) return tc;
|
|
11369
|
+
const frame = parseCodeRunState(tc.result);
|
|
11370
|
+
frame.finalMessage = finalMessage;
|
|
11371
|
+
frame.error = error;
|
|
11372
|
+
frame.inputTokens = inputTokens;
|
|
11373
|
+
frame.outputTokens = outputTokens;
|
|
11374
|
+
return {
|
|
11375
|
+
...tc,
|
|
11376
|
+
status: error ? "error" : "complete",
|
|
11377
|
+
result: JSON.stringify(frame)
|
|
11378
|
+
};
|
|
11379
|
+
})
|
|
11380
|
+
};
|
|
11381
|
+
return next;
|
|
11382
|
+
}
|
|
11005
11383
|
function applyExpertFailure(messages, eventId, data) {
|
|
11006
11384
|
const match = findLatestConsultExpertCall(messages);
|
|
11007
11385
|
if (!match) return messages;
|
|
@@ -11675,6 +12053,7 @@ function AgentChat({
|
|
|
11675
12053
|
disabled,
|
|
11676
12054
|
onComposerError,
|
|
11677
12055
|
deepResearchEnabled = false,
|
|
12056
|
+
codeAgentsEnabled = false,
|
|
11678
12057
|
onOpenIntegrations
|
|
11679
12058
|
}) {
|
|
11680
12059
|
const [workspacePath, setWorkspacePath] = useState(null);
|
|
@@ -11824,6 +12203,7 @@ function AgentChat({
|
|
|
11824
12203
|
viewMode: runtime.viewMode,
|
|
11825
12204
|
onViewModeChange: runtime.setViewMode,
|
|
11826
12205
|
deepResearchEnabled,
|
|
12206
|
+
codeAgentsEnabled,
|
|
11827
12207
|
researchSources: runtime.researchSources,
|
|
11828
12208
|
hideTurnSummary,
|
|
11829
12209
|
agentId,
|
|
@@ -12110,76 +12490,299 @@ function ToolkitRow({
|
|
|
12110
12490
|
] })
|
|
12111
12491
|
] });
|
|
12112
12492
|
}
|
|
12113
|
-
var
|
|
12114
|
-
|
|
12115
|
-
|
|
12116
|
-
|
|
12493
|
+
var PROVIDERS = [
|
|
12494
|
+
{
|
|
12495
|
+
key: "claude",
|
|
12496
|
+
provider: "anthropic",
|
|
12497
|
+
name: "Claude Code",
|
|
12498
|
+
oauthInstructions: "Run `claude setup-token` locally, then paste the `sk-ant-oat...` token it prints to connect your Claude subscription.",
|
|
12499
|
+
apiKeyInstructions: "Paste an Anthropic API key (`sk-ant-...`) to bill usage to your API account instead of a subscription.",
|
|
12500
|
+
oauthPlaceholder: "sk-ant-oat...",
|
|
12501
|
+
apiKeyPlaceholder: "sk-ant-...",
|
|
12502
|
+
validateOauth: (value) => value.startsWith("sk-ant-oat") ? null : "That doesn't look like a setup token \u2014 it should start with `sk-ant-oat`."
|
|
12503
|
+
},
|
|
12504
|
+
{
|
|
12505
|
+
key: "codex",
|
|
12506
|
+
provider: "openai",
|
|
12507
|
+
name: "Codex",
|
|
12508
|
+
oauthInstructions: "Run `codex login` locally, then paste the contents of `~/.codex/auth.json` to connect your ChatGPT plan.",
|
|
12509
|
+
apiKeyInstructions: "Paste an OpenAI API key (`sk-...`) to bill usage to your API account instead of a ChatGPT plan.",
|
|
12510
|
+
oauthPlaceholder: '{"OPENAI_API_KEY": ..., "tokens": { ... }}',
|
|
12511
|
+
apiKeyPlaceholder: "sk-...",
|
|
12512
|
+
validateOauth: (value) => {
|
|
12513
|
+
try {
|
|
12514
|
+
JSON.parse(value);
|
|
12515
|
+
return null;
|
|
12516
|
+
} catch {
|
|
12517
|
+
return "That doesn't look like valid JSON \u2014 paste the whole `~/.codex/auth.json` file.";
|
|
12518
|
+
}
|
|
12519
|
+
}
|
|
12117
12520
|
}
|
|
12118
|
-
|
|
12119
|
-
}
|
|
12120
|
-
|
|
12121
|
-
|
|
12122
|
-
|
|
12123
|
-
|
|
12124
|
-
|
|
12125
|
-
|
|
12126
|
-
};
|
|
12127
|
-
|
|
12128
|
-
|
|
12129
|
-
|
|
12130
|
-
|
|
12131
|
-
|
|
12132
|
-
|
|
12133
|
-
|
|
12134
|
-
|
|
12135
|
-
|
|
12136
|
-
|
|
12137
|
-
|
|
12138
|
-
|
|
12139
|
-
|
|
12140
|
-
if (kind === "action_required") return ExternalLinkIcon;
|
|
12141
|
-
if (kind === "task_complete") return ClipboardCheckIcon;
|
|
12142
|
-
if (kind === "governance_gate") return ShieldAlertIcon;
|
|
12143
|
-
if (kind === "progress_checkin") return TimerIcon;
|
|
12144
|
-
return CircleDotIcon;
|
|
12145
|
-
}
|
|
12146
|
-
function sortItems(items) {
|
|
12147
|
-
return [...items].sort((a, b) => {
|
|
12148
|
-
if (a.createdAt !== b.createdAt) return a.createdAt > b.createdAt ? -1 : 1;
|
|
12149
|
-
return b.id - a.id;
|
|
12150
|
-
});
|
|
12151
|
-
}
|
|
12152
|
-
function QuestionInput({
|
|
12153
|
-
prompt,
|
|
12154
|
-
choices,
|
|
12155
|
-
disabled,
|
|
12156
|
-
value,
|
|
12157
|
-
onChange
|
|
12158
|
-
}) {
|
|
12159
|
-
if (choices && choices.length > 0) {
|
|
12160
|
-
return /* @__PURE__ */ jsxs(
|
|
12161
|
-
"select",
|
|
12521
|
+
];
|
|
12522
|
+
function CodingAgentsPanel({ agentId, adapter, onBack }) {
|
|
12523
|
+
const supported = !!adapter.listCodingAgentConnections && !!adapter.submitCodingAgentCredential && !!adapter.disconnectCodingAgentProvider;
|
|
12524
|
+
const [connections, setConnections] = useState([]);
|
|
12525
|
+
const refresh = useCallback(async () => {
|
|
12526
|
+
if (!adapter.listCodingAgentConnections) return;
|
|
12527
|
+
const res = await adapter.listCodingAgentConnections({ agentId });
|
|
12528
|
+
setConnections(res.connections);
|
|
12529
|
+
}, [adapter, agentId]);
|
|
12530
|
+
useEffect(() => {
|
|
12531
|
+
if (!supported) return;
|
|
12532
|
+
void refresh();
|
|
12533
|
+
}, [supported, refresh]);
|
|
12534
|
+
const byProvider = useMemo(() => {
|
|
12535
|
+
const map = /* @__PURE__ */ new Map();
|
|
12536
|
+
for (const c of connections) map.set(c.provider, c);
|
|
12537
|
+
return map;
|
|
12538
|
+
}, [connections]);
|
|
12539
|
+
if (!supported) return null;
|
|
12540
|
+
return /* @__PURE__ */ jsxs("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-6 p-6", children: [
|
|
12541
|
+
onBack && /* @__PURE__ */ jsxs(
|
|
12542
|
+
"button",
|
|
12162
12543
|
{
|
|
12163
|
-
"
|
|
12164
|
-
|
|
12165
|
-
|
|
12166
|
-
value,
|
|
12167
|
-
onChange: (event) => onChange(event.target.value),
|
|
12544
|
+
type: "button",
|
|
12545
|
+
onClick: onBack,
|
|
12546
|
+
className: "flex w-fit items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground",
|
|
12168
12547
|
children: [
|
|
12169
|
-
/* @__PURE__ */ jsx(
|
|
12170
|
-
|
|
12548
|
+
/* @__PURE__ */ jsx(ArrowLeftIcon, { className: "h-4 w-4" }),
|
|
12549
|
+
"Back"
|
|
12171
12550
|
]
|
|
12172
12551
|
}
|
|
12173
|
-
)
|
|
12174
|
-
|
|
12175
|
-
|
|
12176
|
-
|
|
12177
|
-
|
|
12178
|
-
|
|
12179
|
-
|
|
12180
|
-
|
|
12181
|
-
|
|
12182
|
-
|
|
12552
|
+
),
|
|
12553
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
12554
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold text-foreground", children: "Coding agents" }),
|
|
12555
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Connect your Claude or ChatGPT plan so the agent can run `/code` on your behalf without separate API billing." })
|
|
12556
|
+
] }),
|
|
12557
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4", children: PROVIDERS.map((meta) => /* @__PURE__ */ jsx(
|
|
12558
|
+
ProviderCard,
|
|
12559
|
+
{
|
|
12560
|
+
meta,
|
|
12561
|
+
connection: byProvider.get(meta.provider) ?? null,
|
|
12562
|
+
adapter,
|
|
12563
|
+
agentId,
|
|
12564
|
+
onChanged: refresh
|
|
12565
|
+
},
|
|
12566
|
+
meta.key
|
|
12567
|
+
)) })
|
|
12568
|
+
] });
|
|
12569
|
+
}
|
|
12570
|
+
function ProviderCard({
|
|
12571
|
+
meta,
|
|
12572
|
+
connection,
|
|
12573
|
+
adapter,
|
|
12574
|
+
agentId,
|
|
12575
|
+
onChanged
|
|
12576
|
+
}) {
|
|
12577
|
+
const [mode, setMode] = useState("oauth");
|
|
12578
|
+
const [value, setValue] = useState("");
|
|
12579
|
+
const [busy, setBusy] = useState(false);
|
|
12580
|
+
const [error, setError] = useState(null);
|
|
12581
|
+
const connected = connection?.connected ?? false;
|
|
12582
|
+
const instructions = mode === "oauth" ? meta.oauthInstructions : meta.apiKeyInstructions;
|
|
12583
|
+
const placeholder = mode === "oauth" ? meta.oauthPlaceholder : meta.apiKeyPlaceholder;
|
|
12584
|
+
const submit = async () => {
|
|
12585
|
+
if (!adapter.submitCodingAgentCredential) return;
|
|
12586
|
+
const trimmed = value.trim();
|
|
12587
|
+
setError(null);
|
|
12588
|
+
if (!trimmed) {
|
|
12589
|
+
setError("Paste a value first.");
|
|
12590
|
+
return;
|
|
12591
|
+
}
|
|
12592
|
+
if (mode === "oauth") {
|
|
12593
|
+
const hint = meta.validateOauth(trimmed);
|
|
12594
|
+
if (hint) {
|
|
12595
|
+
setError(hint);
|
|
12596
|
+
return;
|
|
12597
|
+
}
|
|
12598
|
+
}
|
|
12599
|
+
setBusy(true);
|
|
12600
|
+
try {
|
|
12601
|
+
await adapter.submitCodingAgentCredential({
|
|
12602
|
+
agentId,
|
|
12603
|
+
provider: meta.provider,
|
|
12604
|
+
mode,
|
|
12605
|
+
value: trimmed
|
|
12606
|
+
});
|
|
12607
|
+
setValue("");
|
|
12608
|
+
await onChanged();
|
|
12609
|
+
} catch (e) {
|
|
12610
|
+
setError(e instanceof Error ? e.message : "Failed to save the credential");
|
|
12611
|
+
} finally {
|
|
12612
|
+
setBusy(false);
|
|
12613
|
+
}
|
|
12614
|
+
};
|
|
12615
|
+
const disconnect = async () => {
|
|
12616
|
+
if (!adapter.disconnectCodingAgentProvider) return;
|
|
12617
|
+
setBusy(true);
|
|
12618
|
+
setError(null);
|
|
12619
|
+
try {
|
|
12620
|
+
await adapter.disconnectCodingAgentProvider({ agentId, provider: meta.provider });
|
|
12621
|
+
await onChanged();
|
|
12622
|
+
} catch (e) {
|
|
12623
|
+
setError(e instanceof Error ? e.message : "Failed to disconnect");
|
|
12624
|
+
} finally {
|
|
12625
|
+
setBusy(false);
|
|
12626
|
+
}
|
|
12627
|
+
};
|
|
12628
|
+
return /* @__PURE__ */ jsxs("section", { className: "flex flex-col gap-3 rounded-lg border border-border p-4", children: [
|
|
12629
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
12630
|
+
/* @__PURE__ */ jsx("h2", { className: "text-base font-semibold text-foreground", children: meta.name }),
|
|
12631
|
+
/* @__PURE__ */ jsx(
|
|
12632
|
+
"span",
|
|
12633
|
+
{
|
|
12634
|
+
className: `inline-flex items-center rounded px-1.5 py-0.5 text-xs font-semibold ${connected ? "bg-primary/10 text-primary" : "bg-muted text-muted-foreground"}`,
|
|
12635
|
+
children: connected ? `Connected${connection?.auth_mode === "api_key" ? " (API key)" : ""}` : "Not connected"
|
|
12636
|
+
}
|
|
12637
|
+
)
|
|
12638
|
+
] }),
|
|
12639
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-1 text-xs", children: [
|
|
12640
|
+
/* @__PURE__ */ jsx(
|
|
12641
|
+
"button",
|
|
12642
|
+
{
|
|
12643
|
+
type: "button",
|
|
12644
|
+
onClick: () => {
|
|
12645
|
+
setMode("oauth");
|
|
12646
|
+
setError(null);
|
|
12647
|
+
},
|
|
12648
|
+
className: `rounded-md border px-2 py-1 ${mode === "oauth" ? "border-primary bg-primary/10 text-primary" : "border-border text-muted-foreground hover:bg-accent"}`,
|
|
12649
|
+
children: "Subscription"
|
|
12650
|
+
}
|
|
12651
|
+
),
|
|
12652
|
+
/* @__PURE__ */ jsx(
|
|
12653
|
+
"button",
|
|
12654
|
+
{
|
|
12655
|
+
type: "button",
|
|
12656
|
+
onClick: () => {
|
|
12657
|
+
setMode("api_key");
|
|
12658
|
+
setError(null);
|
|
12659
|
+
},
|
|
12660
|
+
className: `rounded-md border px-2 py-1 ${mode === "api_key" ? "border-primary bg-primary/10 text-primary" : "border-border text-muted-foreground hover:bg-accent"}`,
|
|
12661
|
+
children: "API key"
|
|
12662
|
+
}
|
|
12663
|
+
)
|
|
12664
|
+
] }),
|
|
12665
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: instructions }),
|
|
12666
|
+
/* @__PURE__ */ jsx(
|
|
12667
|
+
"textarea",
|
|
12668
|
+
{
|
|
12669
|
+
value,
|
|
12670
|
+
onChange: (e) => setValue(e.target.value),
|
|
12671
|
+
placeholder,
|
|
12672
|
+
spellCheck: false,
|
|
12673
|
+
autoComplete: "off",
|
|
12674
|
+
rows: mode === "oauth" && meta.provider === "openai" ? 4 : 2,
|
|
12675
|
+
"aria-label": `${meta.name} credential`,
|
|
12676
|
+
className: "w-full resize-y rounded-md border border-border bg-background px-3 py-2 font-mono text-xs [-webkit-text-security:disc]"
|
|
12677
|
+
}
|
|
12678
|
+
),
|
|
12679
|
+
error && /* @__PURE__ */ jsx("div", { role: "alert", className: "text-xs text-red-500", children: error }),
|
|
12680
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
12681
|
+
/* @__PURE__ */ jsxs(
|
|
12682
|
+
"button",
|
|
12683
|
+
{
|
|
12684
|
+
type: "button",
|
|
12685
|
+
disabled: busy,
|
|
12686
|
+
onClick: submit,
|
|
12687
|
+
className: "inline-flex items-center justify-center gap-1.5 rounded-md border border-border px-3 py-1.5 text-xs text-foreground hover:bg-accent disabled:opacity-60",
|
|
12688
|
+
children: [
|
|
12689
|
+
busy && /* @__PURE__ */ jsx(Loader2Icon, { className: "h-3.5 w-3.5 animate-spin" }),
|
|
12690
|
+
connected ? "Update" : "Connect"
|
|
12691
|
+
]
|
|
12692
|
+
}
|
|
12693
|
+
),
|
|
12694
|
+
connected && /* @__PURE__ */ jsx(
|
|
12695
|
+
"button",
|
|
12696
|
+
{
|
|
12697
|
+
type: "button",
|
|
12698
|
+
disabled: busy,
|
|
12699
|
+
onClick: disconnect,
|
|
12700
|
+
className: "inline-flex items-center justify-center rounded-md border border-border px-3 py-1.5 text-xs text-muted-foreground hover:bg-accent disabled:opacity-60",
|
|
12701
|
+
children: "Disconnect"
|
|
12702
|
+
}
|
|
12703
|
+
)
|
|
12704
|
+
] })
|
|
12705
|
+
] });
|
|
12706
|
+
}
|
|
12707
|
+
var DEFAULT_LIMIT = 50;
|
|
12708
|
+
function requireInboxAdapter(adapter) {
|
|
12709
|
+
if (!adapter.listInbox || !adapter.getInboxItem || !adapter.markInboxItemRead || !adapter.acknowledgeInboxItem || !adapter.respondGovernanceInboxItem || !adapter.openInboxStream) {
|
|
12710
|
+
throw new Error("Inbox is not supported by this adapter.");
|
|
12711
|
+
}
|
|
12712
|
+
return adapter;
|
|
12713
|
+
}
|
|
12714
|
+
var KIND_LABEL2 = {
|
|
12715
|
+
input_required: "Input needed",
|
|
12716
|
+
action_required: "Action needed",
|
|
12717
|
+
task_complete: "Task complete",
|
|
12718
|
+
governance_gate: "Approval",
|
|
12719
|
+
progress_checkin: "Progress"
|
|
12720
|
+
};
|
|
12721
|
+
function kindLabel(kind) {
|
|
12722
|
+
return KIND_LABEL2[kind] ?? kind.replace(/[_-]+/g, " ");
|
|
12723
|
+
}
|
|
12724
|
+
function statusLabel(status) {
|
|
12725
|
+
return status.split(/[_-]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
12726
|
+
}
|
|
12727
|
+
function formatRelative(value) {
|
|
12728
|
+
const date = new Date(value);
|
|
12729
|
+
if (Number.isNaN(date.getTime())) return "";
|
|
12730
|
+
return formatDistanceToNow(date, { addSuffix: true });
|
|
12731
|
+
}
|
|
12732
|
+
function kindIcon(kind) {
|
|
12733
|
+
if (kind === "input_required") return MessageSquareIcon;
|
|
12734
|
+
if (kind === "action_required") return ExternalLinkIcon;
|
|
12735
|
+
if (kind === "task_complete") return ClipboardCheckIcon;
|
|
12736
|
+
if (kind === "governance_gate") return ShieldAlertIcon;
|
|
12737
|
+
if (kind === "progress_checkin") return TimerIcon;
|
|
12738
|
+
return CircleDotIcon;
|
|
12739
|
+
}
|
|
12740
|
+
function sortItems(items) {
|
|
12741
|
+
return [...items].sort((a, b) => {
|
|
12742
|
+
if (a.createdAt !== b.createdAt) return a.createdAt > b.createdAt ? -1 : 1;
|
|
12743
|
+
return b.id - a.id;
|
|
12744
|
+
});
|
|
12745
|
+
}
|
|
12746
|
+
function InboxBody({ body, muted }) {
|
|
12747
|
+
return /* @__PURE__ */ jsx(
|
|
12748
|
+
MessageResponse,
|
|
12749
|
+
{
|
|
12750
|
+
className: cn("text-sm", muted && "text-muted-foreground"),
|
|
12751
|
+
children: body
|
|
12752
|
+
}
|
|
12753
|
+
);
|
|
12754
|
+
}
|
|
12755
|
+
function QuestionInput({
|
|
12756
|
+
prompt,
|
|
12757
|
+
choices,
|
|
12758
|
+
disabled,
|
|
12759
|
+
value,
|
|
12760
|
+
onChange
|
|
12761
|
+
}) {
|
|
12762
|
+
if (choices && choices.length > 0) {
|
|
12763
|
+
return /* @__PURE__ */ jsxs(
|
|
12764
|
+
"select",
|
|
12765
|
+
{
|
|
12766
|
+
"aria-label": prompt,
|
|
12767
|
+
className: "h-9 w-full border border-line bg-background px-2 text-sm text-foreground outline-none focus:border-primary disabled:opacity-50",
|
|
12768
|
+
disabled,
|
|
12769
|
+
value,
|
|
12770
|
+
onChange: (event) => onChange(event.target.value),
|
|
12771
|
+
children: [
|
|
12772
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "Select" }),
|
|
12773
|
+
choices.map((choice) => /* @__PURE__ */ jsx("option", { value: choice.label, children: choice.label }, choice.label))
|
|
12774
|
+
]
|
|
12775
|
+
}
|
|
12776
|
+
);
|
|
12777
|
+
}
|
|
12778
|
+
return /* @__PURE__ */ jsx(
|
|
12779
|
+
"input",
|
|
12780
|
+
{
|
|
12781
|
+
"aria-label": prompt,
|
|
12782
|
+
className: "h-9 w-full border border-line bg-background px-2 text-sm text-foreground outline-none focus:border-primary disabled:opacity-50",
|
|
12783
|
+
disabled,
|
|
12784
|
+
value,
|
|
12785
|
+
onChange: (event) => onChange(event.target.value)
|
|
12183
12786
|
}
|
|
12184
12787
|
);
|
|
12185
12788
|
}
|
|
@@ -12272,7 +12875,7 @@ function InputRequiredDetail({
|
|
|
12272
12875
|
}
|
|
12273
12876
|
}
|
|
12274
12877
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
12275
|
-
item.body && /* @__PURE__ */ jsx(
|
|
12878
|
+
item.body && /* @__PURE__ */ jsx(InboxBody, { body: item.body, muted: true }),
|
|
12276
12879
|
questions.map((question) => /* @__PURE__ */ jsxs("label", { className: "block space-y-1.5", children: [
|
|
12277
12880
|
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-foreground", children: question.prompt }),
|
|
12278
12881
|
/* @__PURE__ */ jsx(
|
|
@@ -12325,7 +12928,7 @@ function AckDetail({
|
|
|
12325
12928
|
const duration = typeof item.payload.duration_seconds === "number" ? item.payload.duration_seconds : null;
|
|
12326
12929
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
12327
12930
|
outcome && /* @__PURE__ */ jsx(Badge, { variant: "secondary", children: outcome }),
|
|
12328
|
-
item.body && /* @__PURE__ */ jsx(
|
|
12931
|
+
item.body && /* @__PURE__ */ jsx(InboxBody, { body: item.body }),
|
|
12329
12932
|
typeof item.payload.error === "string" && /* @__PURE__ */ jsx("pre", { className: "overflow-x-auto bg-destructive/10 p-3 text-xs text-destructive", children: item.payload.error }),
|
|
12330
12933
|
duration !== null && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
12331
12934
|
"Duration: ",
|
|
@@ -12439,7 +13042,7 @@ function ActionRequiredDetail({
|
|
|
12439
13042
|
}
|
|
12440
13043
|
}
|
|
12441
13044
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
12442
|
-
item.body && /* @__PURE__ */ jsx(
|
|
13045
|
+
item.body && /* @__PURE__ */ jsx(InboxBody, { body: item.body }),
|
|
12443
13046
|
context && context !== item.body && /* @__PURE__ */ jsx("p", { className: "whitespace-pre-wrap text-sm text-muted-foreground", children: context }),
|
|
12444
13047
|
actionType && /* @__PURE__ */ jsx(Badge, { variant: "secondary", children: actionType }),
|
|
12445
13048
|
/* @__PURE__ */ jsx(
|
|
@@ -12488,7 +13091,7 @@ function ProgressDetail({
|
|
|
12488
13091
|
}
|
|
12489
13092
|
}
|
|
12490
13093
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
12491
|
-
item.body && /* @__PURE__ */ jsx(
|
|
13094
|
+
item.body && /* @__PURE__ */ jsx(InboxBody, { body: item.body }),
|
|
12492
13095
|
rows.length > 0 && /* @__PURE__ */ jsx("dl", { className: "space-y-1 text-xs text-muted-foreground", children: rows.map(([label, value]) => /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
12493
13096
|
/* @__PURE__ */ jsx("dt", { className: "w-20 shrink-0", children: String(label) }),
|
|
12494
13097
|
/* @__PURE__ */ jsx("dd", { className: "min-w-0", children: String(value) })
|
|
@@ -12806,6 +13409,45 @@ function Card({
|
|
|
12806
13409
|
}
|
|
12807
13410
|
);
|
|
12808
13411
|
}
|
|
13412
|
+
function CardHeader({ className, ...props }) {
|
|
13413
|
+
return /* @__PURE__ */ jsx(
|
|
13414
|
+
"div",
|
|
13415
|
+
{
|
|
13416
|
+
"data-slot": "card-header",
|
|
13417
|
+
className: cn(
|
|
13418
|
+
"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",
|
|
13419
|
+
className
|
|
13420
|
+
),
|
|
13421
|
+
...props
|
|
13422
|
+
}
|
|
13423
|
+
);
|
|
13424
|
+
}
|
|
13425
|
+
function CardTitle({ className, ...props }) {
|
|
13426
|
+
return /* @__PURE__ */ jsx(
|
|
13427
|
+
"div",
|
|
13428
|
+
{
|
|
13429
|
+
"data-slot": "card-title",
|
|
13430
|
+
className: cn(
|
|
13431
|
+
"font-heading text-lg font-semibold tracking-wider uppercase",
|
|
13432
|
+
className
|
|
13433
|
+
),
|
|
13434
|
+
...props
|
|
13435
|
+
}
|
|
13436
|
+
);
|
|
13437
|
+
}
|
|
13438
|
+
function CardAction({ className, ...props }) {
|
|
13439
|
+
return /* @__PURE__ */ jsx(
|
|
13440
|
+
"div",
|
|
13441
|
+
{
|
|
13442
|
+
"data-slot": "card-action",
|
|
13443
|
+
className: cn(
|
|
13444
|
+
"col-start-2 row-span-2 row-start-1 self-start justify-self-end",
|
|
13445
|
+
className
|
|
13446
|
+
),
|
|
13447
|
+
...props
|
|
13448
|
+
}
|
|
13449
|
+
);
|
|
13450
|
+
}
|
|
12809
13451
|
function CardContent({ className, ...props }) {
|
|
12810
13452
|
return /* @__PURE__ */ jsx(
|
|
12811
13453
|
"div",
|
|
@@ -12862,109 +13504,791 @@ function truncate4(s, max) {
|
|
|
12862
13504
|
if (s.length <= max) return s;
|
|
12863
13505
|
return `${s.slice(0, max - 1)}\u2026`;
|
|
12864
13506
|
}
|
|
12865
|
-
var
|
|
12866
|
-
|
|
12867
|
-
|
|
12868
|
-
|
|
12869
|
-
|
|
12870
|
-
|
|
12871
|
-
|
|
12872
|
-
|
|
12873
|
-
|
|
12874
|
-
|
|
12875
|
-
|
|
12876
|
-
|
|
12877
|
-
|
|
12878
|
-
|
|
12879
|
-
|
|
12880
|
-
|
|
12881
|
-
|
|
12882
|
-
|
|
12883
|
-
|
|
12884
|
-
}
|
|
12885
|
-
var ACTIVITY_KIND_TONE = {
|
|
12886
|
-
"mission.defined": "bg-primary/10 text-primary border-primary/30",
|
|
12887
|
-
"mission.paused": "bg-amber-500/10 text-amber-600 border-amber-500/30",
|
|
12888
|
-
"mission.cancelled": "bg-destructive/10 text-destructive border-destructive/30",
|
|
12889
|
-
"task.spawned": "bg-foreground/5 text-foreground/80 border-foreground/20",
|
|
12890
|
-
"task.completed": "bg-emerald-500/10 text-emerald-600 border-emerald-500/30",
|
|
12891
|
-
"task.failed": "bg-destructive/10 text-destructive border-destructive/30",
|
|
12892
|
-
"task.cancelled": "bg-muted text-muted-foreground border-border",
|
|
12893
|
-
"worker.latest": "bg-foreground/5 text-foreground/70 border-foreground/15",
|
|
12894
|
-
"evaluator.verdict": "bg-primary/10 text-primary border-primary/30"
|
|
12895
|
-
};
|
|
12896
|
-
function buildMissionActivity(mission, tasks, workers) {
|
|
12897
|
-
const entries = [];
|
|
12898
|
-
entries.push({
|
|
12899
|
-
at: mission.createdAt,
|
|
12900
|
-
kind: "mission.defined",
|
|
12901
|
-
label: "Mission defined",
|
|
12902
|
-
detail: mission.description
|
|
12903
|
-
});
|
|
12904
|
-
if (mission.status === "paused" && mission.pausedReason) {
|
|
12905
|
-
entries.push({
|
|
12906
|
-
at: mission.updatedAt,
|
|
12907
|
-
kind: "mission.paused",
|
|
12908
|
-
label: "Paused",
|
|
12909
|
-
detail: mission.pausedReason
|
|
12910
|
-
});
|
|
12911
|
-
}
|
|
12912
|
-
if (mission.status === "cancelled" && mission.cancelledReason) {
|
|
12913
|
-
entries.push({
|
|
12914
|
-
at: mission.updatedAt,
|
|
12915
|
-
kind: "mission.cancelled",
|
|
12916
|
-
label: "Cancelled",
|
|
12917
|
-
detail: mission.cancelledReason
|
|
12918
|
-
});
|
|
13507
|
+
var MISSION_EVENT_CATEGORIES = [
|
|
13508
|
+
"spawn",
|
|
13509
|
+
"output",
|
|
13510
|
+
"done",
|
|
13511
|
+
"verdict",
|
|
13512
|
+
"system"
|
|
13513
|
+
];
|
|
13514
|
+
function missionEventCategory(type) {
|
|
13515
|
+
switch (type) {
|
|
13516
|
+
case "worker.spawned":
|
|
13517
|
+
return "spawn";
|
|
13518
|
+
case "iteration.summary":
|
|
13519
|
+
return "output";
|
|
13520
|
+
case "worker.complete":
|
|
13521
|
+
return "done";
|
|
13522
|
+
case "mission.evaluation.end":
|
|
13523
|
+
return "verdict";
|
|
13524
|
+
default:
|
|
13525
|
+
return "system";
|
|
12919
13526
|
}
|
|
12920
|
-
|
|
12921
|
-
|
|
12922
|
-
|
|
12923
|
-
|
|
12924
|
-
|
|
12925
|
-
|
|
12926
|
-
|
|
12927
|
-
|
|
12928
|
-
|
|
12929
|
-
|
|
12930
|
-
|
|
12931
|
-
|
|
12932
|
-
|
|
12933
|
-
|
|
12934
|
-
|
|
12935
|
-
|
|
12936
|
-
|
|
13527
|
+
}
|
|
13528
|
+
function dataString(data, key) {
|
|
13529
|
+
const v = data?.[key];
|
|
13530
|
+
return typeof v === "string" && v.trim().length > 0 ? v.trim() : null;
|
|
13531
|
+
}
|
|
13532
|
+
var CONTROL_MARKUP_RE = /<next_action\b[^>]*(?:\/>|>[\s\S]*?<\/next_action>)/gi;
|
|
13533
|
+
function stripMissionControlMarkup(text) {
|
|
13534
|
+
return text.replace(CONTROL_MARKUP_RE, "").trim();
|
|
13535
|
+
}
|
|
13536
|
+
function missionEventSummary(event) {
|
|
13537
|
+
return stripMissionControlMarkup(rawMissionEventSummary(event));
|
|
13538
|
+
}
|
|
13539
|
+
function rawMissionEventSummary(event) {
|
|
13540
|
+
const d = event.data ?? null;
|
|
13541
|
+
switch (event.type) {
|
|
13542
|
+
case "worker.spawned":
|
|
13543
|
+
return dataString(d, "goal") ?? "Task spawned";
|
|
13544
|
+
case "worker.complete":
|
|
13545
|
+
return dataString(d, "result") ?? "Worker complete";
|
|
13546
|
+
case "iteration.summary":
|
|
13547
|
+
return dataString(d, "summary") ?? "";
|
|
13548
|
+
case "mission.evaluation.end": {
|
|
13549
|
+
const result = dataString(d, "result");
|
|
13550
|
+
const feedback = dataString(d, "feedback") ?? dataString(d, "explanation");
|
|
13551
|
+
if (result && feedback) return `${result} \u2014 ${feedback}`;
|
|
13552
|
+
return result ?? feedback ?? "Evaluation finished";
|
|
13553
|
+
}
|
|
13554
|
+
case "task.blocked":
|
|
13555
|
+
return dataString(d, "reason") ?? "Task blocked";
|
|
13556
|
+
case "task.failed":
|
|
13557
|
+
return "Task failed";
|
|
13558
|
+
default: {
|
|
13559
|
+
const text = dataString(d, "summary") ?? dataString(d, "text") ?? dataString(d, "message") ?? dataString(d, "reason");
|
|
13560
|
+
if (text) return text;
|
|
13561
|
+
if (!d) return "";
|
|
13562
|
+
try {
|
|
13563
|
+
return truncate4(JSON.stringify(d), 160);
|
|
13564
|
+
} catch {
|
|
13565
|
+
return "";
|
|
13566
|
+
}
|
|
12937
13567
|
}
|
|
12938
13568
|
}
|
|
12939
|
-
|
|
12940
|
-
|
|
12941
|
-
|
|
12942
|
-
|
|
12943
|
-
|
|
12944
|
-
|
|
12945
|
-
|
|
12946
|
-
|
|
13569
|
+
}
|
|
13570
|
+
function missionEventTaskId(event, sessions) {
|
|
13571
|
+
return dataString(event.data ?? null, "task_id") ?? sessions[event.sessionId]?.taskId ?? null;
|
|
13572
|
+
}
|
|
13573
|
+
function missionEventActorLabel(event, sessions) {
|
|
13574
|
+
const meta = sessions[event.sessionId];
|
|
13575
|
+
if (!meta) return event.sessionId.slice(0, 8);
|
|
13576
|
+
if (meta.kind === "coordinator") return "orchestrator";
|
|
13577
|
+
return meta.agentDefName ?? "worker";
|
|
13578
|
+
}
|
|
13579
|
+
function missionTaskBlocks(tasks) {
|
|
13580
|
+
const blocks = {};
|
|
13581
|
+
for (const t of tasks) {
|
|
13582
|
+
for (const parent of t.parentIds) {
|
|
13583
|
+
(blocks[parent] ?? (blocks[parent] = [])).push(t.id);
|
|
12947
13584
|
}
|
|
12948
13585
|
}
|
|
12949
|
-
|
|
12950
|
-
entries.push({
|
|
12951
|
-
at: mission.lastEvaluationAt,
|
|
12952
|
-
kind: "evaluator.verdict",
|
|
12953
|
-
label: `Verdict \xB7 ${mission.lastEvaluationResult}`,
|
|
12954
|
-
detail: mission.lastEvaluationFeedback ?? void 0
|
|
12955
|
-
});
|
|
12956
|
-
}
|
|
12957
|
-
entries.sort((a, b) => b.at.localeCompare(a.at));
|
|
12958
|
-
return entries;
|
|
13586
|
+
return blocks;
|
|
12959
13587
|
}
|
|
12960
|
-
function
|
|
12961
|
-
|
|
12962
|
-
|
|
12963
|
-
|
|
12964
|
-
|
|
13588
|
+
function missionTaskTitle(goal, max = 80) {
|
|
13589
|
+
const line = goal.split("\n").find((l) => l.trim().length > 0)?.trim() ?? goal.trim();
|
|
13590
|
+
return truncate4(line.replace(/\s+/g, " "), max);
|
|
13591
|
+
}
|
|
13592
|
+
var RAIL_GROUP_DEFS = [
|
|
13593
|
+
{ key: "running", label: "Running", match: (s) => s === "running" },
|
|
13594
|
+
{ key: "blocked", label: "Blocked", match: (s) => s === "blocked" },
|
|
13595
|
+
{
|
|
13596
|
+
key: "queued",
|
|
13597
|
+
label: "Queued",
|
|
13598
|
+
match: (s) => s === "ready" || s === "todo"
|
|
13599
|
+
},
|
|
13600
|
+
{ key: "done", label: "Done", match: (s) => s === "done" },
|
|
13601
|
+
{
|
|
13602
|
+
key: "failed",
|
|
13603
|
+
label: "Failed / cancelled",
|
|
13604
|
+
match: (s) => s === "failed" || s === "cancelled"
|
|
12965
13605
|
}
|
|
13606
|
+
];
|
|
13607
|
+
function missionTaskRailGroups(tasks) {
|
|
13608
|
+
const grouped = /* @__PURE__ */ new Set();
|
|
13609
|
+
const groups = RAIL_GROUP_DEFS.map((def) => ({
|
|
13610
|
+
key: def.key,
|
|
13611
|
+
label: def.label,
|
|
13612
|
+
tasks: tasks.filter((t) => {
|
|
13613
|
+
const hit = def.match(t.status);
|
|
13614
|
+
if (hit) grouped.add(t.id);
|
|
13615
|
+
return hit;
|
|
13616
|
+
})
|
|
13617
|
+
}));
|
|
13618
|
+
const stray = tasks.filter((t) => !grouped.has(t.id));
|
|
13619
|
+
if (stray.length > 0) {
|
|
13620
|
+
const queued = groups.find((g) => g.key === "queued");
|
|
13621
|
+
if (queued) queued.tasks.push(...stray);
|
|
13622
|
+
}
|
|
13623
|
+
return groups.filter((g) => g.tasks.length > 0);
|
|
12966
13624
|
}
|
|
12967
|
-
var
|
|
13625
|
+
var TERMINAL_TASK_STATUSES = /* @__PURE__ */ new Set(["done", "failed", "cancelled"]);
|
|
13626
|
+
function defaultSelectedMissionTaskId(tasks) {
|
|
13627
|
+
if (tasks.length === 0) return null;
|
|
13628
|
+
const ordered = missionTaskRailGroups(tasks).flatMap((g) => g.tasks);
|
|
13629
|
+
const firstLive = ordered.find(
|
|
13630
|
+
(t) => !TERMINAL_TASK_STATUSES.has(t.status)
|
|
13631
|
+
);
|
|
13632
|
+
return (firstLive ?? ordered[0] ?? tasks[0]).id;
|
|
13633
|
+
}
|
|
13634
|
+
function mergeMissionEvents(existing, incoming) {
|
|
13635
|
+
if (incoming.length === 0) return existing;
|
|
13636
|
+
const byId = /* @__PURE__ */ new Map();
|
|
13637
|
+
for (const e of existing) byId.set(e.id, e);
|
|
13638
|
+
for (const e of incoming) byId.set(e.id, e);
|
|
13639
|
+
return [...byId.values()].sort((a, b) => a.id - b.id);
|
|
13640
|
+
}
|
|
13641
|
+
function missionTaskStatusDotClass(status) {
|
|
13642
|
+
switch (status) {
|
|
13643
|
+
case "running":
|
|
13644
|
+
return "bg-primary";
|
|
13645
|
+
case "blocked":
|
|
13646
|
+
return "bg-amber-500";
|
|
13647
|
+
case "done":
|
|
13648
|
+
return "bg-emerald-500";
|
|
13649
|
+
case "failed":
|
|
13650
|
+
return "bg-destructive";
|
|
13651
|
+
case "cancelled":
|
|
13652
|
+
return "bg-muted-foreground";
|
|
13653
|
+
default:
|
|
13654
|
+
return "bg-foreground/30";
|
|
13655
|
+
}
|
|
13656
|
+
}
|
|
13657
|
+
function missionWorkerTaskCounts(worker, tasks) {
|
|
13658
|
+
if (worker.kind !== "task") return null;
|
|
13659
|
+
const mine = tasks.filter((t) => t.agentDefName === worker.agentDefName);
|
|
13660
|
+
return {
|
|
13661
|
+
completed: mine.filter((t) => t.status === "done").length,
|
|
13662
|
+
inFlight: mine.filter(
|
|
13663
|
+
(t) => t.status === "running" || t.status === "blocked"
|
|
13664
|
+
).length
|
|
13665
|
+
};
|
|
13666
|
+
}
|
|
13667
|
+
function formatMissionTimestamp(iso) {
|
|
13668
|
+
if (!iso) return "";
|
|
13669
|
+
const parsed = new Date(iso);
|
|
13670
|
+
if (Number.isNaN(parsed.getTime())) return iso;
|
|
13671
|
+
return parsed.toLocaleTimeString();
|
|
13672
|
+
}
|
|
13673
|
+
var CATEGORY_BADGE_CLASS = {
|
|
13674
|
+
spawn: "border-primary/30 bg-primary/10 text-primary",
|
|
13675
|
+
output: "border-foreground/20 bg-foreground/5 text-foreground/80",
|
|
13676
|
+
done: "border-emerald-500/30 bg-emerald-500/10 text-emerald-600",
|
|
13677
|
+
verdict: "border-amber-500/30 bg-amber-500/10 text-amber-600",
|
|
13678
|
+
system: "border-border bg-muted text-muted-foreground"
|
|
13679
|
+
};
|
|
13680
|
+
function MissionActivityTab({ feed }) {
|
|
13681
|
+
const [filter, setFilter] = useState("all");
|
|
13682
|
+
const rows = useMemo(() => {
|
|
13683
|
+
const newestFirst = [...feed.events].reverse();
|
|
13684
|
+
if (filter === "all") return newestFirst;
|
|
13685
|
+
return newestFirst.filter((e) => missionEventCategory(e.type) === filter);
|
|
13686
|
+
}, [feed.events, filter]);
|
|
13687
|
+
if (feed.events.length === 0) {
|
|
13688
|
+
return /* @__PURE__ */ jsx("div", { className: "py-8 text-center text-sm text-muted-foreground/60", children: "No mission activity yet." });
|
|
13689
|
+
}
|
|
13690
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
13691
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-1.5", children: ["all", ...MISSION_EVENT_CATEGORIES].map((cat) => /* @__PURE__ */ jsx(
|
|
13692
|
+
"button",
|
|
13693
|
+
{
|
|
13694
|
+
type: "button",
|
|
13695
|
+
onClick: () => setFilter(cat),
|
|
13696
|
+
className: `rounded-full border px-2.5 py-0.5 font-mono text-[10px] uppercase tracking-wide transition-colors ${filter === cat ? "border-foreground bg-foreground text-background" : "border-border/60 bg-background text-muted-foreground hover:bg-muted/40"}`,
|
|
13697
|
+
children: cat
|
|
13698
|
+
},
|
|
13699
|
+
cat
|
|
13700
|
+
)) }),
|
|
13701
|
+
/* @__PURE__ */ jsx("ol", { className: "space-y-1", children: rows.map((e) => /* @__PURE__ */ jsx(ActivityRow, { event: e, feed }, e.id)) })
|
|
13702
|
+
] });
|
|
13703
|
+
}
|
|
13704
|
+
function ActivityRow({
|
|
13705
|
+
event,
|
|
13706
|
+
feed
|
|
13707
|
+
}) {
|
|
13708
|
+
const category = missionEventCategory(event.type);
|
|
13709
|
+
const taskId = missionEventTaskId(event, feed.sessions);
|
|
13710
|
+
return /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-3 rounded px-2 py-1.5 text-sm hover:bg-muted/30", children: [
|
|
13711
|
+
/* @__PURE__ */ jsx("span", { className: "w-20 shrink-0 font-mono text-[10px] text-muted-foreground/60", children: formatMissionTimestamp(event.createdAt) }),
|
|
13712
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
|
|
13713
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2 items-center", children: [
|
|
13714
|
+
/* @__PURE__ */ jsx(
|
|
13715
|
+
"span",
|
|
13716
|
+
{
|
|
13717
|
+
className: `shrink-0 rounded border px-1.5 font-mono uppercase ${CATEGORY_BADGE_CLASS[category]}`,
|
|
13718
|
+
children: category
|
|
13719
|
+
}
|
|
13720
|
+
),
|
|
13721
|
+
/* @__PURE__ */ jsx("p", { className: "shrink-0 text-xs text-foreground font-mono", children: missionEventActorLabel(event, feed.sessions) }),
|
|
13722
|
+
taskId ? /* @__PURE__ */ jsx("p", { className: "shrink-0 rounded bg-muted px-1.5 py-0.5 font-mono text-[9px] text-muted-foreground/70", children: taskId.slice(0, 8) }) : null
|
|
13723
|
+
] }),
|
|
13724
|
+
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 truncate text-foreground/80", children: missionEventSummary(event) }) })
|
|
13725
|
+
] })
|
|
13726
|
+
] });
|
|
13727
|
+
}
|
|
13728
|
+
function verdictToneClass(result) {
|
|
13729
|
+
if (result === "satisfied") {
|
|
13730
|
+
return "border-emerald-500/30 bg-emerald-500/5 text-emerald-700 dark:text-emerald-400";
|
|
13731
|
+
}
|
|
13732
|
+
if (result === "failed" || result === "blocked") {
|
|
13733
|
+
return "border-destructive/30 bg-destructive/5 text-destructive";
|
|
13734
|
+
}
|
|
13735
|
+
return "border-amber-500/30 bg-amber-500/5 text-amber-700 dark:text-amber-400";
|
|
13736
|
+
}
|
|
13737
|
+
function MissionMetadataTab({ mission }) {
|
|
13738
|
+
const rows = [
|
|
13739
|
+
{
|
|
13740
|
+
label: "Mission ID",
|
|
13741
|
+
value: /* @__PURE__ */ jsx("code", { className: "text-[11px]", children: mission.id })
|
|
13742
|
+
},
|
|
13743
|
+
{
|
|
13744
|
+
label: "Session ID",
|
|
13745
|
+
value: /* @__PURE__ */ jsx("code", { className: "text-[11px]", children: mission.sessionId })
|
|
13746
|
+
},
|
|
13747
|
+
{
|
|
13748
|
+
label: "Agent ID",
|
|
13749
|
+
value: /* @__PURE__ */ jsx("code", { className: "text-[11px]", children: mission.agentId })
|
|
13750
|
+
},
|
|
13751
|
+
{ label: "Status", value: mission.status },
|
|
13752
|
+
{
|
|
13753
|
+
label: "Iteration",
|
|
13754
|
+
value: `${mission.iteration} / ${mission.maxIterations}`
|
|
13755
|
+
},
|
|
13756
|
+
{
|
|
13757
|
+
label: "Owner",
|
|
13758
|
+
value: mission.userId ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13759
|
+
"user ",
|
|
13760
|
+
/* @__PURE__ */ jsx("code", { className: "text-[11px]", children: mission.userId })
|
|
13761
|
+
] }) : mission.serviceAccountId ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13762
|
+
"service account",
|
|
13763
|
+
" ",
|
|
13764
|
+
/* @__PURE__ */ jsx("code", { className: "text-[11px]", children: mission.serviceAccountId })
|
|
13765
|
+
] }) : "\u2014"
|
|
13766
|
+
},
|
|
13767
|
+
{
|
|
13768
|
+
label: "Created",
|
|
13769
|
+
value: /* @__PURE__ */ jsx("span", { className: "font-mono text-[11px]", children: new Date(mission.createdAt).toLocaleString() })
|
|
13770
|
+
},
|
|
13771
|
+
{
|
|
13772
|
+
label: "Updated",
|
|
13773
|
+
value: /* @__PURE__ */ jsx("span", { className: "font-mono text-[11px]", children: new Date(mission.updatedAt).toLocaleString() })
|
|
13774
|
+
}
|
|
13775
|
+
];
|
|
13776
|
+
if (mission.pausedReason) {
|
|
13777
|
+
rows.push({ label: "Paused reason", value: mission.pausedReason });
|
|
13778
|
+
}
|
|
13779
|
+
if (mission.cancelledReason) {
|
|
13780
|
+
rows.push({ label: "Cancelled reason", value: mission.cancelledReason });
|
|
13781
|
+
}
|
|
13782
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
13783
|
+
mission.lastEvaluationResult ? /* @__PURE__ */ jsxs(
|
|
13784
|
+
"section",
|
|
13785
|
+
{
|
|
13786
|
+
className: `space-y-2 rounded-md border p-4 ${verdictToneClass(mission.lastEvaluationResult)}`,
|
|
13787
|
+
children: [
|
|
13788
|
+
/* @__PURE__ */ jsxs("div", { className: "font-mono text-[10px] uppercase tracking-widest", children: [
|
|
13789
|
+
"Last verdict \u2014 ",
|
|
13790
|
+
mission.lastEvaluationResult
|
|
13791
|
+
] }),
|
|
13792
|
+
mission.lastEvaluationFeedback ? /* @__PURE__ */ jsx("p", { className: "whitespace-pre-wrap text-sm font-medium text-foreground/90", children: mission.lastEvaluationFeedback }) : null,
|
|
13793
|
+
mission.lastEvaluationExplanation ? /* @__PURE__ */ jsx("p", { className: "whitespace-pre-wrap text-xs text-muted-foreground/80", children: mission.lastEvaluationExplanation }) : null,
|
|
13794
|
+
mission.lastEvaluationAt ? /* @__PURE__ */ jsx("p", { className: "font-mono text-[10px] text-muted-foreground/60", children: new Date(mission.lastEvaluationAt).toLocaleString() }) : null
|
|
13795
|
+
]
|
|
13796
|
+
}
|
|
13797
|
+
) : null,
|
|
13798
|
+
/* @__PURE__ */ jsxs("section", { children: [
|
|
13799
|
+
/* @__PURE__ */ jsx("div", { className: "mb-2 font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: "Identifiers" }),
|
|
13800
|
+
/* @__PURE__ */ jsx("dl", { className: "grid grid-cols-[max-content_1fr] gap-x-4 gap-y-1 text-xs", children: rows.map((r) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
13801
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground/70", children: r.label }),
|
|
13802
|
+
/* @__PURE__ */ jsx("dd", { className: "break-all text-foreground/90", children: r.value })
|
|
13803
|
+
] }, r.label)) })
|
|
13804
|
+
] })
|
|
13805
|
+
] });
|
|
13806
|
+
}
|
|
13807
|
+
var TASK_STATUS_BADGE_CLASS = {
|
|
13808
|
+
running: "border-primary/30 bg-primary/10 text-primary",
|
|
13809
|
+
blocked: "border-amber-500/30 bg-amber-500/10 text-amber-600",
|
|
13810
|
+
done: "border-emerald-500/30 bg-emerald-500/10 text-emerald-600",
|
|
13811
|
+
failed: "border-destructive/30 bg-destructive/10 text-destructive",
|
|
13812
|
+
cancelled: "border-border bg-muted text-muted-foreground"
|
|
13813
|
+
};
|
|
13814
|
+
function statusBadgeClass(status) {
|
|
13815
|
+
return TASK_STATUS_BADGE_CLASS[status] ?? "border-foreground/20 bg-foreground/5 text-foreground/70";
|
|
13816
|
+
}
|
|
13817
|
+
function TaskChip({
|
|
13818
|
+
task,
|
|
13819
|
+
onSelect
|
|
13820
|
+
}) {
|
|
13821
|
+
return /* @__PURE__ */ jsxs(
|
|
13822
|
+
"button",
|
|
13823
|
+
{
|
|
13824
|
+
type: "button",
|
|
13825
|
+
"data-task-chip": true,
|
|
13826
|
+
onClick: () => onSelect(task.id),
|
|
13827
|
+
className: "inline-flex max-w-full items-center gap-1.5 rounded-full border border-border/60 bg-background px-2.5 py-1 text-xs hover:bg-muted/40",
|
|
13828
|
+
children: [
|
|
13829
|
+
/* @__PURE__ */ jsx(
|
|
13830
|
+
"span",
|
|
13831
|
+
{
|
|
13832
|
+
className: `size-1.5 shrink-0 rounded-full ${missionTaskStatusDotClass(task.status)}`
|
|
13833
|
+
}
|
|
13834
|
+
),
|
|
13835
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-foreground/85", children: missionTaskTitle(task.goal, 40) }),
|
|
13836
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 font-mono text-[9px] text-muted-foreground/60", children: task.id.slice(0, 8) })
|
|
13837
|
+
]
|
|
13838
|
+
}
|
|
13839
|
+
);
|
|
13840
|
+
}
|
|
13841
|
+
function TaskRailRow({
|
|
13842
|
+
task,
|
|
13843
|
+
selected,
|
|
13844
|
+
onSelect
|
|
13845
|
+
}) {
|
|
13846
|
+
const preview = stripMissionControlMarkup(
|
|
13847
|
+
task.status === "done" && task.result ? task.result : task.goal
|
|
13848
|
+
);
|
|
13849
|
+
return /* @__PURE__ */ jsxs(
|
|
13850
|
+
"button",
|
|
13851
|
+
{
|
|
13852
|
+
type: "button",
|
|
13853
|
+
onClick: () => onSelect(task.id),
|
|
13854
|
+
className: `w-full rounded-md border px-3 py-2 text-left text-sm transition-colors ${selected ? "border-primary/40 bg-primary/5" : "border-transparent hover:bg-muted/40"}`,
|
|
13855
|
+
children: [
|
|
13856
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
13857
|
+
/* @__PURE__ */ jsx(
|
|
13858
|
+
"span",
|
|
13859
|
+
{
|
|
13860
|
+
className: `size-2 shrink-0 rounded-full ${missionTaskStatusDotClass(task.status)}`
|
|
13861
|
+
}
|
|
13862
|
+
),
|
|
13863
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate font-medium text-foreground/90", children: task.goal })
|
|
13864
|
+
] }),
|
|
13865
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-1 flex flex-col gap-2 pl-4", children: [
|
|
13866
|
+
task.agentDefName ? /* @__PURE__ */ jsx("span", { className: "shrink-0 text-xs font-mono text-muted-foreground", children: task.agentDefName }) : null,
|
|
13867
|
+
/* @__PURE__ */ jsx("span", { className: "line-clamp-2 min-w-0 flex-1 text-xs text-muted-foreground/70", children: preview })
|
|
13868
|
+
] })
|
|
13869
|
+
]
|
|
13870
|
+
}
|
|
13871
|
+
);
|
|
13872
|
+
}
|
|
13873
|
+
function MissionTasksTab({
|
|
13874
|
+
tasks,
|
|
13875
|
+
feed,
|
|
13876
|
+
onOpenTranscript
|
|
13877
|
+
}) {
|
|
13878
|
+
const [selectedId, setSelectedId] = useState(null);
|
|
13879
|
+
const groups = useMemo(() => missionTaskRailGroups(tasks), [tasks]);
|
|
13880
|
+
const blocks = useMemo(() => missionTaskBlocks(tasks), [tasks]);
|
|
13881
|
+
const byId = useMemo(() => new Map(tasks.map((t) => [t.id, t])), [tasks]);
|
|
13882
|
+
const effectiveId = selectedId && byId.has(selectedId) ? selectedId : defaultSelectedMissionTaskId(tasks);
|
|
13883
|
+
const selected = effectiveId ? byId.get(effectiveId) ?? null : null;
|
|
13884
|
+
const taskEvents = useMemo(() => {
|
|
13885
|
+
if (!selected || !feed.supported) return [];
|
|
13886
|
+
return feed.events.filter(
|
|
13887
|
+
(e) => missionEventTaskId(e, feed.sessions) === selected.id
|
|
13888
|
+
);
|
|
13889
|
+
}, [selected, feed]);
|
|
13890
|
+
const liveOutput = useMemo(() => {
|
|
13891
|
+
if (!selected || selected.status !== "running") return null;
|
|
13892
|
+
const outputs = taskEvents.filter(
|
|
13893
|
+
(e) => missionEventCategory(e.type) === "output"
|
|
13894
|
+
);
|
|
13895
|
+
return outputs.length > 0 ? outputs[outputs.length - 1] : null;
|
|
13896
|
+
}, [selected, taskEvents]);
|
|
13897
|
+
if (tasks.length === 0) {
|
|
13898
|
+
return /* @__PURE__ */ jsx("div", { className: "py-8 text-center text-sm text-muted-foreground/60", children: "No tasks spawned yet." });
|
|
13899
|
+
}
|
|
13900
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-0 gap-4", children: [
|
|
13901
|
+
/* @__PURE__ */ jsx("div", { className: "w-72 shrink-0 space-y-4 overflow-y-auto pr-1", children: groups.map((group) => /* @__PURE__ */ jsxs("div", { children: [
|
|
13902
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-1 px-1 font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: [
|
|
13903
|
+
group.label,
|
|
13904
|
+
" (",
|
|
13905
|
+
group.tasks.length,
|
|
13906
|
+
")"
|
|
13907
|
+
] }),
|
|
13908
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-1", children: group.tasks.map((t) => /* @__PURE__ */ jsx(
|
|
13909
|
+
TaskRailRow,
|
|
13910
|
+
{
|
|
13911
|
+
task: t,
|
|
13912
|
+
selected: t.id === effectiveId,
|
|
13913
|
+
onSelect: setSelectedId
|
|
13914
|
+
},
|
|
13915
|
+
t.id
|
|
13916
|
+
)) })
|
|
13917
|
+
] }, group.key)) }),
|
|
13918
|
+
/* @__PURE__ */ jsx(
|
|
13919
|
+
"div",
|
|
13920
|
+
{
|
|
13921
|
+
"data-testid": "task-detail",
|
|
13922
|
+
className: "min-w-0 flex-1 space-y-4 overflow-y-auto bg-card px-8 py-5",
|
|
13923
|
+
children: selected ? /* @__PURE__ */ jsx(
|
|
13924
|
+
TaskDetail,
|
|
13925
|
+
{
|
|
13926
|
+
task: selected,
|
|
13927
|
+
allTasks: byId,
|
|
13928
|
+
blockedTaskIds: blocks[selected.id] ?? [],
|
|
13929
|
+
taskEvents,
|
|
13930
|
+
liveOutput,
|
|
13931
|
+
eventsSupported: feed.supported,
|
|
13932
|
+
onSelect: setSelectedId,
|
|
13933
|
+
onOpenTranscript
|
|
13934
|
+
}
|
|
13935
|
+
) : null
|
|
13936
|
+
}
|
|
13937
|
+
)
|
|
13938
|
+
] });
|
|
13939
|
+
}
|
|
13940
|
+
function TaskDetail({
|
|
13941
|
+
task,
|
|
13942
|
+
allTasks,
|
|
13943
|
+
blockedTaskIds,
|
|
13944
|
+
taskEvents,
|
|
13945
|
+
liveOutput,
|
|
13946
|
+
eventsSupported,
|
|
13947
|
+
onSelect,
|
|
13948
|
+
onOpenTranscript
|
|
13949
|
+
}) {
|
|
13950
|
+
const parents = task.parentIds.map((id) => allTasks.get(id)).filter((t) => Boolean(t));
|
|
13951
|
+
const children = blockedTaskIds.map((id) => allTasks.get(id)).filter((t) => Boolean(t));
|
|
13952
|
+
const timeLabel = task.startedAt && task.completedAt ? `${formatMissionTimestamp(task.startedAt)} \u2192 ${formatMissionTimestamp(task.completedAt)}` : task.startedAt ? `started ${formatMissionTimestamp(task.startedAt)}` : "not started";
|
|
13953
|
+
const outcome = deriveTaskOutcome({ task, taskEvents, liveOutput, parents });
|
|
13954
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-5", children: [
|
|
13955
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
13956
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
|
|
13957
|
+
/* @__PURE__ */ jsx("h2", { className: "min-w-0 flex-1 truncate text-lg font-semibold text-foreground", children: missionTaskTitle(task.goal) }),
|
|
13958
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 font-mono text-[10px] text-muted-foreground/60", children: task.id.slice(0, 8) })
|
|
13959
|
+
] }),
|
|
13960
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 text-xs", children: [
|
|
13961
|
+
/* @__PURE__ */ jsx(
|
|
13962
|
+
Badge,
|
|
13963
|
+
{
|
|
13964
|
+
variant: "destructive",
|
|
13965
|
+
className: `font-mono text-sm uppercase tracking-wide ${statusBadgeClass(task.status)}`,
|
|
13966
|
+
children: task.status
|
|
13967
|
+
}
|
|
13968
|
+
),
|
|
13969
|
+
task.agentDefName ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: task.agentDefName }) : null,
|
|
13970
|
+
task.attemptCount > 1 ? /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
13971
|
+
"attempts ",
|
|
13972
|
+
task.attemptCount,
|
|
13973
|
+
"/",
|
|
13974
|
+
task.maxAttempts
|
|
13975
|
+
] }) : null,
|
|
13976
|
+
/* @__PURE__ */ jsxs("span", { className: "ml-auto inline-flex items-center gap-1 text-muted-foreground", children: [
|
|
13977
|
+
/* @__PURE__ */ jsx(Clock, { className: "size-3" }),
|
|
13978
|
+
timeLabel
|
|
13979
|
+
] })
|
|
13980
|
+
] })
|
|
13981
|
+
] }),
|
|
13982
|
+
/* @__PURE__ */ jsx(OutcomeCard, { outcome }),
|
|
13983
|
+
parents.length > 0 || children.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
13984
|
+
/* @__PURE__ */ jsx("div", { className: "font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: "Dependencies" }),
|
|
13985
|
+
parents.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [
|
|
13986
|
+
/* @__PURE__ */ jsx("span", { className: "mr-1 text-[10px] uppercase text-muted-foreground/50", children: "Depends on" }),
|
|
13987
|
+
parents.map((p) => /* @__PURE__ */ jsx(TaskChip, { task: p, onSelect }, p.id))
|
|
13988
|
+
] }) : null,
|
|
13989
|
+
children.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [
|
|
13990
|
+
/* @__PURE__ */ jsx("span", { className: "mr-1 text-[10px] uppercase text-muted-foreground/50", children: "Blocks" }),
|
|
13991
|
+
children.map((c) => /* @__PURE__ */ jsx(TaskChip, { task: c, onSelect }, c.id))
|
|
13992
|
+
] }) : null
|
|
13993
|
+
] }) : null,
|
|
13994
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
13995
|
+
/* @__PURE__ */ jsx("div", { className: "mb-1 font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: "Brief" }),
|
|
13996
|
+
/* @__PURE__ */ jsx(MessageResponse, { className: "text-sm leading-relaxed text-foreground/90", children: task.goal })
|
|
13997
|
+
] }),
|
|
13998
|
+
task.resultMetadata ? /* @__PURE__ */ jsxs("details", { children: [
|
|
13999
|
+
/* @__PURE__ */ jsx("summary", { className: "cursor-pointer font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: "Result metadata" }),
|
|
14000
|
+
/* @__PURE__ */ jsx("pre", { className: "mt-1 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) })
|
|
14001
|
+
] }) : null,
|
|
14002
|
+
eventsSupported && taskEvents.length > 0 ? /* @__PURE__ */ jsxs("div", { children: [
|
|
14003
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-2 font-mono font-semibold uppercase text-muted-foreground", children: [
|
|
14004
|
+
"History (",
|
|
14005
|
+
taskEvents.length,
|
|
14006
|
+
")"
|
|
14007
|
+
] }),
|
|
14008
|
+
/* @__PURE__ */ jsx("ol", { className: "space-y-3", children: taskEvents.map((e) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-3 text-xs", children: [
|
|
14009
|
+
/* @__PURE__ */ jsx("span", { className: "w-16 shrink-0 font-mono text-[10px] text-muted-foreground/60", children: formatMissionTimestamp(e.createdAt) }),
|
|
14010
|
+
/* @__PURE__ */ jsxs("div", { className: "", children: [
|
|
14011
|
+
/* @__PURE__ */ jsx("p", { className: "shrink-0 font-mono uppercase text-muted-foreground", children: missionEventCategory(e.type) }),
|
|
14012
|
+
/* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 text-foreground/80", children: missionEventSummary(e) })
|
|
14013
|
+
] })
|
|
14014
|
+
] }, e.id)) })
|
|
14015
|
+
] }) : null,
|
|
14016
|
+
task.currentSessionId && onOpenTranscript ? /* @__PURE__ */ jsxs(
|
|
14017
|
+
Button,
|
|
14018
|
+
{
|
|
14019
|
+
"data-testid": "view-session",
|
|
14020
|
+
variant: "outline",
|
|
14021
|
+
size: "sm",
|
|
14022
|
+
onClick: () => onOpenTranscript(task.currentSessionId),
|
|
14023
|
+
children: [
|
|
14024
|
+
/* @__PURE__ */ jsx(ArrowRight, { className: "size-4" }),
|
|
14025
|
+
"View ",
|
|
14026
|
+
task.agentDefName ?? "worker",
|
|
14027
|
+
" session"
|
|
14028
|
+
]
|
|
14029
|
+
}
|
|
14030
|
+
) : null
|
|
14031
|
+
] });
|
|
14032
|
+
}
|
|
14033
|
+
function deriveTaskOutcome({
|
|
14034
|
+
task,
|
|
14035
|
+
taskEvents,
|
|
14036
|
+
liveOutput,
|
|
14037
|
+
parents
|
|
14038
|
+
}) {
|
|
14039
|
+
const result = task.result ? stripMissionControlMarkup(task.result) : "";
|
|
14040
|
+
switch (task.status) {
|
|
14041
|
+
case "done":
|
|
14042
|
+
return {
|
|
14043
|
+
label: "Result",
|
|
14044
|
+
tone: "bg-emerald-500/5 ring-emerald-500/25",
|
|
14045
|
+
labelTone: "text-emerald-600",
|
|
14046
|
+
icon: /* @__PURE__ */ jsx(CheckCircle2, { className: "size-3" }),
|
|
14047
|
+
timestamp: task.completedAt,
|
|
14048
|
+
markdown: result || void 0,
|
|
14049
|
+
text: result ? void 0 : "Completed."
|
|
14050
|
+
};
|
|
14051
|
+
case "failed":
|
|
14052
|
+
return {
|
|
14053
|
+
label: "Failed",
|
|
14054
|
+
tone: "bg-destructive/5 ring-destructive/25",
|
|
14055
|
+
labelTone: "text-destructive",
|
|
14056
|
+
icon: /* @__PURE__ */ jsx(XCircle, { className: "size-3" }),
|
|
14057
|
+
timestamp: task.completedAt,
|
|
14058
|
+
markdown: result || void 0,
|
|
14059
|
+
text: result ? void 0 : `Failed after ${task.attemptCount}/${task.maxAttempts} attempts.`
|
|
14060
|
+
};
|
|
14061
|
+
case "cancelled":
|
|
14062
|
+
return {
|
|
14063
|
+
label: "Cancelled",
|
|
14064
|
+
tone: "bg-muted/40 ring-border",
|
|
14065
|
+
labelTone: "text-muted-foreground",
|
|
14066
|
+
icon: /* @__PURE__ */ jsx(Ban, { className: "size-3" }),
|
|
14067
|
+
timestamp: task.completedAt,
|
|
14068
|
+
text: "Task cancelled."
|
|
14069
|
+
};
|
|
14070
|
+
case "running":
|
|
14071
|
+
return {
|
|
14072
|
+
label: "Live output",
|
|
14073
|
+
tone: "bg-amber-500/5 ring-amber-500/25",
|
|
14074
|
+
labelTone: "text-amber-600",
|
|
14075
|
+
icon: /* @__PURE__ */ jsx(CircleDot, { className: "size-3 animate-pulse" }),
|
|
14076
|
+
timestamp: liveOutput?.createdAt ?? null,
|
|
14077
|
+
text: liveOutput ? missionEventSummary(liveOutput) : "Working \u2014 no output yet."
|
|
14078
|
+
};
|
|
14079
|
+
case "blocked": {
|
|
14080
|
+
const blockedEvent = [...taskEvents].reverse().find((e) => e.type === "task.blocked");
|
|
14081
|
+
return {
|
|
14082
|
+
label: "Waiting",
|
|
14083
|
+
tone: "bg-amber-500/5 ring-amber-500/20",
|
|
14084
|
+
labelTone: "text-amber-700 dark:text-amber-500",
|
|
14085
|
+
icon: /* @__PURE__ */ jsx(Clock, { className: "size-3" }),
|
|
14086
|
+
timestamp: blockedEvent?.createdAt ?? null,
|
|
14087
|
+
text: blockedEvent ? missionEventSummary(blockedEvent) : "Blocked \u2014 awaiting input."
|
|
14088
|
+
};
|
|
14089
|
+
}
|
|
14090
|
+
default: {
|
|
14091
|
+
const pending = parents.filter((p) => p.status !== "done");
|
|
14092
|
+
const text = pending.length > 0 ? `Waiting on ${pending.map((p) => missionTaskTitle(p.goal, 40)).join(" \xB7 ")} to complete.` : "Queued \u2014 waiting for a worker slot.";
|
|
14093
|
+
return {
|
|
14094
|
+
label: "Waiting",
|
|
14095
|
+
tone: "bg-muted/30 ring-border",
|
|
14096
|
+
labelTone: "text-muted-foreground",
|
|
14097
|
+
icon: /* @__PURE__ */ jsx(Clock, { className: "size-3" }),
|
|
14098
|
+
timestamp: null,
|
|
14099
|
+
text
|
|
14100
|
+
};
|
|
14101
|
+
}
|
|
14102
|
+
}
|
|
14103
|
+
}
|
|
14104
|
+
function OutcomeCard({ outcome }) {
|
|
14105
|
+
return /* @__PURE__ */ jsxs(
|
|
14106
|
+
Card,
|
|
14107
|
+
{
|
|
14108
|
+
"data-testid": "task-outcome",
|
|
14109
|
+
size: "sm",
|
|
14110
|
+
className: `mx-1 gap-3 rounded-lg py-4 shadow-none ${outcome.tone}`,
|
|
14111
|
+
children: [
|
|
14112
|
+
/* @__PURE__ */ jsxs(CardHeader, { children: [
|
|
14113
|
+
/* @__PURE__ */ jsxs(
|
|
14114
|
+
CardTitle,
|
|
14115
|
+
{
|
|
14116
|
+
className: `flex items-center gap-1.5 font-mono text-[11px] font-semibold tracking-widest ${outcome.labelTone}`,
|
|
14117
|
+
children: [
|
|
14118
|
+
outcome.icon,
|
|
14119
|
+
outcome.label
|
|
14120
|
+
]
|
|
14121
|
+
}
|
|
14122
|
+
),
|
|
14123
|
+
outcome.timestamp ? /* @__PURE__ */ jsx(CardAction, { className: "font-mono text-[10px] text-muted-foreground/60", children: formatMissionTimestamp(outcome.timestamp) }) : null
|
|
14124
|
+
] }),
|
|
14125
|
+
/* @__PURE__ */ jsx(CardContent, { children: outcome.markdown ? /* @__PURE__ */ jsx(MessageResponse, { className: "font-mono text-xs leading-relaxed text-foreground/90", children: outcome.markdown }) : /* @__PURE__ */ jsx("p", { className: "whitespace-pre-wrap font-mono text-xs leading-relaxed text-foreground/90", children: outcome.text }) })
|
|
14126
|
+
]
|
|
14127
|
+
}
|
|
14128
|
+
);
|
|
14129
|
+
}
|
|
14130
|
+
var MISSION_WORKER_KIND_BADGE_CLASS = {
|
|
14131
|
+
task: "border-primary/40 bg-primary/10 text-primary uppercase tracking-wide text-[10px]",
|
|
14132
|
+
worker: "border-foreground/30 bg-foreground/5 text-foreground/80 uppercase tracking-wide text-[10px]",
|
|
14133
|
+
delegation: "border-foreground/20 bg-foreground/[0.03] text-foreground/60 uppercase tracking-wide text-[10px]"
|
|
14134
|
+
};
|
|
14135
|
+
var MISSION_WORKER_KIND_TOOLTIP = {
|
|
14136
|
+
task: "Durable Task row created by spawn_task. Retried by the dispatcher; survives across coordinator wakes.",
|
|
14137
|
+
worker: "Async one-shot session spawned by spawn_worker. Durable session, no retry/DAG.",
|
|
14138
|
+
delegation: "Sync fork-join child spawned by delegate_task. Coordinator's wake blocked until it finished."
|
|
14139
|
+
};
|
|
14140
|
+
function MissionWorkersTab({
|
|
14141
|
+
workers,
|
|
14142
|
+
tasks,
|
|
14143
|
+
onOpenTranscript
|
|
14144
|
+
}) {
|
|
14145
|
+
if (workers.length === 0) {
|
|
14146
|
+
return /* @__PURE__ */ jsx("div", { className: "py-8 text-center text-sm text-muted-foreground/60", children: "No workers attached to this mission right now." });
|
|
14147
|
+
}
|
|
14148
|
+
return /* @__PURE__ */ jsx("div", { className: "grid gap-3 sm:grid-cols-2", children: workers.map((w) => /* @__PURE__ */ jsx(
|
|
14149
|
+
WorkerCard,
|
|
14150
|
+
{
|
|
14151
|
+
worker: w,
|
|
14152
|
+
tasks,
|
|
14153
|
+
onOpenTranscript
|
|
14154
|
+
},
|
|
14155
|
+
w.workerSessionId
|
|
14156
|
+
)) });
|
|
14157
|
+
}
|
|
14158
|
+
function WorkerCard({
|
|
14159
|
+
worker,
|
|
14160
|
+
tasks,
|
|
14161
|
+
onOpenTranscript
|
|
14162
|
+
}) {
|
|
14163
|
+
const counts = missionWorkerTaskCounts(worker, tasks);
|
|
14164
|
+
const statusLabel2 = worker.kind === "task" ? worker.taskStatus ?? "\u2014" : worker.sessionStatus;
|
|
14165
|
+
const onTranscriptClick = (e) => {
|
|
14166
|
+
if (onOpenTranscript) {
|
|
14167
|
+
e.preventDefault();
|
|
14168
|
+
onOpenTranscript(worker.workerSessionId);
|
|
14169
|
+
}
|
|
14170
|
+
};
|
|
14171
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 rounded-md border border-border/60 bg-card p-4 shadow-sm", children: [
|
|
14172
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2", children: [
|
|
14173
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
14174
|
+
/* @__PURE__ */ jsx("div", { className: "truncate text-sm font-semibold text-foreground", children: worker.agentDefName ?? "worker" }),
|
|
14175
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
14176
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
14177
|
+
Badge,
|
|
14178
|
+
{
|
|
14179
|
+
variant: "outline",
|
|
14180
|
+
className: `mt-1 ${MISSION_WORKER_KIND_BADGE_CLASS[worker.kind]}`,
|
|
14181
|
+
children: worker.kind
|
|
14182
|
+
}
|
|
14183
|
+
) }),
|
|
14184
|
+
/* @__PURE__ */ jsx(TooltipContent, { className: "max-w-xs", children: MISSION_WORKER_KIND_TOOLTIP[worker.kind] })
|
|
14185
|
+
] })
|
|
14186
|
+
] }),
|
|
14187
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 font-mono text-[10px] uppercase tracking-wider text-muted-foreground/70", children: statusLabel2 })
|
|
14188
|
+
] }),
|
|
14189
|
+
counts ? /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-6", children: [
|
|
14190
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
14191
|
+
/* @__PURE__ */ jsx("div", { className: "text-xl font-bold tabular-nums text-foreground", children: counts.completed }),
|
|
14192
|
+
/* @__PURE__ */ jsx("div", { className: "font-mono text-[9px] uppercase tracking-widest text-muted-foreground/60", children: "Completed" })
|
|
14193
|
+
] }),
|
|
14194
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
14195
|
+
/* @__PURE__ */ jsx(
|
|
14196
|
+
"div",
|
|
14197
|
+
{
|
|
14198
|
+
className: `text-xl font-bold tabular-nums ${counts.inFlight > 0 ? "text-amber-600" : "text-foreground"}`,
|
|
14199
|
+
children: counts.inFlight
|
|
14200
|
+
}
|
|
14201
|
+
),
|
|
14202
|
+
/* @__PURE__ */ jsx("div", { className: "font-mono text-[9px] uppercase tracking-widest text-muted-foreground/60", children: "In flight" })
|
|
14203
|
+
] })
|
|
14204
|
+
] }) : null,
|
|
14205
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-auto space-y-1 border-t border-border/40 pt-2", children: [
|
|
14206
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
14207
|
+
/* @__PURE__ */ jsx("span", { className: "truncate font-mono text-[10px] text-muted-foreground/70", children: worker.latestEventKind ?? "no events yet" }),
|
|
14208
|
+
worker.latestEventAt ? /* @__PURE__ */ jsx("span", { className: "shrink-0 font-mono text-[10px] text-muted-foreground/60", children: formatMissionTimestamp(worker.latestEventAt) }) : null
|
|
14209
|
+
] }),
|
|
14210
|
+
/* @__PURE__ */ jsx("div", { className: "truncate text-xs text-foreground/80", children: deriveMissionWorkerActivityLabel(worker) }),
|
|
14211
|
+
/* @__PURE__ */ jsx(
|
|
14212
|
+
"a",
|
|
14213
|
+
{
|
|
14214
|
+
href: worker.transcriptUrl,
|
|
14215
|
+
target: "_blank",
|
|
14216
|
+
rel: "noreferrer",
|
|
14217
|
+
onClick: onTranscriptClick,
|
|
14218
|
+
className: "inline-block text-xs text-primary hover:underline",
|
|
14219
|
+
children: "View session"
|
|
14220
|
+
}
|
|
14221
|
+
)
|
|
14222
|
+
] })
|
|
14223
|
+
] });
|
|
14224
|
+
}
|
|
14225
|
+
var PAGE_LIMIT = 500;
|
|
14226
|
+
var MAX_PAGES_PER_PUMP = 20;
|
|
14227
|
+
function useMissionEvents(input) {
|
|
14228
|
+
const { adapter, missionId, missionStatus, isTerminal, pollIntervalMs } = input;
|
|
14229
|
+
const supported = typeof adapter.listMissionEvents === "function";
|
|
14230
|
+
const [events, setEvents] = useState([]);
|
|
14231
|
+
const [sessions, setSessions] = useState({});
|
|
14232
|
+
const lastIdRef = useRef(null);
|
|
14233
|
+
const pumpingRef = useRef(false);
|
|
14234
|
+
const mountedRef = useRef(true);
|
|
14235
|
+
useEffect(() => {
|
|
14236
|
+
mountedRef.current = true;
|
|
14237
|
+
return () => {
|
|
14238
|
+
mountedRef.current = false;
|
|
14239
|
+
};
|
|
14240
|
+
}, []);
|
|
14241
|
+
useEffect(() => {
|
|
14242
|
+
lastIdRef.current = null;
|
|
14243
|
+
setEvents([]);
|
|
14244
|
+
setSessions({});
|
|
14245
|
+
}, [missionId]);
|
|
14246
|
+
const pump = useCallback(async () => {
|
|
14247
|
+
const fn = adapter.listMissionEvents;
|
|
14248
|
+
if (typeof fn !== "function" || pumpingRef.current) return;
|
|
14249
|
+
pumpingRef.current = true;
|
|
14250
|
+
try {
|
|
14251
|
+
for (let page = 0; page < MAX_PAGES_PER_PUMP; page += 1) {
|
|
14252
|
+
const resp = await fn.call(adapter, {
|
|
14253
|
+
missionId,
|
|
14254
|
+
afterId: lastIdRef.current ?? void 0,
|
|
14255
|
+
limit: PAGE_LIMIT
|
|
14256
|
+
});
|
|
14257
|
+
if (!mountedRef.current) return;
|
|
14258
|
+
if (resp.events.length > 0) {
|
|
14259
|
+
lastIdRef.current = resp.events[resp.events.length - 1].id;
|
|
14260
|
+
setEvents((prev) => mergeMissionEvents(prev, resp.events));
|
|
14261
|
+
}
|
|
14262
|
+
if (Object.keys(resp.sessions).length > 0) {
|
|
14263
|
+
setSessions((prev) => ({ ...prev, ...resp.sessions }));
|
|
14264
|
+
}
|
|
14265
|
+
if (resp.events.length < PAGE_LIMIT) break;
|
|
14266
|
+
}
|
|
14267
|
+
} catch {
|
|
14268
|
+
} finally {
|
|
14269
|
+
pumpingRef.current = false;
|
|
14270
|
+
}
|
|
14271
|
+
}, [adapter, missionId]);
|
|
14272
|
+
useEffect(() => {
|
|
14273
|
+
void pump();
|
|
14274
|
+
}, [pump]);
|
|
14275
|
+
useEffect(() => {
|
|
14276
|
+
if (!supported || missionStatus === null || isTerminal) return;
|
|
14277
|
+
const id = window.setInterval(() => {
|
|
14278
|
+
void pump();
|
|
14279
|
+
}, pollIntervalMs);
|
|
14280
|
+
return () => {
|
|
14281
|
+
window.clearInterval(id);
|
|
14282
|
+
};
|
|
14283
|
+
}, [supported, missionStatus, isTerminal, pollIntervalMs, pump]);
|
|
14284
|
+
return { supported, events, sessions };
|
|
14285
|
+
}
|
|
14286
|
+
var DEFAULT_POLL_INTERVAL_MS = 5e3;
|
|
14287
|
+
function CountBadge({ n }) {
|
|
14288
|
+
if (n === 0) return null;
|
|
14289
|
+
return /* @__PURE__ */ jsx("span", { className: "ml-1 rounded bg-muted px-1 py-px text-[9px] text-muted-foreground/70", children: n });
|
|
14290
|
+
}
|
|
14291
|
+
var INITIAL_STATE = {
|
|
12968
14292
|
mission: null,
|
|
12969
14293
|
tasks: [],
|
|
12970
14294
|
workers: [],
|
|
@@ -13045,10 +14369,13 @@ function MissionDashboard({
|
|
|
13045
14369
|
window.clearInterval(id);
|
|
13046
14370
|
};
|
|
13047
14371
|
}, [refresh, state.mission, pollIntervalMs]);
|
|
13048
|
-
const
|
|
13049
|
-
|
|
13050
|
-
|
|
13051
|
-
|
|
14372
|
+
const feed = useMissionEvents({
|
|
14373
|
+
adapter,
|
|
14374
|
+
missionId,
|
|
14375
|
+
missionStatus: state.mission?.status ?? null,
|
|
14376
|
+
isTerminal: state.mission ? isTerminalMissionStatus(state.mission.status) : false,
|
|
14377
|
+
pollIntervalMs
|
|
14378
|
+
});
|
|
13052
14379
|
const runningWorkerCount = useMemo(
|
|
13053
14380
|
// "running" means the child is still consuming compute right now.
|
|
13054
14381
|
// For task-backed children that's ``taskStatus === "running"``; for
|
|
@@ -13117,7 +14444,6 @@ function MissionDashboard({
|
|
|
13117
14444
|
}
|
|
13118
14445
|
};
|
|
13119
14446
|
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";
|
|
13120
|
-
const activity = buildMissionActivity(mission, state.tasks, state.workers);
|
|
13121
14447
|
const isActive = ACTIVE_MISSION_STATUSES.has(mission.status);
|
|
13122
14448
|
const iterationPct = mission.maxIterations > 0 ? Math.min(100, mission.iteration / mission.maxIterations * 100) : 0;
|
|
13123
14449
|
return /* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 300, children: /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-1 flex-col overflow-hidden bg-muted/30", children: [
|
|
@@ -13224,18 +14550,18 @@ function MissionDashboard({
|
|
|
13224
14550
|
/* @__PURE__ */ jsxs(
|
|
13225
14551
|
Tabs,
|
|
13226
14552
|
{
|
|
13227
|
-
defaultValue: "
|
|
14553
|
+
defaultValue: "tasks",
|
|
13228
14554
|
className: "mt-5 flex flex-1 flex-col overflow-hidden sm:mt-6",
|
|
13229
14555
|
children: [
|
|
13230
14556
|
/* @__PURE__ */ jsx("div", { className: "shrink-0 border-b border-border bg-background px-5 sm:px-6", children: /* @__PURE__ */ jsxs(TabsList, { variant: "line", children: [
|
|
13231
|
-
/* @__PURE__ */ jsxs(TabsTrigger, { value: "activity", children: [
|
|
13232
|
-
"Activity",
|
|
13233
|
-
/* @__PURE__ */ jsx(CountBadge, { n: activity.length })
|
|
13234
|
-
] }),
|
|
13235
14557
|
/* @__PURE__ */ jsxs(TabsTrigger, { value: "tasks", children: [
|
|
13236
14558
|
"Tasks",
|
|
13237
14559
|
/* @__PURE__ */ jsx(CountBadge, { n: state.tasks.length })
|
|
13238
14560
|
] }),
|
|
14561
|
+
feed.supported ? /* @__PURE__ */ jsxs(TabsTrigger, { value: "activity", children: [
|
|
14562
|
+
"Activity",
|
|
14563
|
+
/* @__PURE__ */ jsx(CountBadge, { n: feed.events.length })
|
|
14564
|
+
] }) : null,
|
|
13239
14565
|
/* @__PURE__ */ jsxs(TabsTrigger, { value: "workers", children: [
|
|
13240
14566
|
"Workers",
|
|
13241
14567
|
/* @__PURE__ */ jsx(CountBadge, { n: state.workers.length })
|
|
@@ -13243,22 +14569,24 @@ function MissionDashboard({
|
|
|
13243
14569
|
/* @__PURE__ */ jsx(TabsTrigger, { value: "metadata", children: "Metadata" })
|
|
13244
14570
|
] }) }),
|
|
13245
14571
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto bg-background px-5 py-4 sm:px-6", children: [
|
|
13246
|
-
/* @__PURE__ */ jsx(TabsContent, { value: "
|
|
13247
|
-
|
|
13248
|
-
TasksList,
|
|
14572
|
+
/* @__PURE__ */ jsx(TabsContent, { value: "tasks", className: "mt-0 h-full", children: /* @__PURE__ */ jsx(
|
|
14573
|
+
MissionTasksTab,
|
|
13249
14574
|
{
|
|
13250
|
-
|
|
13251
|
-
|
|
14575
|
+
tasks: state.tasks,
|
|
14576
|
+
feed,
|
|
14577
|
+
onOpenTranscript
|
|
13252
14578
|
}
|
|
13253
14579
|
) }),
|
|
14580
|
+
feed.supported ? /* @__PURE__ */ jsx(TabsContent, { value: "activity", className: "mt-0", children: /* @__PURE__ */ jsx(MissionActivityTab, { feed }) }) : null,
|
|
13254
14581
|
/* @__PURE__ */ jsx(TabsContent, { value: "workers", className: "mt-0", children: /* @__PURE__ */ jsx(
|
|
13255
|
-
|
|
14582
|
+
MissionWorkersTab,
|
|
13256
14583
|
{
|
|
13257
14584
|
workers: state.workers,
|
|
14585
|
+
tasks: state.tasks,
|
|
13258
14586
|
onOpenTranscript
|
|
13259
14587
|
}
|
|
13260
14588
|
) }),
|
|
13261
|
-
/* @__PURE__ */ jsx(TabsContent, { value: "metadata", className: "mt-0", children: /* @__PURE__ */ jsx(
|
|
14589
|
+
/* @__PURE__ */ jsx(TabsContent, { value: "metadata", className: "mt-0", children: /* @__PURE__ */ jsx(MissionMetadataTab, { mission }) })
|
|
13262
14590
|
] })
|
|
13263
14591
|
]
|
|
13264
14592
|
}
|
|
@@ -13322,234 +14650,6 @@ function MissionDashboard({
|
|
|
13322
14650
|
)
|
|
13323
14651
|
] }) });
|
|
13324
14652
|
}
|
|
13325
|
-
function ActivityTimeline({ entries }) {
|
|
13326
|
-
if (entries.length === 0) {
|
|
13327
|
-
return /* @__PURE__ */ jsx("div", { className: "py-8 text-center text-sm text-muted-foreground/60", children: "No mission activity yet." });
|
|
13328
|
-
}
|
|
13329
|
-
return /* @__PURE__ */ jsx("ol", { className: "space-y-1", children: entries.map((e, i) => /* @__PURE__ */ jsxs(
|
|
13330
|
-
"li",
|
|
13331
|
-
{
|
|
13332
|
-
className: "flex items-start gap-3 rounded px-2 py-1.5 text-sm hover:bg-muted/30",
|
|
13333
|
-
children: [
|
|
13334
|
-
/* @__PURE__ */ jsx("span", { className: "w-20 shrink-0 font-mono text-[10px] text-muted-foreground/60", children: formatTimestamp(e.at) }),
|
|
13335
|
-
/* @__PURE__ */ jsx(
|
|
13336
|
-
"span",
|
|
13337
|
-
{
|
|
13338
|
-
className: `shrink-0 rounded border px-1.5 py-0.5 font-mono text-[9px] uppercase tracking-wide ${ACTIVITY_KIND_TONE[e.kind]}`,
|
|
13339
|
-
children: e.label
|
|
13340
|
-
}
|
|
13341
|
-
),
|
|
13342
|
-
e.detail ? /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-foreground/80", children: e.detail }) : null
|
|
13343
|
-
]
|
|
13344
|
-
},
|
|
13345
|
-
`${e.kind}-${e.at}-${i}`
|
|
13346
|
-
)) });
|
|
13347
|
-
}
|
|
13348
|
-
function TaskRow({ task }) {
|
|
13349
|
-
const [open, setOpen] = useState(false);
|
|
13350
|
-
const goalPreview = firstLine3(task.goal, 160);
|
|
13351
|
-
const hasMore = task.goal.length > 160 || Boolean(task.result) || Boolean(task.resultMetadata);
|
|
13352
|
-
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";
|
|
13353
|
-
return /* @__PURE__ */ jsx(Collapsible, { open, onOpenChange: setOpen, asChild: true, children: /* @__PURE__ */ jsxs("li", { className: "rounded border border-border/40 text-sm", children: [
|
|
13354
|
-
/* @__PURE__ */ jsx(
|
|
13355
|
-
CollapsibleTrigger,
|
|
13356
|
-
{
|
|
13357
|
-
asChild: true,
|
|
13358
|
-
disabled: !hasMore,
|
|
13359
|
-
children: /* @__PURE__ */ jsxs(
|
|
13360
|
-
"button",
|
|
13361
|
-
{
|
|
13362
|
-
type: "button",
|
|
13363
|
-
className: "flex w-full items-start gap-3 px-3 py-2 text-left hover:bg-muted/30 disabled:hover:bg-transparent",
|
|
13364
|
-
children: [
|
|
13365
|
-
/* @__PURE__ */ jsx(
|
|
13366
|
-
ChevronRight,
|
|
13367
|
-
{
|
|
13368
|
-
className: `mt-0.5 size-3.5 shrink-0 text-muted-foreground/60 transition-transform ${open ? "rotate-90" : ""} ${hasMore ? "" : "opacity-0"}`
|
|
13369
|
-
}
|
|
13370
|
-
),
|
|
13371
|
-
/* @__PURE__ */ jsx(
|
|
13372
|
-
"span",
|
|
13373
|
-
{
|
|
13374
|
-
className: `shrink-0 rounded border px-1.5 py-0.5 font-mono text-[9px] uppercase tracking-wide ${statusTone}`,
|
|
13375
|
-
children: task.status
|
|
13376
|
-
}
|
|
13377
|
-
),
|
|
13378
|
-
task.agentDefName ? /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[10px] text-muted-foreground/70", children: task.agentDefName }) : null,
|
|
13379
|
-
task.attemptCount > 1 ? /* @__PURE__ */ jsxs("span", { className: "shrink-0 text-[10px] text-muted-foreground/60", children: [
|
|
13380
|
-
"(",
|
|
13381
|
-
task.attemptCount,
|
|
13382
|
-
"/",
|
|
13383
|
-
task.maxAttempts,
|
|
13384
|
-
")"
|
|
13385
|
-
] }) : null,
|
|
13386
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-foreground/80", children: goalPreview })
|
|
13387
|
-
]
|
|
13388
|
-
}
|
|
13389
|
-
)
|
|
13390
|
-
}
|
|
13391
|
-
),
|
|
13392
|
-
/* @__PURE__ */ jsxs(CollapsibleContent, { className: "border-t border-border/40 px-3 py-2 text-xs", children: [
|
|
13393
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
|
|
13394
|
-
/* @__PURE__ */ jsx("div", { className: "mb-1 font-mono text-[9px] uppercase tracking-wide text-muted-foreground/60", children: "Goal" }),
|
|
13395
|
-
/* @__PURE__ */ 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 })
|
|
13396
|
-
] }),
|
|
13397
|
-
task.parentIds.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "mb-2 text-[10px] text-muted-foreground/70", children: [
|
|
13398
|
-
"after: ",
|
|
13399
|
-
task.parentIds.map((p) => p.slice(0, 8)).join(", ")
|
|
13400
|
-
] }) : null,
|
|
13401
|
-
task.result ? /* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
|
|
13402
|
-
/* @__PURE__ */ jsx("div", { className: "mb-1 font-mono text-[9px] uppercase tracking-wide text-muted-foreground/60", children: "Result" }),
|
|
13403
|
-
/* @__PURE__ */ 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 })
|
|
13404
|
-
] }) : null,
|
|
13405
|
-
task.resultMetadata ? /* @__PURE__ */ jsxs("div", { children: [
|
|
13406
|
-
/* @__PURE__ */ jsx("div", { className: "mb-1 font-mono text-[9px] uppercase tracking-wide text-muted-foreground/60", children: "Result metadata" }),
|
|
13407
|
-
/* @__PURE__ */ 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) })
|
|
13408
|
-
] }) : null
|
|
13409
|
-
] })
|
|
13410
|
-
] }) });
|
|
13411
|
-
}
|
|
13412
|
-
function TasksList({
|
|
13413
|
-
taskBuckets,
|
|
13414
|
-
totalTasks
|
|
13415
|
-
}) {
|
|
13416
|
-
if (totalTasks === 0) {
|
|
13417
|
-
return /* @__PURE__ */ jsx("div", { className: "py-8 text-center text-sm text-muted-foreground/60", children: "No tasks spawned yet." });
|
|
13418
|
-
}
|
|
13419
|
-
const headings = {
|
|
13420
|
-
in_flight: "In flight",
|
|
13421
|
-
blocked: "Blocked",
|
|
13422
|
-
done: "Done",
|
|
13423
|
-
failed_or_cancelled: "Failed / cancelled"
|
|
13424
|
-
};
|
|
13425
|
-
return /* @__PURE__ */ jsx("div", { className: "space-y-4", children: Object.keys(headings).map((bucket) => {
|
|
13426
|
-
const rows = taskBuckets[bucket];
|
|
13427
|
-
if (rows.length === 0) return null;
|
|
13428
|
-
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
13429
|
-
/* @__PURE__ */ jsxs("div", { className: "font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: [
|
|
13430
|
-
headings[bucket],
|
|
13431
|
-
" (",
|
|
13432
|
-
rows.length,
|
|
13433
|
-
")"
|
|
13434
|
-
] }),
|
|
13435
|
-
/* @__PURE__ */ jsx("ul", { className: "space-y-1", children: rows.map((task) => /* @__PURE__ */ jsx(TaskRow, { task }, task.id)) })
|
|
13436
|
-
] }, bucket);
|
|
13437
|
-
}) });
|
|
13438
|
-
}
|
|
13439
|
-
function WorkersList({
|
|
13440
|
-
workers,
|
|
13441
|
-
onOpenTranscript
|
|
13442
|
-
}) {
|
|
13443
|
-
if (workers.length === 0) {
|
|
13444
|
-
return /* @__PURE__ */ jsx("div", { className: "py-8 text-center text-sm text-muted-foreground/60", children: "No workers attached to this mission right now." });
|
|
13445
|
-
}
|
|
13446
|
-
return /* @__PURE__ */ jsx("ul", { className: "space-y-1", children: workers.map((w) => {
|
|
13447
|
-
const onTranscriptClick = (e) => {
|
|
13448
|
-
if (onOpenTranscript) {
|
|
13449
|
-
e.preventDefault();
|
|
13450
|
-
onOpenTranscript(w.workerSessionId);
|
|
13451
|
-
}
|
|
13452
|
-
};
|
|
13453
|
-
return /* @__PURE__ */ jsxs(
|
|
13454
|
-
"li",
|
|
13455
|
-
{
|
|
13456
|
-
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",
|
|
13457
|
-
children: [
|
|
13458
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 space-y-1", children: [
|
|
13459
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
13460
|
-
/* @__PURE__ */ jsx(
|
|
13461
|
-
Badge,
|
|
13462
|
-
{
|
|
13463
|
-
variant: "outline",
|
|
13464
|
-
className: MISSION_WORKER_KIND_BADGE_CLASS[w.kind],
|
|
13465
|
-
title: MISSION_WORKER_KIND_TOOLTIP[w.kind],
|
|
13466
|
-
children: w.kind
|
|
13467
|
-
}
|
|
13468
|
-
),
|
|
13469
|
-
/* @__PURE__ */ jsx(Badge, { className: "text-foreground/70", children: w.kind === "task" ? w.taskStatus ?? "\u2014" : w.sessionStatus }),
|
|
13470
|
-
w.agentDefName ? /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground/70", children: w.agentDefName }) : null,
|
|
13471
|
-
w.latestEventAt ? /* @__PURE__ */ jsx("span", { className: "ml-auto font-mono text-[10px] text-muted-foreground/60", children: formatTimestamp(w.latestEventAt) }) : null
|
|
13472
|
-
] }),
|
|
13473
|
-
/* @__PURE__ */ jsx("div", { className: "truncate text-sm text-foreground/80", children: deriveMissionWorkerActivityLabel(w) })
|
|
13474
|
-
] }),
|
|
13475
|
-
/* @__PURE__ */ jsx(
|
|
13476
|
-
"a",
|
|
13477
|
-
{
|
|
13478
|
-
href: w.transcriptUrl,
|
|
13479
|
-
target: "_blank",
|
|
13480
|
-
rel: "noreferrer",
|
|
13481
|
-
onClick: onTranscriptClick,
|
|
13482
|
-
className: "self-start text-xs text-primary hover:underline",
|
|
13483
|
-
children: "View session"
|
|
13484
|
-
}
|
|
13485
|
-
)
|
|
13486
|
-
]
|
|
13487
|
-
},
|
|
13488
|
-
w.workerSessionId
|
|
13489
|
-
);
|
|
13490
|
-
}) });
|
|
13491
|
-
}
|
|
13492
|
-
function MetadataPane({ mission }) {
|
|
13493
|
-
const rows = [];
|
|
13494
|
-
rows.push({
|
|
13495
|
-
label: "Mission ID",
|
|
13496
|
-
value: /* @__PURE__ */ jsx("code", { className: "text-[11px]", children: mission.id })
|
|
13497
|
-
});
|
|
13498
|
-
rows.push({
|
|
13499
|
-
label: "Session ID",
|
|
13500
|
-
value: /* @__PURE__ */ jsx("code", { className: "text-[11px]", children: mission.sessionId })
|
|
13501
|
-
});
|
|
13502
|
-
rows.push({
|
|
13503
|
-
label: "Agent ID",
|
|
13504
|
-
value: /* @__PURE__ */ jsx("code", { className: "text-[11px]", children: mission.agentId })
|
|
13505
|
-
});
|
|
13506
|
-
rows.push({ label: "Status", value: mission.status });
|
|
13507
|
-
rows.push({
|
|
13508
|
-
label: "Iteration",
|
|
13509
|
-
value: `${mission.iteration} / ${mission.maxIterations}`
|
|
13510
|
-
});
|
|
13511
|
-
rows.push({
|
|
13512
|
-
label: "Owner",
|
|
13513
|
-
value: mission.userId ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13514
|
-
"user ",
|
|
13515
|
-
/* @__PURE__ */ jsx("code", { className: "text-[11px]", children: mission.userId })
|
|
13516
|
-
] }) : mission.serviceAccountId ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13517
|
-
"service account ",
|
|
13518
|
-
/* @__PURE__ */ jsx("code", { className: "text-[11px]", children: mission.serviceAccountId })
|
|
13519
|
-
] }) : "\u2014"
|
|
13520
|
-
});
|
|
13521
|
-
rows.push({
|
|
13522
|
-
label: "Created",
|
|
13523
|
-
value: /* @__PURE__ */ jsx("span", { className: "font-mono text-[11px]", children: new Date(mission.createdAt).toLocaleString() })
|
|
13524
|
-
});
|
|
13525
|
-
rows.push({
|
|
13526
|
-
label: "Updated",
|
|
13527
|
-
value: /* @__PURE__ */ jsx("span", { className: "font-mono text-[11px]", children: new Date(mission.updatedAt).toLocaleString() })
|
|
13528
|
-
});
|
|
13529
|
-
if (mission.pausedReason) {
|
|
13530
|
-
rows.push({ label: "Paused reason", value: mission.pausedReason });
|
|
13531
|
-
}
|
|
13532
|
-
if (mission.cancelledReason) {
|
|
13533
|
-
rows.push({ label: "Cancelled reason", value: mission.cancelledReason });
|
|
13534
|
-
}
|
|
13535
|
-
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
13536
|
-
mission.lastEvaluationResult ? /* @__PURE__ */ jsxs("section", { className: "space-y-2", children: [
|
|
13537
|
-
/* @__PURE__ */ jsxs("div", { className: "font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: [
|
|
13538
|
-
"Last verdict \u2014 ",
|
|
13539
|
-
mission.lastEvaluationResult
|
|
13540
|
-
] }),
|
|
13541
|
-
mission.lastEvaluationFeedback ? /* @__PURE__ */ jsx("p", { className: "whitespace-pre-wrap text-sm text-foreground/90", children: mission.lastEvaluationFeedback }) : null,
|
|
13542
|
-
mission.lastEvaluationExplanation ? /* @__PURE__ */ jsx("p", { className: "whitespace-pre-wrap text-xs text-muted-foreground/70", children: mission.lastEvaluationExplanation }) : null
|
|
13543
|
-
] }) : null,
|
|
13544
|
-
/* @__PURE__ */ jsxs("section", { children: [
|
|
13545
|
-
/* @__PURE__ */ jsx("div", { className: "mb-2 font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: "Identifiers" }),
|
|
13546
|
-
/* @__PURE__ */ jsx("dl", { className: "grid grid-cols-[max-content_1fr] gap-x-4 gap-y-1 text-xs", children: rows.map((r) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
13547
|
-
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground/70", children: r.label }),
|
|
13548
|
-
/* @__PURE__ */ jsx("dd", { className: "break-all text-foreground/90", children: r.value })
|
|
13549
|
-
] }, r.label)) })
|
|
13550
|
-
] })
|
|
13551
|
-
] });
|
|
13552
|
-
}
|
|
13553
14653
|
var DEFAULT_POLL_INTERVAL_MS2 = 3e4;
|
|
13554
14654
|
function fingerprint(items) {
|
|
13555
14655
|
return items.map(
|
|
@@ -13788,7 +14888,7 @@ function MissionsPanel({
|
|
|
13788
14888
|
if (!adapter.cancelMission || busyMissionId) return;
|
|
13789
14889
|
setBusyMissionId(missionId);
|
|
13790
14890
|
try {
|
|
13791
|
-
await adapter.cancelMission({ missionId });
|
|
14891
|
+
await adapter.cancelMission({ missionId, cascadeToWorkers: true });
|
|
13792
14892
|
setItems((current) => {
|
|
13793
14893
|
const next = current.filter((m) => m.id !== missionId);
|
|
13794
14894
|
lastFingerprint.current = fingerprint(next);
|
|
@@ -14574,6 +15674,6 @@ function SessionTreePanel({
|
|
|
14574
15674
|
] });
|
|
14575
15675
|
}
|
|
14576
15676
|
|
|
14577
|
-
export { ACTIVE_MISSION_STATUSES, AgentChat, AgentChatAdapterProvider, CitationText, ComposioConnectCard, InboxPanel, IntegrationsBand, IntegrationsPage, MessageResponse, MissionDashboard, MissionsPanel, ResearchSourcesPanel, ScheduledWorkPanel, SessionTreePanel, deriveMissionWorkerActivityLabel, groupMissionTasksByBucket, isTerminalMissionStatus, missionTaskBucket, splitCitations, useAgentChatAdapterContext, useAgentChatRuntime, useChatViewMode, useInboxUnreadCount };
|
|
15677
|
+
export { ACTIVE_MISSION_STATUSES, AgentChat, AgentChatAdapterProvider, CitationText, CodingAgentsPanel, ComposioConnectCard, InboxPanel, IntegrationsBand, IntegrationsPage, MISSION_EVENT_CATEGORIES, MessageResponse, MissionDashboard, MissionsPanel, ResearchSourcesPanel, ScheduledWorkPanel, SessionTreePanel, defaultSelectedMissionTaskId, deriveMissionWorkerActivityLabel, formatMissionTimestamp, groupMissionTasksByBucket, isTerminalMissionStatus, mergeMissionEvents, missionEventActorLabel, missionEventCategory, missionEventSummary, missionEventTaskId, missionTaskBlocks, missionTaskBucket, missionTaskRailGroups, missionTaskStatusDotClass, missionTaskTitle, missionWorkerTaskCounts, splitCitations, stripMissionControlMarkup, useAgentChatAdapterContext, useAgentChatRuntime, useChatViewMode, useInboxUnreadCount, useMissionEvents };
|
|
14578
15678
|
//# sourceMappingURL=index.js.map
|
|
14579
15679
|
//# sourceMappingURL=index.js.map
|