@tangle-network/sandbox-ui 3.0.2 → 3.0.3
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/AgentTree-D4d06rfH.js +293 -0
- package/dist/{ResearchReport-vqefUbVp.js → ResearchReport-D1TFmldm.js} +2 -1
- package/dist/{VirtualList-CMynqkkh.js → VirtualList-DcSGbEtA.js} +28 -1
- package/dist/{index-gXcuwPOX.d.ts → index-Bv2iiZaN.d.ts} +135 -2
- package/dist/{index-YU_b9xCK.d.ts → index-CHA38az4.d.ts} +3 -61
- package/dist/index.d.ts +3 -3
- package/dist/index.js +9 -8
- package/dist/record/ResearchReport.js +1 -1
- package/dist/{record-B_4XWfUz.js → record-C-EUpK-n.js} +3 -2
- package/dist/record.js +1 -1
- package/dist/report-viewer.js +80 -80
- package/dist/run/live.js +2 -2
- package/dist/run/record.d.ts +2 -2
- package/dist/run/record.js +5 -4
- package/dist/run.d.ts +3 -3
- package/dist/run.js +6 -5
- package/dist/runtime-viewer/{AgentGraphCanvas-DGq7_u8--WPFPgd72.js → AgentGraphCanvas-DGq7_u8--C6yDfIUT.js} +67 -67
- package/dist/runtime-viewer/{latest-events-CRq9sGkK-YFXUh9qO.js → latest-events-CRq9sGkK-CfoBl1dP.js} +215 -209
- package/dist/{trace-workspace-BiJbv9WQ.js → trace-workspace-B634-EcA.js} +287 -201
- package/dist/{tree-data-9D309DqD.js → tree-data-rg5voiY8.js} +1 -1
- package/dist/{AgentTree-Cju8jn51.js → use-follow-tail-DZFn7QDO.js} +144 -385
- package/dist/vault-tree.js +1 -1
- package/dist/{workspace-BrS_rHWN.js → workspace-CJD7oOEa.js} +1 -1
- package/dist/{workspace-files-pane-Di_rn4FL.js → workspace-files-pane-D24G7H_Z.js} +1 -1
- package/dist/workspace-viewer.js +9970 -9624
- package/dist/workspace.js +2 -2
- package/package.json +5 -4
- package/dist/use-follow-tail-Ht7fZGQQ.js +0 -1
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D8jQpDG7.js";
|
|
2
|
-
import { t as VirtualList } from "./VirtualList-CMynqkkh.js";
|
|
3
|
-
import { t as useFollowTail } from "./use-follow-tail-Ht7fZGQQ.js";
|
|
4
2
|
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@tangle-network/ui/primitives";
|
|
5
3
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
-
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
7
4
|
import { Brain, Settings, Timer } from "lucide-react";
|
|
8
5
|
import { getToolCategory, getToolDisplayMetadata } from "@tangle-network/ui/utils";
|
|
9
|
-
import { AgentTimelineColumn, AgentTimelineStep, agentTimelineStepKind } from "@tangle-network/ui/chat/agent-timeline";
|
|
10
6
|
import { formatCompact, formatCompact as fmt, formatCost, formatSpanDuration, formatSpanDuration as interval, formatUtcTime as utcTime, reportedCount, sumReportedCounts } from "@tangle-network/charts";
|
|
7
|
+
import { AgentTimelineStep, agentTimelineStepKind } from "@tangle-network/ui/chat/agent-timeline";
|
|
11
8
|
import { SpeakerHeader } from "@tangle-network/ui/chat/speaker";
|
|
12
9
|
import { ExpandedToolDetail } from "@tangle-network/ui/run/expanded-tool-detail";
|
|
13
10
|
import { InlineThinkingItem } from "@tangle-network/ui/run/inline-thinking-item";
|
|
14
11
|
import { RunRowShell } from "@tangle-network/ui/run/run-row-shell";
|
|
15
|
-
import {
|
|
12
|
+
import { isOpen, runStatus } from "@tangle-network/ui/run/status-meta";
|
|
13
|
+
import { useFollowTail } from "@tangle-network/ui/hooks/use-follow-tail";
|
|
16
14
|
// src/run/record/model.ts
|
|
17
15
|
var model_exports = /* @__PURE__ */ __exportAll({
|
|
18
16
|
agentState: () => agentState,
|
|
@@ -639,13 +637,13 @@ function collapsePolls(items, { callsOf, answered, keyOf, min = 2 }) {
|
|
|
639
637
|
events
|
|
640
638
|
}), min);
|
|
641
639
|
}
|
|
640
|
+
const idleReply = (text) => text.trim().length <= 280 && /\b(waiting|ending the turn|end turn|no new updates|nothing new)\b/i.test(text) ? text.trim() : null;
|
|
642
641
|
/** Exact repeated idle replies fold without hiding changed statements, tools, errors, prompts or source evidence. */
|
|
643
642
|
function collapseIdleTurns(rows, callsOf) {
|
|
644
643
|
return foldRows(rows, (event) => {
|
|
645
644
|
const d = event.detail;
|
|
646
645
|
if (d.role !== "assistant" || event.category === "lifecycle" || d.lifecycle || d.reasoning || d.recordedClaim || d.responseStatus === "error" || d.isError || d.contentOmitted || d.publicationNote || d.clip || thinkingMarkers(d).length || callsOf(event).length) return null;
|
|
647
|
-
|
|
648
|
-
return text.length <= 280 && /\b(waiting|ending the turn|end turn|no new updates|nothing new)\b/i.test(text) ? text : null;
|
|
646
|
+
return idleReply(typeof d.publicText === "string" ? d.publicText : "");
|
|
649
647
|
}, (a, b) => a === b, (events) => ({
|
|
650
648
|
kind: "idle",
|
|
651
649
|
key: `idle:${anchorOf(events[0])}`,
|
|
@@ -714,6 +712,10 @@ function promptText(text) {
|
|
|
714
712
|
/** A run-lifecycle event (start, stop, restart), drawn as a thin marker row. */
|
|
715
713
|
const isLifecycle = (event) => event.category === "lifecycle" || event.detail.lifecycle !== void 0;
|
|
716
714
|
function ToolStep({ item, previous }) {
|
|
715
|
+
if (!item.part) return /* @__PURE__ */ jsx(AgentTimelineStep, {
|
|
716
|
+
item,
|
|
717
|
+
previous
|
|
718
|
+
});
|
|
717
719
|
const part = item.part, cost = part.state.metadata?.costUsd, time = part.state.time, category = getToolCategory(part.tool);
|
|
718
720
|
const tone = part.state.status === "error" ? "var(--surface-danger-text)" : [
|
|
719
721
|
"command",
|
|
@@ -827,11 +829,10 @@ const failureText = (text) => {
|
|
|
827
829
|
return compact(body.split("\n").find((line) => line.trim()) ?? "").slice(0, 200);
|
|
828
830
|
};
|
|
829
831
|
/** One tool call as the kit's row: its verb and subject, collapsed; the input and output when opened; failures inline. */
|
|
830
|
-
function
|
|
831
|
-
const name = toolName(call.name);
|
|
832
|
-
const output = result ? textOf(result) || result.detail.contentOmitted || "" : void 0;
|
|
833
|
-
const status = state === "error" ? "error" : state === "pending" || state === "missing" && live ? "running" : "completed";
|
|
832
|
+
function toolItem(id, call, output, state, durationMs, live, cost) {
|
|
833
|
+
const name = toolName(call.name), status = state === "error" ? "error" : state === "pending" || state === "missing" && live ? "running" : "completed";
|
|
834
834
|
const note = state === "ambiguous" || state === "missing" && !live ? callStatus(state, live) : void 0;
|
|
835
|
+
const duration = durationMs !== null && durationMs >= 0 ? durationMs : void 0;
|
|
835
836
|
const part = {
|
|
836
837
|
type: "tool",
|
|
837
838
|
id,
|
|
@@ -841,20 +842,19 @@ function toolItems(id, call, result, state, durationMs, live, opener) {
|
|
|
841
842
|
input: inputOf(call.input),
|
|
842
843
|
...output !== void 0 ? { output } : {},
|
|
843
844
|
...status === "error" ? { error: failureText(output ?? "") || "The call failed." } : {},
|
|
844
|
-
...
|
|
845
|
+
...duration !== void 0 ? { time: {
|
|
845
846
|
start: 0,
|
|
846
|
-
end:
|
|
847
|
+
end: duration
|
|
847
848
|
} } : {},
|
|
848
849
|
metadata: {
|
|
849
850
|
...note ? { note } : {},
|
|
850
|
-
...
|
|
851
|
+
...cost !== void 0 ? { costUsd: cost } : {}
|
|
851
852
|
}
|
|
852
853
|
}
|
|
853
854
|
};
|
|
854
|
-
const known = KIT_TOOLS.has(name.toLowerCase());
|
|
855
|
-
const meta = getToolDisplayMetadata(part);
|
|
855
|
+
const known = KIT_TOOLS.has(name.toLowerCase()), meta = getToolDisplayMetadata(part);
|
|
856
856
|
const detail = argsLabel(call.input) ?? (meta.description || (known ? void 0 : preview(call)));
|
|
857
|
-
|
|
857
|
+
return {
|
|
858
858
|
id,
|
|
859
859
|
kind: "tool",
|
|
860
860
|
part,
|
|
@@ -864,9 +864,12 @@ function toolItems(id, call, result, state, durationMs, live, opener) {
|
|
|
864
864
|
label: known ? meta.title : name.replaceAll("_", " "),
|
|
865
865
|
status: status === "error" ? "error" : status === "running" ? "running" : "success",
|
|
866
866
|
...detail ? { detail } : {},
|
|
867
|
-
...
|
|
867
|
+
...duration !== void 0 ? { duration } : {}
|
|
868
868
|
}
|
|
869
869
|
};
|
|
870
|
+
}
|
|
871
|
+
function toolItems(id, call, result, state, durationMs, live, opener) {
|
|
872
|
+
const item = toolItem(id, call, result ? textOf(result) || result.detail.contentOmitted || "" : void 0, state, durationMs, live, typeof result?.detail.costListUsd === "number" ? result.detail.costListUsd : void 0);
|
|
870
873
|
const clip = clipOf(result?.detail.clip);
|
|
871
874
|
return result && clip ? [item, {
|
|
872
875
|
id: `${id}:clip`,
|
|
@@ -877,6 +880,86 @@ function toolItems(id, call, result, state, durationMs, live, opener) {
|
|
|
877
880
|
})
|
|
878
881
|
}] : [item];
|
|
879
882
|
}
|
|
883
|
+
/** The same prompt control for retained and streamed turns; opening state belongs to the reader. */
|
|
884
|
+
function PromptMore({ text, id, opened, setOpen }) {
|
|
885
|
+
if (promptText(text).length <= 280) return null;
|
|
886
|
+
const short = !opened.has(id);
|
|
887
|
+
return /* @__PURE__ */ jsx("p", {
|
|
888
|
+
className: "ar-prompt-more",
|
|
889
|
+
children: /* @__PURE__ */ jsx("button", {
|
|
890
|
+
type: "button",
|
|
891
|
+
className: "link-button",
|
|
892
|
+
"data-open-key": id,
|
|
893
|
+
"aria-expanded": !short,
|
|
894
|
+
onClick: () => setOpen(id, short),
|
|
895
|
+
children: short ? "Full prompt" : "Shorter"
|
|
896
|
+
})
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
/** Live values use the same canonical items and tool presentation as retained conversations. */
|
|
900
|
+
function timelineItems(entries, streaming, opened) {
|
|
901
|
+
const rows = foldRows(entries.map((event) => ({
|
|
902
|
+
kind: "event",
|
|
903
|
+
key: event.id,
|
|
904
|
+
event
|
|
905
|
+
})), (entry) => entry.kind === "message" && entry.role === "assistant" && entry.provenance !== "recorded-result" ? idleReply(entry.content) : null, (a, b) => a === b, (events) => ({
|
|
906
|
+
kind: "idle",
|
|
907
|
+
key: events[0].id,
|
|
908
|
+
events
|
|
909
|
+
}));
|
|
910
|
+
return rows.map((row, index) => {
|
|
911
|
+
const entry = row.kind === "event" ? row.event : row.events[0];
|
|
912
|
+
if (row.kind === "idle") return idleItem(entry.id, row.events.map((event) => ({
|
|
913
|
+
id: event.id,
|
|
914
|
+
at: Number.isFinite(event.at) ? new Date(event.at).toISOString() : void 0,
|
|
915
|
+
text: event.content
|
|
916
|
+
})));
|
|
917
|
+
if (entry.kind === "message") {
|
|
918
|
+
const body = entry.role === "user" ? promptText(entry.content) : entry.content;
|
|
919
|
+
const short = entry.role === "user" && opened && !opened.has(`prompt:${entry.id}`) && body.length > 280;
|
|
920
|
+
return {
|
|
921
|
+
id: entry.id,
|
|
922
|
+
kind: "message",
|
|
923
|
+
role: entry.role,
|
|
924
|
+
content: short ? `${body.slice(0, 280).trimEnd()}…` : body,
|
|
925
|
+
isStreaming: streaming && index === rows.length - 1,
|
|
926
|
+
...entry.role === "user" && Number.isFinite(entry.at) ? { timestamp: new Date(entry.at) } : {}
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
if (entry.kind === "tool") return toolItem(entry.id, {
|
|
930
|
+
id: entry.id,
|
|
931
|
+
name: entry.name ?? entry.call.label,
|
|
932
|
+
input: entry.input === void 0 ? entry.call.detail : typeof entry.input === "string" ? entry.input : JSON.stringify(entry.input)
|
|
933
|
+
}, entry.call.output, entry.call.status === "error" ? "error" : entry.call.status === "running" ? streaming ? "pending" : "missing" : "returned", entry.call.duration ?? null, streaming, entry.costUsd);
|
|
934
|
+
if (entry.kind === "notice" && entry.isError) return {
|
|
935
|
+
id: entry.id,
|
|
936
|
+
kind: "status",
|
|
937
|
+
tone: "error",
|
|
938
|
+
label: "Execution error",
|
|
939
|
+
detail: entry.text
|
|
940
|
+
};
|
|
941
|
+
if (entry.kind === "notice") return {
|
|
942
|
+
id: entry.id,
|
|
943
|
+
kind: "custom",
|
|
944
|
+
content: /* @__PURE__ */ jsx("p", {
|
|
945
|
+
className: "text-xs text-muted-foreground",
|
|
946
|
+
children: entry.text
|
|
947
|
+
})
|
|
948
|
+
};
|
|
949
|
+
return {
|
|
950
|
+
id: entry.id,
|
|
951
|
+
kind: "custom",
|
|
952
|
+
content: /* @__PURE__ */ jsx(InlineThinkingItem, {
|
|
953
|
+
part: {
|
|
954
|
+
type: "reasoning",
|
|
955
|
+
text: entry.text
|
|
956
|
+
},
|
|
957
|
+
defaultOpen: false,
|
|
958
|
+
openWhileActive: false
|
|
959
|
+
})
|
|
960
|
+
};
|
|
961
|
+
});
|
|
962
|
+
}
|
|
880
963
|
const toolNote = (part) => {
|
|
881
964
|
const note = part.state.metadata?.note, time = part.state.time;
|
|
882
965
|
const duration = time?.end != null && time.start != null ? formatSpanDuration(time.end - time.start) : "Not recorded";
|
|
@@ -940,30 +1023,14 @@ function pollItem(row) {
|
|
|
940
1023
|
})
|
|
941
1024
|
};
|
|
942
1025
|
}
|
|
943
|
-
/**
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
content: /* @__PURE__ */ jsx(RunRowShell, {
|
|
948
|
-
icon: /* @__PURE__ */ jsx(Settings, {
|
|
949
|
-
size: 14,
|
|
950
|
-
"aria-hidden": "true"
|
|
951
|
-
}),
|
|
952
|
-
title: hollowSummary(row.calls),
|
|
953
|
-
description: "args not captured",
|
|
954
|
-
durationMs: row.spanMs || void 0
|
|
955
|
-
})
|
|
956
|
-
});
|
|
957
|
-
/** What one record row shows, as the kit's timeline items. */
|
|
958
|
-
function rowItems(row, context) {
|
|
959
|
-
if (row.kind === "polls") return [pollItem(row)];
|
|
960
|
-
if (row.kind === "hollow") return [hollowItem(row)];
|
|
961
|
-
if (row.kind === "idle") return [{
|
|
962
|
-
id: `${row.key}:${context.selected ?? ""}`,
|
|
1026
|
+
/** The exact idle replies stay inspectable inside one shared fold in either conversation. */
|
|
1027
|
+
function idleItem(id, events, selected) {
|
|
1028
|
+
return {
|
|
1029
|
+
id,
|
|
963
1030
|
kind: "fold",
|
|
964
|
-
summary: `${
|
|
965
|
-
defaultOpen:
|
|
966
|
-
items:
|
|
1031
|
+
summary: `${events.length} idle turns · ${events[0].text}`,
|
|
1032
|
+
defaultOpen: events.some((event) => event.id === selected),
|
|
1033
|
+
items: events.map((event) => ({
|
|
967
1034
|
id: event.id,
|
|
968
1035
|
kind: "custom",
|
|
969
1036
|
content: /* @__PURE__ */ jsxs("div", {
|
|
@@ -971,16 +1038,38 @@ function rowItems(row, context) {
|
|
|
971
1038
|
"data-message": event.id,
|
|
972
1039
|
children: [/* @__PURE__ */ jsx("time", {
|
|
973
1040
|
dateTime: event.at,
|
|
974
|
-
children: utcTime(event.at)
|
|
1041
|
+
children: event.at ? utcTime(event.at) : "Unknown time"
|
|
975
1042
|
}), /* @__PURE__ */ jsx(AgentTimelineStep, { item: {
|
|
976
1043
|
id: event.id,
|
|
977
1044
|
kind: "message",
|
|
978
1045
|
role: "assistant",
|
|
979
|
-
content:
|
|
1046
|
+
content: event.text
|
|
980
1047
|
} })]
|
|
981
1048
|
})
|
|
982
1049
|
}))
|
|
1050
|
+
};
|
|
1051
|
+
}
|
|
1052
|
+
/** What one record row shows, as the kit's timeline items. */
|
|
1053
|
+
function rowItems(row, context) {
|
|
1054
|
+
if (row.kind === "polls") return [pollItem(row)];
|
|
1055
|
+
if (row.kind === "hollow") return [{
|
|
1056
|
+
id: row.key,
|
|
1057
|
+
kind: "custom",
|
|
1058
|
+
content: /* @__PURE__ */ jsx(RunRowShell, {
|
|
1059
|
+
icon: /* @__PURE__ */ jsx(Settings, {
|
|
1060
|
+
size: 14,
|
|
1061
|
+
"aria-hidden": "true"
|
|
1062
|
+
}),
|
|
1063
|
+
title: hollowSummary(row.calls),
|
|
1064
|
+
description: "args not captured",
|
|
1065
|
+
durationMs: row.spanMs || void 0
|
|
1066
|
+
})
|
|
983
1067
|
}];
|
|
1068
|
+
if (row.kind === "idle") return [idleItem(`${row.key}:${context.selected ?? ""}`, row.events.map((event) => ({
|
|
1069
|
+
id: event.id,
|
|
1070
|
+
at: event.at,
|
|
1071
|
+
text: textOf(event)
|
|
1072
|
+
})), context.selected)];
|
|
984
1073
|
const { index, cutoff, anchor, thinkingSpan, opened, paired, live } = context;
|
|
985
1074
|
const event = row.event;
|
|
986
1075
|
if (isLifecycle(event)) {
|
|
@@ -1085,8 +1174,6 @@ function rowItems(row, context) {
|
|
|
1085
1174
|
}
|
|
1086
1175
|
return items;
|
|
1087
1176
|
}
|
|
1088
|
-
/** The kind of a row's last item, which sets the gap above the next row. */
|
|
1089
|
-
const lastKind = (items) => items.length ? agentTimelineStepKind(items[items.length - 1]) : void 0;
|
|
1090
1177
|
function ConversationRowView({ row, items, previous, turn, context }) {
|
|
1091
1178
|
const { selected, opened, anchor, setOpen, flagMarks, opener, flags } = context;
|
|
1092
1179
|
const events = row.kind === "event" ? [row.event] : row.events;
|
|
@@ -1130,41 +1217,22 @@ function ConversationRowView({ row, items, previous, turn, context }) {
|
|
|
1130
1217
|
const message = textOf(event);
|
|
1131
1218
|
const standalone = event.detail.toolCallId !== void 0 || event.detail.role === "toolResult";
|
|
1132
1219
|
const clip = clipOf(event.detail.clip);
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
const long = promptText(message).length > 280;
|
|
1136
|
-
const short = long && !opened.has(key);
|
|
1137
|
-
return /* @__PURE__ */ jsxs("article", {
|
|
1138
|
-
...rowProps,
|
|
1139
|
-
children: [
|
|
1140
|
-
steps,
|
|
1141
|
-
long && /* @__PURE__ */ jsx("p", {
|
|
1142
|
-
className: "ar-prompt-more",
|
|
1143
|
-
children: /* @__PURE__ */ jsx("button", {
|
|
1144
|
-
type: "button",
|
|
1145
|
-
className: "link-button",
|
|
1146
|
-
"data-open-key": key,
|
|
1147
|
-
"aria-expanded": !short,
|
|
1148
|
-
onClick: () => setOpen(key, short),
|
|
1149
|
-
children: short ? "Full prompt" : "Shorter"
|
|
1150
|
-
})
|
|
1151
|
-
}),
|
|
1152
|
-
!short && /* @__PURE__ */ jsx(ClipNote, {
|
|
1153
|
-
clip,
|
|
1154
|
-
open: opener(event)
|
|
1155
|
-
}),
|
|
1156
|
-
flagMarks(event)
|
|
1157
|
-
]
|
|
1158
|
-
});
|
|
1159
|
-
}
|
|
1220
|
+
const prompt = event.detail.role === "user" && !!message && !standalone, key = `prompt:${anchor(event)}`;
|
|
1221
|
+
const short = prompt && promptText(message).length > 280 && !opened.has(key);
|
|
1160
1222
|
const finding = event.detail.recordedClaim !== void 0;
|
|
1161
|
-
const notes = [event.detail.publicationNote, finding ? event.detail.assessment : void 0].filter((note) => Boolean(note));
|
|
1223
|
+
const notes = (prompt ? [] : [event.detail.publicationNote, finding ? event.detail.assessment : void 0]).filter((note) => Boolean(note));
|
|
1162
1224
|
return /* @__PURE__ */ jsxs("article", {
|
|
1163
1225
|
...rowProps,
|
|
1164
1226
|
children: [
|
|
1165
1227
|
steps,
|
|
1166
|
-
|
|
1167
|
-
|
|
1228
|
+
prompt && /* @__PURE__ */ jsx(PromptMore, {
|
|
1229
|
+
text: message,
|
|
1230
|
+
id: key,
|
|
1231
|
+
opened,
|
|
1232
|
+
setOpen
|
|
1233
|
+
}),
|
|
1234
|
+
message && !standalone && !short && /* @__PURE__ */ jsx(ClipNote, {
|
|
1235
|
+
clip: !prompt && callsOf(event).length ? void 0 : clip,
|
|
1168
1236
|
open: opener(event)
|
|
1169
1237
|
}),
|
|
1170
1238
|
notes.map((note) => /* @__PURE__ */ jsx("p", {
|
|
@@ -1175,313 +1243,4 @@ function ConversationRowView({ row, items, previous, turn, context }) {
|
|
|
1175
1243
|
]
|
|
1176
1244
|
});
|
|
1177
1245
|
}
|
|
1178
|
-
|
|
1179
|
-
function Conversation({ index, actor, cutoff, query, category, selected, openSource, flags, onFlag, lifecycle = false, live = false, follow = live, opening }) {
|
|
1180
|
-
const [opened, setOpened] = useState(() => {
|
|
1181
|
-
const at = anchorsOf(index.events);
|
|
1182
|
-
return new Set(index.events.filter((event) => event.detail.promptKind === "initial").map((event) => `prompt:${at.get(event.id) ?? event.id}`));
|
|
1183
|
-
});
|
|
1184
|
-
const scroll = useRef(null);
|
|
1185
|
-
const anchors = useMemo(() => anchorsOf(index.events), [index]);
|
|
1186
|
-
const anchor = useCallback((event) => anchors.get(event.id) ?? event.id, [anchors]);
|
|
1187
|
-
const opener = (event) => openSource ? (sha256) => openSource(sha256, event) : void 0;
|
|
1188
|
-
const setOpen = (key, open) => setOpened((current) => {
|
|
1189
|
-
if (current.has(key) === open) return current;
|
|
1190
|
-
const next = new Set(current);
|
|
1191
|
-
if (open) next.add(key);
|
|
1192
|
-
else next.delete(key);
|
|
1193
|
-
return next;
|
|
1194
|
-
});
|
|
1195
|
-
const paired = (event, call) => {
|
|
1196
|
-
const key = toolKey(event.node, call.id);
|
|
1197
|
-
return index.calls.get(key)?.length === 1 ? index.results.get(key) ?? [] : [];
|
|
1198
|
-
};
|
|
1199
|
-
const target = useMemo(() => {
|
|
1200
|
-
if (!selected) return void 0;
|
|
1201
|
-
const event = index.byEvent.get(selected);
|
|
1202
|
-
if (event?.detail.toolCallId !== void 0) {
|
|
1203
|
-
const calls = index.calls.get(toolKey(event.node, event.detail.toolCallId));
|
|
1204
|
-
if (calls?.length === 1) return calls[0].event.id;
|
|
1205
|
-
}
|
|
1206
|
-
return selected;
|
|
1207
|
-
}, [selected, index]);
|
|
1208
|
-
const items = useMemo(() => (index.byActor.get(actor) ?? []).filter((event) => {
|
|
1209
|
-
if (ms(event.at) > cutoff) return false;
|
|
1210
|
-
if (event.id === target) return true;
|
|
1211
|
-
if (isLifecycle(event)) return lifecycle && eventMatches(event, index, query, category);
|
|
1212
|
-
if (event.detail.toolCallId !== void 0) {
|
|
1213
|
-
const matching = index.calls.get(toolKey(event.node, event.detail.toolCallId));
|
|
1214
|
-
if (matching?.length === 1 && ms(matching[0].event.at) <= cutoff) return false;
|
|
1215
|
-
}
|
|
1216
|
-
const calls = callsOf(event);
|
|
1217
|
-
if (!(event.detail.role || textOf(event) || event.detail.reasoning || event.detail.responseStatus === "error" || calls.length)) return false;
|
|
1218
|
-
if (event.detail.role === "assistant" && !textOf(event) && !event.detail.reasoning && !calls.length && event.detail.responseStatus !== "error" && !event.detail.contentOmitted && (!thinkingMarkers(event.detail).length || quietThinking(event.detail))) return false;
|
|
1219
|
-
if (eventMatches(event, index, query, category)) return true;
|
|
1220
|
-
return calls.some((call) => {
|
|
1221
|
-
const key = toolKey(event.node, call.id);
|
|
1222
|
-
return index.calls.get(key)?.length === 1 && (index.results.get(key) ?? []).some((result) => ms(result.at) <= cutoff && eventMatches(result, index, query, category));
|
|
1223
|
-
});
|
|
1224
|
-
}), [
|
|
1225
|
-
index,
|
|
1226
|
-
actor,
|
|
1227
|
-
cutoff,
|
|
1228
|
-
query,
|
|
1229
|
-
category,
|
|
1230
|
-
lifecycle,
|
|
1231
|
-
target
|
|
1232
|
-
]);
|
|
1233
|
-
const shown = useMemo(() => {
|
|
1234
|
-
if (!opening?.text || query || category !== "all" || items.some((event) => event.detail.role === "user" && event.detail.promptKind !== "steering")) return items;
|
|
1235
|
-
const first = items[0]?.at ?? opening.at;
|
|
1236
|
-
return [{
|
|
1237
|
-
id: `${actor}:opening`,
|
|
1238
|
-
node: actor,
|
|
1239
|
-
at: first < opening.at ? first : opening.at,
|
|
1240
|
-
kind: "message",
|
|
1241
|
-
category: "other",
|
|
1242
|
-
label: "prompt",
|
|
1243
|
-
detail: {
|
|
1244
|
-
role: "user",
|
|
1245
|
-
publicText: opening.text,
|
|
1246
|
-
promptKind: "initial"
|
|
1247
|
-
}
|
|
1248
|
-
}, ...items];
|
|
1249
|
-
}, [
|
|
1250
|
-
items,
|
|
1251
|
-
opening,
|
|
1252
|
-
actor,
|
|
1253
|
-
query,
|
|
1254
|
-
category
|
|
1255
|
-
]);
|
|
1256
|
-
const rows = useMemo(() => collapseIdleTurns(collapseHollowTurns(collapsePolls(shown, {
|
|
1257
|
-
callsOf,
|
|
1258
|
-
answered: (event, id) => answeredBy(index.results.get(toolKey(event.node, id))),
|
|
1259
|
-
keyOf: anchor
|
|
1260
|
-
}), {
|
|
1261
|
-
callsOf,
|
|
1262
|
-
captured: (event, id) => (index.results.get(toolKey(event.node, id)) ?? []).some((result) => textOf(result)),
|
|
1263
|
-
keyOf: anchor
|
|
1264
|
-
}), callsOf), [
|
|
1265
|
-
shown,
|
|
1266
|
-
index,
|
|
1267
|
-
anchor
|
|
1268
|
-
]);
|
|
1269
|
-
const thinkingSpan = useMemo(() => {
|
|
1270
|
-
const spans = /* @__PURE__ */ new Map();
|
|
1271
|
-
let previous = null;
|
|
1272
|
-
for (const event of index.byActor.get(actor) ?? []) {
|
|
1273
|
-
const at = ms(event.at);
|
|
1274
|
-
if (previous !== null && Number.isFinite(at) && thinkingMarkers(event.detail).length) spans.set(event.id, Math.max(0, at - previous));
|
|
1275
|
-
if (Number.isFinite(at)) previous = at;
|
|
1276
|
-
}
|
|
1277
|
-
return spans;
|
|
1278
|
-
}, [index, actor]);
|
|
1279
|
-
const rowOf = useMemo(() => {
|
|
1280
|
-
const map = /* @__PURE__ */ new Map();
|
|
1281
|
-
for (const row of rows) if (row.kind !== "event") for (const event of row.events) map.set(event.id, row.key);
|
|
1282
|
-
else map.set(row.event.id, row.key);
|
|
1283
|
-
return map;
|
|
1284
|
-
}, [rows]);
|
|
1285
|
-
const retained = (index.byActor.get(actor) ?? []).some((item) => !isLifecycle(item) && (item.detail.role || textOf(item) || callsOf(item).length));
|
|
1286
|
-
const { following } = useFollowTail(scroll, {
|
|
1287
|
-
identity: actor,
|
|
1288
|
-
content: rows,
|
|
1289
|
-
follow,
|
|
1290
|
-
target
|
|
1291
|
-
});
|
|
1292
|
-
const arrival = useRef({ actor });
|
|
1293
|
-
useLayoutEffect(() => {
|
|
1294
|
-
const tail = rows.at(-1), event = tail?.kind === "event" ? tail.event : tail?.events.at(-1), entry = tail?.kind === "event" ? tail.event.id : tail?.events[0]?.id;
|
|
1295
|
-
let animate = live && arrival.current.actor === actor && !!arrival.current.id && arrival.current.id !== event?.id;
|
|
1296
|
-
arrival.current = {
|
|
1297
|
-
actor,
|
|
1298
|
-
id: event?.id
|
|
1299
|
-
};
|
|
1300
|
-
const element = scroll.current;
|
|
1301
|
-
if (!element || !following.current) return;
|
|
1302
|
-
const frame = requestAnimationFrame(() => {
|
|
1303
|
-
if (!following.current) return;
|
|
1304
|
-
const row = entry && element.querySelector(`[data-entry="${CSS.escape(entry)}"]`);
|
|
1305
|
-
if (animate && row) {
|
|
1306
|
-
animate = false;
|
|
1307
|
-
const style = getComputedStyle(element), value = style.getPropertyValue("--duration-stream").trim(), duration = parseFloat(value) * (value.endsWith("ms") ? 1 : 1e3);
|
|
1308
|
-
if (duration > 0 && !matchMedia("(prefers-reduced-motion: reduce)").matches) row.animate([{ opacity: 0 }, { opacity: 1 }], {
|
|
1309
|
-
duration,
|
|
1310
|
-
easing: style.getPropertyValue("--ease-expo").trim() || "linear"
|
|
1311
|
-
});
|
|
1312
|
-
}
|
|
1313
|
-
});
|
|
1314
|
-
return () => cancelAnimationFrame(frame);
|
|
1315
|
-
}, [rows]);
|
|
1316
|
-
useEffect(() => {
|
|
1317
|
-
if (!selected) return;
|
|
1318
|
-
const event = index.byEvent.get(selected);
|
|
1319
|
-
if (!event) return;
|
|
1320
|
-
const keys = [`prompt:${anchor(event)}`, `reasoning:${anchor(event)}`];
|
|
1321
|
-
if (event.detail.toolCallId !== void 0) for (const match of index.calls.get(toolKey(event.node, event.detail.toolCallId)) ?? []) keys.push(`tool:${anchor(match.event)}:${match.call.id}`, rowOf.get(match.event.id) ?? "");
|
|
1322
|
-
for (const call of callsOf(event)) keys.push(`tool:${anchor(event)}:${call.id}`);
|
|
1323
|
-
const row = rowOf.get(selected);
|
|
1324
|
-
if (row?.startsWith("polls:")) keys.push(row);
|
|
1325
|
-
setOpened((current) => /* @__PURE__ */ new Set([...current, ...keys.filter(Boolean)]));
|
|
1326
|
-
}, [selected, index]);
|
|
1327
|
-
const flagMarks = (event) => {
|
|
1328
|
-
const marks = flags?.get(event.id);
|
|
1329
|
-
if (!marks?.length) return null;
|
|
1330
|
-
return /* @__PURE__ */ jsx("span", {
|
|
1331
|
-
className: "event-flags",
|
|
1332
|
-
children: marks.map((flag) => /* @__PURE__ */ jsx("button", {
|
|
1333
|
-
type: "button",
|
|
1334
|
-
className: `event-flag polarity-${flag.polarity}`,
|
|
1335
|
-
title: flag.title,
|
|
1336
|
-
"data-flag": flag.dimension,
|
|
1337
|
-
onClick: () => onFlag?.(flag, event),
|
|
1338
|
-
children: flag.dimension
|
|
1339
|
-
}, `${flag.dimension}:${flag.label}`))
|
|
1340
|
-
});
|
|
1341
|
-
};
|
|
1342
|
-
const keyOf = useCallback((row) => row.key, []);
|
|
1343
|
-
const estimate = useCallback((row) => {
|
|
1344
|
-
if (row.kind !== "event") return 36;
|
|
1345
|
-
if (isLifecycle(row.event)) return 26;
|
|
1346
|
-
return !textOf(row.event) && callsOf(row.event).length ? 16 + 36 * callsOf(row.event).length : 96;
|
|
1347
|
-
}, []);
|
|
1348
|
-
const context = {
|
|
1349
|
-
index,
|
|
1350
|
-
cutoff,
|
|
1351
|
-
selected,
|
|
1352
|
-
opened,
|
|
1353
|
-
anchor,
|
|
1354
|
-
opener,
|
|
1355
|
-
setOpen,
|
|
1356
|
-
flagMarks,
|
|
1357
|
-
paired,
|
|
1358
|
-
thinkingSpan,
|
|
1359
|
-
flags,
|
|
1360
|
-
live
|
|
1361
|
-
};
|
|
1362
|
-
const itemsOf = useMemo(() => rows.map((row) => rowItems(row, context)), [
|
|
1363
|
-
rows,
|
|
1364
|
-
opened,
|
|
1365
|
-
cutoff,
|
|
1366
|
-
selected,
|
|
1367
|
-
live,
|
|
1368
|
-
index,
|
|
1369
|
-
thinkingSpan
|
|
1370
|
-
]);
|
|
1371
|
-
const turns = useMemo(() => {
|
|
1372
|
-
let previous;
|
|
1373
|
-
return rows.map((row) => {
|
|
1374
|
-
const event = row.kind === "event" ? row.event : row.events[0];
|
|
1375
|
-
const turn = event.detail.role === "assistant" && !isLifecycle(event) && (!previous || previous.detail.role === "user" || (event.detail.attempt !== void 0 ? event.detail.attempt !== previous.detail.attempt : ms(event.at) - ms(previous.at) > 12e4));
|
|
1376
|
-
previous = row.kind === "event" ? event : row.events.at(-1);
|
|
1377
|
-
return turn;
|
|
1378
|
-
});
|
|
1379
|
-
}, [rows]);
|
|
1380
|
-
const render = (row, i) => /* @__PURE__ */ jsx(ConversationRowView, {
|
|
1381
|
-
row,
|
|
1382
|
-
items: itemsOf[i] ?? [],
|
|
1383
|
-
previous: i ? lastKind(itemsOf[i - 1] ?? []) : void 0,
|
|
1384
|
-
turn: turns[i],
|
|
1385
|
-
context
|
|
1386
|
-
});
|
|
1387
|
-
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", {
|
|
1388
|
-
className: "record-conversation conversation-scroll",
|
|
1389
|
-
"data-chat": true,
|
|
1390
|
-
ref: scroll,
|
|
1391
|
-
tabIndex: 0,
|
|
1392
|
-
"aria-label": "Scrollable retained conversation",
|
|
1393
|
-
children: [!rows.length && /* @__PURE__ */ jsx("p", {
|
|
1394
|
-
className: "chat-empty",
|
|
1395
|
-
children: query || category !== "all" ? "No messages match this filter." : retained ? "No messages at the selected time." : "Conversation not retained. Its absence does not mean the agent did no work."
|
|
1396
|
-
}), /* @__PURE__ */ jsx(AgentTimelineColumn, {
|
|
1397
|
-
className: "ar-chat",
|
|
1398
|
-
children: /* @__PURE__ */ jsx(VirtualList, {
|
|
1399
|
-
items: rows,
|
|
1400
|
-
keyOf,
|
|
1401
|
-
render,
|
|
1402
|
-
scroller: scroll,
|
|
1403
|
-
target: target ? rowOf.get(target) : void 0,
|
|
1404
|
-
estimate
|
|
1405
|
-
})
|
|
1406
|
-
})]
|
|
1407
|
-
}) });
|
|
1408
|
-
}
|
|
1409
|
-
// src/run/record/AgentTree.tsx
|
|
1410
|
-
/** Retained identity and recorded time define the hierarchy; labels never join sessions or invent parents. */
|
|
1411
|
-
function AgentTree({ index, actor, cutoff, select }) {
|
|
1412
|
-
const roots = useMemo(() => {
|
|
1413
|
-
const nodes = index.actors.filter((node) => node.kind !== "finding");
|
|
1414
|
-
const byId = new Map(nodes.map((node) => [node.id, node]));
|
|
1415
|
-
const children = /* @__PURE__ */ new Map();
|
|
1416
|
-
for (const node of nodes) {
|
|
1417
|
-
if (!node.parent) continue;
|
|
1418
|
-
const parent = index.canonical(node.parent), siblings = children.get(parent) ?? [];
|
|
1419
|
-
siblings.push(node);
|
|
1420
|
-
children.set(parent, siblings);
|
|
1421
|
-
}
|
|
1422
|
-
const visited = /* @__PURE__ */ new Set();
|
|
1423
|
-
const visit = (node) => {
|
|
1424
|
-
if (visited.has(node.id)) return [];
|
|
1425
|
-
visited.add(node.id);
|
|
1426
|
-
return [{
|
|
1427
|
-
node,
|
|
1428
|
-
children: (children.get(node.id) ?? []).flatMap(visit)
|
|
1429
|
-
}];
|
|
1430
|
-
};
|
|
1431
|
-
const roots = nodes.filter((node) => !node.parent || !byId.has(index.canonical(node.parent))).flatMap(visit);
|
|
1432
|
-
for (const node of nodes) roots.push(...visit(node));
|
|
1433
|
-
return roots;
|
|
1434
|
-
}, [index]);
|
|
1435
|
-
const renderNodes = (entries, nested = false) => /* @__PURE__ */ jsx("ul", {
|
|
1436
|
-
className: nested ? "m-0 ml-3 list-none border-l border-border pl-2" : "m-0 grid list-none gap-1 p-0",
|
|
1437
|
-
children: entries.map(({ node, children }) => {
|
|
1438
|
-
const firstEvent = index.byActor.get(node.id)?.[0];
|
|
1439
|
-
const begin = node.start ? ms(node.start) : firstEvent ? ms(firstEvent.at) : void 0;
|
|
1440
|
-
const future = begin !== void 0 && begin > cutoff, pending = typeof node.end === "string" && ms(node.end) > cutoff;
|
|
1441
|
-
const status = runStatus(future || pending ? "unknown" : node.status ?? "unknown");
|
|
1442
|
-
const state = future ? "Not yet started" : pending ? "Not yet settled" : statusMeta(status).label;
|
|
1443
|
-
return /* @__PURE__ */ jsxs("li", {
|
|
1444
|
-
className: "min-w-0",
|
|
1445
|
-
children: [/* @__PURE__ */ jsxs("button", {
|
|
1446
|
-
type: "button",
|
|
1447
|
-
className: "flex w-full min-w-0 items-start gap-2 rounded border border-transparent px-2 py-1.5 text-left text-sm text-foreground hover:border-border focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring aria-pressed:border-border aria-pressed:bg-muted data-[future]:opacity-55",
|
|
1448
|
-
"aria-label": "Read " + roleOf(node) + " " + node.label + " conversation. " + state + ".",
|
|
1449
|
-
"aria-pressed": actor === node.id,
|
|
1450
|
-
"data-node": node.id,
|
|
1451
|
-
"data-future": future ? "" : void 0,
|
|
1452
|
-
title: node.label + (node.assignment ? " · " + node.assignment : "") + " · " + state,
|
|
1453
|
-
onClick: () => select(node.id),
|
|
1454
|
-
children: [/* @__PURE__ */ jsx(RunStatusIcon, {
|
|
1455
|
-
status,
|
|
1456
|
-
className: "mt-0.5 size-3.5 shrink-0",
|
|
1457
|
-
"aria-hidden": true
|
|
1458
|
-
}), /* @__PURE__ */ jsxs("span", {
|
|
1459
|
-
className: "grid min-w-0 gap-0.5 break-words",
|
|
1460
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
1461
|
-
className: "font-semibold",
|
|
1462
|
-
children: node.label
|
|
1463
|
-
}), /* @__PURE__ */ jsxs("span", {
|
|
1464
|
-
className: "text-muted-foreground",
|
|
1465
|
-
children: [
|
|
1466
|
-
roleOf(node),
|
|
1467
|
-
" · ",
|
|
1468
|
-
state
|
|
1469
|
-
]
|
|
1470
|
-
})]
|
|
1471
|
-
})]
|
|
1472
|
-
}), children.length > 0 && renderNodes(children, true)]
|
|
1473
|
-
}, node.id);
|
|
1474
|
-
})
|
|
1475
|
-
});
|
|
1476
|
-
return /* @__PURE__ */ jsx("div", {
|
|
1477
|
-
className: "record-agent-tree max-h-80 overflow-auto px-2 py-2",
|
|
1478
|
-
"data-graph": true,
|
|
1479
|
-
role: "group",
|
|
1480
|
-
"aria-label": "Recorded agent hierarchy. Select an agent to read its conversation.",
|
|
1481
|
-
children: roots.length ? renderNodes(roots) : /* @__PURE__ */ jsx("p", {
|
|
1482
|
-
className: "text-sm text-muted-foreground",
|
|
1483
|
-
children: "No agent topology was retained."
|
|
1484
|
-
})
|
|
1485
|
-
});
|
|
1486
|
-
}
|
|
1487
|
-
export { fmt as a, modelIdentity as c, recordFlowTrace as d, roleOf as f, utcTime as h, eventSource as i, model_exports as l, toolKey as m, Conversation as n, indexRecord as o, textOf as p, eventMatches as r, interval as s, AgentTree as t, ms as u };
|
|
1246
|
+
export { ms as C, toolKey as D, textOf as E, utcTime as O, model_exports as S, roleOf as T, eventSource as _, isLifecycle as a, interval as b, anchorsOf as c, collapseIdleTurns as d, collapsePolls as f, eventMatches as g, callsOf as h, ToolStep as i, answeredBy as l, thinkingMarkers as m, ConversationRowView as n, rowItems as o, quietThinking as p, PromptMore as r, timelineItems as s, useFollowTail as t, collapseHollowTurns as u, fmt as v, recordFlowTrace as w, modelIdentity as x, indexRecord as y };
|
package/dist/vault-tree.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { r as VAULT_TREE_CHILD_PAGE, i as VaultTree, t as fileTreeFromPaths, n as filterFileNodes } from "./tree-data-
|
|
1
|
+
export { r as VAULT_TREE_CHILD_PAGE, i as VaultTree, t as fileTreeFromPaths, n as filterFileNodes } from "./tree-data-rg5voiY8.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as cn$1 } from "./utils-BER_bdgE.js";
|
|
2
2
|
import { r as ShellHeader } from "./shell-header-CwqDzC4I.js";
|
|
3
3
|
import { t as MOTION_CONTROL } from "./motion-2Ine0j_s.js";
|
|
4
|
-
import "./workspace-files-pane-
|
|
4
|
+
import "./workspace-files-pane-D24G7H_Z.js";
|
|
5
5
|
import { ArtifactPane, ArtifactPane as ArtifactPane$1, EmptyState, Input, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@tangle-network/ui/primitives";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { Markdown } from "@tangle-network/ui/markdown";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as cn } from "./utils-BER_bdgE.js";
|
|
2
|
-
import { i as VaultTree, n as filterFileNodes, t as fileTreeFromPaths } from "./tree-data-
|
|
2
|
+
import { i as VaultTree, n as filterFileNodes, t as fileTreeFromPaths } from "./tree-data-rg5voiY8.js";
|
|
3
3
|
import { Button, EmptyState, Input, SegmentedControl } from "@tangle-network/ui/primitives";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
import { useEffect, useId, useMemo, useRef, useState } from "react";
|