@tangle-network/agent-runtime 0.349.0 → 0.352.1
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/{activation-wBipBkCf.d.ts → activation-BidzGkUQ.d.ts} +2 -24
- package/dist/{activation-tNGW73Y9.js → activation-C6zNC2kx.js} +12 -14
- package/dist/{activation-tNGW73Y9.js.map → activation-C6zNC2kx.js.map} +1 -1
- package/dist/agent.d.ts +8 -12
- package/dist/agent.js +9 -12
- package/dist/agent.js.map +1 -1
- package/dist/{analyst-loop-DZw5QWT9.js → analyst-loop-BZvXCDKy.js} +2 -3
- package/dist/{analyst-loop-DZw5QWT9.js.map → analyst-loop-BZvXCDKy.js.map} +1 -1
- package/dist/analyst-loop.d.ts +3 -5
- package/dist/analyst-loop.js +1 -2
- package/dist/{bundle-1xaJEgjq.js → bundle-DeDkJbsr.js} +3 -4
- package/dist/{bundle-1xaJEgjq.js.map → bundle-DeDkJbsr.js.map} +1 -1
- package/dist/candidate-execution/index.d.ts +13 -33
- package/dist/candidate-execution/index.js +16 -18
- package/dist/candidate-execution/index.js.map +1 -1
- package/dist/chat-turn.d.ts +2 -0
- package/dist/chat-turn.js +1 -0
- package/dist/{coordination-manager-B2Z_MmL9.js → coordination-manager-B7QadgrI.js} +101 -132
- package/dist/{coordination-manager-B2Z_MmL9.js.map → coordination-manager-B7QadgrI.js.map} +1 -1
- package/dist/{delegate-Dr-63jFl.js → delegate-CoscoyEo.js} +19 -21
- package/dist/delegate-CoscoyEo.js.map +1 -0
- package/dist/durable.d.ts +16 -149
- package/dist/durable.js +57 -980
- package/dist/durable.js.map +1 -1
- package/dist/{errors-DodWX-cb.js → errors-AzSuGI23.js} +5 -3
- package/dist/errors-AzSuGI23.js.map +1 -0
- package/dist/execution-handle-Bd2_nUB6.js +167 -0
- package/dist/execution-handle-Bd2_nUB6.js.map +1 -0
- package/dist/execution-handle-CujvqgCn.d.ts +130 -0
- package/dist/{graph-DPejYB3C.js → graph-mojMML8e.js} +192 -14
- package/dist/graph-mojMML8e.js.map +1 -0
- package/dist/{improve-DwSahPi1.js → improve-Dm5ZE8mr.js} +36 -53
- package/dist/{improve-DwSahPi1.js.map → improve-Dm5ZE8mr.js.map} +1 -1
- package/dist/{improvement-adapter-sIthWkcN.d.ts → improvement-adapter-D5GRU1eY.d.ts} +2 -6
- package/dist/index.d.ts +41 -89
- package/dist/index.js +45 -61
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +39 -59
- package/dist/intelligence.js +24 -33
- package/dist/intelligence.js.map +1 -1
- package/dist/journal-store-BJPMUydp.js +3925 -0
- package/dist/journal-store-BJPMUydp.js.map +1 -0
- package/dist/kernel.d.ts +5 -5
- package/dist/kernel.js +12 -11
- package/dist/{loop-runner-CP6MfO1b.js → loop-runner-5cL_vZi0.js} +5 -6
- package/dist/{loop-runner-CP6MfO1b.js.map → loop-runner-5cL_vZi0.js.map} +1 -1
- package/dist/{loop-runner-C6pGq-2l.d.ts → loop-runner-DyLD-aNb.d.ts} +3 -5
- package/dist/loop-runner-bin.d.ts +5 -8
- package/dist/loop-runner-bin.js +2 -3
- package/dist/mcp/bin.js +6 -8
- package/dist/mcp/bin.js.map +1 -1
- package/dist/mcp/index.d.ts +8 -18
- package/dist/mcp/index.js +17 -25
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/memory-bin.js +4 -6
- package/dist/mcp/memory-bin.js.map +1 -1
- package/dist/{model-policy-CyCUwHed.js → model-policy-C-RGAUW4.js} +11 -13
- package/dist/{model-policy-CyCUwHed.js.map → model-policy-C-RGAUW4.js.map} +1 -1
- package/dist/placement.d.ts +12 -14
- package/dist/placement.js +1 -2
- package/dist/platform.d.ts +7 -13
- package/dist/platform.js +3 -6
- package/dist/platform.js.map +1 -1
- package/dist/{prepare-B9wWffjO.js → prepare-XWwsOh8O.js} +50 -69
- package/dist/{prepare-B9wWffjO.js.map → prepare-XWwsOh8O.js.map} +1 -1
- package/dist/{profile-JLJd2wFG.js → profile-C01SQZKa.js} +58 -92
- package/dist/profile-C01SQZKa.js.map +1 -0
- package/dist/{profile-materialization-bPm0gGLO.d.ts → profile-materialization-BRY22Oh8.d.ts} +1 -3
- package/dist/profiles.d.ts +25 -12
- package/dist/profiles.js +52 -11
- package/dist/profiles.js.map +1 -1
- package/dist/{protected-model-port-DVVh-hEk.d.ts → protected-model-port-IKqhTypD.d.ts} +2 -14
- package/dist/{protected-redaction-DFCeo4vg.js → protected-redaction-DilFZch5.js} +2 -3
- package/dist/{protected-redaction-DFCeo4vg.js.map → protected-redaction-DilFZch5.js.map} +1 -1
- package/dist/{provision-supervisor-C4v2vqDo.js → provision-supervisor-D9pO-iPl.js} +11 -15
- package/dist/{provision-supervisor-C4v2vqDo.js.map → provision-supervisor-D9pO-iPl.js.map} +1 -1
- package/dist/{run-cancellation-CzFhQGMa.js → run-cancellation-CoJRKvih.js} +6 -7
- package/dist/{run-cancellation-CzFhQGMa.js.map → run-cancellation-CoJRKvih.js.map} +1 -1
- package/dist/{runtime-CsvGCQpl.js → runtime-BJPXHWbc.js} +652 -215
- package/dist/runtime-BJPXHWbc.js.map +1 -0
- package/dist/{runtime-hooks-tXpAarhW.js → runtime-hooks-CsW2pfFk.js} +2 -3
- package/dist/{runtime-hooks-tXpAarhW.js.map → runtime-hooks-CsW2pfFk.js.map} +1 -1
- package/dist/{runtime-hooks-nsqxSUFL.d.ts → runtime-hooks-ZQqPw-0g.d.ts} +1 -3
- package/dist/{sandbox-profile-compat-DtuJWFrM.js → sandbox-profile-compat-CXjozdWL.js} +52 -653
- package/dist/sandbox-profile-compat-CXjozdWL.js.map +1 -0
- package/dist/{search-executor-CCb82Umc.js → search-executor-CQEHMXoT.js} +12 -15
- package/dist/{search-executor-CCb82Umc.js.map → search-executor-CQEHMXoT.js.map} +1 -1
- package/dist/{server-CKPwZU-I.js → server-U9NGgudQ.js} +19 -30
- package/dist/{server-CKPwZU-I.js.map → server-U9NGgudQ.js.map} +1 -1
- package/dist/{structural-rollout-DylC_fwU.js → structural-rollout-wMSxE7bn.js} +71 -70
- package/dist/structural-rollout-wMSxE7bn.js.map +1 -0
- package/dist/{substrate-CGDFTSRh.js → substrate-Db2pp6y3.js} +2 -3
- package/dist/{substrate-CGDFTSRh.js.map → substrate-Db2pp6y3.js.map} +1 -1
- package/dist/{supervise-BGfm2GlY.js → supervise-CNNhX0ab.js} +460 -195
- package/dist/supervise-CNNhX0ab.js.map +1 -0
- package/dist/supervision-discovery-CewADdEs.js +772 -0
- package/dist/supervision-discovery-CewADdEs.js.map +1 -0
- package/dist/{supervisor-wS9Ehz_x.js → supervisor-rK5Y8en6.js} +521 -4320
- package/dist/supervisor-rK5Y8en6.js.map +1 -0
- package/dist/{task-queue-0fKkoweu.d.ts → task-queue-kefGy79U.d.ts} +1 -3
- package/dist/task-queue.d.ts +1 -1
- package/dist/task-queue.js +1 -2
- package/dist/testing.d.ts +7 -15
- package/dist/testing.js +241 -244
- package/dist/testing.js.map +1 -1
- package/dist/tool-loop.d.ts +16 -19
- package/dist/tool-loop.js +2 -3
- package/dist/{tool-server-XV4aJwoQ.js → tool-server-CZWd_Opp.js} +3 -4
- package/dist/{tool-server-XV4aJwoQ.js.map → tool-server-CZWd_Opp.js.map} +1 -1
- package/dist/{top-snapshot-CflmaDgk.js → top-snapshot-DcV7VG4m.js} +179 -163
- package/dist/top-snapshot-DcV7VG4m.js.map +1 -0
- package/dist/tui/bin.js +50 -81
- package/dist/tui/bin.js.map +1 -1
- package/dist/tui/index.d.ts +27 -58
- package/dist/tui/index.js +2 -2
- package/dist/{types-C8BGOCBn.d.ts → types-0uzVKtFW.d.ts} +388 -484
- package/dist/{types-Cwrea-bU.d.ts → types-qsqfyQoY.d.ts} +1 -3
- package/dist/util-ebWMWzY0.js +624 -0
- package/dist/util-ebWMWzY0.js.map +1 -0
- package/dist/workspace-store/index.d.ts +12 -22
- package/dist/workspace-store/index.js +13 -10
- package/dist/workspace-store/index.js.map +1 -1
- package/dist/{workspace-streams-BiS4ABah.d.ts → workspace-streams-Dq2Fzk3c.d.ts} +1 -11
- package/package.json +31 -26
- package/skills/agent-graphs/SKILL.md +17 -4
- package/skills/be-ambitious/SKILL.md +46 -0
- package/skills/graph-designer/SKILL.md +9 -2
- package/dist/delegate-Dr-63jFl.js.map +0 -1
- package/dist/errors-DodWX-cb.js.map +0 -1
- package/dist/graph-DPejYB3C.js.map +0 -1
- package/dist/profile-JLJd2wFG.js.map +0 -1
- package/dist/record-events-D93DkpAx.js +0 -263
- package/dist/record-events-D93DkpAx.js.map +0 -1
- package/dist/runtime-CsvGCQpl.js.map +0 -1
- package/dist/sandbox-profile-compat-DtuJWFrM.js.map +0 -1
- package/dist/structural-rollout-DylC_fwU.js.map +0 -1
- package/dist/supervise-BGfm2GlY.js.map +0 -1
- package/dist/supervisor-wS9Ehz_x.js.map +0 -1
- package/dist/top-snapshot-CflmaDgk.js.map +0 -1
|
@@ -1,23 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { _ as safeWorkerFile, b as supervisorWorkersDir, f as legacySupervisorRunsRoot, y as supervisorRunsRoot } from "./run-cancellation-
|
|
1
|
+
import { r as spawnJournalRecordEvents, t as FileSpawnJournal } from "./journal-store-BJPMUydp.js";
|
|
2
|
+
import { _ as safeWorkerFile, b as supervisorWorkersDir, f as legacySupervisorRunsRoot, y as supervisorRunsRoot } from "./run-cancellation-CoJRKvih.js";
|
|
3
|
+
import { n as projectPursuit, r as FileObserverJournal, t as discoverDurableSupervisionRun } from "./supervision-discovery-CewADdEs.js";
|
|
3
4
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
4
5
|
import { basename, join, resolve } from "node:path";
|
|
5
|
-
|
|
6
|
+
// src/tui/top-snapshot.ts
|
|
6
7
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* from `../runtime/supervise/run-layout` — the same module the writers use — so the reader cannot
|
|
12
|
-
* drift from the layout the way an independently-versioned copy of the contract would.
|
|
13
|
-
*
|
|
14
|
-
* Extracted from the `loops` repo (`src/top-model.ts`), which held a hand-joined copy of the
|
|
15
|
-
* layout. Rendering is deliberately unchanged: raw ANSI, zero dependencies.
|
|
16
|
-
*
|
|
17
|
-
* This is the OPERATOR view: what is on disk right now, for a human watching a workspace. It
|
|
18
|
-
* carries no model-call identity, so its per-supervisor totals cannot be joined with root stream
|
|
19
|
-
* events without double counting. A client that needs one execution's totals reads
|
|
20
|
-
* `projectPursuit` from `../durable` instead.
|
|
8
|
+
* Read-only operator snapshots over the writer-owned supervisor layout and explicit durable runs.
|
|
9
|
+
* Workspace reads preserve legacy files; durable reads use discovery, journals and the canonical
|
|
10
|
+
* pursuit projection for model identity, failure and accounting evidence. Run totals count once.
|
|
11
|
+
* ANSI presentation lives in `./top-frame`.
|
|
21
12
|
*
|
|
22
13
|
* @experimental
|
|
23
14
|
*/
|
|
@@ -28,16 +19,9 @@ const emptySpend = {
|
|
|
28
19
|
usd: 0,
|
|
29
20
|
ms: 0
|
|
30
21
|
};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
* Pure with respect to the process: it only reads, and it never throws for a writer mid-append.
|
|
35
|
-
* An unreadable or half-written source is still skipped — an operator view must survive a live
|
|
36
|
-
* writer — but every skip is reported as one bounded `TopSnapshotDiagnostic`, so a client can
|
|
37
|
-
* tell a removed run from a partial read. `now` is injectable so elapsed time is deterministic
|
|
38
|
-
* under test.
|
|
39
|
-
*/
|
|
40
|
-
function loadTopSnapshot(rootDir, now = Date.now()) {
|
|
22
|
+
function loadTopSnapshot(rootDir, input = Date.now()) {
|
|
23
|
+
if (typeof input !== "number") return loadDurableTopSnapshot(rootDir, input.runDir, input.now ?? Date.now());
|
|
24
|
+
const now = input;
|
|
41
25
|
const root = resolve(rootDir);
|
|
42
26
|
const supervisors = [];
|
|
43
27
|
const diagnostics = [];
|
|
@@ -58,25 +42,83 @@ function loadTopSnapshot(rootDir, now = Date.now()) {
|
|
|
58
42
|
report(entry, state.diagnostics);
|
|
59
43
|
if (!state.value) continue;
|
|
60
44
|
const journal = readJournal(dir);
|
|
61
|
-
const progress =
|
|
45
|
+
const progress = readSourceFile(join(dir, "progress.ndjson"), "progress", "progress.ndjson");
|
|
62
46
|
const workerEvents = readWorkerEventTails(supervisorWorkersDir(dir), 8);
|
|
63
47
|
report(entry, [
|
|
64
48
|
...journal.diagnostics,
|
|
65
49
|
...progress.diagnostics,
|
|
66
50
|
...workerEvents.diagnostics
|
|
67
51
|
]);
|
|
68
|
-
supervisors.push(buildSupervisorView(state.value, dir, journal.value, progress.value, now, workerEvents.value));
|
|
52
|
+
supervisors.push(buildSupervisorView(state.value, dir, journal.value, tailLines(progress.value, 8), now, workerEvents.value));
|
|
69
53
|
}
|
|
70
54
|
}
|
|
71
55
|
supervisors.sort((a, b) => String(b.startedAt ?? "").localeCompare(String(a.startedAt ?? "")));
|
|
56
|
+
return topSnapshot(root, now, supervisors, diagnostics, discovered);
|
|
57
|
+
}
|
|
58
|
+
function topSnapshot(root, now, supervisors, diagnostics = [], discovered = 1, pursuit) {
|
|
72
59
|
return {
|
|
73
60
|
root,
|
|
74
61
|
generatedAt: now,
|
|
75
62
|
supervisors,
|
|
76
|
-
completeness: diagnostics.length
|
|
63
|
+
completeness: diagnostics.length ? "partial" : "complete",
|
|
77
64
|
diagnostics,
|
|
78
65
|
discovered,
|
|
79
|
-
loaded: supervisors.length
|
|
66
|
+
loaded: supervisors.length,
|
|
67
|
+
...pursuit ? { pursuit } : {}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
async function loadDurableTopSnapshot(rootDir, runDir, now) {
|
|
71
|
+
const root = resolve(rootDir);
|
|
72
|
+
let pursuit;
|
|
73
|
+
let source = "observer-journal";
|
|
74
|
+
let path = "observer.jsonl";
|
|
75
|
+
try {
|
|
76
|
+
if (typeof runDir !== "string" || !runDir.trim()) throw new TypeError("runDir must be non-empty");
|
|
77
|
+
const journal = await FileObserverJournal.open(join(resolve(runDir), path));
|
|
78
|
+
if (!journal) return topSnapshot(root, now, [], [{
|
|
79
|
+
source,
|
|
80
|
+
path,
|
|
81
|
+
reason: "missing"
|
|
82
|
+
}]);
|
|
83
|
+
pursuit = projectPursuit(await journal.read());
|
|
84
|
+
source = "journal";
|
|
85
|
+
path = ".";
|
|
86
|
+
const discovery = await discoverDurableSupervisionRun(runDir);
|
|
87
|
+
const latest = new Map(pursuit.runs.map((run) => [run.runId, run]));
|
|
88
|
+
path = "spawn-journal.jsonl";
|
|
89
|
+
const spawnJournal = new FileSpawnJournal(discovery.spawnJournalPath);
|
|
90
|
+
return topSnapshot(root, now, await Promise.all([...latest.values()].map(async (run) => {
|
|
91
|
+
const binding = discovery.roots.find((id) => id === run.runId);
|
|
92
|
+
if (!binding) throw new Error("observer run has no discovered spawn root");
|
|
93
|
+
const events = await spawnJournal.loadTree(binding) ?? [];
|
|
94
|
+
const rootSpawn = events.find((event) => event.kind === "spawned" && event.id === binding);
|
|
95
|
+
const budget = rootSpawn?.kind === "spawned" ? rootSpawn.budget?.maxTokens : void 0;
|
|
96
|
+
return buildSupervisorView({
|
|
97
|
+
id: run.runId,
|
|
98
|
+
status: run.status,
|
|
99
|
+
task: run.runId,
|
|
100
|
+
workspaceDir: root,
|
|
101
|
+
budget: budget ?? 0,
|
|
102
|
+
budgetKnown: budget !== void 0,
|
|
103
|
+
startedAt: new Date(run.firstObservedAt).toISOString(),
|
|
104
|
+
...run.settledAt === void 0 ? {} : { completedAt: new Date(run.settledAt).toISOString() }
|
|
105
|
+
}, discovery.runDir, events.filter(isSpawnEvent), run.error ? [run.error] : [], now, void 0, run);
|
|
106
|
+
})), [], 1, pursuit);
|
|
107
|
+
} catch (error) {
|
|
108
|
+
const reason = isRecord(error) && typeof error.code === "string" ? "unreadable" : "invalid-state";
|
|
109
|
+
return topSnapshot(root, now, [], [{
|
|
110
|
+
source,
|
|
111
|
+
path,
|
|
112
|
+
reason
|
|
113
|
+
}], 1, pursuit);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function observerSpend(spend, gaps = []) {
|
|
117
|
+
const parsed = parseSpend(spend);
|
|
118
|
+
return {
|
|
119
|
+
...parsed,
|
|
120
|
+
usdKnown: spend !== void 0 && parsed.usdKnown !== false && !gaps.includes("usd"),
|
|
121
|
+
tokensKnown: spend !== void 0 && parsed.tokensKnown !== false && !gaps.includes("tokens")
|
|
80
122
|
};
|
|
81
123
|
}
|
|
82
124
|
/**
|
|
@@ -119,15 +161,18 @@ function readJournal(eventDir) {
|
|
|
119
161
|
}] : []
|
|
120
162
|
};
|
|
121
163
|
}
|
|
122
|
-
function buildSupervisorView(state, stateDir, events, progressTail, now, workerEventTails = /* @__PURE__ */ new Map()) {
|
|
164
|
+
function buildSupervisorView(state, stateDir, events, progressTail, now, workerEventTails = /* @__PURE__ */ new Map(), accounting) {
|
|
123
165
|
const workers = /* @__PURE__ */ new Map();
|
|
124
166
|
let driverSpend = emptySpend;
|
|
125
167
|
const journalRootId = events.find((event) => event.kind === "spawned" && !event.parent && event.label === "root")?.id;
|
|
126
168
|
const isRoot = (id) => id === state.id || id === journalRootId;
|
|
127
169
|
for (const event of events) {
|
|
170
|
+
if (isRoot(event.id) || event.kind === "spawned" && !event.parent && event.label === "root") {
|
|
171
|
+
if (event.kind === "metered" && event.accountingOnly !== true) driverSpend = addSpend(driverSpend, parseSpend(event.spend));
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
const worker = ensureWorker(workers, event.id);
|
|
128
175
|
if (event.kind === "spawned") {
|
|
129
|
-
if (isRoot(event.id) || !event.parent && event.label === "root") continue;
|
|
130
|
-
const worker = ensureWorker(workers, event.id, event.label ?? event.id);
|
|
131
176
|
worker.label = event.label ?? worker.label;
|
|
132
177
|
if (event.parent) worker.parent = event.parent;
|
|
133
178
|
if (event.runtime) worker.runtime = event.runtime;
|
|
@@ -135,47 +180,30 @@ function buildSupervisorView(state, stateDir, events, progressTail, now, workerE
|
|
|
135
180
|
if (event.at) worker.startedAt = event.at;
|
|
136
181
|
const budget = parseBudget(event.budget);
|
|
137
182
|
if (budget) worker.budget = budget;
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
if (event.kind === "settled") {
|
|
141
|
-
if (isRoot(event.id)) continue;
|
|
142
|
-
const worker = ensureWorker(workers, event.id, event.id);
|
|
143
|
-
worker.status = event.status === "down" ? "down" : "done";
|
|
144
|
-
if (event.at) worker.endedAt = event.at;
|
|
145
|
-
if (event.outRef) worker.outRef = event.outRef;
|
|
146
|
-
if (event.infra !== void 0) worker.infra = event.infra;
|
|
147
|
-
const verdict = describeVerdict(event.verdict);
|
|
148
|
-
if (verdict) worker.verdict = verdict;
|
|
149
|
-
worker.spend = addSpend(worker.spend, parseSpend(event.spent));
|
|
150
|
-
worker.metered = emptySpend;
|
|
151
|
-
continue;
|
|
152
|
-
}
|
|
153
|
-
if (event.kind === "cancelled") {
|
|
154
|
-
if (isRoot(event.id)) continue;
|
|
155
|
-
const worker = ensureWorker(workers, event.id, event.id);
|
|
156
|
-
worker.status = "cancelled";
|
|
183
|
+
} else if (event.kind === "settled" || event.kind === "cancelled") {
|
|
157
184
|
if (event.at) worker.endedAt = event.at;
|
|
158
|
-
if (event.
|
|
159
|
-
|
|
185
|
+
if (event.kind === "settled") {
|
|
186
|
+
worker.status = event.status === "down" ? "down" : "done";
|
|
187
|
+
if (event.outRef) worker.outRef = event.outRef;
|
|
188
|
+
if (event.infra !== void 0) worker.infra = event.infra;
|
|
189
|
+
const verdict = describeVerdict(event.verdict);
|
|
190
|
+
if (verdict) worker.verdict = verdict;
|
|
191
|
+
} else {
|
|
192
|
+
worker.status = "cancelled";
|
|
193
|
+
if (event.reason) worker.reason = event.reason;
|
|
194
|
+
}
|
|
195
|
+
if (event.kind === "settled" || event.spent !== void 0) {
|
|
160
196
|
worker.spend = addSpend(worker.spend, parseSpend(event.spent));
|
|
161
197
|
worker.metered = emptySpend;
|
|
162
198
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
if (event.accountingOnly !== true) worker.metered = addSpend(worker.metered, spend);
|
|
172
|
-
}
|
|
173
|
-
continue;
|
|
174
|
-
}
|
|
175
|
-
if (event.kind === "progress") {
|
|
176
|
-
if (isRoot(event.id)) continue;
|
|
177
|
-
const worker = ensureWorker(workers, event.id, event.id);
|
|
178
|
-
worker.metered = parseSpend(event.spend);
|
|
199
|
+
} else if (event.kind === "progress") worker.metered = parseSpend(event.spend);
|
|
200
|
+
else if (event.accountingOnly !== true) worker.metered = addSpend(worker.metered, parseSpend(event.spend));
|
|
201
|
+
}
|
|
202
|
+
if (accounting) {
|
|
203
|
+
driverSpend = observerSpend(accounting.totals.exclusiveByNode[accounting.runId]);
|
|
204
|
+
for (const worker of workers.values()) {
|
|
205
|
+
worker.spend = observerSpend(accounting.totals.exclusiveByNode[worker.id], accounting.spendGaps?.find((gap) => gap.id === worker.id)?.channels);
|
|
206
|
+
worker.metered = emptySpend;
|
|
179
207
|
}
|
|
180
208
|
}
|
|
181
209
|
const workerViews = [...workers.values()].map((worker) => {
|
|
@@ -185,6 +213,10 @@ function buildSupervisorView(state, stateDir, events, progressTail, now, workerE
|
|
|
185
213
|
return finalizeWorker(worker, now);
|
|
186
214
|
}).sort((a, b) => compareWorker(a, b));
|
|
187
215
|
const totals = supervisorTotals(state, workerViews, driverSpend, now);
|
|
216
|
+
if (accounting) {
|
|
217
|
+
const spend = observerSpend(accounting.totals.inclusive, accounting.spendGaps?.flatMap((gap) => gap.channels));
|
|
218
|
+
Object.assign(totals, spend, { tokensTotal: spend.tokensInput + spend.tokensOutput });
|
|
219
|
+
}
|
|
188
220
|
return {
|
|
189
221
|
id: state.id,
|
|
190
222
|
stateDir,
|
|
@@ -192,18 +224,23 @@ function buildSupervisorView(state, stateDir, events, progressTail, now, workerE
|
|
|
192
224
|
task: state.task,
|
|
193
225
|
workspaceDir: state.workspaceDir,
|
|
194
226
|
budget: state.budget,
|
|
195
|
-
...state.
|
|
196
|
-
...state
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
...state
|
|
206
|
-
|
|
227
|
+
...state.budgetKnown === void 0 ? {} : { budgetKnown: state.budgetKnown },
|
|
228
|
+
...selectFields(state, [
|
|
229
|
+
"verifyCmd",
|
|
230
|
+
"workerModel",
|
|
231
|
+
"driverModel",
|
|
232
|
+
"verdict",
|
|
233
|
+
"progress",
|
|
234
|
+
"startedAt",
|
|
235
|
+
"completedAt"
|
|
236
|
+
], Boolean),
|
|
237
|
+
...selectFields(state, [
|
|
238
|
+
"maxSandboxes",
|
|
239
|
+
"maxLifetimeSeconds",
|
|
240
|
+
"idleTimeoutSeconds",
|
|
241
|
+
"maxUsd",
|
|
242
|
+
"maxDepth"
|
|
243
|
+
], (value) => value !== void 0),
|
|
207
244
|
...state.result?.spentUsd !== void 0 ? { resultSpentUsd: state.result.spentUsd } : {},
|
|
208
245
|
...state.result?.spentTokens !== void 0 ? { resultSpentTokens: state.result.spentTokens } : {},
|
|
209
246
|
workers: workerViews,
|
|
@@ -213,12 +250,17 @@ function buildSupervisorView(state, stateDir, events, progressTail, now, workerE
|
|
|
213
250
|
totals
|
|
214
251
|
};
|
|
215
252
|
}
|
|
216
|
-
function
|
|
253
|
+
function selectFields(value, keys, include) {
|
|
254
|
+
const selected = {};
|
|
255
|
+
for (const key of keys) if (include(value[key])) selected[key] = value[key];
|
|
256
|
+
return selected;
|
|
257
|
+
}
|
|
258
|
+
function ensureWorker(workers, id) {
|
|
217
259
|
const existing = workers.get(id);
|
|
218
260
|
if (existing) return existing;
|
|
219
261
|
const created = {
|
|
220
262
|
id,
|
|
221
|
-
label,
|
|
263
|
+
label: id,
|
|
222
264
|
status: "running",
|
|
223
265
|
spend: emptySpend,
|
|
224
266
|
metered: emptySpend,
|
|
@@ -232,53 +274,43 @@ function finalizeWorker(worker, now) {
|
|
|
232
274
|
const endMs = parseTime(worker.endedAt) ?? (worker.status === "running" ? now : startMs);
|
|
233
275
|
const latencyMs = startMs !== void 0 && endMs !== void 0 ? Math.max(0, endMs - startMs) : 0;
|
|
234
276
|
return {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
...worker.eventFile ? { eventFile: worker.eventFile } : {},
|
|
238
|
-
...worker.parent ? { parent: worker.parent } : {},
|
|
239
|
-
...worker.runtime ? { runtime: worker.runtime } : {},
|
|
240
|
-
status: worker.status,
|
|
241
|
-
...worker.verdict ? { verdict: worker.verdict } : {},
|
|
242
|
-
...worker.infra !== void 0 ? { infra: worker.infra } : {},
|
|
243
|
-
...worker.startedAt ? { startedAt: worker.startedAt } : {},
|
|
244
|
-
...worker.endedAt ? { endedAt: worker.endedAt } : {},
|
|
245
|
-
latencyMs,
|
|
246
|
-
...worker.budget ? { budget: worker.budget } : {},
|
|
247
|
-
spend: worker.spend,
|
|
248
|
-
metered: worker.metered,
|
|
249
|
-
liveTail: worker.liveTail,
|
|
250
|
-
...worker.outRef ? { outRef: worker.outRef } : {},
|
|
251
|
-
...worker.reason ? { reason: worker.reason } : {}
|
|
277
|
+
...worker,
|
|
278
|
+
latencyMs
|
|
252
279
|
};
|
|
253
280
|
}
|
|
254
281
|
function supervisorTotals(state, workers, driverSpend, now) {
|
|
255
|
-
const
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
282
|
+
const spend = workers.map(totalSpend).reduce(addSpend, driverSpend);
|
|
283
|
+
const counts = {
|
|
284
|
+
running: 0,
|
|
285
|
+
done: 0,
|
|
286
|
+
down: 0,
|
|
287
|
+
cancelled: 0
|
|
288
|
+
};
|
|
289
|
+
for (const worker of workers) counts[worker.status] += 1;
|
|
260
290
|
const started = parseTime(state.startedAt);
|
|
261
291
|
const completed = parseTime(state.completedAt);
|
|
262
292
|
const latencyMs = started !== void 0 ? Math.max(0, (completed ?? now) - started) : 0;
|
|
263
293
|
const latencies = workers.map((worker) => worker.latencyMs).filter((ms) => ms > 0);
|
|
264
294
|
return {
|
|
265
295
|
workers: workers.length,
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
usd,
|
|
296
|
+
...counts,
|
|
297
|
+
...spend.usdKnown === false ? { usdKnown: false } : {},
|
|
298
|
+
...spend.tokensKnown === false ? { tokensKnown: false } : {},
|
|
299
|
+
inFlight: counts.running,
|
|
300
|
+
settled: workers.length - counts.running,
|
|
301
|
+
tokensInput: spend.tokensInput,
|
|
302
|
+
tokensOutput: spend.tokensOutput,
|
|
303
|
+
tokensTotal: spend.tokensInput + spend.tokensOutput,
|
|
304
|
+
usd: spend.usd > 0 ? spend.usd : state.result?.spentUsd ?? 0,
|
|
276
305
|
latencyMs,
|
|
277
306
|
workerLatency: distribution(latencies)
|
|
278
307
|
};
|
|
279
308
|
}
|
|
280
309
|
function aggregateSnapshot(snapshot) {
|
|
310
|
+
const complete = snapshot.completeness === "complete";
|
|
281
311
|
return {
|
|
312
|
+
usdKnown: complete && snapshot.supervisors.every((row) => row.totals.usdKnown !== false),
|
|
313
|
+
tokensKnown: complete && snapshot.supervisors.every((row) => row.totals.tokensKnown !== false),
|
|
282
314
|
supervisors: snapshot.supervisors.length,
|
|
283
315
|
workers: sum(snapshot.supervisors.map((supervisor) => supervisor.totals.workers)),
|
|
284
316
|
running: sum(snapshot.supervisors.map((supervisor) => supervisor.totals.running)),
|
|
@@ -305,13 +337,17 @@ function addSpend(a, b) {
|
|
|
305
337
|
tokensInput: a.tokensInput + b.tokensInput,
|
|
306
338
|
tokensOutput: a.tokensOutput + b.tokensOutput,
|
|
307
339
|
usd: a.usd + b.usd,
|
|
308
|
-
ms: a.ms + b.ms
|
|
340
|
+
ms: a.ms + b.ms,
|
|
341
|
+
...a.usdKnown === false || b.usdKnown === false ? { usdKnown: false } : {},
|
|
342
|
+
...a.tokensKnown === false || b.tokensKnown === false ? { tokensKnown: false } : {}
|
|
309
343
|
};
|
|
310
344
|
}
|
|
311
345
|
function parseSpend(value) {
|
|
312
346
|
if (!isRecord(value)) return emptySpend;
|
|
313
347
|
const tokens = isRecord(value.tokens) ? value.tokens : {};
|
|
314
348
|
return {
|
|
349
|
+
...value.usdKnown === false ? { usdKnown: false } : {},
|
|
350
|
+
...value.tokensKnown === false || tokens.tokensKnown === false ? { tokensKnown: false } : {},
|
|
315
351
|
iterations: numberValue(value.iterations),
|
|
316
352
|
tokensInput: numberValue(tokens.input),
|
|
317
353
|
tokensOutput: numberValue(tokens.output),
|
|
@@ -334,13 +370,6 @@ function describeVerdict(value) {
|
|
|
334
370
|
if (typeof value.score === "number") return `score ${value.score.toFixed(2)}`;
|
|
335
371
|
}
|
|
336
372
|
function distribution(values) {
|
|
337
|
-
if (values.length === 0) return {
|
|
338
|
-
n: 0,
|
|
339
|
-
min: 0,
|
|
340
|
-
median: 0,
|
|
341
|
-
p90: 0,
|
|
342
|
-
max: 0
|
|
343
|
-
};
|
|
344
373
|
const sorted = [...values].sort((a, b) => a - b);
|
|
345
374
|
return {
|
|
346
375
|
n: sorted.length,
|
|
@@ -384,14 +413,6 @@ function tailLines(raw, maxLines) {
|
|
|
384
413
|
if (raw === void 0) return [];
|
|
385
414
|
return raw.trim().split("\n").filter(Boolean).slice(-maxLines);
|
|
386
415
|
}
|
|
387
|
-
function readProgressTail(dir, maxLines) {
|
|
388
|
-
const path = "progress.ndjson";
|
|
389
|
-
const read = readSourceFile(join(dir, path), "progress", path);
|
|
390
|
-
return {
|
|
391
|
-
value: tailLines(read.value, maxLines),
|
|
392
|
-
diagnostics: read.diagnostics
|
|
393
|
-
};
|
|
394
|
-
}
|
|
395
416
|
function readWorkerEventTails(dir, maxLines) {
|
|
396
417
|
const out = /* @__PURE__ */ new Map();
|
|
397
418
|
if (!existsSync(dir)) return {
|
|
@@ -436,46 +457,42 @@ function readSupervisorState(dir) {
|
|
|
436
457
|
value: void 0,
|
|
437
458
|
diagnostics: read.diagnostics
|
|
438
459
|
};
|
|
439
|
-
|
|
460
|
+
const failed = (reason) => ({
|
|
440
461
|
value: void 0,
|
|
441
462
|
diagnostics: [{
|
|
442
463
|
source: "supervisor-state",
|
|
443
464
|
path,
|
|
444
|
-
reason
|
|
465
|
+
reason
|
|
445
466
|
}]
|
|
446
|
-
};
|
|
447
|
-
|
|
467
|
+
});
|
|
468
|
+
if (read.value === void 0) return failed("missing");
|
|
448
469
|
try {
|
|
449
|
-
parsed = JSON.parse(read.value);
|
|
470
|
+
const parsed = JSON.parse(read.value);
|
|
471
|
+
return isSupervisorState(parsed) ? {
|
|
472
|
+
value: parsed,
|
|
473
|
+
diagnostics: []
|
|
474
|
+
} : failed("invalid-state");
|
|
450
475
|
} catch {
|
|
451
|
-
return
|
|
452
|
-
value: void 0,
|
|
453
|
-
diagnostics: [{
|
|
454
|
-
source: "supervisor-state",
|
|
455
|
-
path,
|
|
456
|
-
reason: "partial-json"
|
|
457
|
-
}]
|
|
458
|
-
};
|
|
476
|
+
return failed("partial-json");
|
|
459
477
|
}
|
|
460
|
-
if (!isSupervisorState(parsed)) return {
|
|
461
|
-
value: void 0,
|
|
462
|
-
diagnostics: [{
|
|
463
|
-
source: "supervisor-state",
|
|
464
|
-
path,
|
|
465
|
-
reason: "invalid-state"
|
|
466
|
-
}]
|
|
467
|
-
};
|
|
468
|
-
return {
|
|
469
|
-
value: parsed,
|
|
470
|
-
diagnostics: []
|
|
471
|
-
};
|
|
472
478
|
}
|
|
473
479
|
function isSupervisorState(value) {
|
|
474
|
-
return value
|
|
480
|
+
return isRecord(value) && Object.entries({
|
|
481
|
+
id: "string",
|
|
482
|
+
status: "string",
|
|
483
|
+
task: "string",
|
|
484
|
+
workspaceDir: "string",
|
|
485
|
+
budget: "number"
|
|
486
|
+
}).every(([key, type]) => typeof value[key] === type);
|
|
475
487
|
}
|
|
476
488
|
function isSpawnEvent(value) {
|
|
477
|
-
|
|
478
|
-
|
|
489
|
+
return isRecord(value) && typeof value.id === "string" && typeof value.kind === "string" && [
|
|
490
|
+
"spawned",
|
|
491
|
+
"settled",
|
|
492
|
+
"cancelled",
|
|
493
|
+
"metered",
|
|
494
|
+
"progress"
|
|
495
|
+
].includes(value.kind);
|
|
479
496
|
}
|
|
480
497
|
function isRecord(value) {
|
|
481
498
|
return typeof value === "object" && value !== null;
|
|
@@ -498,7 +515,6 @@ function parseTime(value) {
|
|
|
498
515
|
function sum(values) {
|
|
499
516
|
return values.reduce((total, value) => total + value, 0);
|
|
500
517
|
}
|
|
501
|
-
//#endregion
|
|
502
518
|
export { parseTime as a, parseSpend as i, loadTopSnapshot as n, totalSpend as o, numberValue as r, aggregateSnapshot as t };
|
|
503
519
|
|
|
504
|
-
//# sourceMappingURL=top-snapshot-
|
|
520
|
+
//# sourceMappingURL=top-snapshot-DcV7VG4m.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"top-snapshot-DcV7VG4m.js","names":[],"sources":["../src/tui/top-snapshot.ts"],"sourcesContent":["/**\n * Read-only operator snapshots over the writer-owned supervisor layout and explicit durable runs.\n * Workspace reads preserve legacy files; durable reads use discovery, journals and the canonical\n * pursuit projection for model identity, failure and accounting evidence. Run totals count once.\n * ANSI presentation lives in `./top-frame`.\n *\n * @experimental\n */\n\nimport { existsSync, readdirSync, readFileSync, statSync } from 'node:fs'\nimport { basename, join, resolve } from 'node:path'\nimport { FileObserverJournal } from '../durable/observer-journal'\nimport {\n type PursuitProjection,\n type PursuitRunProjection,\n projectPursuit,\n} from '../durable/observer-projection'\nimport { FileSpawnJournal } from '../durable/spawn-journal/journal-store'\nimport { spawnJournalRecordEvents } from '../durable/spawn-journal/record-events'\nimport { discoverDurableSupervisionRun } from '../durable/supervision-discovery'\nimport {\n legacySupervisorRunsRoot,\n safeWorkerFile,\n supervisorRunsRoot,\n supervisorWorkersDir,\n} from '../runtime/supervise/run-layout'\nimport type { Budget, Spend, SpendChannel } from '../runtime/supervise/types'\n\nexport interface TopSnapshot {\n readonly root: string\n readonly generatedAt: number\n readonly supervisors: SupervisorView[]\n /** Canonical facts, including unknown accounting and requested/observed identities. */\n readonly pursuit?: PursuitProjection\n /** `partial` when at least one discovered source could not be read completely. */\n readonly completeness: TopSnapshotCompleteness\n /** One bounded entry per skipped or partially read source; empty when complete. */\n readonly diagnostics: ReadonlyArray<TopSnapshotDiagnostic>\n /** Run directories found under the runs roots, readable or not. */\n readonly discovered: number\n /** Run directories projected into a valid supervisor view. */\n readonly loaded: number\n}\n\nexport type TopSnapshotCompleteness = 'complete' | 'partial'\n\nexport type TopSnapshotDiagnosticSource =\n | 'observer-journal'\n | 'supervisor-state'\n | 'journal'\n | 'progress'\n | 'worker-tail'\n\nexport type TopSnapshotDiagnosticReason =\n | 'unreadable'\n | 'partial-json'\n | 'invalid-state'\n | 'missing'\n\n/**\n * One skipped or partially read snapshot source. `path` is relative to the run directory and\n * never carries file contents, so a diagnostic is safe to show or log without leaking run data.\n */\nexport interface TopSnapshotDiagnostic extends SourceDiagnostic {\n readonly runId?: string\n}\n\ninterface SupervisorBase {\n readonly id: string\n readonly status: string\n readonly task: string\n readonly workspaceDir: string\n readonly budget: number\n readonly budgetKnown?: boolean\n readonly verifyCmd?: string\n readonly workerModel?: string\n readonly driverModel?: string\n readonly verdict?: string\n readonly progress?: string\n readonly startedAt?: string\n readonly completedAt?: string\n readonly maxSandboxes?: number\n readonly maxLifetimeSeconds?: number\n readonly idleTimeoutSeconds?: number\n readonly maxUsd?: number\n readonly maxDepth?: number\n}\n\nexport interface SupervisorView extends SupervisorBase {\n readonly stateDir: string\n readonly resultSpentUsd?: number\n readonly resultSpentTokens?: number\n readonly workers: WorkerView[]\n readonly progressTail: string[]\n readonly journalTail: TopJournalEvent[]\n readonly driverSpend: SpendStats\n readonly totals: SupervisorTotals\n}\n\nexport interface WorkerView {\n readonly id: string\n readonly label: string\n readonly eventFile?: string\n readonly parent?: string\n readonly runtime?: string\n readonly status: 'running' | 'done' | 'down' | 'cancelled'\n readonly verdict?: string\n readonly infra?: boolean\n readonly startedAt?: string\n readonly endedAt?: string\n readonly latencyMs: number\n readonly budget?: BudgetStats\n readonly spend: SpendStats\n readonly metered: SpendStats\n readonly liveTail: string[]\n readonly outRef?: string\n readonly reason?: string\n}\n\nexport interface SupervisorTotals\n extends Pick<SpendStats, 'tokensInput' | 'tokensOutput' | 'usd' | 'usdKnown' | 'tokensKnown'> {\n readonly workers: number\n readonly running: number\n readonly done: number\n readonly down: number\n readonly cancelled: number\n readonly inFlight: number\n readonly settled: number\n readonly tokensTotal: number\n readonly latencyMs: number\n readonly workerLatency: Distribution\n}\n\nexport interface Distribution {\n readonly n: number\n readonly min: number\n readonly median: number\n readonly p90: number\n readonly max: number\n}\n\nexport type BudgetStats = Partial<Pick<Budget, 'maxIterations' | 'maxTokens' | 'maxUsd'>>\n\nexport interface SpendStats\n extends Readonly<Pick<Spend, 'iterations' | 'usd' | 'ms' | 'usdKnown' | 'tokensKnown'>> {\n readonly tokensInput: number\n readonly tokensOutput: number\n}\n\nexport type TopJournalEvent = {\n readonly id: string\n readonly seq?: number\n readonly at?: string\n} & (\n | {\n readonly kind: 'spawned'\n readonly parent?: string\n readonly label?: string\n readonly budget?: unknown\n readonly runtime?: string\n }\n | {\n readonly kind: 'settled'\n readonly status?: string\n readonly outRef?: string\n readonly verdict?: unknown\n readonly spent?: unknown\n readonly infra?: boolean\n }\n | {\n readonly kind: 'cancelled'\n readonly spent?: unknown\n readonly reason?: string\n }\n | {\n readonly kind: 'metered'\n readonly spend?: unknown\n readonly accountingOnly?: boolean\n }\n | {\n readonly kind: 'progress'\n readonly spend?: unknown\n }\n)\n\ninterface SupervisorState extends SupervisorBase {\n readonly result?: {\n readonly spentUsd?: number\n readonly spentTokens?: number\n }\n}\n\ntype MutableWorker = {\n -readonly [Key in keyof Omit<WorkerView, 'latencyMs'>]: WorkerView[Key]\n}\n\ninterface WorkerEventTail {\n readonly file: string\n readonly lines: string[]\n}\n\n/** A diagnostic before its run id is attached; `loadTopSnapshot` adds `runId`. */\ninterface SourceDiagnostic {\n readonly source: TopSnapshotDiagnosticSource\n readonly path: string\n readonly reason: TopSnapshotDiagnosticReason\n}\n\n/**\n * What one snapshot source read produced: the value it could recover, and the bounded diagnostics\n * the read raised. Every reader returns this one shape, so the loader folds them identically.\n */\ninterface SourceRead<T> {\n readonly value: T\n readonly diagnostics: readonly SourceDiagnostic[]\n}\n\nconst emptySpend: SpendStats = { iterations: 0, tokensInput: 0, tokensOutput: 0, usd: 0, ms: 0 }\n\n/**\n * Read every supervisor run under one workspace into a single point-in-time snapshot.\n *\n * Pure with respect to the process: it only reads, and it never throws for a writer mid-append.\n * An unreadable or half-written source is still skipped — an operator view must survive a live\n * writer — but every skip is reported as one bounded `TopSnapshotDiagnostic`, so a client can\n * tell a removed run from a partial read. `now` is injectable so elapsed time is deterministic\n * under test.\n */\nexport function loadTopSnapshot(rootDir: string, now?: number): TopSnapshot\nexport function loadTopSnapshot(\n rootDir: string,\n options: { runDir: string; now?: number },\n): Promise<TopSnapshot>\nexport function loadTopSnapshot(\n rootDir: string,\n input: number | { runDir: string; now?: number } = Date.now(),\n): TopSnapshot | Promise<TopSnapshot> {\n if (typeof input !== 'number')\n return loadDurableTopSnapshot(rootDir, input.runDir, input.now ?? Date.now())\n const now = input\n const root = resolve(rootDir)\n const supervisors: SupervisorView[] = []\n const diagnostics: TopSnapshotDiagnostic[] = []\n let discovered = 0\n const report = (runId: string, sources: readonly SourceDiagnostic[]): void => {\n for (const source of sources) diagnostics.push({ ...source, runId })\n }\n // `.loops` is the pre-rename state dir; runs already on disk there stay visible.\n for (const runsRoot of [supervisorRunsRoot(root), legacySupervisorRunsRoot(root)]) {\n if (!existsSync(runsRoot)) continue\n for (const entry of readdirSync(runsRoot)) {\n const dir = join(runsRoot, entry)\n if (!isDirectory(dir)) continue\n discovered += 1\n const state = readSupervisorState(dir)\n report(entry, state.diagnostics)\n if (!state.value) continue\n const journal = readJournal(dir)\n const progress = readSourceFile(join(dir, 'progress.ndjson'), 'progress', 'progress.ndjson')\n const workerEvents = readWorkerEventTails(supervisorWorkersDir(dir), 8)\n report(entry, [...journal.diagnostics, ...progress.diagnostics, ...workerEvents.diagnostics])\n supervisors.push(\n buildSupervisorView(\n state.value,\n dir,\n journal.value,\n tailLines(progress.value, 8),\n now,\n workerEvents.value,\n ),\n )\n }\n }\n supervisors.sort((a, b) => String(b.startedAt ?? '').localeCompare(String(a.startedAt ?? '')))\n return topSnapshot(root, now, supervisors, diagnostics, discovered)\n}\n\nfunction topSnapshot(\n root: string,\n now: number,\n supervisors: SupervisorView[],\n diagnostics: TopSnapshotDiagnostic[] = [],\n discovered = 1,\n pursuit?: PursuitProjection,\n): TopSnapshot {\n return {\n root,\n generatedAt: now,\n supervisors,\n completeness: diagnostics.length ? 'partial' : 'complete',\n diagnostics,\n discovered,\n loaded: supervisors.length,\n ...(pursuit ? { pursuit } : {}),\n }\n}\n\nasync function loadDurableTopSnapshot(\n rootDir: string,\n runDir: string,\n now: number,\n): Promise<TopSnapshot> {\n const root = resolve(rootDir)\n let pursuit: PursuitProjection | undefined\n let source: TopSnapshotDiagnosticSource = 'observer-journal'\n let path = 'observer.jsonl'\n try {\n if (typeof runDir !== 'string' || !runDir.trim())\n throw new TypeError('runDir must be non-empty')\n const journal = await FileObserverJournal.open(join(resolve(runDir), path))\n if (!journal) return topSnapshot(root, now, [], [{ source, path, reason: 'missing' }])\n pursuit = projectPursuit(await journal.read())\n source = 'journal'\n path = '.'\n const discovery = await discoverDurableSupervisionRun(runDir)\n // An actual run id stays the row identity; the canonical projection retains every attempt.\n const latest = new Map(pursuit.runs.map((run) => [run.runId, run]))\n path = 'spawn-journal.jsonl'\n const spawnJournal = new FileSpawnJournal(discovery.spawnJournalPath)\n const supervisors = await Promise.all(\n [...latest.values()].map(async (run) => {\n // SupervisorOpts.runId is the journal root key; require its recorded discovery binding.\n const binding = discovery.roots.find((id) => id === run.runId)\n if (!binding) throw new Error('observer run has no discovered spawn root')\n const events = (await spawnJournal.loadTree(binding)) ?? []\n const rootSpawn = events.find((event) => event.kind === 'spawned' && event.id === binding)\n const budget = rootSpawn?.kind === 'spawned' ? rootSpawn.budget?.maxTokens : undefined\n return buildSupervisorView(\n {\n id: run.runId,\n status: run.status,\n task: run.runId,\n workspaceDir: root,\n budget: budget ?? 0,\n budgetKnown: budget !== undefined,\n startedAt: new Date(run.firstObservedAt).toISOString(),\n ...(run.settledAt === undefined\n ? {}\n : { completedAt: new Date(run.settledAt).toISOString() }),\n },\n discovery.runDir,\n events.filter(isSpawnEvent),\n run.error ? [run.error] : [],\n now,\n undefined,\n run,\n )\n }),\n )\n return topSnapshot(root, now, supervisors, [], 1, pursuit)\n } catch (error) {\n const reason =\n isRecord(error) && typeof error.code === 'string' ? 'unreadable' : 'invalid-state'\n return topSnapshot(root, now, [], [{ source, path, reason }], 1, pursuit)\n }\n}\n\nfunction observerSpend(spend: Spend | undefined, gaps: readonly SpendChannel[] = []): SpendStats {\n const parsed = parseSpend(spend)\n return {\n ...parsed,\n usdKnown: spend !== undefined && parsed.usdKnown !== false && !gaps.includes('usd'),\n tokensKnown: spend !== undefined && parsed.tokensKnown !== false && !gaps.includes('tokens'),\n }\n}\n\n/**\n * The journal file a run dir actually carries. `createFileRunContext` — this repo's own durable\n * writer — names it `spawn-journal.jsonl`; `journal.jsonl` is the retired bare-event file older\n * runs left behind. First existing name wins; a reader that knew only the retired name would show\n * zero workers for every current run.\n */\nconst journalFileNames = ['spawn-journal.jsonl', 'journal.jsonl'] as const\n\nfunction readJournal(eventDir: string): SourceRead<TopJournalEvent[]> {\n const path = journalFileNames.find((candidate) => existsSync(join(eventDir, candidate)))\n if (!path) return { value: [], diagnostics: [] }\n const read = readSourceFile(join(eventDir, path), 'journal', path)\n if (read.value === undefined) return { value: [], diagnostics: read.diagnostics }\n const out: TopJournalEvent[] = []\n let partial = false\n for (const line of read.value.split('\\n')) {\n const trimmed = line.trim()\n if (!trimmed) continue\n try {\n const parsed = JSON.parse(trimmed) as Record<string, unknown>\n const events =\n parsed.kind === 'event' || parsed.kind === 'events'\n ? spawnJournalRecordEvents(parsed)\n : [parsed]\n for (const event of events) if (isSpawnEvent(event)) out.push(event)\n } catch {\n // A corrupt line is expected while the writer is mid-append; keep the lines that parsed.\n partial = true\n }\n }\n return {\n value: out,\n diagnostics: partial ? [{ source: 'journal', path, reason: 'partial-json' }] : [],\n }\n}\n\nfunction buildSupervisorView(\n state: SupervisorState,\n stateDir: string,\n events: readonly TopJournalEvent[],\n progressTail: readonly string[],\n now: number,\n workerEventTails = new Map<string, WorkerEventTail>(),\n accounting?: PursuitRunProjection,\n): SupervisorView {\n const workers = new Map<string, MutableWorker>()\n let driverSpend = emptySpend\n // State and journal have different producers and root ids. Exclude both, or the journal's\n // root becomes a phantom running worker that captures steer and cancel operations.\n const journalRootId = events.find(\n (event) => event.kind === 'spawned' && !event.parent && event.label === 'root',\n )?.id\n const isRoot = (id: string): boolean => id === state.id || id === journalRootId\n\n for (const event of events) {\n if (isRoot(event.id) || (event.kind === 'spawned' && !event.parent && event.label === 'root')) {\n if (event.kind === 'metered' && event.accountingOnly !== true) {\n driverSpend = addSpend(driverSpend, parseSpend(event.spend))\n }\n continue\n }\n const worker = ensureWorker(workers, event.id)\n if (event.kind === 'spawned') {\n worker.label = event.label ?? worker.label\n if (event.parent) worker.parent = event.parent\n if (event.runtime) worker.runtime = event.runtime\n worker.status = 'running'\n if (event.at) worker.startedAt = event.at\n const budget = parseBudget(event.budget)\n if (budget) worker.budget = budget\n } else if (event.kind === 'settled' || event.kind === 'cancelled') {\n if (event.at) worker.endedAt = event.at\n if (event.kind === 'settled') {\n worker.status = event.status === 'down' ? 'down' : 'done'\n if (event.outRef) worker.outRef = event.outRef\n if (event.infra !== undefined) worker.infra = event.infra\n const verdict = describeVerdict(event.verdict)\n if (verdict) worker.verdict = verdict\n } else {\n worker.status = 'cancelled'\n if (event.reason) worker.reason = event.reason\n }\n if (event.kind === 'settled' || event.spent !== undefined) {\n worker.spend = addSpend(worker.spend, parseSpend(event.spent))\n // Live progress is cumulative; terminal spend replaces it rather than counting it twice.\n worker.metered = emptySpend\n }\n } else if (event.kind === 'progress') {\n worker.metered = parseSpend(event.spend)\n } else if (event.accountingOnly !== true) {\n worker.metered = addSpend(worker.metered, parseSpend(event.spend))\n }\n }\n\n if (accounting) {\n driverSpend = observerSpend(accounting.totals.exclusiveByNode[accounting.runId])\n for (const worker of workers.values()) {\n worker.spend = observerSpend(\n accounting.totals.exclusiveByNode[worker.id],\n accounting.spendGaps?.find((gap) => gap.id === worker.id)?.channels,\n )\n worker.metered = emptySpend\n }\n }\n const workerViews = [...workers.values()]\n .map((worker) => {\n // Tails are keyed by file stem, which the writer put through `safeWorkerFile`; a label\n // carrying characters that stem strips would otherwise never find its own events.\n const tail =\n workerEventTails.get(worker.label) ??\n workerEventTails.get(safeWorkerFile(worker.label)) ??\n workerEventTails.get(safeWorkerFile(worker.id)) ??\n workerEventTails.get(worker.id)\n worker.liveTail = tail?.lines ?? []\n if (tail?.file) worker.eventFile = tail.file\n return finalizeWorker(worker, now)\n })\n .sort((a, b) => compareWorker(a, b))\n\n const totals = supervisorTotals(state, workerViews, driverSpend, now)\n if (accounting) {\n const spend = observerSpend(\n accounting.totals.inclusive,\n accounting.spendGaps?.flatMap((gap) => gap.channels),\n )\n Object.assign(totals, spend, { tokensTotal: spend.tokensInput + spend.tokensOutput })\n }\n return {\n id: state.id,\n stateDir,\n status: state.status,\n task: state.task,\n workspaceDir: state.workspaceDir,\n budget: state.budget,\n ...(state.budgetKnown === undefined ? {} : { budgetKnown: state.budgetKnown }),\n ...selectFields(\n state,\n [\n 'verifyCmd',\n 'workerModel',\n 'driverModel',\n 'verdict',\n 'progress',\n 'startedAt',\n 'completedAt',\n ],\n Boolean,\n ),\n ...selectFields(\n state,\n ['maxSandboxes', 'maxLifetimeSeconds', 'idleTimeoutSeconds', 'maxUsd', 'maxDepth'],\n (value) => value !== undefined,\n ),\n ...(state.result?.spentUsd !== undefined ? { resultSpentUsd: state.result.spentUsd } : {}),\n ...(state.result?.spentTokens !== undefined\n ? { resultSpentTokens: state.result.spentTokens }\n : {}),\n workers: workerViews,\n progressTail: [...progressTail],\n journalTail: events.slice(-12),\n driverSpend,\n totals,\n }\n}\n\nfunction selectFields<T, K extends keyof T>(\n value: T,\n keys: readonly K[],\n include: (value: T[K]) => boolean,\n): Partial<Pick<T, K>> {\n const selected: Partial<Pick<T, K>> = {}\n for (const key of keys) if (include(value[key])) selected[key] = value[key]\n return selected\n}\n\nfunction ensureWorker(workers: Map<string, MutableWorker>, id: string): MutableWorker {\n const existing = workers.get(id)\n if (existing) return existing\n const created: MutableWorker = {\n id,\n label: id,\n status: 'running',\n spend: emptySpend,\n metered: emptySpend,\n liveTail: [],\n }\n workers.set(id, created)\n return created\n}\n\nfunction finalizeWorker(worker: MutableWorker, now: number): WorkerView {\n const startMs = parseTime(worker.startedAt)\n const endMs = parseTime(worker.endedAt) ?? (worker.status === 'running' ? now : startMs)\n const latencyMs = startMs !== undefined && endMs !== undefined ? Math.max(0, endMs - startMs) : 0\n return { ...worker, latencyMs }\n}\n\nfunction supervisorTotals(\n state: SupervisorState,\n workers: readonly WorkerView[],\n driverSpend: SpendStats,\n now: number,\n): SupervisorTotals {\n const spend = workers.map(totalSpend).reduce(addSpend, driverSpend)\n const counts = { running: 0, done: 0, down: 0, cancelled: 0 }\n for (const worker of workers) counts[worker.status] += 1\n const started = parseTime(state.startedAt)\n const completed = parseTime(state.completedAt)\n const latencyMs = started !== undefined ? Math.max(0, (completed ?? now) - started) : 0\n const latencies = workers.map((worker) => worker.latencyMs).filter((ms) => ms > 0)\n return {\n workers: workers.length,\n ...counts,\n ...(spend.usdKnown === false ? { usdKnown: false } : {}),\n ...(spend.tokensKnown === false ? { tokensKnown: false } : {}),\n inFlight: counts.running,\n settled: workers.length - counts.running,\n tokensInput: spend.tokensInput,\n tokensOutput: spend.tokensOutput,\n tokensTotal: spend.tokensInput + spend.tokensOutput,\n usd: spend.usd > 0 ? spend.usd : (state.result?.spentUsd ?? 0),\n latencyMs,\n workerLatency: distribution(latencies),\n }\n}\n\nexport function aggregateSnapshot(snapshot: TopSnapshot) {\n const complete = snapshot.completeness === 'complete'\n return {\n usdKnown: complete && snapshot.supervisors.every((row) => row.totals.usdKnown !== false),\n tokensKnown: complete && snapshot.supervisors.every((row) => row.totals.tokensKnown !== false),\n supervisors: snapshot.supervisors.length,\n workers: sum(snapshot.supervisors.map((supervisor) => supervisor.totals.workers)),\n running: sum(snapshot.supervisors.map((supervisor) => supervisor.totals.running)),\n done: sum(snapshot.supervisors.map((supervisor) => supervisor.totals.done)),\n down: sum(snapshot.supervisors.map((supervisor) => supervisor.totals.down)),\n usd: sum(snapshot.supervisors.map((supervisor) => supervisor.totals.usd)),\n tokensInput: sum(snapshot.supervisors.map((supervisor) => supervisor.totals.tokensInput)),\n tokensOutput: sum(snapshot.supervisors.map((supervisor) => supervisor.totals.tokensOutput)),\n }\n}\n\nfunction compareWorker(a: WorkerView, b: WorkerView): number {\n const aStart = parseTime(a.startedAt) ?? 0\n const bStart = parseTime(b.startedAt) ?? 0\n if (a.status === 'running' && b.status !== 'running') return -1\n if (b.status === 'running' && a.status !== 'running') return 1\n return aStart - bStart || a.label.localeCompare(b.label)\n}\n\nexport function totalSpend(worker: WorkerView): SpendStats {\n return addSpend(worker.spend, worker.metered)\n}\n\nfunction addSpend(a: SpendStats, b: SpendStats): SpendStats {\n return {\n iterations: a.iterations + b.iterations,\n tokensInput: a.tokensInput + b.tokensInput,\n tokensOutput: a.tokensOutput + b.tokensOutput,\n usd: a.usd + b.usd,\n ms: a.ms + b.ms,\n ...(a.usdKnown === false || b.usdKnown === false ? { usdKnown: false } : {}),\n ...(a.tokensKnown === false || b.tokensKnown === false ? { tokensKnown: false } : {}),\n }\n}\n\nexport function parseSpend(value: unknown): SpendStats {\n if (!isRecord(value)) return emptySpend\n const tokens = isRecord(value.tokens) ? value.tokens : {}\n return {\n ...(value.usdKnown === false ? { usdKnown: false } : {}),\n ...(value.tokensKnown === false || tokens.tokensKnown === false ? { tokensKnown: false } : {}),\n iterations: numberValue(value.iterations),\n tokensInput: numberValue(tokens.input),\n tokensOutput: numberValue(tokens.output),\n usd: numberValue(value.usd),\n ms: numberValue(value.ms),\n }\n}\n\nfunction parseBudget(value: unknown): BudgetStats | undefined {\n if (!isRecord(value)) return undefined\n const budget: BudgetStats = {\n ...(typeof value.maxIterations === 'number' ? { maxIterations: value.maxIterations } : {}),\n ...(typeof value.maxTokens === 'number' ? { maxTokens: value.maxTokens } : {}),\n ...(typeof value.maxUsd === 'number' ? { maxUsd: value.maxUsd } : {}),\n }\n return Object.keys(budget).length ? budget : undefined\n}\n\nfunction describeVerdict(value: unknown): string | undefined {\n if (!isRecord(value)) return undefined\n if (typeof value.valid === 'boolean') return value.valid ? 'valid' : 'invalid'\n if (typeof value.score === 'number') return `score ${value.score.toFixed(2)}`\n return undefined\n}\n\nfunction distribution(values: readonly number[]): Distribution {\n const sorted = [...values].sort((a, b) => a - b)\n return {\n n: sorted.length,\n min: sorted[0] ?? 0,\n median: percentile(sorted, 0.5),\n p90: percentile(sorted, 0.9),\n max: sorted[sorted.length - 1] ?? 0,\n }\n}\n\nfunction percentile(sorted: readonly number[], p: number): number {\n if (sorted.length === 0) return 0\n const idx = Math.min(sorted.length - 1, Math.max(0, Math.ceil(sorted.length * p) - 1))\n return sorted[idx] ?? 0\n}\n\n/**\n * Read one source file under a run directory. An absent file is not a defect on its own — the\n * writer may not have reached it yet — so it reads as `undefined` with no diagnostic; only a\n * failed read raises one. `path` stays run-relative and never carries file contents.\n */\nfunction readSourceFile(\n file: string,\n source: TopSnapshotDiagnosticSource,\n path: string,\n): SourceRead<string | undefined> {\n if (!existsSync(file)) return { value: undefined, diagnostics: [] }\n try {\n return { value: readFileSync(file, 'utf8'), diagnostics: [] }\n } catch {\n return { value: undefined, diagnostics: [{ source, path, reason: 'unreadable' }] }\n }\n}\n\nfunction tailLines(raw: string | undefined, maxLines: number): string[] {\n if (raw === undefined) return []\n return raw.trim().split('\\n').filter(Boolean).slice(-maxLines)\n}\n\nfunction readWorkerEventTails(\n dir: string,\n maxLines: number,\n): SourceRead<Map<string, WorkerEventTail>> {\n const out = new Map<string, WorkerEventTail>()\n if (!existsSync(dir)) return { value: out, diagnostics: [] }\n const workersDir = basename(dir)\n let entries: string[]\n try {\n entries = readdirSync(dir)\n } catch {\n return {\n value: out,\n diagnostics: [{ source: 'worker-tail', path: workersDir, reason: 'unreadable' }],\n }\n }\n const diagnostics: SourceDiagnostic[] = []\n for (const entry of entries) {\n // `<label>.inbox.ndjson` is the down-leg steer queue, not this worker's control-event log.\n if (!entry.endsWith('.ndjson') || entry.endsWith('.inbox.ndjson')) continue\n const file = join(dir, entry)\n const read = readSourceFile(file, 'worker-tail', join(workersDir, entry))\n diagnostics.push(...read.diagnostics)\n const lines = tailLines(read.value, maxLines)\n out.set(entry.slice(0, -'.ndjson'.length), { file, lines })\n }\n return { value: out, diagnostics }\n}\n\nfunction readSupervisorState(dir: string): SourceRead<SupervisorState | undefined> {\n const path = 'state.json'\n const read = readSourceFile(join(dir, path), 'supervisor-state', path)\n if (read.diagnostics.length > 0) return { value: undefined, diagnostics: read.diagnostics }\n const failed = (reason: TopSnapshotDiagnosticReason): SourceRead<undefined> => ({\n value: undefined,\n diagnostics: [{ source: 'supervisor-state', path, reason }],\n })\n if (read.value === undefined) return failed('missing')\n try {\n const parsed: unknown = JSON.parse(read.value)\n return isSupervisorState(parsed) ? { value: parsed, diagnostics: [] } : failed('invalid-state')\n } catch {\n return failed('partial-json')\n }\n}\n\nfunction isSupervisorState(value: unknown): value is SupervisorState {\n return (\n isRecord(value) &&\n Object.entries({\n id: 'string',\n status: 'string',\n task: 'string',\n workspaceDir: 'string',\n budget: 'number',\n }).every(([key, type]) => typeof value[key] === type)\n )\n}\n\nfunction isSpawnEvent<T>(value: T): value is T & TopJournalEvent {\n return (\n isRecord(value) &&\n typeof value.id === 'string' &&\n typeof value.kind === 'string' &&\n ['spawned', 'settled', 'cancelled', 'metered', 'progress'].includes(value.kind)\n )\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\nfunction isDirectory(path: string): boolean {\n try {\n return statSync(path).isDirectory()\n } catch {\n return false\n }\n}\n\nexport function numberValue(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value) ? value : 0\n}\n\nexport function parseTime(value: string | undefined): number | undefined {\n if (!value) return undefined\n const parsed = Date.parse(value)\n return Number.isFinite(parsed) ? parsed : undefined\n}\n\nfunction sum(values: readonly number[]): number {\n return values.reduce((total, value) => total + value, 0)\n}\n"],"mappings":"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"}
|