@tangle-network/sandbox-ui 5.0.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/globals.css +6 -0
- package/dist/{index-CeZgMx53.d.ts → index-D6fZ1Hgz.d.ts} +8 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/run/live.js +75 -60
- package/dist/run.d.ts +1 -1
- package/dist/run.js +1 -1
- package/dist/styles.css +6 -0
- package/dist/{trace-workspace-DtoQ3tio.js → trace-workspace-CTMV8zw_.js} +168 -149
- package/dist/workspace-viewer.js +6289 -6257
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import { i as modelBrandFor, t as ModelBrandStack } from "./model-brand-BQlarCIo
|
|
|
3
3
|
import { t as ProviderIcon } from "./provider-logo-CPKRPHcS.js";
|
|
4
4
|
import { t as AgentGraph$1 } from "./AgentGraph-BGWx9hhS.js";
|
|
5
5
|
import { s as timelineItems, t as useFollowTail } from "./use-follow-tail-DZFn7QDO.js";
|
|
6
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
8
8
|
import { X } from "lucide-react";
|
|
9
9
|
import { activityTiming, ambientStyle, syncAmbient } from "@tangle-network/charts/react/agent-graph/presentation";
|
|
@@ -176,6 +176,7 @@ function foldAgentRows(entries, rows) {
|
|
|
176
176
|
const empty = (identity, history) => ({
|
|
177
177
|
identity,
|
|
178
178
|
rows: [],
|
|
179
|
+
entries: [],
|
|
179
180
|
first: null,
|
|
180
181
|
lastSeq: -1,
|
|
181
182
|
alive: !!identity && (history?.alive ?? true),
|
|
@@ -195,9 +196,11 @@ function receive(prior, page, direction, fromHead) {
|
|
|
195
196
|
if (trimmed) rows = prior.reading ? rows.slice(0, 2e3) : rows.slice(-2e3);
|
|
196
197
|
const first = fresh ? page.firstSeq ?? rows[0]?.seq ?? null : direction === "before" ? page.firstSeq ?? prior.first : trimmed && !prior.reading ? rows[0]?.seq ?? prior.first : prior.first;
|
|
197
198
|
const lastSeq = fresh ? page.lastSeq ?? rows.at(-1)?.seq ?? -1 : direction === "before" ? prior.lastSeq : page.lastSeq ?? rows.at(-1)?.seq ?? prior.lastSeq;
|
|
199
|
+
const entries = fresh ? foldAgentRows([], rows) : direction === "after" ? foldAgentRows(prior.entries, page.events) : foldAgentRows([], rows);
|
|
198
200
|
return {
|
|
199
201
|
...prior,
|
|
200
202
|
rows,
|
|
203
|
+
entries,
|
|
201
204
|
first,
|
|
202
205
|
lastSeq,
|
|
203
206
|
generation: page.generation ?? prior.generation,
|
|
@@ -356,9 +359,9 @@ function useAgentStream(url, openEventSource, history) {
|
|
|
356
359
|
})
|
|
357
360
|
}
|
|
358
361
|
});
|
|
359
|
-
let entries =
|
|
360
|
-
try {
|
|
361
|
-
entries = foldAgentRows([], history
|
|
362
|
+
let entries = state.entries, error = state.error;
|
|
363
|
+
if (history?.projectRows) try {
|
|
364
|
+
entries = foldAgentRows([], history.projectRows(state.rows) ?? state.rows);
|
|
362
365
|
} catch (cause) {
|
|
363
366
|
error = cause instanceof Error ? cause.message : String(cause);
|
|
364
367
|
}
|
|
@@ -482,7 +485,7 @@ function agentGraphAt(spans, byId, at, epoch, cards, extraEdges = []) {
|
|
|
482
485
|
* streaming in a right-hand drawer, and the page's code workspace and scoreboard following the time cursor. Scrubbing is time travel:
|
|
483
486
|
* every panel shows what was true at the cursor, and the conversation shows what had been said by then.
|
|
484
487
|
*/
|
|
485
|
-
function TraceWorkspace({ trace, streamUrl, openEventSource, events, onTimeChange, files, scoreboard, selectedAgentId, conversationOpen, onSelectAgent, renderAgentDrawer, agentCards, agentGraph, className, ...waterfall }) {
|
|
488
|
+
function TraceWorkspace({ trace, streamUrl, openEventSource, events, onTimeChange, files, scoreboard, selectedAgentId, conversationOpen, onSelectAgent, renderAgentDrawer, docked, commission, agentCards, agentGraph, className, ...waterfall }) {
|
|
486
489
|
const byId = useMemo(() => new Map(trace.spans.flatMap((span) => span.id ? [[span.id, span]] : [])), [trace]);
|
|
487
490
|
const [ownSelection, setOwnSelection] = useState();
|
|
488
491
|
const selected = selectedAgentId ?? ownSelection;
|
|
@@ -524,165 +527,181 @@ function TraceWorkspace({ trace, streamUrl, openEventSource, events, onTimeChang
|
|
|
524
527
|
const graphNow = cursor !== null && waterfall.startedAt !== void 0 ? waterfall.startedAt + cursor : void 0;
|
|
525
528
|
const shown = cursor === null || origin === void 0 ? stream.entries : stream.entries.filter((entry) => entry.at - origin <= cursor);
|
|
526
529
|
const live = stream.alive && !stream.error && cursor === null;
|
|
530
|
+
const ended = !stream.alive && !stream.error;
|
|
527
531
|
const items = useMemo(() => timelineItems(shown, live), [shown, live]);
|
|
528
532
|
const scroller = useRef(null);
|
|
529
533
|
const { unseen, jump } = useFollowTail(scroller, {
|
|
530
534
|
identity: showConversation ? selected : void 0,
|
|
531
535
|
content: items
|
|
532
536
|
});
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
/* @__PURE__ */ jsx(
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
537
|
+
const left = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
538
|
+
/* @__PURE__ */ jsx("div", {
|
|
539
|
+
className: showConversation && !docked ? "min-w-0 lg:mr-[420px]" : "min-w-0",
|
|
540
|
+
children: /* @__PURE__ */ jsx(TraceWaterfall, {
|
|
541
|
+
...waterfall,
|
|
542
|
+
trace,
|
|
543
|
+
markers: events,
|
|
544
|
+
selectedId: agentId,
|
|
545
|
+
onDeselect: () => select(void 0),
|
|
546
|
+
onSelect: (span) => {
|
|
547
|
+
const owner = agentOf(span, byId);
|
|
548
|
+
if (owner?.id) select(owner.id);
|
|
549
|
+
},
|
|
550
|
+
onTimeChange: (time) => {
|
|
551
|
+
setCursor(time);
|
|
552
|
+
onTimeChange?.(time);
|
|
553
|
+
},
|
|
554
|
+
latestEvents: /* @__PURE__ */ jsx(LatestEvents, {
|
|
555
|
+
agents: graph.nodes,
|
|
556
|
+
now: graphNow,
|
|
557
|
+
live: cursor === null,
|
|
542
558
|
selectedId: agentId,
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
"aria-label": "Agent graph",
|
|
562
|
-
children: [/* @__PURE__ */ jsxs("label", {
|
|
563
|
-
className: "flex h-8 shrink-0 items-center justify-end gap-2 px-3 text-xs text-muted-foreground",
|
|
564
|
-
children: ["Layout", /* @__PURE__ */ jsxs("select", {
|
|
565
|
-
"aria-label": "Graph layout",
|
|
566
|
-
value: graphLayout,
|
|
567
|
-
onChange: (event) => setGraphLayout(event.currentTarget.value),
|
|
568
|
-
className: "rounded-[var(--radius-control)] border border-border bg-card px-2 py-1 text-foreground",
|
|
569
|
-
children: [/* @__PURE__ */ jsx("option", {
|
|
570
|
-
value: "tree",
|
|
571
|
-
children: "Tree"
|
|
572
|
-
}), /* @__PURE__ */ jsx("option", {
|
|
573
|
-
value: "hub",
|
|
574
|
-
children: "Hub"
|
|
575
|
-
})]
|
|
559
|
+
onSelect: select
|
|
560
|
+
}),
|
|
561
|
+
graph: /* @__PURE__ */ jsxs("section", {
|
|
562
|
+
className: "flex h-[60vh] min-h-[480px] flex-col",
|
|
563
|
+
"aria-label": "Agent graph",
|
|
564
|
+
children: [/* @__PURE__ */ jsxs("label", {
|
|
565
|
+
className: "flex h-8 shrink-0 items-center justify-end gap-2 px-3 text-xs text-muted-foreground",
|
|
566
|
+
children: ["Layout", /* @__PURE__ */ jsxs("select", {
|
|
567
|
+
"aria-label": "Graph layout",
|
|
568
|
+
value: graphLayout,
|
|
569
|
+
onChange: (event) => setGraphLayout(event.currentTarget.value),
|
|
570
|
+
className: "rounded-[var(--radius-control)] border border-border bg-card px-2 py-1 text-foreground",
|
|
571
|
+
children: [/* @__PURE__ */ jsx("option", {
|
|
572
|
+
value: "tree",
|
|
573
|
+
children: "Tree"
|
|
574
|
+
}), /* @__PURE__ */ jsx("option", {
|
|
575
|
+
value: "hub",
|
|
576
|
+
children: "Hub"
|
|
576
577
|
})]
|
|
577
|
-
}), /* @__PURE__ */ jsx(AgentGraph$1, {
|
|
578
|
-
...graphOptions,
|
|
579
|
-
layout: graphLayout,
|
|
580
|
-
renderEventIcon: (event) => toolGlyph(event.label),
|
|
581
|
-
nodes: graph.nodes,
|
|
582
|
-
edges: graph.edges,
|
|
583
|
-
selectedId: agentId ?? null,
|
|
584
|
-
onSelect: select,
|
|
585
|
-
showLatestEvents: false,
|
|
586
|
-
now: graphNow,
|
|
587
|
-
live: cursor === null && graph.nodes.some((node) => [
|
|
588
|
-
"running",
|
|
589
|
-
"waiting",
|
|
590
|
-
"needs-you",
|
|
591
|
-
"failed"
|
|
592
|
-
].includes(node.status)),
|
|
593
|
-
className: cn("min-h-0 flex-1", graphOptions.className)
|
|
594
578
|
})]
|
|
595
|
-
})
|
|
579
|
+
}), /* @__PURE__ */ jsx(AgentGraph$1, {
|
|
580
|
+
...graphOptions,
|
|
581
|
+
layout: graphLayout,
|
|
582
|
+
renderEventIcon: (event) => toolGlyph(event.label),
|
|
583
|
+
nodes: graph.nodes,
|
|
584
|
+
edges: graph.edges,
|
|
585
|
+
selectedId: agentId ?? null,
|
|
586
|
+
onSelect: select,
|
|
587
|
+
showLatestEvents: false,
|
|
588
|
+
now: graphNow,
|
|
589
|
+
live: cursor === null && graph.nodes.some((node) => [
|
|
590
|
+
"running",
|
|
591
|
+
"waiting",
|
|
592
|
+
"needs-you",
|
|
593
|
+
"failed"
|
|
594
|
+
].includes(node.status)),
|
|
595
|
+
className: cn("min-h-0 flex-1", graphOptions.className)
|
|
596
|
+
})]
|
|
596
597
|
})
|
|
597
|
-
})
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
598
|
+
})
|
|
599
|
+
}),
|
|
600
|
+
files && /* @__PURE__ */ jsx("section", {
|
|
601
|
+
"aria-label": "Code at the cursor",
|
|
602
|
+
className: "flex h-[70vh] min-h-0 flex-col overflow-hidden rounded-xl border border-border bg-card",
|
|
603
|
+
children: files
|
|
604
|
+
}),
|
|
605
|
+
scoreboard && /* @__PURE__ */ jsx("section", {
|
|
606
|
+
"aria-label": "Scoreboard at the cursor",
|
|
607
|
+
className: "overflow-hidden rounded-xl border border-border bg-card",
|
|
608
|
+
children: scoreboard
|
|
609
|
+
})
|
|
610
|
+
] });
|
|
611
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
612
|
+
className: cn("sandbox-trace-workspace flex min-h-0 gap-3", docked && showConversation ? "flex-row" : "flex-col", className),
|
|
613
|
+
children: [docked && showConversation ? /* @__PURE__ */ jsx("div", {
|
|
614
|
+
className: "flex min-w-0 flex-1 flex-col gap-3",
|
|
615
|
+
children: left
|
|
616
|
+
}) : left, showConversation && /* @__PURE__ */ jsxs("aside", {
|
|
617
|
+
"aria-label": `${agentName} conversation`,
|
|
618
|
+
onKeyDown: (event) => {
|
|
619
|
+
if (event.key === "Escape") select(void 0);
|
|
620
|
+
},
|
|
621
|
+
className: docked ? "flex min-h-0 w-[clamp(320px,32vw,560px)] shrink-0 resize-x flex-col overflow-hidden rounded-xl border border-border bg-card" : "fixed inset-y-0 right-0 z-40 flex w-full max-w-[420px] flex-col border-l border-border bg-card shadow-2xl",
|
|
622
|
+
children: [
|
|
623
|
+
/* @__PURE__ */ jsxs("header", {
|
|
624
|
+
className: "flex shrink-0 items-center gap-2 border-b border-border px-3 py-2",
|
|
625
|
+
children: [
|
|
626
|
+
/* @__PURE__ */ jsx("span", {
|
|
627
|
+
className: cn("h-1.5 w-1.5 shrink-0 rounded-full", live ? "bg-[var(--surface-info-text)]" : "bg-muted-foreground"),
|
|
628
|
+
"aria-hidden": true,
|
|
629
|
+
"data-motion": live ? "essential" : void 0,
|
|
630
|
+
style: live ? ambientStyle : void 0,
|
|
631
|
+
onAnimationStart: syncAmbient
|
|
632
|
+
}),
|
|
633
|
+
/* @__PURE__ */ jsx("h3", {
|
|
634
|
+
className: "min-w-0 flex-1 truncate text-sm font-semibold",
|
|
635
|
+
children: agentName
|
|
636
|
+
}),
|
|
637
|
+
agentModel && /* @__PURE__ */ jsx("span", {
|
|
638
|
+
className: "truncate text-xs text-muted-foreground",
|
|
639
|
+
children: agentModel
|
|
640
|
+
}),
|
|
641
|
+
/* @__PURE__ */ jsx("button", {
|
|
642
|
+
type: "button",
|
|
643
|
+
"aria-label": "Close conversation",
|
|
644
|
+
title: "Close (Esc)",
|
|
645
|
+
onClick: () => select(void 0),
|
|
646
|
+
className: "shrink-0 rounded-md p-1 text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
647
|
+
children: /* @__PURE__ */ jsx(X, {
|
|
620
648
|
"aria-hidden": true,
|
|
621
|
-
"
|
|
622
|
-
style: live ? ambientStyle : void 0,
|
|
623
|
-
onAnimationStart: syncAmbient
|
|
624
|
-
}),
|
|
625
|
-
/* @__PURE__ */ jsx("h3", {
|
|
626
|
-
className: "min-w-0 flex-1 truncate text-sm font-semibold",
|
|
627
|
-
children: agentName
|
|
628
|
-
}),
|
|
629
|
-
agentModel && /* @__PURE__ */ jsx("span", {
|
|
630
|
-
className: "truncate text-xs text-muted-foreground",
|
|
631
|
-
children: agentModel
|
|
632
|
-
}),
|
|
633
|
-
/* @__PURE__ */ jsx("button", {
|
|
634
|
-
type: "button",
|
|
635
|
-
"aria-label": "Close conversation",
|
|
636
|
-
title: "Close (Esc)",
|
|
637
|
-
onClick: () => select(void 0),
|
|
638
|
-
className: "shrink-0 rounded-md p-1 text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
639
|
-
children: /* @__PURE__ */ jsx(X, {
|
|
640
|
-
"aria-hidden": true,
|
|
641
|
-
className: "h-4 w-4"
|
|
642
|
-
})
|
|
649
|
+
className: "h-4 w-4"
|
|
643
650
|
})
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
}),
|
|
660
|
-
}),
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
651
|
+
})
|
|
652
|
+
]
|
|
653
|
+
}),
|
|
654
|
+
(facts.length > 0 || detail) && /* @__PURE__ */ jsxs("section", {
|
|
655
|
+
"aria-label": "Recorded agent details",
|
|
656
|
+
tabIndex: 0,
|
|
657
|
+
className: "max-h-[35vh] shrink-0 overflow-y-auto border-b border-border px-3 py-2 text-sm",
|
|
658
|
+
children: [facts.length > 0 && /* @__PURE__ */ jsx("dl", {
|
|
659
|
+
className: "space-y-2",
|
|
660
|
+
children: facts.map((fact, index) => /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", {
|
|
661
|
+
className: "text-xs text-muted-foreground",
|
|
662
|
+
children: fact.label
|
|
663
|
+
}), /* @__PURE__ */ jsx("dd", {
|
|
664
|
+
className: "m-0 whitespace-pre-wrap break-words",
|
|
665
|
+
children: fact.value
|
|
666
|
+
})] }, index))
|
|
667
|
+
}), detail]
|
|
668
|
+
}),
|
|
669
|
+
commission && (commission.text || commission.by) && /* @__PURE__ */ jsxs("section", {
|
|
670
|
+
"aria-label": "Commission",
|
|
671
|
+
className: "shrink-0 border-b border-border bg-muted/40 px-3 py-2 text-sm",
|
|
672
|
+
children: [commission.by && /* @__PURE__ */ jsxs("p", {
|
|
673
|
+
className: "m-0 mb-1 text-xs text-muted-foreground",
|
|
674
|
+
children: ["commissioned by ", commission.by]
|
|
675
|
+
}), commission.text && /* @__PURE__ */ jsx("p", {
|
|
676
|
+
className: "m-0 line-clamp-6 whitespace-pre-wrap break-words",
|
|
677
|
+
children: commission.text
|
|
678
|
+
})]
|
|
679
|
+
}),
|
|
680
|
+
/* @__PURE__ */ jsx("div", {
|
|
681
|
+
ref: scroller,
|
|
682
|
+
"data-primary-content": "",
|
|
683
|
+
className: "min-h-0 flex-1 overflow-y-auto px-3 py-2",
|
|
684
|
+
children: streamUrl && (cursor === null || origin !== void 0) ? /* @__PURE__ */ jsx(AgentTimeline, {
|
|
685
|
+
items,
|
|
686
|
+
isThinking: live && items.length === 0,
|
|
687
|
+
emptyState: /* @__PURE__ */ jsx("p", {
|
|
673
688
|
className: "p-4 text-sm text-muted-foreground",
|
|
674
|
-
|
|
689
|
+
"data-stream": stream.error ? "reconnecting" : ended ? "ended" : "empty",
|
|
690
|
+
children: stream.error ? ended ? stream.error : `Reconnecting… ${stream.error}` : ended ? "The conversation ended." : "No messages yet."
|
|
675
691
|
})
|
|
676
|
-
}),
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
onClick: () => jump(),
|
|
680
|
-
className: "absolute bottom-3 left-1/2 -translate-x-1/2 rounded-full border border-border bg-background px-3 py-1 text-xs shadow-sm",
|
|
681
|
-
children: "New output"
|
|
692
|
+
}) : /* @__PURE__ */ jsx("p", {
|
|
693
|
+
className: "p-4 text-sm text-muted-foreground",
|
|
694
|
+
children: "Conversation: not time-indexed"
|
|
682
695
|
})
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
696
|
+
}),
|
|
697
|
+
unseen && /* @__PURE__ */ jsx("button", {
|
|
698
|
+
type: "button",
|
|
699
|
+
onClick: () => jump(),
|
|
700
|
+
className: "absolute bottom-3 left-1/2 -translate-x-1/2 rounded-full border border-border bg-background px-3 py-1 text-xs shadow-sm",
|
|
701
|
+
children: "New output"
|
|
702
|
+
})
|
|
703
|
+
]
|
|
704
|
+
})]
|
|
686
705
|
});
|
|
687
706
|
}
|
|
688
707
|
export { useEventStream as a, useAgentStream as i, LatestEvents as n, TraceWaterfall as o, foldAgentRows as r, traceSpanMark as s, TraceWorkspace as t };
|