@tangle-network/sandbox-ui 4.0.1 → 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-CHA38az4.d.ts → index-D6fZ1Hgz.d.ts} +12 -6
- 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-BULdFHrf.js → trace-workspace-CTMV8zw_.js} +168 -148
- package/dist/workspace-viewer.js +6288 -6256
- package/package.json +2 -2
|
@@ -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, 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;
|
|
@@ -493,6 +496,7 @@ function TraceWorkspace({ trace, streamUrl, openEventSource, events, onTimeChang
|
|
|
493
496
|
const agent = selected ? byId.get(selected) : void 0, card = selected ? agentCards?.[selected] : void 0;
|
|
494
497
|
const agentId = agent?.id ?? (card ? selected : void 0), agentName = agent?.name ?? card?.label ?? agentId, agentModel = agent?.detail ?? card?.model;
|
|
495
498
|
const showConversation = !!agentId && conversationOpen !== false;
|
|
499
|
+
const detail = showConversation && agentId ? renderAgentDrawer?.(agentId) : void 0;
|
|
496
500
|
const { defaultLayout = "tree", ...graphOptions } = agentGraph ?? {};
|
|
497
501
|
const [graphLayout, setGraphLayout] = useState(defaultLayout);
|
|
498
502
|
const [cursor, setCursor] = useState(null);
|
|
@@ -523,165 +527,181 @@ function TraceWorkspace({ trace, streamUrl, openEventSource, events, onTimeChang
|
|
|
523
527
|
const graphNow = cursor !== null && waterfall.startedAt !== void 0 ? waterfall.startedAt + cursor : void 0;
|
|
524
528
|
const shown = cursor === null || origin === void 0 ? stream.entries : stream.entries.filter((entry) => entry.at - origin <= cursor);
|
|
525
529
|
const live = stream.alive && !stream.error && cursor === null;
|
|
530
|
+
const ended = !stream.alive && !stream.error;
|
|
526
531
|
const items = useMemo(() => timelineItems(shown, live), [shown, live]);
|
|
527
532
|
const scroller = useRef(null);
|
|
528
533
|
const { unseen, jump } = useFollowTail(scroller, {
|
|
529
534
|
identity: showConversation ? selected : void 0,
|
|
530
535
|
content: items
|
|
531
536
|
});
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
/* @__PURE__ */ jsx(
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
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,
|
|
541
558
|
selectedId: agentId,
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
"aria-label": "Agent graph",
|
|
561
|
-
children: [/* @__PURE__ */ jsxs("label", {
|
|
562
|
-
className: "flex h-8 shrink-0 items-center justify-end gap-2 px-3 text-xs text-muted-foreground",
|
|
563
|
-
children: ["Layout", /* @__PURE__ */ jsxs("select", {
|
|
564
|
-
"aria-label": "Graph layout",
|
|
565
|
-
value: graphLayout,
|
|
566
|
-
onChange: (event) => setGraphLayout(event.currentTarget.value),
|
|
567
|
-
className: "rounded-[var(--radius-control)] border border-border bg-card px-2 py-1 text-foreground",
|
|
568
|
-
children: [/* @__PURE__ */ jsx("option", {
|
|
569
|
-
value: "tree",
|
|
570
|
-
children: "Tree"
|
|
571
|
-
}), /* @__PURE__ */ jsx("option", {
|
|
572
|
-
value: "hub",
|
|
573
|
-
children: "Hub"
|
|
574
|
-
})]
|
|
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"
|
|
575
577
|
})]
|
|
576
|
-
}), /* @__PURE__ */ jsx(AgentGraph$1, {
|
|
577
|
-
...graphOptions,
|
|
578
|
-
layout: graphLayout,
|
|
579
|
-
renderEventIcon: (event) => toolGlyph(event.label),
|
|
580
|
-
nodes: graph.nodes,
|
|
581
|
-
edges: graph.edges,
|
|
582
|
-
selectedId: agentId ?? null,
|
|
583
|
-
onSelect: select,
|
|
584
|
-
showLatestEvents: false,
|
|
585
|
-
now: graphNow,
|
|
586
|
-
live: cursor === null && graph.nodes.some((node) => [
|
|
587
|
-
"running",
|
|
588
|
-
"waiting",
|
|
589
|
-
"needs-you",
|
|
590
|
-
"failed"
|
|
591
|
-
].includes(node.status)),
|
|
592
|
-
className: cn("min-h-0 flex-1", graphOptions.className)
|
|
593
578
|
})]
|
|
594
|
-
})
|
|
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
|
+
})]
|
|
595
597
|
})
|
|
596
|
-
})
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
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, {
|
|
619
648
|
"aria-hidden": true,
|
|
620
|
-
"
|
|
621
|
-
style: live ? ambientStyle : void 0,
|
|
622
|
-
onAnimationStart: syncAmbient
|
|
623
|
-
}),
|
|
624
|
-
/* @__PURE__ */ jsx("h3", {
|
|
625
|
-
className: "min-w-0 flex-1 truncate text-sm font-semibold",
|
|
626
|
-
children: agentName
|
|
627
|
-
}),
|
|
628
|
-
agentModel && /* @__PURE__ */ jsx("span", {
|
|
629
|
-
className: "truncate text-xs text-muted-foreground",
|
|
630
|
-
children: agentModel
|
|
631
|
-
}),
|
|
632
|
-
/* @__PURE__ */ jsx("button", {
|
|
633
|
-
type: "button",
|
|
634
|
-
"aria-label": "Close conversation",
|
|
635
|
-
title: "Close (Esc)",
|
|
636
|
-
onClick: () => select(void 0),
|
|
637
|
-
className: "shrink-0 rounded-md p-1 text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
638
|
-
children: /* @__PURE__ */ jsx(X, {
|
|
639
|
-
"aria-hidden": true,
|
|
640
|
-
className: "h-4 w-4"
|
|
641
|
-
})
|
|
649
|
+
className: "h-4 w-4"
|
|
642
650
|
})
|
|
643
|
-
]
|
|
644
|
-
}),
|
|
645
|
-
facts.length > 0 && /* @__PURE__ */ jsx("section", {
|
|
646
|
-
"aria-label": "Recorded agent details",
|
|
647
|
-
tabIndex: 0,
|
|
648
|
-
className: "max-h-[35vh] shrink-0 overflow-y-auto border-b border-border px-3 py-2 text-sm",
|
|
649
|
-
children: /* @__PURE__ */ jsx("dl", {
|
|
650
|
-
className: "space-y-2",
|
|
651
|
-
children: facts.map((fact, index) => /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("dt", {
|
|
652
|
-
className: "text-xs text-muted-foreground",
|
|
653
|
-
children: fact.label
|
|
654
|
-
}), /* @__PURE__ */ jsx("dd", {
|
|
655
|
-
className: "m-0 whitespace-pre-wrap break-words",
|
|
656
|
-
children: fact.value
|
|
657
|
-
})] }, index))
|
|
658
651
|
})
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
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", {
|
|
672
688
|
className: "p-4 text-sm text-muted-foreground",
|
|
673
|
-
|
|
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."
|
|
674
691
|
})
|
|
675
|
-
}),
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
onClick: () => jump(),
|
|
679
|
-
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",
|
|
680
|
-
children: "New output"
|
|
692
|
+
}) : /* @__PURE__ */ jsx("p", {
|
|
693
|
+
className: "p-4 text-sm text-muted-foreground",
|
|
694
|
+
children: "Conversation: not time-indexed"
|
|
681
695
|
})
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
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
|
+
})]
|
|
685
705
|
});
|
|
686
706
|
}
|
|
687
707
|
export { useEventStream as a, useAgentStream as i, LatestEvents as n, TraceWaterfall as o, foldAgentRows as r, traceSpanMark as s, TraceWorkspace as t };
|