@invergent/agent-chat-react 2.0.1 → 2.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +558 -271
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +561 -271
- package/dist/index.js.map +1 -1
- package/package.json +10 -9
- package/LICENSE.AGPL-3.0 +0 -661
package/dist/index.cjs
CHANGED
|
@@ -794,29 +794,6 @@ var ConversationScrollButton = ({
|
|
|
794
794
|
);
|
|
795
795
|
};
|
|
796
796
|
|
|
797
|
-
// src/components/ui/separator.tsx
|
|
798
|
-
init_utils();
|
|
799
|
-
function Separator({
|
|
800
|
-
className,
|
|
801
|
-
orientation = "horizontal",
|
|
802
|
-
decorative = true,
|
|
803
|
-
...props
|
|
804
|
-
}) {
|
|
805
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
806
|
-
radixUi.Separator.Root,
|
|
807
|
-
{
|
|
808
|
-
"data-slot": "separator",
|
|
809
|
-
decorative,
|
|
810
|
-
orientation,
|
|
811
|
-
className: cn(
|
|
812
|
-
"shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
|
|
813
|
-
className
|
|
814
|
-
),
|
|
815
|
-
...props
|
|
816
|
-
}
|
|
817
|
-
);
|
|
818
|
-
}
|
|
819
|
-
|
|
820
797
|
// src/components/ai-elements/message.tsx
|
|
821
798
|
init_utils();
|
|
822
799
|
var Message = ({ className, from, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -5982,7 +5959,13 @@ function ChatComposerInner({
|
|
|
5982
5959
|
disabled = false,
|
|
5983
5960
|
disabledReason,
|
|
5984
5961
|
tokenUsage,
|
|
5985
|
-
onComposerError
|
|
5962
|
+
onComposerError,
|
|
5963
|
+
showBrowser = false,
|
|
5964
|
+
onToggleBrowser,
|
|
5965
|
+
showWorkspace = false,
|
|
5966
|
+
onToggleWorkspace,
|
|
5967
|
+
canShowBrowser = false,
|
|
5968
|
+
canShowWorkspace = false
|
|
5986
5969
|
}) {
|
|
5987
5970
|
const { adapter } = useAgentChatAdapterContext();
|
|
5988
5971
|
const { textInput, attachments } = usePromptInputController();
|
|
@@ -6289,6 +6272,28 @@ function ChatComposerInner({
|
|
|
6289
6272
|
}
|
|
6290
6273
|
)
|
|
6291
6274
|
] }),
|
|
6275
|
+
canShowBrowser && onToggleBrowser && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6276
|
+
PromptInputButton,
|
|
6277
|
+
{
|
|
6278
|
+
"aria-label": showBrowser ? "Hide browser pane" : "Show browser pane",
|
|
6279
|
+
"aria-pressed": showBrowser,
|
|
6280
|
+
onClick: onToggleBrowser,
|
|
6281
|
+
tooltip: showBrowser ? "Hide browser pane" : "Show browser pane",
|
|
6282
|
+
className: showBrowser ? "bg-accent text-foreground" : void 0,
|
|
6283
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GlobeIcon, { className: "size-4" })
|
|
6284
|
+
}
|
|
6285
|
+
),
|
|
6286
|
+
canShowWorkspace && onToggleWorkspace && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6287
|
+
PromptInputButton,
|
|
6288
|
+
{
|
|
6289
|
+
"aria-label": showWorkspace ? "Hide workspace pane" : "Show workspace pane",
|
|
6290
|
+
"aria-pressed": showWorkspace,
|
|
6291
|
+
onClick: onToggleWorkspace,
|
|
6292
|
+
tooltip: showWorkspace ? "Hide workspace pane" : "Show workspace pane",
|
|
6293
|
+
className: showWorkspace ? "bg-accent text-foreground" : void 0,
|
|
6294
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FolderIcon, { className: "size-4" })
|
|
6295
|
+
}
|
|
6296
|
+
),
|
|
6292
6297
|
tokenUsage && tokenUsage.contextWindow > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6293
6298
|
Context,
|
|
6294
6299
|
{
|
|
@@ -7517,7 +7522,13 @@ function ChatThread({
|
|
|
7517
7522
|
tokenUsage,
|
|
7518
7523
|
retryIndicator,
|
|
7519
7524
|
onRetry,
|
|
7520
|
-
onComposerError
|
|
7525
|
+
onComposerError,
|
|
7526
|
+
showBrowser = false,
|
|
7527
|
+
onToggleBrowser,
|
|
7528
|
+
showWorkspace = false,
|
|
7529
|
+
onToggleWorkspace,
|
|
7530
|
+
canShowBrowser = false,
|
|
7531
|
+
canShowWorkspace = false
|
|
7521
7532
|
}) {
|
|
7522
7533
|
const groups = react.useMemo(() => groupMessages(messages), [messages]);
|
|
7523
7534
|
const artifactFallbacks = react.useMemo(() => {
|
|
@@ -7634,7 +7645,13 @@ function ChatThread({
|
|
|
7634
7645
|
disabled,
|
|
7635
7646
|
disabledReason,
|
|
7636
7647
|
tokenUsage,
|
|
7637
|
-
onComposerError
|
|
7648
|
+
onComposerError,
|
|
7649
|
+
showBrowser,
|
|
7650
|
+
onToggleBrowser,
|
|
7651
|
+
showWorkspace,
|
|
7652
|
+
onToggleWorkspace,
|
|
7653
|
+
canShowBrowser,
|
|
7654
|
+
canShowWorkspace
|
|
7638
7655
|
}
|
|
7639
7656
|
)
|
|
7640
7657
|
] })
|
|
@@ -9580,6 +9597,16 @@ function useAgentChatRuntime({
|
|
|
9580
9597
|
}));
|
|
9581
9598
|
}
|
|
9582
9599
|
}).catch(() => void 0);
|
|
9600
|
+
void adapter.getBrowserState(sessionId).then((browserState) => {
|
|
9601
|
+
if (sessionIdRef.current !== sessionId) return;
|
|
9602
|
+
setState((prev) => ({
|
|
9603
|
+
...prev,
|
|
9604
|
+
browser: browserState ? {
|
|
9605
|
+
status: browserState.status,
|
|
9606
|
+
controlOwner: browserState.controlOwner ?? null
|
|
9607
|
+
} : null
|
|
9608
|
+
}));
|
|
9609
|
+
}).catch(() => void 0);
|
|
9583
9610
|
return () => {
|
|
9584
9611
|
clearReconnectTimer();
|
|
9585
9612
|
closeStream();
|
|
@@ -9824,6 +9851,8 @@ function AgentChat({
|
|
|
9824
9851
|
}) {
|
|
9825
9852
|
const [workspacePath, setWorkspacePath] = react.useState(null);
|
|
9826
9853
|
const [mobileView, setMobileView] = react.useState("chat");
|
|
9854
|
+
const [showBrowser, setShowBrowser] = react.useState(true);
|
|
9855
|
+
const [showWorkspace, setShowWorkspace] = react.useState(true);
|
|
9827
9856
|
const runtime = useAgentChatRuntime({
|
|
9828
9857
|
adapter,
|
|
9829
9858
|
agentId,
|
|
@@ -9834,7 +9863,12 @@ function AgentChat({
|
|
|
9834
9863
|
const effectiveDisabled = disabled || isReadOnlySession;
|
|
9835
9864
|
const disabledReason = isReadOnlySession ? "Scheduled run is read-only" : void 0;
|
|
9836
9865
|
const browserState = runtime.state.browser;
|
|
9837
|
-
const
|
|
9866
|
+
const browserAvailable = browserState !== null && browserState.status !== "closed" && !!sessionId;
|
|
9867
|
+
const browserVisible = browserAvailable && showBrowser;
|
|
9868
|
+
const workspaceAvailable = !!sessionId;
|
|
9869
|
+
const workspaceVisible = workspaceAvailable && showWorkspace;
|
|
9870
|
+
const rightStackVisible = browserVisible || workspaceVisible;
|
|
9871
|
+
const bothPanesVisible = browserVisible && workspaceVisible;
|
|
9838
9872
|
react.useEffect(() => {
|
|
9839
9873
|
onMessagesChange?.(runtime.messages);
|
|
9840
9874
|
}, [onMessagesChange, runtime.messages]);
|
|
@@ -9842,11 +9876,18 @@ function AgentChat({
|
|
|
9842
9876
|
(path) => {
|
|
9843
9877
|
setWorkspacePath(path);
|
|
9844
9878
|
setMobileView("workspace");
|
|
9879
|
+
setShowWorkspace(true);
|
|
9845
9880
|
onFileSelect?.(path);
|
|
9846
9881
|
},
|
|
9847
9882
|
[onFileSelect]
|
|
9848
9883
|
);
|
|
9849
|
-
const
|
|
9884
|
+
const handleToggleBrowser = react.useCallback(() => {
|
|
9885
|
+
setShowBrowser((prev) => !prev);
|
|
9886
|
+
}, []);
|
|
9887
|
+
const handleToggleWorkspace = react.useCallback(() => {
|
|
9888
|
+
setShowWorkspace((prev) => !prev);
|
|
9889
|
+
}, []);
|
|
9890
|
+
const showMobileToggle = rightStackVisible;
|
|
9850
9891
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9851
9892
|
AgentChatAdapterProvider,
|
|
9852
9893
|
{
|
|
@@ -9864,8 +9905,11 @@ function AgentChat({
|
|
|
9864
9905
|
// Phone: flex column, tab toggle on top, then either chat or
|
|
9865
9906
|
// right stack visible based on `data-mobile-view`.
|
|
9866
9907
|
"flex min-h-0 flex-1 flex-col overflow-hidden bg-background text-sm text-foreground",
|
|
9867
|
-
// md+: restore desktop two-pane layout
|
|
9868
|
-
|
|
9908
|
+
// md+: restore desktop two-pane layout when the right stack
|
|
9909
|
+
// is visible. With both panes, absolute positioning lets the
|
|
9910
|
+
// browser/workspace split occupy a fixed width. Without the
|
|
9911
|
+
// right stack, the chat takes the full width.
|
|
9912
|
+
browserVisible ? "md:relative md:flex-row" : "md:flex-row"
|
|
9869
9913
|
),
|
|
9870
9914
|
style: { direction: "ltr", ...RIGHT_STACK_STYLE },
|
|
9871
9915
|
children: [
|
|
@@ -9906,8 +9950,13 @@ function AgentChat({
|
|
|
9906
9950
|
// Phone: full width column, hidden when workspace tab active.
|
|
9907
9951
|
"flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden",
|
|
9908
9952
|
showMobileToggle && "data-[mobile-view=workspace]:hidden md:flex!",
|
|
9909
|
-
// md+:
|
|
9910
|
-
|
|
9953
|
+
// md+: positioning depends on whether the browser/workspace
|
|
9954
|
+
// right stack is laid out. When the browser pane is shown
|
|
9955
|
+
// we pin a fixed-width column on the right and absolutely
|
|
9956
|
+
// position the chat panel beside it. Otherwise the chat
|
|
9957
|
+
// panel just flexes alongside the workspace (or fills the
|
|
9958
|
+
// space when nothing else is visible).
|
|
9959
|
+
browserVisible ? "md:absolute md:inset-y-0 md:left-0 md:right-(--right-stack-w,440px) md:flex" : "md:relative md:flex-1"
|
|
9911
9960
|
),
|
|
9912
9961
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9913
9962
|
ChatThread,
|
|
@@ -9924,12 +9973,18 @@ function AgentChat({
|
|
|
9924
9973
|
disabledReason,
|
|
9925
9974
|
tokenUsage: runtime.tokenUsage,
|
|
9926
9975
|
retryIndicator: runtime.retryIndicator,
|
|
9927
|
-
onComposerError
|
|
9976
|
+
onComposerError,
|
|
9977
|
+
showBrowser,
|
|
9978
|
+
onToggleBrowser: handleToggleBrowser,
|
|
9979
|
+
showWorkspace,
|
|
9980
|
+
onToggleWorkspace: handleToggleWorkspace,
|
|
9981
|
+
canShowBrowser: browserAvailable,
|
|
9982
|
+
canShowWorkspace: workspaceAvailable
|
|
9928
9983
|
}
|
|
9929
9984
|
)
|
|
9930
9985
|
}
|
|
9931
9986
|
),
|
|
9932
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
9987
|
+
rightStackVisible && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9933
9988
|
"div",
|
|
9934
9989
|
{
|
|
9935
9990
|
"data-testid": "right-stack",
|
|
@@ -9938,17 +9993,23 @@ function AgentChat({
|
|
|
9938
9993
|
// Phone: full width column, hidden when chat tab active.
|
|
9939
9994
|
"flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden",
|
|
9940
9995
|
showMobileToggle && "data-[mobile-view=chat]:hidden md:flex!",
|
|
9941
|
-
// md+:
|
|
9942
|
-
//
|
|
9943
|
-
//
|
|
9944
|
-
|
|
9996
|
+
// md+: positioning differs depending on what is inside.
|
|
9997
|
+
// - browser visible (with or without workspace): absolute
|
|
9998
|
+
// right column at the configured width.
|
|
9999
|
+
// - workspace only: relative shrink-0 column letting
|
|
10000
|
+
// WorkspacePanel manage its own width via the resize
|
|
10001
|
+
// handle.
|
|
10002
|
+
browserVisible ? "md:absolute md:inset-y-0 md:right-0 md:w-(--right-stack-w,440px) md:flex-none" : "md:relative md:shrink-0 md:flex-none md:w-auto"
|
|
9945
10003
|
),
|
|
9946
10004
|
children: [
|
|
9947
|
-
|
|
10005
|
+
browserVisible && /* @__PURE__ */ jsxRuntime.jsx(
|
|
9948
10006
|
"div",
|
|
9949
10007
|
{
|
|
9950
10008
|
"data-testid": "browser-panel",
|
|
9951
|
-
className:
|
|
10009
|
+
className: cn(
|
|
10010
|
+
"min-h-0 w-full overflow-hidden",
|
|
10011
|
+
bothPanesVisible ? "h-1/2 border-b border-line" : "h-full"
|
|
10012
|
+
),
|
|
9952
10013
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9953
10014
|
BrowserPane,
|
|
9954
10015
|
{
|
|
@@ -9959,11 +10020,11 @@ function AgentChat({
|
|
|
9959
10020
|
)
|
|
9960
10021
|
}
|
|
9961
10022
|
),
|
|
9962
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
10023
|
+
workspaceVisible && /* @__PURE__ */ jsxRuntime.jsx(
|
|
9963
10024
|
"div",
|
|
9964
10025
|
{
|
|
9965
10026
|
"data-testid": "workspace-panel-frame",
|
|
9966
|
-
className:
|
|
10027
|
+
className: bothPanesVisible ? "h-1/2 min-h-0 w-full overflow-hidden" : "min-h-0 h-full",
|
|
9967
10028
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9968
10029
|
WorkspacePanel,
|
|
9969
10030
|
{
|
|
@@ -9973,7 +10034,7 @@ function AgentChat({
|
|
|
9973
10034
|
onSelectedPathChange: setWorkspacePath,
|
|
9974
10035
|
refreshSignal: runtime.workspaceRefreshKey,
|
|
9975
10036
|
disabled: effectiveDisabled,
|
|
9976
|
-
fillParent:
|
|
10037
|
+
fillParent: bothPanesVisible
|
|
9977
10038
|
}
|
|
9978
10039
|
)
|
|
9979
10040
|
}
|
|
@@ -10687,42 +10748,6 @@ function Card({
|
|
|
10687
10748
|
}
|
|
10688
10749
|
);
|
|
10689
10750
|
}
|
|
10690
|
-
function CardHeader({ className, ...props }) {
|
|
10691
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10692
|
-
"div",
|
|
10693
|
-
{
|
|
10694
|
-
"data-slot": "card-header",
|
|
10695
|
-
className: cn(
|
|
10696
|
-
"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",
|
|
10697
|
-
className
|
|
10698
|
-
),
|
|
10699
|
-
...props
|
|
10700
|
-
}
|
|
10701
|
-
);
|
|
10702
|
-
}
|
|
10703
|
-
function CardTitle({ className, ...props }) {
|
|
10704
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10705
|
-
"div",
|
|
10706
|
-
{
|
|
10707
|
-
"data-slot": "card-title",
|
|
10708
|
-
className: cn(
|
|
10709
|
-
"font-heading text-lg font-semibold tracking-wider uppercase",
|
|
10710
|
-
className
|
|
10711
|
-
),
|
|
10712
|
-
...props
|
|
10713
|
-
}
|
|
10714
|
-
);
|
|
10715
|
-
}
|
|
10716
|
-
function CardDescription({ className, ...props }) {
|
|
10717
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10718
|
-
"div",
|
|
10719
|
-
{
|
|
10720
|
-
"data-slot": "card-description",
|
|
10721
|
-
className: cn("text-sm leading-relaxed text-muted-foreground", className),
|
|
10722
|
-
...props
|
|
10723
|
-
}
|
|
10724
|
-
);
|
|
10725
|
-
}
|
|
10726
10751
|
function CardContent({ className, ...props }) {
|
|
10727
10752
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10728
10753
|
"div",
|
|
@@ -10790,6 +10815,97 @@ var MISSION_WORKER_KIND_TOOLTIP = {
|
|
|
10790
10815
|
worker: "Async one-shot session spawned by spawn_worker. Durable session, no retry/DAG.",
|
|
10791
10816
|
delegation: "Sync fork-join child spawned by delegate_task. Coordinator's wake blocked until it finished."
|
|
10792
10817
|
};
|
|
10818
|
+
function CountBadge({ n }) {
|
|
10819
|
+
if (n === 0) return null;
|
|
10820
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 rounded bg-muted px-1 py-px text-[9px] text-muted-foreground/70", children: n });
|
|
10821
|
+
}
|
|
10822
|
+
function firstLine3(text, max = 140) {
|
|
10823
|
+
const trimmed = text.replace(/\s+/g, " ").trim();
|
|
10824
|
+
if (trimmed.length <= max) return trimmed;
|
|
10825
|
+
return `${trimmed.slice(0, max).trimEnd()}\u2026`;
|
|
10826
|
+
}
|
|
10827
|
+
var ACTIVITY_KIND_TONE = {
|
|
10828
|
+
"mission.defined": "bg-primary/10 text-primary border-primary/30",
|
|
10829
|
+
"mission.paused": "bg-amber-500/10 text-amber-600 border-amber-500/30",
|
|
10830
|
+
"mission.cancelled": "bg-destructive/10 text-destructive border-destructive/30",
|
|
10831
|
+
"task.spawned": "bg-foreground/5 text-foreground/80 border-foreground/20",
|
|
10832
|
+
"task.completed": "bg-emerald-500/10 text-emerald-600 border-emerald-500/30",
|
|
10833
|
+
"task.failed": "bg-destructive/10 text-destructive border-destructive/30",
|
|
10834
|
+
"task.cancelled": "bg-muted text-muted-foreground border-border",
|
|
10835
|
+
"worker.latest": "bg-foreground/5 text-foreground/70 border-foreground/15",
|
|
10836
|
+
"evaluator.verdict": "bg-primary/10 text-primary border-primary/30"
|
|
10837
|
+
};
|
|
10838
|
+
function buildMissionActivity(mission, tasks, workers) {
|
|
10839
|
+
const entries = [];
|
|
10840
|
+
entries.push({
|
|
10841
|
+
at: mission.createdAt,
|
|
10842
|
+
kind: "mission.defined",
|
|
10843
|
+
label: "Mission defined",
|
|
10844
|
+
detail: mission.description
|
|
10845
|
+
});
|
|
10846
|
+
if (mission.status === "paused" && mission.pausedReason) {
|
|
10847
|
+
entries.push({
|
|
10848
|
+
at: mission.updatedAt,
|
|
10849
|
+
kind: "mission.paused",
|
|
10850
|
+
label: "Paused",
|
|
10851
|
+
detail: mission.pausedReason
|
|
10852
|
+
});
|
|
10853
|
+
}
|
|
10854
|
+
if (mission.status === "cancelled" && mission.cancelledReason) {
|
|
10855
|
+
entries.push({
|
|
10856
|
+
at: mission.updatedAt,
|
|
10857
|
+
kind: "mission.cancelled",
|
|
10858
|
+
label: "Cancelled",
|
|
10859
|
+
detail: mission.cancelledReason
|
|
10860
|
+
});
|
|
10861
|
+
}
|
|
10862
|
+
for (const task of tasks) {
|
|
10863
|
+
if (task.createdAt) {
|
|
10864
|
+
entries.push({
|
|
10865
|
+
at: task.createdAt,
|
|
10866
|
+
kind: "task.spawned",
|
|
10867
|
+
label: `Spawn \xB7 ${task.agentDefName ?? "task"}`,
|
|
10868
|
+
detail: firstLine3(task.goal, 200)
|
|
10869
|
+
});
|
|
10870
|
+
}
|
|
10871
|
+
if (task.completedAt) {
|
|
10872
|
+
const kind = task.status === "done" ? "task.completed" : task.status === "failed" ? "task.failed" : task.status === "cancelled" ? "task.cancelled" : "task.completed";
|
|
10873
|
+
entries.push({
|
|
10874
|
+
at: task.completedAt,
|
|
10875
|
+
kind,
|
|
10876
|
+
label: `${task.status} \xB7 ${task.agentDefName ?? "task"}`,
|
|
10877
|
+
detail: task.result ? firstLine3(task.result, 200) : void 0
|
|
10878
|
+
});
|
|
10879
|
+
}
|
|
10880
|
+
}
|
|
10881
|
+
for (const worker of workers) {
|
|
10882
|
+
if (worker.latestEventAt && worker.latestEventKind) {
|
|
10883
|
+
entries.push({
|
|
10884
|
+
at: worker.latestEventAt,
|
|
10885
|
+
kind: "worker.latest",
|
|
10886
|
+
label: `${worker.kind} \xB7 ${worker.latestEventKind}`,
|
|
10887
|
+
detail: deriveMissionWorkerActivityLabel(worker)
|
|
10888
|
+
});
|
|
10889
|
+
}
|
|
10890
|
+
}
|
|
10891
|
+
if (mission.lastEvaluationAt && mission.lastEvaluationResult) {
|
|
10892
|
+
entries.push({
|
|
10893
|
+
at: mission.lastEvaluationAt,
|
|
10894
|
+
kind: "evaluator.verdict",
|
|
10895
|
+
label: `Verdict \xB7 ${mission.lastEvaluationResult}`,
|
|
10896
|
+
detail: mission.lastEvaluationFeedback ?? void 0
|
|
10897
|
+
});
|
|
10898
|
+
}
|
|
10899
|
+
entries.sort((a, b) => b.at.localeCompare(a.at));
|
|
10900
|
+
return entries;
|
|
10901
|
+
}
|
|
10902
|
+
function formatTimestamp(iso) {
|
|
10903
|
+
try {
|
|
10904
|
+
return new Date(iso).toLocaleTimeString();
|
|
10905
|
+
} catch {
|
|
10906
|
+
return iso;
|
|
10907
|
+
}
|
|
10908
|
+
}
|
|
10793
10909
|
var INITIAL_STATE = {
|
|
10794
10910
|
mission: null,
|
|
10795
10911
|
tasks: [],
|
|
@@ -10942,210 +11058,153 @@ function MissionDashboard({
|
|
|
10942
11058
|
setBusy(false);
|
|
10943
11059
|
}
|
|
10944
11060
|
};
|
|
10945
|
-
const
|
|
10946
|
-
|
|
10947
|
-
|
|
10948
|
-
|
|
10949
|
-
|
|
10950
|
-
|
|
10951
|
-
|
|
10952
|
-
|
|
10953
|
-
|
|
10954
|
-
|
|
10955
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1 pt-2 text-xs text-foreground/70", children: [
|
|
10956
|
-
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant, className: "font-mono text-foreground", children: mission.status }),
|
|
10957
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono text-primary", children: [
|
|
10958
|
-
"Iteration ",
|
|
10959
|
-
mission.iteration,
|
|
10960
|
-
"/",
|
|
10961
|
-
mission.maxIterations
|
|
10962
|
-
] }),
|
|
10963
|
-
mission.lastEvaluationResult ? /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
10964
|
-
"Last verdict:",
|
|
10965
|
-
" ",
|
|
10966
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-primary", children: mission.lastEvaluationResult })
|
|
10967
|
-
] }) : null
|
|
10968
|
-
] })
|
|
10969
|
-
] }),
|
|
10970
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-2 shrink-0", children: ACTIVE_MISSION_STATUSES.has(mission.status) ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
10971
|
-
mission.status === "active" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10972
|
-
Button,
|
|
10973
|
-
{
|
|
10974
|
-
size: "sm",
|
|
10975
|
-
variant: "outline",
|
|
10976
|
-
onClick: doPause,
|
|
10977
|
-
disabled: busy,
|
|
10978
|
-
children: [
|
|
10979
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pause, { className: "size-4" }),
|
|
10980
|
-
" Pause"
|
|
10981
|
-
]
|
|
10982
|
-
}
|
|
10983
|
-
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10984
|
-
Button,
|
|
11061
|
+
const statusTone = mission.status === "satisfied" ? "border-emerald-500/40 bg-emerald-500/10 text-emerald-700 dark:text-emerald-400" : mission.status === "failed" || mission.status === "cancelled" ? "border-destructive/40 bg-destructive/10 text-destructive" : mission.status === "paused" ? "border-amber-500/40 bg-amber-500/10 text-amber-700 dark:text-amber-400" : "border-primary/40 bg-primary/10 text-primary";
|
|
11062
|
+
const activity = buildMissionActivity(mission, state.tasks, state.workers);
|
|
11063
|
+
const isActive = ACTIVE_MISSION_STATUSES.has(mission.status);
|
|
11064
|
+
const iterationPct = mission.maxIterations > 0 ? Math.min(100, mission.iteration / mission.maxIterations * 100) : 0;
|
|
11065
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { delayDuration: 300, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-1 flex-col overflow-hidden bg-muted/30", children: [
|
|
11066
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 px-5 pt-5 sm:px-6 sm:pt-6", children: /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "border-border/60 bg-card shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: "space-y-4 p-5 sm:p-6", children: [
|
|
11067
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [
|
|
11068
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
11069
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11070
|
+
"span",
|
|
10985
11071
|
{
|
|
10986
|
-
|
|
10987
|
-
|
|
10988
|
-
onClick: doResume,
|
|
10989
|
-
disabled: busy,
|
|
10990
|
-
children: [
|
|
10991
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Play, { className: "size-4" }),
|
|
10992
|
-
" Resume"
|
|
10993
|
-
]
|
|
11072
|
+
className: `rounded-md border px-2 py-0.5 font-mono text-[10px] font-semibold uppercase tracking-wider ${statusTone}`,
|
|
11073
|
+
children: mission.status
|
|
10994
11074
|
}
|
|
10995
11075
|
),
|
|
10996
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
11076
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-1.5", children: [
|
|
11077
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-display text-2xl font-bold tracking-tight tabular-nums text-foreground", children: mission.iteration }),
|
|
11078
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-muted-foreground/70", children: [
|
|
11079
|
+
"/ ",
|
|
11080
|
+
mission.maxIterations
|
|
11081
|
+
] }),
|
|
11082
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-[10px] uppercase tracking-wider text-muted-foreground/60", children: "iterations" })
|
|
11083
|
+
] }),
|
|
11084
|
+
mission.lastEvaluationResult ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-[11px] text-muted-foreground/70", children: [
|
|
11085
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "opacity-70", children: "last verdict" }),
|
|
11086
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded border border-primary/30 bg-primary/10 px-1.5 py-0.5 font-mono text-[10px] uppercase tracking-wider text-primary", children: mission.lastEvaluationResult })
|
|
11087
|
+
] }) : null
|
|
11088
|
+
] }),
|
|
11089
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 flex-wrap items-center gap-2", children: [
|
|
11090
|
+
isActive ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
11091
|
+
mission.status === "active" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11092
|
+
Button,
|
|
11093
|
+
{
|
|
11094
|
+
size: "sm",
|
|
11095
|
+
variant: "outline",
|
|
11096
|
+
onClick: doPause,
|
|
11097
|
+
disabled: busy,
|
|
11098
|
+
children: [
|
|
11099
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pause, { className: "size-4" }),
|
|
11100
|
+
" Pause"
|
|
11101
|
+
]
|
|
11102
|
+
}
|
|
11103
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11104
|
+
Button,
|
|
11105
|
+
{
|
|
11106
|
+
size: "sm",
|
|
11107
|
+
variant: "outline",
|
|
11108
|
+
onClick: doResume,
|
|
11109
|
+
disabled: busy,
|
|
11110
|
+
children: [
|
|
11111
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Play, { className: "size-4" }),
|
|
11112
|
+
" Resume"
|
|
11113
|
+
]
|
|
11114
|
+
}
|
|
11115
|
+
),
|
|
11116
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
11117
|
+
Button,
|
|
11118
|
+
{
|
|
11119
|
+
size: "sm",
|
|
11120
|
+
variant: "destructive",
|
|
11121
|
+
onClick: () => {
|
|
11122
|
+
setCancelCascade(false);
|
|
11123
|
+
setCancelOpen(true);
|
|
11124
|
+
},
|
|
11125
|
+
disabled: busy,
|
|
11126
|
+
children: [
|
|
11127
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Ban, { className: "size-4" }),
|
|
11128
|
+
" Cancel"
|
|
11129
|
+
]
|
|
11130
|
+
}
|
|
11131
|
+
)
|
|
11132
|
+
] }) : onNavigateBack ? /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", variant: "outline", onClick: onNavigateBack, children: "Back" }) : null,
|
|
11133
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
10997
11134
|
Button,
|
|
10998
11135
|
{
|
|
11136
|
+
variant: "ghost",
|
|
10999
11137
|
size: "sm",
|
|
11000
|
-
|
|
11001
|
-
onClick: () => {
|
|
11002
|
-
setCancelCascade(false);
|
|
11003
|
-
setCancelOpen(true);
|
|
11004
|
-
},
|
|
11138
|
+
onClick: () => void refresh(),
|
|
11005
11139
|
disabled: busy,
|
|
11006
|
-
|
|
11007
|
-
|
|
11008
|
-
|
|
11009
|
-
]
|
|
11140
|
+
"aria-label": "Refresh",
|
|
11141
|
+
title: "Refresh",
|
|
11142
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "size-4" })
|
|
11010
11143
|
}
|
|
11011
11144
|
)
|
|
11012
|
-
] })
|
|
11013
|
-
] }) }),
|
|
11014
|
-
mission.lastEvaluationFeedback ? /* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: "space-y-2", children: [
|
|
11015
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-semibold uppercase tracking-widest text-foreground/70", children: "Evaluator feedback" }),
|
|
11016
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm whitespace-pre-wrap wrap-break-word", children: mission.lastEvaluationFeedback }),
|
|
11017
|
-
mission.lastEvaluationExplanation ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-foreground/70 whitespace-pre-wrap wrap-break-word", children: mission.lastEvaluationExplanation }) : null
|
|
11018
|
-
] }) : null
|
|
11019
|
-
] }),
|
|
11020
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Card, { children: [
|
|
11021
|
-
/* @__PURE__ */ jsxRuntime.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(CardTitle, { children: [
|
|
11022
|
-
"Tasks (",
|
|
11023
|
-
state.tasks.length,
|
|
11024
|
-
")"
|
|
11025
|
-
] }) }),
|
|
11026
|
-
/* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: "space-y-4", children: [
|
|
11027
|
-
["in_flight", "blocked", "done", "failed_or_cancelled"].map((bucket) => {
|
|
11028
|
-
const rows = taskBuckets[bucket];
|
|
11029
|
-
if (rows.length === 0) return null;
|
|
11030
|
-
const heading = {
|
|
11031
|
-
in_flight: "In flight",
|
|
11032
|
-
blocked: "Blocked",
|
|
11033
|
-
done: "Done",
|
|
11034
|
-
failed_or_cancelled: "Failed / cancelled"
|
|
11035
|
-
}[bucket];
|
|
11036
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
11037
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs font-semibold uppercase tracking-widest text-foreground/70", children: [
|
|
11038
|
-
heading,
|
|
11039
|
-
" (",
|
|
11040
|
-
rows.length,
|
|
11041
|
-
")"
|
|
11042
|
-
] }),
|
|
11043
|
-
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-1.5", children: rows.map((task) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
11044
|
-
"li",
|
|
11045
|
-
{
|
|
11046
|
-
className: "flex items-start justify-between gap-3 rounded border border-border/40 px-3 py-2 text-sm",
|
|
11047
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 space-y-1", children: [
|
|
11048
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
11049
|
-
task.agentDefName ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-foreground/70", children: task.agentDefName }) : null,
|
|
11050
|
-
task.attemptCount > 1 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-foreground/70", children: [
|
|
11051
|
-
"attempt ",
|
|
11052
|
-
task.attemptCount,
|
|
11053
|
-
"/",
|
|
11054
|
-
task.maxAttempts
|
|
11055
|
-
] }) : null
|
|
11056
|
-
] }),
|
|
11057
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm wrap-break-word", children: task.goal }),
|
|
11058
|
-
task.parentIds.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-foreground/70", children: [
|
|
11059
|
-
"after:",
|
|
11060
|
-
" ",
|
|
11061
|
-
task.parentIds.map((p) => p.slice(0, 8)).join(", ")
|
|
11062
|
-
] }) : null,
|
|
11063
|
-
task.result ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs whitespace-pre-wrap bg-muted/30 rounded px-2 py-1 max-h-32 overflow-auto", children: task.result }) : null,
|
|
11064
|
-
task.resultMetadata ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-xs whitespace-pre-wrap bg-muted/30 rounded px-2 py-1 max-h-32 overflow-auto", children: JSON.stringify(task.resultMetadata, null, 2) }) : null
|
|
11065
|
-
] })
|
|
11066
|
-
},
|
|
11067
|
-
task.id
|
|
11068
|
-
)) })
|
|
11069
|
-
] }, bucket);
|
|
11070
|
-
}),
|
|
11071
|
-
state.tasks.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-foreground/70", children: "No tasks spawned yet." }) : null
|
|
11072
|
-
] })
|
|
11073
|
-
] }),
|
|
11074
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Card, { children: [
|
|
11075
|
-
/* @__PURE__ */ jsxRuntime.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(CardTitle, { children: [
|
|
11076
|
-
"Live workers (",
|
|
11077
|
-
state.workers.length,
|
|
11078
|
-
")"
|
|
11079
|
-
] }) }),
|
|
11080
|
-
/* @__PURE__ */ jsxRuntime.jsx(CardContent, { children: state.workers.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-foreground/70", children: "No workers attached to this mission right now." }) : /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-1.5", children: state.workers.map((w) => {
|
|
11081
|
-
const onTranscriptClick = (e) => {
|
|
11082
|
-
if (onOpenTranscript) {
|
|
11083
|
-
e.preventDefault();
|
|
11084
|
-
onOpenTranscript(w.workerSessionId);
|
|
11085
|
-
}
|
|
11086
|
-
};
|
|
11087
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11088
|
-
"li",
|
|
11089
|
-
{
|
|
11090
|
-
className: "flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between rounded border border-border/40 px-3 py-2 text-sm",
|
|
11091
|
-
children: [
|
|
11092
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 space-y-1", children: [
|
|
11093
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
11094
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11095
|
-
Badge,
|
|
11096
|
-
{
|
|
11097
|
-
variant: "outline",
|
|
11098
|
-
className: MISSION_WORKER_KIND_BADGE_CLASS[w.kind],
|
|
11099
|
-
title: MISSION_WORKER_KIND_TOOLTIP[w.kind],
|
|
11100
|
-
children: w.kind
|
|
11101
|
-
}
|
|
11102
|
-
),
|
|
11103
|
-
/* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "text-foreground/70", children: w.kind === "task" ? w.taskStatus ?? "\u2014" : w.sessionStatus }),
|
|
11104
|
-
w.agentDefName ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-foreground/70", children: w.agentDefName }) : null
|
|
11105
|
-
] }),
|
|
11106
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm wrap-break-word", children: deriveMissionWorkerActivityLabel(w) }),
|
|
11107
|
-
w.latestEventAt ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-foreground/70", children: new Date(w.latestEventAt).toLocaleTimeString() }) : null
|
|
11108
|
-
] }),
|
|
11109
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11110
|
-
"a",
|
|
11111
|
-
{
|
|
11112
|
-
href: w.transcriptUrl,
|
|
11113
|
-
target: "_blank",
|
|
11114
|
-
rel: "noreferrer",
|
|
11115
|
-
onClick: onTranscriptClick,
|
|
11116
|
-
className: "text-xs text-primary hover:underline self-start",
|
|
11117
|
-
children: "View session"
|
|
11118
|
-
}
|
|
11119
|
-
)
|
|
11120
|
-
]
|
|
11121
|
-
},
|
|
11122
|
-
w.workerSessionId
|
|
11123
|
-
);
|
|
11124
|
-
}) }) })
|
|
11125
|
-
] }),
|
|
11126
|
-
/* @__PURE__ */ jsxRuntime.jsx(Separator, {}),
|
|
11127
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center text-xs text-foreground/70", children: [
|
|
11128
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
11129
|
-
"Auto-refresh every ",
|
|
11130
|
-
pollIntervalMs / 1e3,
|
|
11131
|
-
"s while mission is active."
|
|
11145
|
+
] })
|
|
11132
11146
|
] }),
|
|
11133
|
-
/* @__PURE__ */ jsxRuntime.
|
|
11134
|
-
|
|
11147
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11148
|
+
Progress,
|
|
11135
11149
|
{
|
|
11136
|
-
|
|
11137
|
-
|
|
11138
|
-
onClick: () => {
|
|
11139
|
-
void refresh();
|
|
11140
|
-
},
|
|
11141
|
-
disabled: busy,
|
|
11142
|
-
children: [
|
|
11143
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "size-4" }),
|
|
11144
|
-
" Refresh"
|
|
11145
|
-
]
|
|
11150
|
+
value: iterationPct,
|
|
11151
|
+
className: `h-1 ${isActive ? "" : "opacity-40"}`
|
|
11146
11152
|
}
|
|
11147
|
-
)
|
|
11148
|
-
|
|
11153
|
+
),
|
|
11154
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
11155
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "line-clamp-4 cursor-default font-display text-lg font-semibold leading-snug text-foreground wrap-break-word", children: mission.description }) }),
|
|
11156
|
+
mission.description.length > 240 ? /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { className: "max-w-lg", side: "bottom", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap text-xs", children: mission.description }) }) : null
|
|
11157
|
+
] }) }),
|
|
11158
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-md border border-border/60 bg-muted/40 px-3 py-2", children: [
|
|
11159
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-0.5 font-mono text-[9px] uppercase tracking-widest text-muted-foreground/70", children: "Rubric" }),
|
|
11160
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
11161
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "line-clamp-3 cursor-default text-sm leading-relaxed text-foreground/90 wrap-break-word", children: mission.rubric }) }),
|
|
11162
|
+
mission.rubric.length > 200 ? /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { className: "max-w-lg", side: "bottom", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap text-xs", children: mission.rubric }) }) : null
|
|
11163
|
+
] })
|
|
11164
|
+
] })
|
|
11165
|
+
] }) }) }),
|
|
11166
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
11167
|
+
Tabs,
|
|
11168
|
+
{
|
|
11169
|
+
defaultValue: "activity",
|
|
11170
|
+
className: "mt-5 flex flex-1 flex-col overflow-hidden sm:mt-6",
|
|
11171
|
+
children: [
|
|
11172
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 border-b border-border bg-background px-5 sm:px-6", children: /* @__PURE__ */ jsxRuntime.jsxs(TabsList, { variant: "line", children: [
|
|
11173
|
+
/* @__PURE__ */ jsxRuntime.jsxs(TabsTrigger, { value: "activity", children: [
|
|
11174
|
+
"Activity",
|
|
11175
|
+
/* @__PURE__ */ jsxRuntime.jsx(CountBadge, { n: activity.length })
|
|
11176
|
+
] }),
|
|
11177
|
+
/* @__PURE__ */ jsxRuntime.jsxs(TabsTrigger, { value: "tasks", children: [
|
|
11178
|
+
"Tasks",
|
|
11179
|
+
/* @__PURE__ */ jsxRuntime.jsx(CountBadge, { n: state.tasks.length })
|
|
11180
|
+
] }),
|
|
11181
|
+
/* @__PURE__ */ jsxRuntime.jsxs(TabsTrigger, { value: "workers", children: [
|
|
11182
|
+
"Workers",
|
|
11183
|
+
/* @__PURE__ */ jsxRuntime.jsx(CountBadge, { n: state.workers.length })
|
|
11184
|
+
] }),
|
|
11185
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: "metadata", children: "Metadata" })
|
|
11186
|
+
] }) }),
|
|
11187
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto bg-background px-5 py-4 sm:px-6", children: [
|
|
11188
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value: "activity", className: "mt-0", children: /* @__PURE__ */ jsxRuntime.jsx(ActivityTimeline, { entries: activity }) }),
|
|
11189
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value: "tasks", className: "mt-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
11190
|
+
TasksList,
|
|
11191
|
+
{
|
|
11192
|
+
taskBuckets,
|
|
11193
|
+
totalTasks: state.tasks.length
|
|
11194
|
+
}
|
|
11195
|
+
) }),
|
|
11196
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value: "workers", className: "mt-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
11197
|
+
WorkersList,
|
|
11198
|
+
{
|
|
11199
|
+
workers: state.workers,
|
|
11200
|
+
onOpenTranscript
|
|
11201
|
+
}
|
|
11202
|
+
) }),
|
|
11203
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value: "metadata", className: "mt-0", children: /* @__PURE__ */ jsxRuntime.jsx(MetadataPane, { mission }) })
|
|
11204
|
+
] })
|
|
11205
|
+
]
|
|
11206
|
+
}
|
|
11207
|
+
),
|
|
11149
11208
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11150
11209
|
Dialog,
|
|
11151
11210
|
{
|
|
@@ -11203,6 +11262,234 @@ function MissionDashboard({
|
|
|
11203
11262
|
] })
|
|
11204
11263
|
}
|
|
11205
11264
|
)
|
|
11265
|
+
] }) });
|
|
11266
|
+
}
|
|
11267
|
+
function ActivityTimeline({ entries }) {
|
|
11268
|
+
if (entries.length === 0) {
|
|
11269
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-8 text-center text-sm text-muted-foreground/60", children: "No mission activity yet." });
|
|
11270
|
+
}
|
|
11271
|
+
return /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "space-y-1", children: entries.map((e, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11272
|
+
"li",
|
|
11273
|
+
{
|
|
11274
|
+
className: "flex items-start gap-3 rounded px-2 py-1.5 text-sm hover:bg-muted/30",
|
|
11275
|
+
children: [
|
|
11276
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-20 shrink-0 font-mono text-[10px] text-muted-foreground/60", children: formatTimestamp(e.at) }),
|
|
11277
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11278
|
+
"span",
|
|
11279
|
+
{
|
|
11280
|
+
className: `shrink-0 rounded border px-1.5 py-0.5 font-mono text-[9px] uppercase tracking-wide ${ACTIVITY_KIND_TONE[e.kind]}`,
|
|
11281
|
+
children: e.label
|
|
11282
|
+
}
|
|
11283
|
+
),
|
|
11284
|
+
e.detail ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate text-foreground/80", children: e.detail }) : null
|
|
11285
|
+
]
|
|
11286
|
+
},
|
|
11287
|
+
`${e.kind}-${e.at}-${i}`
|
|
11288
|
+
)) });
|
|
11289
|
+
}
|
|
11290
|
+
function TaskRow({ task }) {
|
|
11291
|
+
const [open, setOpen] = react.useState(false);
|
|
11292
|
+
const goalPreview = firstLine3(task.goal, 160);
|
|
11293
|
+
const hasMore = task.goal.length > 160 || Boolean(task.result) || Boolean(task.resultMetadata);
|
|
11294
|
+
const statusTone = task.status === "done" ? "border-emerald-500/30 bg-emerald-500/10 text-emerald-600" : task.status === "failed" ? "border-destructive/30 bg-destructive/10 text-destructive" : task.status === "cancelled" ? "border-border bg-muted text-muted-foreground" : task.status === "running" ? "border-primary/30 bg-primary/10 text-primary" : "border-foreground/20 bg-foreground/5 text-foreground/70";
|
|
11295
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Collapsible, { open, onOpenChange: setOpen, asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "rounded border border-border/40 text-sm", children: [
|
|
11296
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11297
|
+
CollapsibleTrigger,
|
|
11298
|
+
{
|
|
11299
|
+
asChild: true,
|
|
11300
|
+
disabled: !hasMore,
|
|
11301
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11302
|
+
"button",
|
|
11303
|
+
{
|
|
11304
|
+
type: "button",
|
|
11305
|
+
className: "flex w-full items-start gap-3 px-3 py-2 text-left hover:bg-muted/30 disabled:hover:bg-transparent",
|
|
11306
|
+
children: [
|
|
11307
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11308
|
+
lucideReact.ChevronRight,
|
|
11309
|
+
{
|
|
11310
|
+
className: `mt-0.5 size-3.5 shrink-0 text-muted-foreground/60 transition-transform ${open ? "rotate-90" : ""} ${hasMore ? "" : "opacity-0"}`
|
|
11311
|
+
}
|
|
11312
|
+
),
|
|
11313
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11314
|
+
"span",
|
|
11315
|
+
{
|
|
11316
|
+
className: `shrink-0 rounded border px-1.5 py-0.5 font-mono text-[9px] uppercase tracking-wide ${statusTone}`,
|
|
11317
|
+
children: task.status
|
|
11318
|
+
}
|
|
11319
|
+
),
|
|
11320
|
+
task.agentDefName ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-[10px] text-muted-foreground/70", children: task.agentDefName }) : null,
|
|
11321
|
+
task.attemptCount > 1 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "shrink-0 text-[10px] text-muted-foreground/60", children: [
|
|
11322
|
+
"(",
|
|
11323
|
+
task.attemptCount,
|
|
11324
|
+
"/",
|
|
11325
|
+
task.maxAttempts,
|
|
11326
|
+
")"
|
|
11327
|
+
] }) : null,
|
|
11328
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate text-foreground/80", children: goalPreview })
|
|
11329
|
+
]
|
|
11330
|
+
}
|
|
11331
|
+
)
|
|
11332
|
+
}
|
|
11333
|
+
),
|
|
11334
|
+
/* @__PURE__ */ jsxRuntime.jsxs(CollapsibleContent, { className: "border-t border-border/40 px-3 py-2 text-xs", children: [
|
|
11335
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-2", children: [
|
|
11336
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-1 font-mono text-[9px] uppercase tracking-wide text-muted-foreground/60", children: "Goal" }),
|
|
11337
|
+
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "max-h-64 overflow-auto whitespace-pre-wrap rounded bg-muted/30 px-2 py-1.5 text-[11px] text-foreground/90", children: task.goal })
|
|
11338
|
+
] }),
|
|
11339
|
+
task.parentIds.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-2 text-[10px] text-muted-foreground/70", children: [
|
|
11340
|
+
"after: ",
|
|
11341
|
+
task.parentIds.map((p) => p.slice(0, 8)).join(", ")
|
|
11342
|
+
] }) : null,
|
|
11343
|
+
task.result ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-2", children: [
|
|
11344
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-1 font-mono text-[9px] uppercase tracking-wide text-muted-foreground/60", children: "Result" }),
|
|
11345
|
+
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "max-h-64 overflow-auto whitespace-pre-wrap rounded bg-muted/30 px-2 py-1.5 text-[11px] text-foreground/90", children: task.result })
|
|
11346
|
+
] }) : null,
|
|
11347
|
+
task.resultMetadata ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
11348
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-1 font-mono text-[9px] uppercase tracking-wide text-muted-foreground/60", children: "Result metadata" }),
|
|
11349
|
+
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "max-h-64 overflow-auto whitespace-pre-wrap rounded bg-muted/30 px-2 py-1.5 text-[11px] text-foreground/90", children: JSON.stringify(task.resultMetadata, null, 2) })
|
|
11350
|
+
] }) : null
|
|
11351
|
+
] })
|
|
11352
|
+
] }) });
|
|
11353
|
+
}
|
|
11354
|
+
function TasksList({
|
|
11355
|
+
taskBuckets,
|
|
11356
|
+
totalTasks
|
|
11357
|
+
}) {
|
|
11358
|
+
if (totalTasks === 0) {
|
|
11359
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-8 text-center text-sm text-muted-foreground/60", children: "No tasks spawned yet." });
|
|
11360
|
+
}
|
|
11361
|
+
const headings = {
|
|
11362
|
+
in_flight: "In flight",
|
|
11363
|
+
blocked: "Blocked",
|
|
11364
|
+
done: "Done",
|
|
11365
|
+
failed_or_cancelled: "Failed / cancelled"
|
|
11366
|
+
};
|
|
11367
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4", children: Object.keys(headings).map((bucket) => {
|
|
11368
|
+
const rows = taskBuckets[bucket];
|
|
11369
|
+
if (rows.length === 0) return null;
|
|
11370
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
|
|
11371
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: [
|
|
11372
|
+
headings[bucket],
|
|
11373
|
+
" (",
|
|
11374
|
+
rows.length,
|
|
11375
|
+
")"
|
|
11376
|
+
] }),
|
|
11377
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-1", children: rows.map((task) => /* @__PURE__ */ jsxRuntime.jsx(TaskRow, { task }, task.id)) })
|
|
11378
|
+
] }, bucket);
|
|
11379
|
+
}) });
|
|
11380
|
+
}
|
|
11381
|
+
function WorkersList({
|
|
11382
|
+
workers,
|
|
11383
|
+
onOpenTranscript
|
|
11384
|
+
}) {
|
|
11385
|
+
if (workers.length === 0) {
|
|
11386
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-8 text-center text-sm text-muted-foreground/60", children: "No workers attached to this mission right now." });
|
|
11387
|
+
}
|
|
11388
|
+
return /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-1", children: workers.map((w) => {
|
|
11389
|
+
const onTranscriptClick = (e) => {
|
|
11390
|
+
if (onOpenTranscript) {
|
|
11391
|
+
e.preventDefault();
|
|
11392
|
+
onOpenTranscript(w.workerSessionId);
|
|
11393
|
+
}
|
|
11394
|
+
};
|
|
11395
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11396
|
+
"li",
|
|
11397
|
+
{
|
|
11398
|
+
className: "flex flex-col gap-2 rounded border border-border/40 px-3 py-2 text-sm sm:flex-row sm:items-start sm:justify-between",
|
|
11399
|
+
children: [
|
|
11400
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 space-y-1", children: [
|
|
11401
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
11402
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11403
|
+
Badge,
|
|
11404
|
+
{
|
|
11405
|
+
variant: "outline",
|
|
11406
|
+
className: MISSION_WORKER_KIND_BADGE_CLASS[w.kind],
|
|
11407
|
+
title: MISSION_WORKER_KIND_TOOLTIP[w.kind],
|
|
11408
|
+
children: w.kind
|
|
11409
|
+
}
|
|
11410
|
+
),
|
|
11411
|
+
/* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "text-foreground/70", children: w.kind === "task" ? w.taskStatus ?? "\u2014" : w.sessionStatus }),
|
|
11412
|
+
w.agentDefName ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground/70", children: w.agentDefName }) : null,
|
|
11413
|
+
w.latestEventAt ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto font-mono text-[10px] text-muted-foreground/60", children: formatTimestamp(w.latestEventAt) }) : null
|
|
11414
|
+
] }),
|
|
11415
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-sm text-foreground/80", children: deriveMissionWorkerActivityLabel(w) })
|
|
11416
|
+
] }),
|
|
11417
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11418
|
+
"a",
|
|
11419
|
+
{
|
|
11420
|
+
href: w.transcriptUrl,
|
|
11421
|
+
target: "_blank",
|
|
11422
|
+
rel: "noreferrer",
|
|
11423
|
+
onClick: onTranscriptClick,
|
|
11424
|
+
className: "self-start text-xs text-primary hover:underline",
|
|
11425
|
+
children: "View session"
|
|
11426
|
+
}
|
|
11427
|
+
)
|
|
11428
|
+
]
|
|
11429
|
+
},
|
|
11430
|
+
w.workerSessionId
|
|
11431
|
+
);
|
|
11432
|
+
}) });
|
|
11433
|
+
}
|
|
11434
|
+
function MetadataPane({ mission }) {
|
|
11435
|
+
const rows = [];
|
|
11436
|
+
rows.push({
|
|
11437
|
+
label: "Mission ID",
|
|
11438
|
+
value: /* @__PURE__ */ jsxRuntime.jsx("code", { className: "text-[11px]", children: mission.id })
|
|
11439
|
+
});
|
|
11440
|
+
rows.push({
|
|
11441
|
+
label: "Session ID",
|
|
11442
|
+
value: /* @__PURE__ */ jsxRuntime.jsx("code", { className: "text-[11px]", children: mission.sessionId })
|
|
11443
|
+
});
|
|
11444
|
+
rows.push({
|
|
11445
|
+
label: "Agent ID",
|
|
11446
|
+
value: /* @__PURE__ */ jsxRuntime.jsx("code", { className: "text-[11px]", children: mission.agentId })
|
|
11447
|
+
});
|
|
11448
|
+
rows.push({ label: "Status", value: mission.status });
|
|
11449
|
+
rows.push({
|
|
11450
|
+
label: "Iteration",
|
|
11451
|
+
value: `${mission.iteration} / ${mission.maxIterations}`
|
|
11452
|
+
});
|
|
11453
|
+
rows.push({
|
|
11454
|
+
label: "Owner",
|
|
11455
|
+
value: mission.userId ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
11456
|
+
"user ",
|
|
11457
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "text-[11px]", children: mission.userId })
|
|
11458
|
+
] }) : mission.serviceAccountId ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
11459
|
+
"service account ",
|
|
11460
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "text-[11px]", children: mission.serviceAccountId })
|
|
11461
|
+
] }) : "\u2014"
|
|
11462
|
+
});
|
|
11463
|
+
rows.push({
|
|
11464
|
+
label: "Created",
|
|
11465
|
+
value: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[11px]", children: new Date(mission.createdAt).toLocaleString() })
|
|
11466
|
+
});
|
|
11467
|
+
rows.push({
|
|
11468
|
+
label: "Updated",
|
|
11469
|
+
value: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[11px]", children: new Date(mission.updatedAt).toLocaleString() })
|
|
11470
|
+
});
|
|
11471
|
+
if (mission.pausedReason) {
|
|
11472
|
+
rows.push({ label: "Paused reason", value: mission.pausedReason });
|
|
11473
|
+
}
|
|
11474
|
+
if (mission.cancelledReason) {
|
|
11475
|
+
rows.push({ label: "Cancelled reason", value: mission.cancelledReason });
|
|
11476
|
+
}
|
|
11477
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
|
|
11478
|
+
mission.lastEvaluationResult ? /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-2", children: [
|
|
11479
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: [
|
|
11480
|
+
"Last verdict \u2014 ",
|
|
11481
|
+
mission.lastEvaluationResult
|
|
11482
|
+
] }),
|
|
11483
|
+
mission.lastEvaluationFeedback ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap text-sm text-foreground/90", children: mission.lastEvaluationFeedback }) : null,
|
|
11484
|
+
mission.lastEvaluationExplanation ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap text-xs text-muted-foreground/70", children: mission.lastEvaluationExplanation }) : null
|
|
11485
|
+
] }) : null,
|
|
11486
|
+
/* @__PURE__ */ jsxRuntime.jsxs("section", { children: [
|
|
11487
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2 font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: "Identifiers" }),
|
|
11488
|
+
/* @__PURE__ */ jsxRuntime.jsx("dl", { className: "grid grid-cols-[max-content_1fr] gap-x-4 gap-y-1 text-xs", children: rows.map((r) => /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
|
|
11489
|
+
/* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-muted-foreground/70", children: r.label }),
|
|
11490
|
+
/* @__PURE__ */ jsxRuntime.jsx("dd", { className: "break-all text-foreground/90", children: r.value })
|
|
11491
|
+
] }, r.label)) })
|
|
11492
|
+
] })
|
|
11206
11493
|
] });
|
|
11207
11494
|
}
|
|
11208
11495
|
init_utils();
|