@getcatalystiq/agent-plane-ui 0.1.30 → 0.1.31
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 +641 -258
- package/dist/index.d.cts +75 -2
- package/dist/index.d.ts +75 -2
- package/dist/index.js +394 -24
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,16 +1,76 @@
|
|
|
1
1
|
import { Card, CardHeader, CardTitle, CardContent, useApi, Skeleton, FileTreeEditor } from './chunk-CE2RHDPY.js';
|
|
2
2
|
export { Card, CardContent, CardDescription, CardHeader, CardTitle, Skeleton, useApi } from './chunk-CE2RHDPY.js';
|
|
3
|
-
import { cn, Dialog, DialogContent, DialogHeader, DialogTitle, DialogBody, DialogFooter, Button, Badge, useNavigation,
|
|
3
|
+
import { cn, useAgentPlaneClient, Dialog, DialogContent, DialogHeader, DialogTitle, DialogBody, DialogFooter, Button, Badge, useNavigation, DialogDescription, FormField, Input, supportsClaudeRunner, buttonVariants } from './chunk-XFI227OB.js';
|
|
4
4
|
export { AgentPlaneProvider, Badge, Button, Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, FormField, Input, badgeVariants, buttonVariants, cn, useAgentPlaneClient, useAuthError, useNavigation } from './chunk-XFI227OB.js';
|
|
5
|
+
import * as React4 from 'react';
|
|
6
|
+
import React4__default, { lazy, useState, useRef, useCallback, useEffect, useMemo, Suspense } from 'react';
|
|
5
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
|
-
import * as React from 'react';
|
|
7
|
-
import React__default, { lazy, useState, useCallback, useMemo, useRef, useEffect, Suspense } from 'react';
|
|
8
8
|
import { useSWRConfig } from 'swr';
|
|
9
9
|
import ReactMarkdown from 'react-markdown';
|
|
10
10
|
import { Command } from 'cmdk';
|
|
11
11
|
import * as Popover from '@radix-ui/react-popover';
|
|
12
12
|
import remarkGfm from 'remark-gfm';
|
|
13
|
+
import * as ToastPrimitives from '@radix-ui/react-toast';
|
|
14
|
+
import { cva } from 'class-variance-authority';
|
|
13
15
|
|
|
16
|
+
var ACTIVE_STATUSES = /* @__PURE__ */ new Set(["running", "pending"]);
|
|
17
|
+
function useRunStream(runId, status) {
|
|
18
|
+
const client = useAgentPlaneClient();
|
|
19
|
+
const [events, setEvents] = useState([]);
|
|
20
|
+
const [isStreaming, setIsStreaming] = useState(false);
|
|
21
|
+
const [terminalEvent, setTerminalEvent] = useState(null);
|
|
22
|
+
const [streamingText, setStreamingText] = useState("");
|
|
23
|
+
const [error, setError] = useState(null);
|
|
24
|
+
const abortRef = useRef(null);
|
|
25
|
+
const startStream = useCallback(async (id, signal) => {
|
|
26
|
+
setIsStreaming(true);
|
|
27
|
+
setError(null);
|
|
28
|
+
try {
|
|
29
|
+
const stream = await client.runs.stream(id, { signal });
|
|
30
|
+
for await (const event of stream) {
|
|
31
|
+
if (signal.aborted) break;
|
|
32
|
+
if (event.type === "text_delta") {
|
|
33
|
+
const text = event.text ?? "";
|
|
34
|
+
setStreamingText((prev) => prev + text);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (event.type === "assistant") {
|
|
38
|
+
setStreamingText("");
|
|
39
|
+
}
|
|
40
|
+
if (event.type === "stream_detached") {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
setEvents((prev) => [...prev, event]);
|
|
44
|
+
if (event.type === "result" || event.type === "error") {
|
|
45
|
+
setTerminalEvent(event);
|
|
46
|
+
setIsStreaming(false);
|
|
47
|
+
setStreamingText("");
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
setIsStreaming(false);
|
|
52
|
+
} catch (err) {
|
|
53
|
+
if (signal.aborted) return;
|
|
54
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
55
|
+
setIsStreaming(false);
|
|
56
|
+
}
|
|
57
|
+
}, [client]);
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (!runId || !ACTIVE_STATUSES.has(status)) {
|
|
60
|
+
setIsStreaming(false);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (terminalEvent) return;
|
|
64
|
+
const controller = new AbortController();
|
|
65
|
+
abortRef.current = controller;
|
|
66
|
+
startStream(runId, controller.signal);
|
|
67
|
+
return () => {
|
|
68
|
+
controller.abort();
|
|
69
|
+
abortRef.current = null;
|
|
70
|
+
};
|
|
71
|
+
}, [runId, status, startStream, terminalEvent]);
|
|
72
|
+
return { events, isStreaming, terminalEvent, streamingText, error };
|
|
73
|
+
}
|
|
14
74
|
function Select({ className = "", ...props }) {
|
|
15
75
|
return /* @__PURE__ */ jsxs("div", { className: "relative w-full", children: [
|
|
16
76
|
/* @__PURE__ */ jsx(
|
|
@@ -27,7 +87,7 @@ function Select({ className = "", ...props }) {
|
|
|
27
87
|
] }) })
|
|
28
88
|
] });
|
|
29
89
|
}
|
|
30
|
-
var Textarea =
|
|
90
|
+
var Textarea = React4.forwardRef(
|
|
31
91
|
({ className, ...props }, ref) => {
|
|
32
92
|
return /* @__PURE__ */ jsx(
|
|
33
93
|
"textarea",
|
|
@@ -133,7 +193,7 @@ function PaginationBar({
|
|
|
133
193
|
return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-3 py-2 border-t border-border bg-muted/20 text-sm", children: [
|
|
134
194
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-muted-foreground", children: [
|
|
135
195
|
/* @__PURE__ */ jsx("span", { children: "Rows per page:" }),
|
|
136
|
-
PAGE_SIZE_OPTIONS.map((ps) => /* @__PURE__ */ jsx(
|
|
196
|
+
PAGE_SIZE_OPTIONS.map((ps) => /* @__PURE__ */ jsx(React4__default.Fragment, { children: renderLink(
|
|
137
197
|
buildHref(1, ps),
|
|
138
198
|
ps,
|
|
139
199
|
`px-2 py-0.5 rounded text-xs ${pageSize === ps ? "bg-primary text-primary-foreground font-medium" : "hover:bg-muted"}`
|
|
@@ -299,6 +359,102 @@ function DashboardPage({ initialData, chartComponent: ChartComponent }) {
|
|
|
299
359
|
ChartComponent && /* @__PURE__ */ jsx(ChartComponent, { stats: daily_stats })
|
|
300
360
|
] });
|
|
301
361
|
}
|
|
362
|
+
var TOAST_LIMIT = 5;
|
|
363
|
+
var TOAST_REMOVE_DELAY = 1e6;
|
|
364
|
+
var count = 0;
|
|
365
|
+
function genId() {
|
|
366
|
+
count = (count + 1) % Number.MAX_SAFE_INTEGER;
|
|
367
|
+
return count.toString();
|
|
368
|
+
}
|
|
369
|
+
var toastTimeouts = /* @__PURE__ */ new Map();
|
|
370
|
+
function addToRemoveQueue(toastId) {
|
|
371
|
+
if (toastTimeouts.has(toastId)) return;
|
|
372
|
+
const timeout = setTimeout(() => {
|
|
373
|
+
toastTimeouts.delete(toastId);
|
|
374
|
+
dispatch({ type: "REMOVE_TOAST", toastId });
|
|
375
|
+
}, TOAST_REMOVE_DELAY);
|
|
376
|
+
toastTimeouts.set(toastId, timeout);
|
|
377
|
+
}
|
|
378
|
+
function reducer(state, action) {
|
|
379
|
+
switch (action.type) {
|
|
380
|
+
case "ADD_TOAST":
|
|
381
|
+
return {
|
|
382
|
+
...state,
|
|
383
|
+
toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT)
|
|
384
|
+
};
|
|
385
|
+
case "UPDATE_TOAST":
|
|
386
|
+
return {
|
|
387
|
+
...state,
|
|
388
|
+
toasts: state.toasts.map(
|
|
389
|
+
(t) => t.id === action.toast.id ? { ...t, ...action.toast } : t
|
|
390
|
+
)
|
|
391
|
+
};
|
|
392
|
+
case "DISMISS_TOAST": {
|
|
393
|
+
const { toastId } = action;
|
|
394
|
+
if (toastId) {
|
|
395
|
+
addToRemoveQueue(toastId);
|
|
396
|
+
} else {
|
|
397
|
+
state.toasts.forEach((t) => addToRemoveQueue(t.id));
|
|
398
|
+
}
|
|
399
|
+
return {
|
|
400
|
+
...state,
|
|
401
|
+
toasts: state.toasts.map(
|
|
402
|
+
(t) => t.id === toastId || toastId === void 0 ? { ...t, open: false } : t
|
|
403
|
+
)
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
case "REMOVE_TOAST":
|
|
407
|
+
if (action.toastId === void 0) {
|
|
408
|
+
return { ...state, toasts: [] };
|
|
409
|
+
}
|
|
410
|
+
return {
|
|
411
|
+
...state,
|
|
412
|
+
toasts: state.toasts.filter((t) => t.id !== action.toastId)
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
var listeners = [];
|
|
417
|
+
var memoryState = { toasts: [] };
|
|
418
|
+
function dispatch(action) {
|
|
419
|
+
memoryState = reducer(memoryState, action);
|
|
420
|
+
listeners.forEach((listener) => listener(memoryState));
|
|
421
|
+
}
|
|
422
|
+
function toast(props) {
|
|
423
|
+
const id = genId();
|
|
424
|
+
const update = (updateProps) => dispatch({ type: "UPDATE_TOAST", toast: { ...updateProps, id } });
|
|
425
|
+
const dismiss2 = () => dispatch({ type: "DISMISS_TOAST", toastId: id });
|
|
426
|
+
dispatch({
|
|
427
|
+
type: "ADD_TOAST",
|
|
428
|
+
toast: {
|
|
429
|
+
...props,
|
|
430
|
+
id,
|
|
431
|
+
open: true,
|
|
432
|
+
onOpenChange: (open) => {
|
|
433
|
+
if (!open) dismiss2();
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
return { id, dismiss: dismiss2, update };
|
|
438
|
+
}
|
|
439
|
+
function dismiss(toastId) {
|
|
440
|
+
const action = toastId !== void 0 ? { type: "DISMISS_TOAST", toastId } : { type: "DISMISS_TOAST" };
|
|
441
|
+
dispatch(action);
|
|
442
|
+
}
|
|
443
|
+
function useToast() {
|
|
444
|
+
const [state, setState] = React4.useState(memoryState);
|
|
445
|
+
React4.useEffect(() => {
|
|
446
|
+
listeners.push(setState);
|
|
447
|
+
return () => {
|
|
448
|
+
const index = listeners.indexOf(setState);
|
|
449
|
+
if (index > -1) listeners.splice(index, 1);
|
|
450
|
+
};
|
|
451
|
+
}, [state]);
|
|
452
|
+
return {
|
|
453
|
+
...state,
|
|
454
|
+
toast,
|
|
455
|
+
dismiss
|
|
456
|
+
};
|
|
457
|
+
}
|
|
302
458
|
var SOURCES = [
|
|
303
459
|
{ value: "", label: "All Sources" },
|
|
304
460
|
{ value: "api", label: "API" },
|
|
@@ -308,11 +464,18 @@ var SOURCES = [
|
|
|
308
464
|
{ value: "a2a", label: "A2A" }
|
|
309
465
|
];
|
|
310
466
|
var VALID_SOURCES = SOURCES.filter((s) => s.value).map((s) => s.value);
|
|
467
|
+
var ACTIVE_STATUSES2 = /* @__PURE__ */ new Set(["running", "pending"]);
|
|
468
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "timed_out"]);
|
|
311
469
|
function RunListPage({ initialData }) {
|
|
312
470
|
const { LinkComponent, basePath } = useNavigation();
|
|
471
|
+
const { toast: toast2 } = useToast();
|
|
313
472
|
const [page, setPage] = useState(1);
|
|
314
473
|
const [pageSize, setPageSize] = useState(20);
|
|
315
474
|
const [sourceFilter, setSourceFilter] = useState(null);
|
|
475
|
+
const prevStatusesRef = useRef(/* @__PURE__ */ new Map());
|
|
476
|
+
const [activeRunsExist, setActiveRunsExist] = useState(
|
|
477
|
+
() => initialData?.data?.some((r) => ACTIVE_STATUSES2.has(r.status)) ?? false
|
|
478
|
+
);
|
|
316
479
|
const cacheKey = `runs-${page}-${pageSize}-${sourceFilter || "all"}`;
|
|
317
480
|
const { data, error, isLoading } = useApi(
|
|
318
481
|
cacheKey,
|
|
@@ -323,8 +486,29 @@ function RunListPage({ initialData }) {
|
|
|
323
486
|
...sourceFilter ? { triggered_by: sourceFilter } : {}
|
|
324
487
|
});
|
|
325
488
|
},
|
|
326
|
-
|
|
489
|
+
{
|
|
490
|
+
...initialData ? { fallbackData: initialData } : {},
|
|
491
|
+
refreshInterval: activeRunsExist ? 5e3 : 0
|
|
492
|
+
}
|
|
327
493
|
);
|
|
494
|
+
useEffect(() => {
|
|
495
|
+
if (!data?.data) return;
|
|
496
|
+
const prev = prevStatusesRef.current;
|
|
497
|
+
const next = /* @__PURE__ */ new Map();
|
|
498
|
+
for (const run of data.data) {
|
|
499
|
+
next.set(run.id, run.status);
|
|
500
|
+
const oldStatus = prev.get(run.id);
|
|
501
|
+
if (oldStatus && ACTIVE_STATUSES2.has(oldStatus) && TERMINAL_STATUSES.has(run.status)) {
|
|
502
|
+
toast2({
|
|
503
|
+
title: `Run ${run.status}`,
|
|
504
|
+
description: run.agent_name,
|
|
505
|
+
variant: run.status === "completed" ? "success" : "destructive"
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
prevStatusesRef.current = next;
|
|
510
|
+
setActiveRunsExist(data.data.some((r) => ACTIVE_STATUSES2.has(r.status)));
|
|
511
|
+
}, [data, toast2]);
|
|
328
512
|
const handleSourceChange = useCallback((e) => {
|
|
329
513
|
const value = e.target.value;
|
|
330
514
|
setSourceFilter(VALID_SOURCES.includes(value) ? value : null);
|
|
@@ -505,17 +689,51 @@ function buildConversation(events) {
|
|
|
505
689
|
}
|
|
506
690
|
return items;
|
|
507
691
|
}
|
|
508
|
-
function TranscriptViewer({ transcript, prompt }) {
|
|
692
|
+
function TranscriptViewer({ transcript, prompt, isStreaming = false }) {
|
|
509
693
|
const conversation = useMemo(() => buildConversation(transcript), [transcript]);
|
|
694
|
+
const scrollContainerRef = useRef(null);
|
|
695
|
+
const sentinelRef = useRef(null);
|
|
696
|
+
const userHasScrolledUpRef = useRef(false);
|
|
697
|
+
const [userHasScrolledUp, setUserHasScrolledUp] = useState(false);
|
|
698
|
+
const handleScroll = useCallback(() => {
|
|
699
|
+
const el = scrollContainerRef.current;
|
|
700
|
+
if (!el) return;
|
|
701
|
+
const atBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 50;
|
|
702
|
+
if (atBottom) {
|
|
703
|
+
userHasScrolledUpRef.current = false;
|
|
704
|
+
setUserHasScrolledUp(false);
|
|
705
|
+
} else {
|
|
706
|
+
userHasScrolledUpRef.current = true;
|
|
707
|
+
setUserHasScrolledUp(true);
|
|
708
|
+
}
|
|
709
|
+
}, []);
|
|
710
|
+
useEffect(() => {
|
|
711
|
+
if (isStreaming && !userHasScrolledUpRef.current) {
|
|
712
|
+
sentinelRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
713
|
+
}
|
|
714
|
+
}, [transcript.length, isStreaming]);
|
|
510
715
|
return /* @__PURE__ */ jsxs(Card, { children: [
|
|
511
716
|
/* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx(CardTitle, { className: "text-base", children: "Transcript" }) }),
|
|
512
|
-
/* @__PURE__ */
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
717
|
+
/* @__PURE__ */ jsx(CardContent, { className: "p-0", children: /* @__PURE__ */ jsxs(
|
|
718
|
+
"div",
|
|
719
|
+
{
|
|
720
|
+
ref: scrollContainerRef,
|
|
721
|
+
onScroll: isStreaming ? handleScroll : void 0,
|
|
722
|
+
className: "space-y-3 overflow-y-auto px-6 pb-6",
|
|
723
|
+
children: [
|
|
724
|
+
prompt && /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-border bg-muted/20 px-4 py-3", children: [
|
|
725
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Prompt" }),
|
|
726
|
+
/* @__PURE__ */ jsx("pre", { className: "text-xs font-mono whitespace-pre-wrap", children: prompt })
|
|
727
|
+
] }),
|
|
728
|
+
transcript.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No transcript available" }) : /* @__PURE__ */ jsx(ConversationView, { items: conversation }),
|
|
729
|
+
isStreaming && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-4 py-2 text-xs text-muted-foreground", children: [
|
|
730
|
+
/* @__PURE__ */ jsx("span", { className: "h-2 w-2 rounded-full bg-blue-400 animate-pulse" }),
|
|
731
|
+
"Streaming..."
|
|
732
|
+
] }),
|
|
733
|
+
/* @__PURE__ */ jsx("div", { ref: sentinelRef })
|
|
734
|
+
]
|
|
735
|
+
}
|
|
736
|
+
) })
|
|
519
737
|
] });
|
|
520
738
|
}
|
|
521
739
|
function ConversationView({ items }) {
|
|
@@ -669,6 +887,7 @@ function ErrorItem({ item }) {
|
|
|
669
887
|
}
|
|
670
888
|
function RunDetailPage({ runId, initialData, initialTranscript }) {
|
|
671
889
|
const { mutate } = useSWRConfig();
|
|
890
|
+
const { toast: toast2 } = useToast();
|
|
672
891
|
const { data: run, error, isLoading } = useApi(
|
|
673
892
|
`run-${runId}`,
|
|
674
893
|
(client) => client.runs.get(runId),
|
|
@@ -679,6 +898,20 @@ function RunDetailPage({ runId, initialData, initialTranscript }) {
|
|
|
679
898
|
(client) => client.runs.transcriptArray(runId),
|
|
680
899
|
initialTranscript ? { fallbackData: initialTranscript } : void 0
|
|
681
900
|
);
|
|
901
|
+
const isActive = run?.status === "running" || run?.status === "pending";
|
|
902
|
+
const { events, isStreaming, terminalEvent, streamingText } = useRunStream(
|
|
903
|
+
runId,
|
|
904
|
+
run?.status ?? ""
|
|
905
|
+
);
|
|
906
|
+
useEffect(() => {
|
|
907
|
+
if (!terminalEvent) return;
|
|
908
|
+
toast2({
|
|
909
|
+
title: terminalEvent.type === "result" ? "Run completed" : "Run failed",
|
|
910
|
+
variant: terminalEvent.type === "result" ? "success" : "destructive"
|
|
911
|
+
});
|
|
912
|
+
mutate(`run-${runId}`);
|
|
913
|
+
mutate(`transcript-${runId}`);
|
|
914
|
+
}, [terminalEvent, toast2, mutate, runId]);
|
|
682
915
|
if (error) {
|
|
683
916
|
return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center min-h-[40vh]", children: /* @__PURE__ */ jsxs("p", { className: "text-destructive", children: [
|
|
684
917
|
"Failed to load run: ",
|
|
@@ -711,16 +944,26 @@ function RunDetailPage({ runId, initialData, initialTranscript }) {
|
|
|
711
944
|
] }),
|
|
712
945
|
/* @__PURE__ */ jsx(MetricCard, { label: "Cost", children: /* @__PURE__ */ jsxs("span", { className: "font-mono", children: [
|
|
713
946
|
"$",
|
|
714
|
-
|
|
947
|
+
(() => {
|
|
948
|
+
const cost = terminalEvent?.cost_usd ?? run.cost_usd;
|
|
949
|
+
return cost != null ? Number(cost).toFixed(4) : "\u2014";
|
|
950
|
+
})()
|
|
715
951
|
] }) }),
|
|
716
|
-
/* @__PURE__ */ jsx(MetricCard, { label: "Turns", children: run.num_turns }),
|
|
717
|
-
/* @__PURE__ */ jsx(MetricCard, { label: "Duration", children:
|
|
952
|
+
/* @__PURE__ */ jsx(MetricCard, { label: "Turns", children: terminalEvent?.num_turns ?? run.num_turns }),
|
|
953
|
+
/* @__PURE__ */ jsx(MetricCard, { label: "Duration", children: (() => {
|
|
954
|
+
const ms = terminalEvent?.duration_ms ?? run.duration_ms;
|
|
955
|
+
return ms > 0 ? `${(ms / 1e3).toFixed(1)}s` : "\u2014";
|
|
956
|
+
})() }),
|
|
718
957
|
/* @__PURE__ */ jsxs(MetricCard, { label: "Tokens", children: [
|
|
719
|
-
(
|
|
958
|
+
(() => {
|
|
959
|
+
const inTok = terminalEvent?.total_input_tokens ?? run.total_input_tokens;
|
|
960
|
+
const outTok = terminalEvent?.total_output_tokens ?? run.total_output_tokens;
|
|
961
|
+
return (inTok + outTok).toLocaleString();
|
|
962
|
+
})(),
|
|
720
963
|
/* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground mt-0.5 font-normal", children: [
|
|
721
|
-
run.total_input_tokens.toLocaleString(),
|
|
964
|
+
(terminalEvent?.total_input_tokens ?? run.total_input_tokens).toLocaleString(),
|
|
722
965
|
" in / ",
|
|
723
|
-
run.total_output_tokens.toLocaleString(),
|
|
966
|
+
(terminalEvent?.total_output_tokens ?? run.total_output_tokens).toLocaleString(),
|
|
724
967
|
" out"
|
|
725
968
|
] })
|
|
726
969
|
] })
|
|
@@ -732,7 +975,18 @@ function RunDetailPage({ runId, initialData, initialTranscript }) {
|
|
|
732
975
|
run.error_messages.map((msg, i) => /* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap text-sm text-destructive font-mono bg-destructive/10 rounded-md p-3", children: msg }, i))
|
|
733
976
|
] })
|
|
734
977
|
] }),
|
|
735
|
-
/* @__PURE__ */ jsx(
|
|
978
|
+
/* @__PURE__ */ jsx(
|
|
979
|
+
TranscriptViewer,
|
|
980
|
+
{
|
|
981
|
+
transcript: isActive && isStreaming ? events : transcript || [],
|
|
982
|
+
prompt: run.prompt,
|
|
983
|
+
isStreaming: isActive && isStreaming
|
|
984
|
+
}
|
|
985
|
+
),
|
|
986
|
+
isActive && streamingText && /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-muted/30 p-4", children: /* @__PURE__ */ jsxs("pre", { className: "whitespace-pre-wrap text-sm font-mono", children: [
|
|
987
|
+
streamingText,
|
|
988
|
+
/* @__PURE__ */ jsx("span", { className: "inline-block w-2 h-4 ml-0.5 bg-foreground/70 animate-pulse align-text-bottom" })
|
|
989
|
+
] }) }),
|
|
736
990
|
/* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs("details", { children: [
|
|
737
991
|
/* @__PURE__ */ jsxs("summary", { className: "flex items-center justify-between px-6 py-4 cursor-pointer list-none hover:bg-muted/30 transition-colors rounded-xl", children: [
|
|
738
992
|
/* @__PURE__ */ jsx("span", { className: "text-base font-semibold", children: "Metadata" }),
|
|
@@ -4693,7 +4947,7 @@ function renderEvent(event, idx) {
|
|
|
4693
4947
|
/* @__PURE__ */ jsx(CollapsibleJson, { data: event, maxHeight: "8rem" })
|
|
4694
4948
|
] }, idx);
|
|
4695
4949
|
}
|
|
4696
|
-
var
|
|
4950
|
+
var TERMINAL_STATUSES2 = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "timed_out"]);
|
|
4697
4951
|
function PlaygroundPage({ agentId }) {
|
|
4698
4952
|
const client = useAgentPlaneClient();
|
|
4699
4953
|
const { LinkComponent, basePath } = useNavigation();
|
|
@@ -4735,7 +4989,7 @@ function PlaygroundPage({ agentId }) {
|
|
|
4735
4989
|
if (abortRef.current?.signal.aborted) break;
|
|
4736
4990
|
try {
|
|
4737
4991
|
const run = await client.runs.get(runId);
|
|
4738
|
-
if (
|
|
4992
|
+
if (TERMINAL_STATUSES2.has(run.status)) {
|
|
4739
4993
|
try {
|
|
4740
4994
|
const transcriptEvents = await client.runs.transcriptArray(runId);
|
|
4741
4995
|
if (transcriptEvents.length > 0) {
|
|
@@ -4971,5 +5225,121 @@ function PlaygroundPage({ agentId }) {
|
|
|
4971
5225
|
] })
|
|
4972
5226
|
] });
|
|
4973
5227
|
}
|
|
5228
|
+
var ToastProvider = ToastPrimitives.Provider;
|
|
5229
|
+
var ToastViewport = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
5230
|
+
ToastPrimitives.Viewport,
|
|
5231
|
+
{
|
|
5232
|
+
ref,
|
|
5233
|
+
className: cn(
|
|
5234
|
+
"fixed top-0 right-0 z-[100] flex max-h-screen w-full flex-col-reverse gap-2 p-4 sm:flex-col sm:max-w-[420px]",
|
|
5235
|
+
className
|
|
5236
|
+
),
|
|
5237
|
+
...props
|
|
5238
|
+
}
|
|
5239
|
+
));
|
|
5240
|
+
ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
|
|
5241
|
+
var toastVariants = cva(
|
|
5242
|
+
"group pointer-events-auto relative flex w-full items-center justify-between gap-4 overflow-hidden rounded-lg border p-4 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-right-full",
|
|
5243
|
+
{
|
|
5244
|
+
variants: {
|
|
5245
|
+
variant: {
|
|
5246
|
+
default: "bg-zinc-800 border-zinc-700 text-zinc-100",
|
|
5247
|
+
success: "bg-green-950 border-green-900 text-green-400",
|
|
5248
|
+
destructive: "bg-red-950 border-red-900 text-red-400"
|
|
5249
|
+
}
|
|
5250
|
+
},
|
|
5251
|
+
defaultVariants: {
|
|
5252
|
+
variant: "default"
|
|
5253
|
+
}
|
|
5254
|
+
}
|
|
5255
|
+
);
|
|
5256
|
+
var Toast = React4.forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
5257
|
+
ToastPrimitives.Root,
|
|
5258
|
+
{
|
|
5259
|
+
ref,
|
|
5260
|
+
className: cn(toastVariants({ variant }), className),
|
|
5261
|
+
...props
|
|
5262
|
+
}
|
|
5263
|
+
));
|
|
5264
|
+
Toast.displayName = ToastPrimitives.Root.displayName;
|
|
5265
|
+
var ToastAction = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
5266
|
+
ToastPrimitives.Action,
|
|
5267
|
+
{
|
|
5268
|
+
ref,
|
|
5269
|
+
className: cn(
|
|
5270
|
+
"inline-flex h-8 shrink-0 items-center justify-center rounded-md border border-zinc-600 bg-transparent px-3 text-sm font-medium transition-colors hover:bg-zinc-700 focus:outline-none focus:ring-1 focus:ring-zinc-500 disabled:pointer-events-none disabled:opacity-50",
|
|
5271
|
+
"group-[.destructive]:border-red-800 group-[.destructive]:hover:border-red-700 group-[.destructive]:hover:bg-red-900 group-[.destructive]:focus:ring-red-800",
|
|
5272
|
+
"group-[.success]:border-green-800 group-[.success]:hover:border-green-700 group-[.success]:hover:bg-green-900 group-[.success]:focus:ring-green-800",
|
|
5273
|
+
className
|
|
5274
|
+
),
|
|
5275
|
+
...props
|
|
5276
|
+
}
|
|
5277
|
+
));
|
|
5278
|
+
ToastAction.displayName = ToastPrimitives.Action.displayName;
|
|
5279
|
+
var ToastClose = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
5280
|
+
ToastPrimitives.Close,
|
|
5281
|
+
{
|
|
5282
|
+
ref,
|
|
5283
|
+
className: cn(
|
|
5284
|
+
"absolute right-1 top-1 rounded-md p-1 text-zinc-400 opacity-0 transition-opacity hover:text-zinc-100 focus:opacity-100 focus:outline-none group-hover:opacity-100",
|
|
5285
|
+
"group-[.destructive]:text-red-400 group-[.destructive]:hover:text-red-300",
|
|
5286
|
+
"group-[.success]:text-green-400 group-[.success]:hover:text-green-300",
|
|
5287
|
+
className
|
|
5288
|
+
),
|
|
5289
|
+
"toast-close": "",
|
|
5290
|
+
...props,
|
|
5291
|
+
children: /* @__PURE__ */ jsxs(
|
|
5292
|
+
"svg",
|
|
5293
|
+
{
|
|
5294
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
5295
|
+
width: "16",
|
|
5296
|
+
height: "16",
|
|
5297
|
+
viewBox: "0 0 24 24",
|
|
5298
|
+
fill: "none",
|
|
5299
|
+
stroke: "currentColor",
|
|
5300
|
+
strokeWidth: "2",
|
|
5301
|
+
strokeLinecap: "round",
|
|
5302
|
+
strokeLinejoin: "round",
|
|
5303
|
+
children: [
|
|
5304
|
+
/* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
|
|
5305
|
+
/* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
|
|
5306
|
+
]
|
|
5307
|
+
}
|
|
5308
|
+
)
|
|
5309
|
+
}
|
|
5310
|
+
));
|
|
5311
|
+
ToastClose.displayName = ToastPrimitives.Close.displayName;
|
|
5312
|
+
var ToastTitle = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
5313
|
+
ToastPrimitives.Title,
|
|
5314
|
+
{
|
|
5315
|
+
ref,
|
|
5316
|
+
className: cn("text-sm font-semibold [&+div]:text-xs", className),
|
|
5317
|
+
...props
|
|
5318
|
+
}
|
|
5319
|
+
));
|
|
5320
|
+
ToastTitle.displayName = ToastPrimitives.Title.displayName;
|
|
5321
|
+
var ToastDescription = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
5322
|
+
ToastPrimitives.Description,
|
|
5323
|
+
{
|
|
5324
|
+
ref,
|
|
5325
|
+
className: cn("text-sm opacity-90", className),
|
|
5326
|
+
...props
|
|
5327
|
+
}
|
|
5328
|
+
));
|
|
5329
|
+
ToastDescription.displayName = ToastPrimitives.Description.displayName;
|
|
5330
|
+
function Toaster() {
|
|
5331
|
+
const { toasts } = useToast();
|
|
5332
|
+
return /* @__PURE__ */ jsxs(ToastProvider, { children: [
|
|
5333
|
+
toasts.map(({ id, title, description, action, ...props }) => /* @__PURE__ */ jsxs(Toast, { ...props, children: [
|
|
5334
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-1", children: [
|
|
5335
|
+
title && /* @__PURE__ */ jsx(ToastTitle, { children: title }),
|
|
5336
|
+
description && /* @__PURE__ */ jsx(ToastDescription, { children: description })
|
|
5337
|
+
] }),
|
|
5338
|
+
action,
|
|
5339
|
+
/* @__PURE__ */ jsx(ToastClose, {})
|
|
5340
|
+
] }, id)),
|
|
5341
|
+
/* @__PURE__ */ jsx(ToastViewport, {})
|
|
5342
|
+
] });
|
|
5343
|
+
}
|
|
4974
5344
|
|
|
4975
|
-
export { AdminTable, AdminTableHead, AdminTableRow, AgentA2aInfo, AgentConnectorsManager, AgentDetailPage, AgentEditForm, AgentListPage, AgentPluginManager, AgentRuns, AgentScheduleForm, AgentSkillManager, ConfirmDialog, CopyButton, DashboardPage, DetailPageHeader, EmptyRow, FormError, LocalDate, McpServerListPage, MetricCard, ModelSelector, PaginationBar, PlaygroundPage, PluginDetailPage, PluginMarketplaceDetailPage, PluginMarketplaceListPage, RunDetailPage, RunListPage, RunSourceBadge, RunStatusBadge, SectionHeader, Select, SettingsPage, Tabs, Textarea, Th, ToolkitMultiselect, TranscriptViewer, parsePaginationParams };
|
|
5345
|
+
export { AdminTable, AdminTableHead, AdminTableRow, AgentA2aInfo, AgentConnectorsManager, AgentDetailPage, AgentEditForm, AgentListPage, AgentPluginManager, AgentRuns, AgentScheduleForm, AgentSkillManager, ConfirmDialog, CopyButton, DashboardPage, DetailPageHeader, EmptyRow, FormError, LocalDate, McpServerListPage, MetricCard, ModelSelector, PaginationBar, PlaygroundPage, PluginDetailPage, PluginMarketplaceDetailPage, PluginMarketplaceListPage, RunDetailPage, RunListPage, RunSourceBadge, RunStatusBadge, SectionHeader, Select, SettingsPage, Tabs, Textarea, Th, Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport, Toaster, ToolkitMultiselect, TranscriptViewer, parsePaginationParams, toast, toastVariants, useRunStream, useToast };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getcatalystiq/agent-plane-ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.31",
|
|
4
4
|
"description": "Embeddable React component library for AgentPlane",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -92,6 +92,7 @@
|
|
|
92
92
|
},
|
|
93
93
|
"dependencies": {
|
|
94
94
|
"@radix-ui/react-popover": "^1.0.0",
|
|
95
|
+
"@radix-ui/react-toast": "^1.2.15",
|
|
95
96
|
"class-variance-authority": "^0.7.0",
|
|
96
97
|
"clsx": "^2.0.0",
|
|
97
98
|
"cmdk": "^1.0.0",
|