@invergent/agent-chat-react 2.7.0 → 2.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +477 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +101 -2
- package/dist/index.d.ts +101 -2
- package/dist/index.js +478 -21
- 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, __publicField } from './chunk-47MF6JUW.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, 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';
|
|
3
|
+
import { ChevronDownIcon, AlertTriangle, ChevronDown, ChevronRight, RefreshCw, CreditCard, 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';
|
|
@@ -4663,6 +4663,74 @@ function AttachmentChip({
|
|
|
4663
4663
|
}
|
|
4664
4664
|
);
|
|
4665
4665
|
}
|
|
4666
|
+
function tokenizeInline(text) {
|
|
4667
|
+
const tokens = [];
|
|
4668
|
+
let buf = "";
|
|
4669
|
+
let i = 0;
|
|
4670
|
+
const flush = () => {
|
|
4671
|
+
if (buf) {
|
|
4672
|
+
tokens.push({ kind: "text", value: buf });
|
|
4673
|
+
buf = "";
|
|
4674
|
+
}
|
|
4675
|
+
};
|
|
4676
|
+
while (i < text.length) {
|
|
4677
|
+
const ch = text[i];
|
|
4678
|
+
if (ch === "`") {
|
|
4679
|
+
const end = text.indexOf("`", i + 1);
|
|
4680
|
+
if (end > i) {
|
|
4681
|
+
flush();
|
|
4682
|
+
tokens.push({ kind: "code", value: text.slice(i + 1, end) });
|
|
4683
|
+
i = end + 1;
|
|
4684
|
+
continue;
|
|
4685
|
+
}
|
|
4686
|
+
}
|
|
4687
|
+
if (ch === "*" && text[i + 1] === "*") {
|
|
4688
|
+
const end = text.indexOf("**", i + 2);
|
|
4689
|
+
if (end > i + 1) {
|
|
4690
|
+
flush();
|
|
4691
|
+
tokens.push({ kind: "strong", value: text.slice(i + 2, end) });
|
|
4692
|
+
i = end + 2;
|
|
4693
|
+
continue;
|
|
4694
|
+
}
|
|
4695
|
+
}
|
|
4696
|
+
if (ch === "*") {
|
|
4697
|
+
const end = text.indexOf("*", i + 1);
|
|
4698
|
+
if (end > i + 1) {
|
|
4699
|
+
flush();
|
|
4700
|
+
tokens.push({ kind: "em", value: text.slice(i + 1, end) });
|
|
4701
|
+
i = end + 1;
|
|
4702
|
+
continue;
|
|
4703
|
+
}
|
|
4704
|
+
}
|
|
4705
|
+
buf += ch;
|
|
4706
|
+
i += 1;
|
|
4707
|
+
}
|
|
4708
|
+
flush();
|
|
4709
|
+
return tokens;
|
|
4710
|
+
}
|
|
4711
|
+
function renderInlineMarkdown(text) {
|
|
4712
|
+
if (!text || !/[*`]/.test(text)) return text ?? null;
|
|
4713
|
+
const tokens = tokenizeInline(text);
|
|
4714
|
+
return tokens.map((tok, idx) => {
|
|
4715
|
+
switch (tok.kind) {
|
|
4716
|
+
case "strong":
|
|
4717
|
+
return /* @__PURE__ */ jsx("strong", { className: "font-semibold", children: tok.value }, idx);
|
|
4718
|
+
case "em":
|
|
4719
|
+
return /* @__PURE__ */ jsx("em", { children: tok.value }, idx);
|
|
4720
|
+
case "code":
|
|
4721
|
+
return /* @__PURE__ */ jsx(
|
|
4722
|
+
"code",
|
|
4723
|
+
{
|
|
4724
|
+
className: "rounded bg-muted px-1 py-0.5 font-mono text-[0.9em]",
|
|
4725
|
+
children: tok.value
|
|
4726
|
+
},
|
|
4727
|
+
idx
|
|
4728
|
+
);
|
|
4729
|
+
default:
|
|
4730
|
+
return /* @__PURE__ */ jsx(Fragment$1, { children: tok.value }, idx);
|
|
4731
|
+
}
|
|
4732
|
+
});
|
|
4733
|
+
}
|
|
4666
4734
|
function InputGroup({ className, ...props }) {
|
|
4667
4735
|
return /* @__PURE__ */ jsx(
|
|
4668
4736
|
"div",
|
|
@@ -6066,6 +6134,7 @@ function ChatComposerInner({
|
|
|
6066
6134
|
canShowBrowser = false,
|
|
6067
6135
|
canShowWorkspace = false,
|
|
6068
6136
|
deepResearchEnabled = false,
|
|
6137
|
+
researchEnabled = false,
|
|
6069
6138
|
codeAgentsEnabled = false,
|
|
6070
6139
|
viewMode = "simple",
|
|
6071
6140
|
onViewModeChange
|
|
@@ -6136,6 +6205,13 @@ function ChatComposerInner({
|
|
|
6136
6205
|
description: "Delegate a topic to the deep-research workflow"
|
|
6137
6206
|
});
|
|
6138
6207
|
}
|
|
6208
|
+
if (researchEnabled) {
|
|
6209
|
+
base.push({
|
|
6210
|
+
value: "/auto-research ",
|
|
6211
|
+
label: "/auto-research",
|
|
6212
|
+
description: "Launch an autonomous research mission (Arbor)"
|
|
6213
|
+
});
|
|
6214
|
+
}
|
|
6139
6215
|
if (codeAgentsEnabled) {
|
|
6140
6216
|
base.push(
|
|
6141
6217
|
{ value: "/code claude ", label: "/code claude", description: "Run Claude Code on the workspace (your plan)" },
|
|
@@ -6147,7 +6223,7 @@ function ChatComposerInner({
|
|
|
6147
6223
|
}
|
|
6148
6224
|
return base;
|
|
6149
6225
|
},
|
|
6150
|
-
[deepResearchEnabled, codeAgentsEnabled]
|
|
6226
|
+
[deepResearchEnabled, researchEnabled, codeAgentsEnabled]
|
|
6151
6227
|
);
|
|
6152
6228
|
const scheduledExamples = useMemo(
|
|
6153
6229
|
() => [
|
|
@@ -7668,6 +7744,16 @@ var ErrorMessage = memo(function ErrorMessage2({
|
|
|
7668
7744
|
const [detailOpen, setDetailOpen] = useState(false);
|
|
7669
7745
|
const [retryPending, setRetryPending] = useState(false);
|
|
7670
7746
|
const [retryError, setRetryError] = useState(null);
|
|
7747
|
+
if (errorInfo.insufficientCredits) {
|
|
7748
|
+
return /* @__PURE__ */ jsx(
|
|
7749
|
+
InsufficientCreditsCard,
|
|
7750
|
+
{
|
|
7751
|
+
detail: errorInfo.detail,
|
|
7752
|
+
onDismiss,
|
|
7753
|
+
className
|
|
7754
|
+
}
|
|
7755
|
+
);
|
|
7756
|
+
}
|
|
7671
7757
|
const showRetry = errorInfo.retryable && !!onRetry;
|
|
7672
7758
|
const handleRetry = async () => {
|
|
7673
7759
|
if (!onRetry) return;
|
|
@@ -7739,6 +7825,46 @@ var ErrorMessage = memo(function ErrorMessage2({
|
|
|
7739
7825
|
}
|
|
7740
7826
|
);
|
|
7741
7827
|
});
|
|
7828
|
+
function parseRequestedTokens(detail) {
|
|
7829
|
+
const m = detail.match(/["']?requested["']?\s*[:=]\s*(\d+)/);
|
|
7830
|
+
return m ? Number(m[1]) : null;
|
|
7831
|
+
}
|
|
7832
|
+
var InsufficientCreditsCard = memo(function InsufficientCreditsCard2({
|
|
7833
|
+
detail,
|
|
7834
|
+
onDismiss,
|
|
7835
|
+
className
|
|
7836
|
+
}) {
|
|
7837
|
+
const { onOpenBilling } = useAgentChatAdapterContext();
|
|
7838
|
+
const requested = parseRequestedTokens(detail);
|
|
7839
|
+
return /* @__PURE__ */ jsxs(
|
|
7840
|
+
"div",
|
|
7841
|
+
{
|
|
7842
|
+
role: "alert",
|
|
7843
|
+
className: cn(
|
|
7844
|
+
"flex w-full gap-3 rounded-md border border-amber-500/30 bg-amber-500/5 p-4",
|
|
7845
|
+
className
|
|
7846
|
+
),
|
|
7847
|
+
children: [
|
|
7848
|
+
/* @__PURE__ */ jsx(CreditCard, { className: "mt-0.5 size-5 shrink-0 text-amber-600 dark:text-amber-400" }),
|
|
7849
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-2", children: [
|
|
7850
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-foreground", children: "You're out of credits" }),
|
|
7851
|
+
/* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
7852
|
+
"This run was blocked by the token-credit limit",
|
|
7853
|
+
requested ? ` (it needed ~${requested.toLocaleString()} tokens)` : "",
|
|
7854
|
+
". Buy additional credits or upgrade your plan to keep your agents running."
|
|
7855
|
+
] }),
|
|
7856
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2 pt-1", children: [
|
|
7857
|
+
onOpenBilling && /* @__PURE__ */ jsxs(Button, { size: "sm", onClick: onOpenBilling, children: [
|
|
7858
|
+
/* @__PURE__ */ jsx(CreditCard, { className: "size-4" }),
|
|
7859
|
+
"Go to Billing"
|
|
7860
|
+
] }),
|
|
7861
|
+
onDismiss && /* @__PURE__ */ jsx(Button, { size: "sm", variant: "ghost", onClick: onDismiss, children: "Dismiss" })
|
|
7862
|
+
] })
|
|
7863
|
+
] })
|
|
7864
|
+
]
|
|
7865
|
+
}
|
|
7866
|
+
);
|
|
7867
|
+
});
|
|
7742
7868
|
var SKELETON_WIDTHS = [70, 85, 55, 90, 60, 78, 45, 82, 65, 72];
|
|
7743
7869
|
var PDF_WORKER_SRC = new URL(
|
|
7744
7870
|
"pdfjs-dist/legacy/build/pdf.worker.mjs",
|
|
@@ -8756,7 +8882,11 @@ function cancelledToolLabel(toolName) {
|
|
|
8756
8882
|
research_memory: "Research",
|
|
8757
8883
|
research_outline: "Research",
|
|
8758
8884
|
generate_image: "image generation",
|
|
8759
|
-
generate_video: "video generation"
|
|
8885
|
+
generate_video: "video generation",
|
|
8886
|
+
// Arbor research-mission tools (the /auto-research coordinator loop).
|
|
8887
|
+
idea_tree: "Idea tree",
|
|
8888
|
+
dispatch_experiments: "Dispatch experiments",
|
|
8889
|
+
merge_experiment: "Merge experiment"
|
|
8760
8890
|
};
|
|
8761
8891
|
if (map[toolName]) return map[toolName];
|
|
8762
8892
|
if (toolName.startsWith("mcp__")) return formatMcpToolLabel(toolName);
|
|
@@ -8933,7 +9063,7 @@ function NarrationEntry({
|
|
|
8933
9063
|
/* @__PURE__ */ jsx(TimelineSeparator, { style: { backgroundColor: "var(--color-border)" } }),
|
|
8934
9064
|
/* @__PURE__ */ jsx(TimelineIndicator, { className: "size-2 border-none bg-foreground/30" })
|
|
8935
9065
|
] }),
|
|
8936
|
-
/* @__PURE__ */ jsx(TimelineContent, { children: /* @__PURE__ */ jsx("p", { children: line }) })
|
|
9066
|
+
/* @__PURE__ */ jsx(TimelineContent, { children: /* @__PURE__ */ jsx("p", { children: renderInlineMarkdown(line) }) })
|
|
8937
9067
|
] });
|
|
8938
9068
|
}
|
|
8939
9069
|
function TextEntry({
|
|
@@ -9049,6 +9179,17 @@ function extractToolDetail(tc) {
|
|
|
9049
9179
|
const prompt = stringArg("prompt");
|
|
9050
9180
|
return prompt ? truncate3(prompt, 60) : null;
|
|
9051
9181
|
}
|
|
9182
|
+
case "idea_tree":
|
|
9183
|
+
return stringArg("action");
|
|
9184
|
+
case "dispatch_experiments": {
|
|
9185
|
+
const keys = args.node_keys;
|
|
9186
|
+
if (Array.isArray(keys) && keys.length > 0) {
|
|
9187
|
+
return truncate3(keys.map((k) => String(k)).join(", "), 40);
|
|
9188
|
+
}
|
|
9189
|
+
return stringArg("action");
|
|
9190
|
+
}
|
|
9191
|
+
case "merge_experiment":
|
|
9192
|
+
return stringArg("node_key") ?? stringArg("action");
|
|
9052
9193
|
case "memory":
|
|
9053
9194
|
return stringArg("action") ?? stringArg("key");
|
|
9054
9195
|
case "research_memory": {
|
|
@@ -9350,7 +9491,7 @@ function IterationGroup({
|
|
|
9350
9491
|
"aria-expanded": open,
|
|
9351
9492
|
className: "flex w-full items-center gap-2 rounded py-0.5 text-left text-sm hover:bg-muted/40",
|
|
9352
9493
|
children: [
|
|
9353
|
-
/* @__PURE__ */ jsx("span", { className: cn("flex-1 truncate", labelTone), children: label }),
|
|
9494
|
+
/* @__PURE__ */ jsx("span", { className: cn("flex-1 truncate", labelTone), children: renderInlineMarkdown(label) }),
|
|
9354
9495
|
/* @__PURE__ */ jsx(
|
|
9355
9496
|
ChevronDown,
|
|
9356
9497
|
{
|
|
@@ -9477,7 +9618,7 @@ function SimpleAssistantGroup({
|
|
|
9477
9618
|
const narrationLine = action ? action.body.trim().toLowerCase() === "done" ? null : action.body : inferredNarration;
|
|
9478
9619
|
const askBody = hasUserFacingAskContent(message) ? cleaned : null;
|
|
9479
9620
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
9480
|
-
askBody ? /* @__PURE__ */ jsx(MessageResponse, { children: askBody }) : narrationLine ? /* @__PURE__ */ jsx("p", { className: "text-sm text-foreground", children: narrationLine }) : null,
|
|
9621
|
+
askBody ? /* @__PURE__ */ jsx(MessageResponse, { children: askBody }) : narrationLine ? /* @__PURE__ */ jsx("p", { className: "text-sm text-foreground", children: renderInlineMarkdown(narrationLine) }) : null,
|
|
9481
9622
|
/* @__PURE__ */ jsx(
|
|
9482
9623
|
IterationGroup,
|
|
9483
9624
|
{
|
|
@@ -9639,6 +9780,7 @@ function ChatThread({
|
|
|
9639
9780
|
viewMode = "simple",
|
|
9640
9781
|
onViewModeChange,
|
|
9641
9782
|
deepResearchEnabled = false,
|
|
9783
|
+
researchEnabled = false,
|
|
9642
9784
|
codeAgentsEnabled = false,
|
|
9643
9785
|
researchSources = [],
|
|
9644
9786
|
hideTurnSummary = false,
|
|
@@ -9705,6 +9847,7 @@ function ChatThread({
|
|
|
9705
9847
|
viewMode,
|
|
9706
9848
|
onViewModeChange,
|
|
9707
9849
|
deepResearchEnabled,
|
|
9850
|
+
researchEnabled,
|
|
9708
9851
|
codeAgentsEnabled
|
|
9709
9852
|
}
|
|
9710
9853
|
),
|
|
@@ -10539,6 +10682,9 @@ var AGENT_CHAT_LISTENED_EVENTS = [
|
|
|
10539
10682
|
"iteration.summary",
|
|
10540
10683
|
"turn.summary"
|
|
10541
10684
|
];
|
|
10685
|
+
var AGENT_CHAT_LISTENED_EVENT_SET = new Set(
|
|
10686
|
+
AGENT_CHAT_LISTENED_EVENTS
|
|
10687
|
+
);
|
|
10542
10688
|
|
|
10543
10689
|
// src/runtime/reducer.ts
|
|
10544
10690
|
var EMPTY_TOKEN_USAGE = {
|
|
@@ -10561,6 +10707,7 @@ function createInitialAgentChatState(options = {}) {
|
|
|
10561
10707
|
sessionDone: false,
|
|
10562
10708
|
hadDeltas: false,
|
|
10563
10709
|
terminal: false,
|
|
10710
|
+
stopped: false,
|
|
10564
10711
|
workspaceRefreshKey: 0,
|
|
10565
10712
|
browser: null,
|
|
10566
10713
|
viewMode: options.viewMode ?? "simple",
|
|
@@ -10575,13 +10722,13 @@ function applyAgentChatEvent(state, event) {
|
|
|
10575
10722
|
sessionDone: state.sessionDone || event.type === "session.done"
|
|
10576
10723
|
};
|
|
10577
10724
|
nextState = applyRetryIndicator(nextState, event);
|
|
10578
|
-
if (state.
|
|
10725
|
+
if (state.stopped && isPostTerminalLiveEvent(event.type)) {
|
|
10579
10726
|
return nextState;
|
|
10580
10727
|
}
|
|
10581
10728
|
switch (event.type) {
|
|
10582
10729
|
case "user.message":
|
|
10583
10730
|
return withMessages(
|
|
10584
|
-
{ ...nextState, terminal: false, isRunning: true },
|
|
10731
|
+
{ ...nextState, terminal: false, stopped: false, isRunning: true },
|
|
10585
10732
|
applyUserMessage(nextState.messages, event.eventId, event.data)
|
|
10586
10733
|
);
|
|
10587
10734
|
case "skill.invoked":
|
|
@@ -11204,13 +11351,21 @@ function buildErrorInfo(event) {
|
|
|
11204
11351
|
if (event.type !== "session.fail" || typeof event.data.error_category !== "string") {
|
|
11205
11352
|
return void 0;
|
|
11206
11353
|
}
|
|
11354
|
+
const detail = stringValue2(event.data.error_detail) || stringValue2(event.data.error);
|
|
11355
|
+
const insufficientCredits = isInsufficientCreditsError(detail);
|
|
11207
11356
|
return {
|
|
11208
11357
|
category: event.data.error_category,
|
|
11209
|
-
title: stringValue2(event.data.error_title) || "The session failed due to an internal error.",
|
|
11210
|
-
detail
|
|
11211
|
-
|
|
11358
|
+
title: insufficientCredits ? "You're out of credits" : stringValue2(event.data.error_title) || "The session failed due to an internal error.",
|
|
11359
|
+
detail,
|
|
11360
|
+
// A credit shortfall is not a transient failure — retrying just hits
|
|
11361
|
+
// the same 402. The billing CTA replaces Retry.
|
|
11362
|
+
retryable: insufficientCredits ? false : Boolean(event.data.retryable),
|
|
11363
|
+
insufficientCredits
|
|
11212
11364
|
};
|
|
11213
11365
|
}
|
|
11366
|
+
function isInsufficientCreditsError(text) {
|
|
11367
|
+
return typeof text === "string" && text.includes("insufficient_credits");
|
|
11368
|
+
}
|
|
11214
11369
|
function applyExpertResult(messages, eventId, data) {
|
|
11215
11370
|
const match = findLatestConsultExpertCall(messages);
|
|
11216
11371
|
if (!match) return messages;
|
|
@@ -11610,6 +11765,15 @@ function readTurnMeta(data) {
|
|
|
11610
11765
|
}
|
|
11611
11766
|
|
|
11612
11767
|
// src/runtime/use-agent-chat-runtime.ts
|
|
11768
|
+
var RECONCILE_FIRST_DELAY = 4e3;
|
|
11769
|
+
var RECONCILE_FAST = 1500;
|
|
11770
|
+
var RECONCILE_ACTIVE = 4e3;
|
|
11771
|
+
var RECONCILE_MISSION_IDLE = 5e3;
|
|
11772
|
+
var RECONCILE_IDLE = 15e3;
|
|
11773
|
+
function applyRuntimeEvent(prev, event) {
|
|
11774
|
+
if (event.eventId > 0 && event.eventId <= prev.lastEventId) return prev;
|
|
11775
|
+
return applyAgentChatEvent(prev, event);
|
|
11776
|
+
}
|
|
11613
11777
|
var VIEW_MODE_KEY = "@invergent/agent-chat-react:viewMode";
|
|
11614
11778
|
var VIEW_MODE_EVENT = "@invergent/agent-chat-react:viewMode:change";
|
|
11615
11779
|
function readPersistedViewMode() {
|
|
@@ -11677,6 +11841,7 @@ function useAgentChatRuntime({
|
|
|
11677
11841
|
const stateRef = useRef(state);
|
|
11678
11842
|
const streamRef = useRef(null);
|
|
11679
11843
|
const reconnectTimerRef = useRef(null);
|
|
11844
|
+
const reconcileTimerRef = useRef(null);
|
|
11680
11845
|
const previousSessionIdRef = useRef(sessionId);
|
|
11681
11846
|
const sessionIdRef = useRef(sessionId);
|
|
11682
11847
|
useEffect(() => {
|
|
@@ -11709,7 +11874,7 @@ function useAgentChatRuntime({
|
|
|
11709
11874
|
const data = parseEventData(messageEvent.data);
|
|
11710
11875
|
const eventId = messageEvent.lastEventId ? Number(messageEvent.lastEventId) : 0;
|
|
11711
11876
|
setState(
|
|
11712
|
-
(prev) =>
|
|
11877
|
+
(prev) => applyRuntimeEvent(prev, {
|
|
11713
11878
|
type: eventType,
|
|
11714
11879
|
eventId,
|
|
11715
11880
|
data
|
|
@@ -11741,12 +11906,110 @@ function useAgentChatRuntime({
|
|
|
11741
11906
|
stateRef.current = {
|
|
11742
11907
|
...stateRef.current,
|
|
11743
11908
|
sessionDone: false,
|
|
11744
|
-
terminal: false
|
|
11909
|
+
terminal: false,
|
|
11910
|
+
stopped: false
|
|
11745
11911
|
};
|
|
11746
11912
|
openStream(targetSessionId, after);
|
|
11747
11913
|
},
|
|
11748
11914
|
[clearReconnectTimer, closeStream, openStream]
|
|
11749
11915
|
);
|
|
11916
|
+
const reviveStreamIfNeeded = useCallback(
|
|
11917
|
+
(targetSessionId) => {
|
|
11918
|
+
if (streamRef.current) return;
|
|
11919
|
+
if (reconnectTimerRef.current) return;
|
|
11920
|
+
stateRef.current = { ...stateRef.current, sessionDone: false };
|
|
11921
|
+
setState(
|
|
11922
|
+
(prev) => prev.sessionDone ? { ...prev, sessionDone: false } : prev
|
|
11923
|
+
);
|
|
11924
|
+
openStream(targetSessionId, stateRef.current.lastEventId);
|
|
11925
|
+
},
|
|
11926
|
+
[openStream]
|
|
11927
|
+
);
|
|
11928
|
+
const applyPolledEvents = useCallback((events) => {
|
|
11929
|
+
if (events.length === 0) return;
|
|
11930
|
+
setState((prev) => {
|
|
11931
|
+
let next = prev;
|
|
11932
|
+
for (const event of events) {
|
|
11933
|
+
if (!AGENT_CHAT_LISTENED_EVENT_SET.has(event.type)) continue;
|
|
11934
|
+
next = applyRuntimeEvent(next, {
|
|
11935
|
+
type: event.type,
|
|
11936
|
+
eventId: event.id,
|
|
11937
|
+
data: event.data ?? {}
|
|
11938
|
+
});
|
|
11939
|
+
}
|
|
11940
|
+
return next;
|
|
11941
|
+
});
|
|
11942
|
+
}, []);
|
|
11943
|
+
const reconcileTick = useCallback(async () => {
|
|
11944
|
+
const targetSessionId = sessionIdRef.current;
|
|
11945
|
+
if (!targetSessionId) return RECONCILE_IDLE;
|
|
11946
|
+
let appliedNew = false;
|
|
11947
|
+
if (adapter.pollEvents) {
|
|
11948
|
+
let cursor = stateRef.current.lastEventId;
|
|
11949
|
+
try {
|
|
11950
|
+
for (let page = 0; page < 5; page++) {
|
|
11951
|
+
const res = await adapter.pollEvents({
|
|
11952
|
+
sessionId: targetSessionId,
|
|
11953
|
+
after: cursor,
|
|
11954
|
+
limit: 200
|
|
11955
|
+
});
|
|
11956
|
+
if (sessionIdRef.current !== targetSessionId) return RECONCILE_IDLE;
|
|
11957
|
+
const events = res.events ?? [];
|
|
11958
|
+
if (events.length === 0) break;
|
|
11959
|
+
const fresh = events.filter((event) => event.id > cursor);
|
|
11960
|
+
const known = fresh.filter(
|
|
11961
|
+
(event) => AGENT_CHAT_LISTENED_EVENT_SET.has(event.type)
|
|
11962
|
+
);
|
|
11963
|
+
if (known.length > 0) {
|
|
11964
|
+
applyPolledEvents(known);
|
|
11965
|
+
appliedNew = true;
|
|
11966
|
+
}
|
|
11967
|
+
for (const event of events) cursor = Math.max(cursor, event.id);
|
|
11968
|
+
if (!res.hasMore) break;
|
|
11969
|
+
}
|
|
11970
|
+
} catch {
|
|
11971
|
+
}
|
|
11972
|
+
}
|
|
11973
|
+
let live = false;
|
|
11974
|
+
let isMission = false;
|
|
11975
|
+
let statusKnown = false;
|
|
11976
|
+
try {
|
|
11977
|
+
const session2 = await adapter.getSession({ sessionId: targetSessionId });
|
|
11978
|
+
if (sessionIdRef.current !== targetSessionId) return RECONCILE_IDLE;
|
|
11979
|
+
statusKnown = true;
|
|
11980
|
+
live = session2.status === "active";
|
|
11981
|
+
isMission = Boolean(
|
|
11982
|
+
session2.config?.active_mission_id
|
|
11983
|
+
);
|
|
11984
|
+
} catch {
|
|
11985
|
+
}
|
|
11986
|
+
if (live) reviveStreamIfNeeded(targetSessionId);
|
|
11987
|
+
if (appliedNew) return RECONCILE_FAST;
|
|
11988
|
+
if (live || !statusKnown) return RECONCILE_ACTIVE;
|
|
11989
|
+
return isMission || stateRef.current.isRunning ? RECONCILE_MISSION_IDLE : RECONCILE_IDLE;
|
|
11990
|
+
}, [adapter, applyPolledEvents, reviveStreamIfNeeded]);
|
|
11991
|
+
useEffect(() => {
|
|
11992
|
+
if (!sessionId) return;
|
|
11993
|
+
let cancelled = false;
|
|
11994
|
+
const schedule = (delay) => {
|
|
11995
|
+
if (cancelled) return;
|
|
11996
|
+
reconcileTimerRef.current = setTimeout(() => {
|
|
11997
|
+
if (cancelled) return;
|
|
11998
|
+
void reconcileTick().catch(() => RECONCILE_ACTIVE).then((next) => {
|
|
11999
|
+
if (cancelled) return;
|
|
12000
|
+
schedule(next);
|
|
12001
|
+
});
|
|
12002
|
+
}, delay);
|
|
12003
|
+
};
|
|
12004
|
+
schedule(RECONCILE_FIRST_DELAY);
|
|
12005
|
+
return () => {
|
|
12006
|
+
cancelled = true;
|
|
12007
|
+
if (reconcileTimerRef.current) {
|
|
12008
|
+
clearTimeout(reconcileTimerRef.current);
|
|
12009
|
+
reconcileTimerRef.current = null;
|
|
12010
|
+
}
|
|
12011
|
+
};
|
|
12012
|
+
}, [sessionId, reconcileTick]);
|
|
11750
12013
|
useEffect(() => {
|
|
11751
12014
|
const previousSessionId = previousSessionIdRef.current;
|
|
11752
12015
|
previousSessionIdRef.current = sessionId;
|
|
@@ -11871,6 +12134,10 @@ function useAgentChatRuntime({
|
|
|
11871
12134
|
return {
|
|
11872
12135
|
...prev,
|
|
11873
12136
|
terminal: true,
|
|
12137
|
+
// User-initiated stop: gate the aborted turn's late in-flight
|
|
12138
|
+
// events (a natural session.complete leaves this false so an
|
|
12139
|
+
// autonomous mission resume still streams).
|
|
12140
|
+
stopped: true,
|
|
11874
12141
|
isRunning: false,
|
|
11875
12142
|
messages
|
|
11876
12143
|
};
|
|
@@ -11953,6 +12220,7 @@ function useAgentChatRuntime({
|
|
|
11953
12220
|
setState((prev) => ({
|
|
11954
12221
|
...prev,
|
|
11955
12222
|
terminal: false,
|
|
12223
|
+
stopped: false,
|
|
11956
12224
|
retryIndicator: null,
|
|
11957
12225
|
isRunning: true
|
|
11958
12226
|
}));
|
|
@@ -12080,8 +12348,10 @@ function AgentChat({
|
|
|
12080
12348
|
disabled,
|
|
12081
12349
|
onComposerError,
|
|
12082
12350
|
deepResearchEnabled = false,
|
|
12351
|
+
researchEnabled = false,
|
|
12083
12352
|
codeAgentsEnabled = false,
|
|
12084
|
-
onOpenIntegrations
|
|
12353
|
+
onOpenIntegrations,
|
|
12354
|
+
onOpenBilling
|
|
12085
12355
|
}) {
|
|
12086
12356
|
const [workspacePath, setWorkspacePath] = useState(null);
|
|
12087
12357
|
const [mobileView, setMobileView] = useState("chat");
|
|
@@ -12140,7 +12410,8 @@ function AgentChat({
|
|
|
12140
12410
|
value: {
|
|
12141
12411
|
adapter,
|
|
12142
12412
|
sessionId,
|
|
12143
|
-
onFileSelect: handleFileSelect
|
|
12413
|
+
onFileSelect: handleFileSelect,
|
|
12414
|
+
onOpenBilling
|
|
12144
12415
|
},
|
|
12145
12416
|
children: /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(
|
|
12146
12417
|
"section",
|
|
@@ -12230,6 +12501,7 @@ function AgentChat({
|
|
|
12230
12501
|
viewMode: runtime.viewMode,
|
|
12231
12502
|
onViewModeChange: runtime.setViewMode,
|
|
12232
12503
|
deepResearchEnabled,
|
|
12504
|
+
researchEnabled,
|
|
12233
12505
|
codeAgentsEnabled,
|
|
12234
12506
|
researchSources: runtime.researchSources,
|
|
12235
12507
|
hideTurnSummary,
|
|
@@ -13902,7 +14174,7 @@ function ActivityRow({
|
|
|
13902
14174
|
/* @__PURE__ */ jsx("p", { className: "shrink-0 text-xs text-foreground font-mono", children: missionEventActorLabel(event, feed.sessions) }),
|
|
13903
14175
|
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
|
|
13904
14176
|
] }),
|
|
13905
|
-
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 truncate text-foreground/80", children: missionEventSummary(event) }) })
|
|
14177
|
+
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 truncate text-foreground/80", children: renderInlineMarkdown(missionEventSummary(event)) }) })
|
|
13906
14178
|
] })
|
|
13907
14179
|
] });
|
|
13908
14180
|
}
|
|
@@ -13985,6 +14257,182 @@ function MissionMetadataTab({ mission }) {
|
|
|
13985
14257
|
] })
|
|
13986
14258
|
] });
|
|
13987
14259
|
}
|
|
14260
|
+
function compareNodes(a, b) {
|
|
14261
|
+
if (a.nodeKey === b.nodeKey) return 0;
|
|
14262
|
+
if (a.nodeKey === "ROOT") return -1;
|
|
14263
|
+
if (b.nodeKey === "ROOT") return 1;
|
|
14264
|
+
const pa = a.nodeKey.split(".").map((p) => Number.parseInt(p, 10));
|
|
14265
|
+
const pb = b.nodeKey.split(".").map((p) => Number.parseInt(p, 10));
|
|
14266
|
+
const n = Math.min(pa.length, pb.length);
|
|
14267
|
+
for (let i = 0; i < n; i += 1) {
|
|
14268
|
+
if (pa[i] !== pb[i]) return pa[i] - pb[i];
|
|
14269
|
+
}
|
|
14270
|
+
return pa.length - pb.length;
|
|
14271
|
+
}
|
|
14272
|
+
function statusToneClass(status) {
|
|
14273
|
+
switch (status) {
|
|
14274
|
+
case "merged":
|
|
14275
|
+
return "border-emerald-500/30 bg-emerald-500/10 text-emerald-700 dark:text-emerald-400";
|
|
14276
|
+
case "done":
|
|
14277
|
+
return "border-sky-500/30 bg-sky-500/10 text-sky-700 dark:text-sky-400";
|
|
14278
|
+
case "running":
|
|
14279
|
+
return "border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-400";
|
|
14280
|
+
case "failed":
|
|
14281
|
+
return "border-destructive/30 bg-destructive/10 text-destructive";
|
|
14282
|
+
case "pruned":
|
|
14283
|
+
return "border-border bg-muted/40 text-muted-foreground/70 line-through";
|
|
14284
|
+
default:
|
|
14285
|
+
return "border-border bg-muted/30 text-muted-foreground/80";
|
|
14286
|
+
}
|
|
14287
|
+
}
|
|
14288
|
+
function fmtScore(n) {
|
|
14289
|
+
if (n === null || n === void 0) return "\u2014";
|
|
14290
|
+
return n.toFixed(3).replace(/\.?0+$/, "") || "0";
|
|
14291
|
+
}
|
|
14292
|
+
function deltaLabel(score, ref, direction) {
|
|
14293
|
+
if (score === null || score === void 0 || ref === null || ref === void 0) {
|
|
14294
|
+
return null;
|
|
14295
|
+
}
|
|
14296
|
+
const raw = score - ref;
|
|
14297
|
+
const good = direction === "minimize" ? raw < 0 : raw > 0;
|
|
14298
|
+
const sign = raw > 0 ? "+" : raw < 0 ? "\u2212" : "\xB1";
|
|
14299
|
+
return { text: `${sign}${fmtScore(Math.abs(raw))}`, good };
|
|
14300
|
+
}
|
|
14301
|
+
function ScorePair({
|
|
14302
|
+
label,
|
|
14303
|
+
from,
|
|
14304
|
+
to,
|
|
14305
|
+
direction
|
|
14306
|
+
}) {
|
|
14307
|
+
const delta = deltaLabel(to, from, direction);
|
|
14308
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
14309
|
+
/* @__PURE__ */ jsx("div", { className: "font-mono text-[10px] uppercase tracking-widest text-muted-foreground/60", children: label }),
|
|
14310
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-1.5 tabular-nums", children: [
|
|
14311
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground/70", children: fmtScore(from) }),
|
|
14312
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground/40", children: "\u2192" }),
|
|
14313
|
+
/* @__PURE__ */ jsx("span", { className: "text-lg font-semibold text-foreground", children: fmtScore(to) }),
|
|
14314
|
+
delta ? /* @__PURE__ */ jsx(
|
|
14315
|
+
"span",
|
|
14316
|
+
{
|
|
14317
|
+
className: delta.good ? "text-xs font-medium text-emerald-600 dark:text-emerald-400" : "text-xs font-medium text-muted-foreground/60",
|
|
14318
|
+
children: delta.text
|
|
14319
|
+
}
|
|
14320
|
+
) : null
|
|
14321
|
+
] })
|
|
14322
|
+
] });
|
|
14323
|
+
}
|
|
14324
|
+
function RunHeader({ run }) {
|
|
14325
|
+
return /* @__PURE__ */ jsxs("section", { className: "space-y-4 rounded-md border bg-card/40 p-4", children: [
|
|
14326
|
+
run.objective ? /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground/90", children: run.objective }) : null,
|
|
14327
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
14328
|
+
/* @__PURE__ */ jsx(
|
|
14329
|
+
ScorePair,
|
|
14330
|
+
{
|
|
14331
|
+
label: "Dev (working)",
|
|
14332
|
+
from: run.baselineScore,
|
|
14333
|
+
to: run.trunkScore ?? run.baselineScore,
|
|
14334
|
+
direction: run.metricDirection
|
|
14335
|
+
}
|
|
14336
|
+
),
|
|
14337
|
+
/* @__PURE__ */ jsx(
|
|
14338
|
+
ScorePair,
|
|
14339
|
+
{
|
|
14340
|
+
label: "Held-out test (authoritative)",
|
|
14341
|
+
from: run.testBaselineScore,
|
|
14342
|
+
to: run.testTrunkScore ?? run.testBaselineScore,
|
|
14343
|
+
direction: run.metricDirection
|
|
14344
|
+
}
|
|
14345
|
+
)
|
|
14346
|
+
] }),
|
|
14347
|
+
/* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-[max-content_1fr] gap-x-4 gap-y-1 text-[11px]", children: [
|
|
14348
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground/60", children: "Status" }),
|
|
14349
|
+
/* @__PURE__ */ jsx("dd", { className: "text-foreground/80", children: run.status }),
|
|
14350
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground/60", children: "Repo" }),
|
|
14351
|
+
/* @__PURE__ */ jsx("dd", { children: /* @__PURE__ */ jsx("code", { className: "text-[11px]", children: run.repoPath }) }),
|
|
14352
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground/60", children: "Trunk" }),
|
|
14353
|
+
/* @__PURE__ */ jsx("dd", { children: /* @__PURE__ */ jsx("code", { className: "text-[11px]", children: run.trunkBranch }) }),
|
|
14354
|
+
run.evalCmd ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
14355
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground/60", children: "Dev eval" }),
|
|
14356
|
+
/* @__PURE__ */ jsx("dd", { children: /* @__PURE__ */ jsx("code", { className: "text-[11px]", children: run.evalCmd }) })
|
|
14357
|
+
] }) : null,
|
|
14358
|
+
run.evalCmdTest ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
14359
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground/60", children: "Held-out eval" }),
|
|
14360
|
+
/* @__PURE__ */ jsx("dd", { children: /* @__PURE__ */ jsx("code", { className: "text-[11px]", children: run.evalCmdTest }) })
|
|
14361
|
+
] }) : null
|
|
14362
|
+
] })
|
|
14363
|
+
] });
|
|
14364
|
+
}
|
|
14365
|
+
function IdeaRow({
|
|
14366
|
+
node,
|
|
14367
|
+
baseline,
|
|
14368
|
+
direction
|
|
14369
|
+
}) {
|
|
14370
|
+
const indent = node.nodeKey === "ROOT" ? 0 : node.depth;
|
|
14371
|
+
const delta = deltaLabel(node.score, baseline, direction);
|
|
14372
|
+
const headline = (node.hypothesis || "").split("\n")[0];
|
|
14373
|
+
const insight = node.insight ? node.insight.split("\n").slice(-1)[0] : null;
|
|
14374
|
+
return /* @__PURE__ */ jsxs(
|
|
14375
|
+
"li",
|
|
14376
|
+
{
|
|
14377
|
+
className: "flex flex-col gap-0.5 border-b border-border/40 py-2 last:border-b-0",
|
|
14378
|
+
style: { paddingLeft: `${indent * 16}px` },
|
|
14379
|
+
children: [
|
|
14380
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
14381
|
+
/* @__PURE__ */ jsx("code", { className: "shrink-0 text-[11px] text-muted-foreground/60", children: node.nodeKey }),
|
|
14382
|
+
/* @__PURE__ */ jsx(
|
|
14383
|
+
"span",
|
|
14384
|
+
{
|
|
14385
|
+
className: `shrink-0 rounded border px-1.5 py-0.5 font-mono text-[9px] uppercase tracking-wider ${statusToneClass(node.status)}`,
|
|
14386
|
+
children: node.status
|
|
14387
|
+
}
|
|
14388
|
+
),
|
|
14389
|
+
node.score !== null && node.score !== void 0 ? /* @__PURE__ */ jsxs("span", { className: "shrink-0 tabular-nums text-xs font-medium text-foreground/90", children: [
|
|
14390
|
+
fmtScore(node.score),
|
|
14391
|
+
delta ? /* @__PURE__ */ jsxs(
|
|
14392
|
+
"span",
|
|
14393
|
+
{
|
|
14394
|
+
className: delta.good ? " text-emerald-600 dark:text-emerald-400" : " text-muted-foreground/50",
|
|
14395
|
+
children: [
|
|
14396
|
+
" ",
|
|
14397
|
+
delta.text
|
|
14398
|
+
]
|
|
14399
|
+
}
|
|
14400
|
+
) : null
|
|
14401
|
+
] }) : null,
|
|
14402
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-xs text-foreground/80", title: headline, children: headline })
|
|
14403
|
+
] }),
|
|
14404
|
+
insight ? /* @__PURE__ */ jsx("p", { className: "truncate pl-[calc(1.5rem)] text-[11px] text-muted-foreground/60", title: node.insight ?? void 0, children: insight }) : null
|
|
14405
|
+
]
|
|
14406
|
+
}
|
|
14407
|
+
);
|
|
14408
|
+
}
|
|
14409
|
+
function MissionResearchTab({ research }) {
|
|
14410
|
+
const sorted = useMemo(
|
|
14411
|
+
() => [...research.nodes].sort(compareNodes),
|
|
14412
|
+
[research.nodes]
|
|
14413
|
+
);
|
|
14414
|
+
const { run } = research;
|
|
14415
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
14416
|
+
/* @__PURE__ */ jsx(RunHeader, { run }),
|
|
14417
|
+
/* @__PURE__ */ jsxs("section", { children: [
|
|
14418
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-2 font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: [
|
|
14419
|
+
"Idea Tree \xB7 ",
|
|
14420
|
+
sorted.length,
|
|
14421
|
+
" node",
|
|
14422
|
+
sorted.length === 1 ? "" : "s"
|
|
14423
|
+
] }),
|
|
14424
|
+
sorted.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground/60", children: "No hypotheses yet." }) : /* @__PURE__ */ jsx("ul", { className: "rounded-md border", children: sorted.map((n) => /* @__PURE__ */ jsx(
|
|
14425
|
+
IdeaRow,
|
|
14426
|
+
{
|
|
14427
|
+
node: n,
|
|
14428
|
+
baseline: run.baselineScore,
|
|
14429
|
+
direction: run.metricDirection
|
|
14430
|
+
},
|
|
14431
|
+
n.nodeKey
|
|
14432
|
+
)) })
|
|
14433
|
+
] })
|
|
14434
|
+
] });
|
|
14435
|
+
}
|
|
13988
14436
|
var TASK_STATUS_BADGE_CLASS = {
|
|
13989
14437
|
running: "border-primary/30 bg-primary/10 text-primary",
|
|
13990
14438
|
blocked: "border-amber-500/30 bg-amber-500/10 text-amber-600",
|
|
@@ -14190,7 +14638,7 @@ function TaskDetail({
|
|
|
14190
14638
|
/* @__PURE__ */ jsx("span", { className: "w-16 shrink-0 font-mono text-[10px] text-muted-foreground/60", children: formatMissionTimestamp(e.createdAt) }),
|
|
14191
14639
|
/* @__PURE__ */ jsxs("div", { className: "", children: [
|
|
14192
14640
|
/* @__PURE__ */ jsx("p", { className: "shrink-0 font-mono uppercase text-muted-foreground", children: missionEventCategory(e.type) }),
|
|
14193
|
-
/* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 text-foreground/80", children: missionEventSummary(e) })
|
|
14641
|
+
/* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 text-foreground/80", children: renderInlineMarkdown(missionEventSummary(e)) })
|
|
14194
14642
|
] })
|
|
14195
14643
|
] }, e.id)) })
|
|
14196
14644
|
] }) : null,
|
|
@@ -14303,7 +14751,7 @@ function OutcomeCard({ outcome }) {
|
|
|
14303
14751
|
),
|
|
14304
14752
|
outcome.timestamp ? /* @__PURE__ */ jsx(CardAction, { className: "font-mono text-[10px] text-muted-foreground/60", children: formatMissionTimestamp(outcome.timestamp) }) : null
|
|
14305
14753
|
] }),
|
|
14306
|
-
/* @__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 }) })
|
|
14754
|
+
/* @__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: renderInlineMarkdown(outcome.text) }) })
|
|
14307
14755
|
]
|
|
14308
14756
|
}
|
|
14309
14757
|
);
|
|
@@ -14473,6 +14921,7 @@ var INITIAL_STATE = {
|
|
|
14473
14921
|
mission: null,
|
|
14474
14922
|
tasks: [],
|
|
14475
14923
|
workers: [],
|
|
14924
|
+
research: null,
|
|
14476
14925
|
loading: true,
|
|
14477
14926
|
error: null
|
|
14478
14927
|
};
|
|
@@ -14515,16 +14964,19 @@ function MissionDashboard({
|
|
|
14515
14964
|
}, []);
|
|
14516
14965
|
const refresh = useCallback(async () => {
|
|
14517
14966
|
try {
|
|
14518
|
-
const
|
|
14967
|
+
const researchFn = adapter.getMissionResearch;
|
|
14968
|
+
const [mission2, tasksResp, workersResp, research] = await Promise.all([
|
|
14519
14969
|
api.getMission({ missionId }),
|
|
14520
14970
|
api.getMissionTasks({ missionId }),
|
|
14521
|
-
api.getMissionWorkers({ missionId })
|
|
14971
|
+
api.getMissionWorkers({ missionId }),
|
|
14972
|
+
researchFn ? researchFn({ missionId }).catch(() => null) : Promise.resolve(null)
|
|
14522
14973
|
]);
|
|
14523
14974
|
if (!isMounted.current) return;
|
|
14524
14975
|
setState({
|
|
14525
14976
|
mission: mission2,
|
|
14526
14977
|
tasks: tasksResp.tasks,
|
|
14527
14978
|
workers: workersResp.workers,
|
|
14979
|
+
research,
|
|
14528
14980
|
loading: false,
|
|
14529
14981
|
error: null
|
|
14530
14982
|
});
|
|
@@ -14536,7 +14988,7 @@ function MissionDashboard({
|
|
|
14536
14988
|
error: err instanceof Error ? err.message : String(err)
|
|
14537
14989
|
}));
|
|
14538
14990
|
}
|
|
14539
|
-
}, [api, missionId]);
|
|
14991
|
+
}, [adapter, api, missionId]);
|
|
14540
14992
|
useEffect(() => {
|
|
14541
14993
|
void refresh();
|
|
14542
14994
|
}, [refresh]);
|
|
@@ -14735,6 +15187,10 @@ function MissionDashboard({
|
|
|
14735
15187
|
className: "mt-5 flex flex-1 flex-col overflow-hidden sm:mt-6",
|
|
14736
15188
|
children: [
|
|
14737
15189
|
/* @__PURE__ */ jsx("div", { className: "shrink-0 border-b border-border bg-background px-5 sm:px-6", children: /* @__PURE__ */ jsxs(TabsList, { variant: "line", children: [
|
|
15190
|
+
state.research ? /* @__PURE__ */ jsxs(TabsTrigger, { value: "research", children: [
|
|
15191
|
+
"Research",
|
|
15192
|
+
/* @__PURE__ */ jsx(CountBadge, { n: state.research.nodes.length })
|
|
15193
|
+
] }) : null,
|
|
14738
15194
|
/* @__PURE__ */ jsxs(TabsTrigger, { value: "tasks", children: [
|
|
14739
15195
|
"Tasks",
|
|
14740
15196
|
/* @__PURE__ */ jsx(CountBadge, { n: state.tasks.length })
|
|
@@ -14750,6 +15206,7 @@ function MissionDashboard({
|
|
|
14750
15206
|
/* @__PURE__ */ jsx(TabsTrigger, { value: "metadata", children: "Metadata" })
|
|
14751
15207
|
] }) }),
|
|
14752
15208
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto bg-background px-5 py-4 sm:px-6", children: [
|
|
15209
|
+
state.research ? /* @__PURE__ */ jsx(TabsContent, { value: "research", className: "mt-0", children: /* @__PURE__ */ jsx(MissionResearchTab, { research: state.research }) }) : null,
|
|
14753
15210
|
/* @__PURE__ */ jsx(TabsContent, { value: "tasks", className: "mt-0 h-full", children: /* @__PURE__ */ jsx(
|
|
14754
15211
|
MissionTasksTab,
|
|
14755
15212
|
{
|