@tangle-network/agent-runtime 0.353.3 → 2.0.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.
Files changed (96) hide show
  1. package/dist/{activation-CFS31SWI.d.ts → activation-BuK2H7qx.d.ts} +2 -2
  2. package/dist/{activation-DTgC0RvI.js → activation-ZQWz04u8.js} +4 -4
  3. package/dist/{activation-DTgC0RvI.js.map → activation-ZQWz04u8.js.map} +1 -1
  4. package/dist/agent.d.ts +1 -1
  5. package/dist/agent.js +4 -3
  6. package/dist/agent.js.map +1 -1
  7. package/dist/{bundle-DeDkJbsr.js → bundle-PDYNXIEf.js} +2 -2
  8. package/dist/{bundle-DeDkJbsr.js.map → bundle-PDYNXIEf.js.map} +1 -1
  9. package/dist/candidate-execution/index.js +4 -4
  10. package/dist/{coordination-manager-D-J0Osf4.js → coordination-manager-BZLp9qpE.js} +8 -363
  11. package/dist/coordination-manager-BZLp9qpE.js.map +1 -0
  12. package/dist/coordination-map-routing-CUvwHAtv.js +362 -0
  13. package/dist/coordination-map-routing-CUvwHAtv.js.map +1 -0
  14. package/dist/{delegate-DfRQSGVk.js → delegate-C-MUU6ML.js} +2 -2
  15. package/dist/{delegate-DfRQSGVk.js.map → delegate-C-MUU6ML.js.map} +1 -1
  16. package/dist/durable-file-CksURHlH.js +1 -0
  17. package/dist/durable-file-DstVeHcj.js +228 -0
  18. package/dist/durable-file-DstVeHcj.js.map +1 -0
  19. package/dist/durable.d.ts +1 -1
  20. package/dist/durable.js +10 -8
  21. package/dist/durable.js.map +1 -1
  22. package/dist/{graph-BtGsqcOF.js → graph-CM-6CV_K.js} +6 -5
  23. package/dist/{graph-BtGsqcOF.js.map → graph-CM-6CV_K.js.map} +1 -1
  24. package/dist/graph-registry-72DlMnUl.js +585 -0
  25. package/dist/graph-registry-72DlMnUl.js.map +1 -0
  26. package/dist/graph-registry-CAX15LO6.js +1 -0
  27. package/dist/{improve-CL-Dsf63.js → improve-BuZ-I8DP.js} +9 -8
  28. package/dist/{improve-CL-Dsf63.js.map → improve-BuZ-I8DP.js.map} +1 -1
  29. package/dist/index.d.ts +3 -3
  30. package/dist/index.js +12 -11
  31. package/dist/index.js.map +1 -1
  32. package/dist/intelligence.d.ts +2 -2
  33. package/dist/intelligence.js +7 -7
  34. package/dist/{journal-store-BJPMUydp.js → journal-store-BpCOCDoO.js} +208 -635
  35. package/dist/journal-store-BpCOCDoO.js.map +1 -0
  36. package/dist/jsonl-file-BBP9Dz9w.js +429 -0
  37. package/dist/jsonl-file-BBP9Dz9w.js.map +1 -0
  38. package/dist/kernel.d.ts +1 -1
  39. package/dist/kernel.js +13 -12
  40. package/dist/{loop-runner-B1Xpgp2w.js → loop-runner-BWD6v1rd.js} +2 -2
  41. package/dist/{loop-runner-B1Xpgp2w.js.map → loop-runner-BWD6v1rd.js.map} +1 -1
  42. package/dist/{loop-runner-D9rcTNf2.d.ts → loop-runner-BpLTU_J4.d.ts} +2 -2
  43. package/dist/loop-runner-bin.d.ts +1 -1
  44. package/dist/loop-runner-bin.js +1 -1
  45. package/dist/mcp/bin.js +3 -3
  46. package/dist/mcp/index.d.ts +1 -1
  47. package/dist/mcp/index.js +5 -5
  48. package/dist/{prepare-XWwsOh8O.js → prepare-Bv6X2Wnx.js} +4 -4
  49. package/dist/{prepare-XWwsOh8O.js.map → prepare-Bv6X2Wnx.js.map} +1 -1
  50. package/dist/{profile-C01SQZKa.js → profile-Dir2A1_2.js} +2 -2
  51. package/dist/{profile-C01SQZKa.js.map → profile-Dir2A1_2.js.map} +1 -1
  52. package/dist/profiles.d.ts +1 -1
  53. package/dist/{provision-supervisor-CzCFHTxe.js → provision-supervisor-BWEeWag1.js} +8 -6
  54. package/dist/{provision-supervisor-CzCFHTxe.js.map → provision-supervisor-BWEeWag1.js.map} +1 -1
  55. package/dist/{run-cancellation-CoJRKvih.js → run-cancellation-Cpm-BIUu.js} +3 -2
  56. package/dist/{run-cancellation-CoJRKvih.js.map → run-cancellation-Cpm-BIUu.js.map} +1 -1
  57. package/dist/{runtime-DmdhgaTH.js → runtime-Cnr3213E.js} +18 -15
  58. package/dist/{runtime-DmdhgaTH.js.map → runtime-Cnr3213E.js.map} +1 -1
  59. package/dist/{sandbox-profile-compat-CXjozdWL.js → sandbox-profile-compat-DRiz9kME.js} +2 -2
  60. package/dist/{sandbox-profile-compat-CXjozdWL.js.map → sandbox-profile-compat-DRiz9kME.js.map} +1 -1
  61. package/dist/{search-executor-Djo4ssci.js → search-executor-__X1VKnU.js} +5 -5
  62. package/dist/{search-executor-Djo4ssci.js.map → search-executor-__X1VKnU.js.map} +1 -1
  63. package/dist/{server-DAanPY7z.js → server-CntFSTpW.js} +4 -4
  64. package/dist/{server-DAanPY7z.js.map → server-CntFSTpW.js.map} +1 -1
  65. package/dist/{structural-rollout-qqsbQW8M.js → structural-rollout-s8W19Mws.js} +5 -5
  66. package/dist/{structural-rollout-qqsbQW8M.js.map → structural-rollout-s8W19Mws.js.map} +1 -1
  67. package/dist/{supervise-DKwnVruI.js → supervise-Cl0F57m9.js} +13 -601
  68. package/dist/supervise-Cl0F57m9.js.map +1 -0
  69. package/dist/{supervision-discovery-CewADdEs.js → supervision-discovery-C3t0Xw-T.js} +5 -158
  70. package/dist/supervision-discovery-C3t0Xw-T.js.map +1 -0
  71. package/dist/{supervisor-C3JhrVVU.js → supervisor-L7u3pQ1j.js} +84 -140
  72. package/dist/supervisor-L7u3pQ1j.js.map +1 -0
  73. package/dist/task-queue-DbpZAp6C.js +49 -0
  74. package/dist/task-queue-DbpZAp6C.js.map +1 -0
  75. package/dist/task-queue.js +1 -49
  76. package/dist/testing.d.ts +1 -1
  77. package/dist/testing.js +13 -13
  78. package/dist/top-web-CkXPPXjI.js +1114 -0
  79. package/dist/top-web-CkXPPXjI.js.map +1 -0
  80. package/dist/tui/bin.js +4 -3
  81. package/dist/tui/bin.js.map +1 -1
  82. package/dist/tui/index.d.ts +22 -2
  83. package/dist/tui/index.js +3 -3
  84. package/dist/{types-DTHxh4X9.d.ts → types-BfnQq-_k.d.ts} +17 -21
  85. package/dist/{util-ebWMWzY0.js → util-BX20UJ9X.js} +2 -2
  86. package/dist/{util-ebWMWzY0.js.map → util-BX20UJ9X.js.map} +1 -1
  87. package/package.json +11 -11
  88. package/skills/agent-graphs/references/authoring.md +1 -0
  89. package/dist/coordination-manager-D-J0Osf4.js.map +0 -1
  90. package/dist/journal-store-BJPMUydp.js.map +0 -1
  91. package/dist/supervise-DKwnVruI.js.map +0 -1
  92. package/dist/supervision-discovery-CewADdEs.js.map +0 -1
  93. package/dist/supervisor-C3JhrVVU.js.map +0 -1
  94. package/dist/task-queue.js.map +0 -1
  95. package/dist/top-snapshot-DcV7VG4m.js +0 -520
  96. package/dist/top-snapshot-DcV7VG4m.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"task-queue.js","names":[],"sources":["../src/runtime/task-queue.ts"],"sourcesContent":["/** One identified task admitted by a caller-owned ready queue. */\nexport interface TaskQueueEntry<T> {\n readonly id: string\n readonly value: T\n}\n\n/** Native promise settlement, retaining the exact returned or thrown value. */\nexport type TaskQueueSettlement<T, R> = {\n readonly task: TaskQueueEntry<T>\n} & (\n | { readonly status: 'fulfilled'; readonly value: R }\n | { readonly status: 'rejected'; readonly reason: unknown }\n)\n\nexport interface TaskQueueOptions<T, R> {\n readonly concurrency: number\n /** Return the next ready task, or undefined when none is currently admissible.\n * Called again after each yielded settlement; awaiting admission may persist a\n * checkpoint before execute starts. Active identities cannot be admitted twice. */\n readonly take: (\n activeIds: ReadonlySet<string>,\n ) => TaskQueueEntry<T> | undefined | Promise<TaskQueueEntry<T> | undefined>\n readonly execute: (task: TaskQueueEntry<T>) => Promise<R>\n}\n\n/**\n * Admit bounded work and yield settlements for the caller's policy to interpret.\n * Readiness, cancellation, retries, and persistence belong to that caller.\n * A throw or early iterator return stops admission and awaits every started task.\n * Settlements are delivered in completion order, before further admission.\n * Task failures are yielded, never normalized or substituted for caller failures.\n */\nexport async function* runTaskQueue<T, R>(\n options: TaskQueueOptions<T, R>,\n): AsyncGenerator<TaskQueueSettlement<T, R>> {\n if (!Number.isSafeInteger(options.concurrency) || options.concurrency < 1) {\n throw new RangeError('runTaskQueue: concurrency must be a positive safe integer')\n }\n const active = new Map<string, Promise<TaskQueueSettlement<T, R>>>()\n const completed: TaskQueueSettlement<T, R>[] = []\n try {\n for (;;) {\n while (active.size < options.concurrency && completed.length === 0) {\n const admitted = await options.take(new Set(active.keys()))\n if (admitted === undefined) break\n const task = Object.freeze({ id: admitted.id, value: admitted.value })\n if (active.has(task.id)) {\n throw new Error(`runTaskQueue: task \"${task.id}\" is already active`)\n }\n const settlement = Promise.resolve()\n .then(() => options.execute(task))\n .then(\n (value): TaskQueueSettlement<T, R> => ({ task, status: 'fulfilled', value }),\n (reason: unknown): TaskQueueSettlement<T, R> => ({ task, status: 'rejected', reason }),\n )\n active.set(\n task.id,\n settlement.then((result) => {\n completed.push(result)\n return result\n }),\n )\n }\n if (active.size === 0) return\n if (completed.length === 0) await Promise.race(active.values())\n const settlement = completed.shift()!\n active.delete(settlement.task.id)\n yield settlement\n }\n } finally {\n await Promise.allSettled(active.values())\n }\n}\n"],"mappings":";;;;;;;;AAgCA,gBAAuB,aACrB,SAC2C;CAC3C,IAAI,CAAC,OAAO,cAAc,QAAQ,WAAW,KAAK,QAAQ,cAAc,GACtE,MAAM,IAAI,WAAW,2DAA2D;CAElF,MAAM,yBAAS,IAAI,IAAgD;CACnE,MAAM,YAAyC,CAAC;CAChD,IAAI;EACF,SAAS;GACP,OAAO,OAAO,OAAO,QAAQ,eAAe,UAAU,WAAW,GAAG;IAClE,MAAM,WAAW,MAAM,QAAQ,KAAK,IAAI,IAAI,OAAO,KAAK,CAAC,CAAC;IAC1D,IAAI,aAAa,KAAA,GAAW;IAC5B,MAAM,OAAO,OAAO,OAAO;KAAE,IAAI,SAAS;KAAI,OAAO,SAAS;IAAM,CAAC;IACrE,IAAI,OAAO,IAAI,KAAK,EAAE,GACpB,MAAM,IAAI,MAAM,uBAAuB,KAAK,GAAG,oBAAoB;IAErE,MAAM,aAAa,QAAQ,QAAQ,CAAC,CACjC,WAAW,QAAQ,QAAQ,IAAI,CAAC,CAAC,CACjC,MACE,WAAsC;KAAE;KAAM,QAAQ;KAAa;IAAM,KACzE,YAAgD;KAAE;KAAM,QAAQ;KAAY;IAAO,EACtF;IACF,OAAO,IACL,KAAK,IACL,WAAW,MAAM,WAAW;KAC1B,UAAU,KAAK,MAAM;KACrB,OAAO;IACT,CAAC,CACH;GACF;GACA,IAAI,OAAO,SAAS,GAAG;GACvB,IAAI,UAAU,WAAW,GAAG,MAAM,QAAQ,KAAK,OAAO,OAAO,CAAC;GAC9D,MAAM,aAAa,UAAU,MAAM;GACnC,OAAO,OAAO,WAAW,KAAK,EAAE;GAChC,MAAM;EACR;CACF,UAAU;EACR,MAAM,QAAQ,WAAW,OAAO,OAAO,CAAC;CAC1C;AACF"}
@@ -1,520 +0,0 @@
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";
4
- import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
5
- import { basename, join, resolve } from "node:path";
6
- // src/tui/top-snapshot.ts
7
- /**
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`.
12
- *
13
- * @experimental
14
- */
15
- const emptySpend = {
16
- iterations: 0,
17
- tokensInput: 0,
18
- tokensOutput: 0,
19
- usd: 0,
20
- ms: 0
21
- };
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;
25
- const root = resolve(rootDir);
26
- const supervisors = [];
27
- const diagnostics = [];
28
- let discovered = 0;
29
- const report = (runId, sources) => {
30
- for (const source of sources) diagnostics.push({
31
- ...source,
32
- runId
33
- });
34
- };
35
- for (const runsRoot of [supervisorRunsRoot(root), legacySupervisorRunsRoot(root)]) {
36
- if (!existsSync(runsRoot)) continue;
37
- for (const entry of readdirSync(runsRoot)) {
38
- const dir = join(runsRoot, entry);
39
- if (!isDirectory(dir)) continue;
40
- discovered += 1;
41
- const state = readSupervisorState(dir);
42
- report(entry, state.diagnostics);
43
- if (!state.value) continue;
44
- const journal = readJournal(dir);
45
- const progress = readSourceFile(join(dir, "progress.ndjson"), "progress", "progress.ndjson");
46
- const workerEvents = readWorkerEventTails(supervisorWorkersDir(dir), 8);
47
- report(entry, [
48
- ...journal.diagnostics,
49
- ...progress.diagnostics,
50
- ...workerEvents.diagnostics
51
- ]);
52
- supervisors.push(buildSupervisorView(state.value, dir, journal.value, tailLines(progress.value, 8), now, workerEvents.value));
53
- }
54
- }
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) {
59
- return {
60
- root,
61
- generatedAt: now,
62
- supervisors,
63
- completeness: diagnostics.length ? "partial" : "complete",
64
- diagnostics,
65
- discovered,
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")
122
- };
123
- }
124
- /**
125
- * The journal file a run dir actually carries. `createFileRunContext` — this repo's own durable
126
- * writer — names it `spawn-journal.jsonl`; `journal.jsonl` is the retired bare-event file older
127
- * runs left behind. First existing name wins; a reader that knew only the retired name would show
128
- * zero workers for every current run.
129
- */
130
- const journalFileNames = ["spawn-journal.jsonl", "journal.jsonl"];
131
- function readJournal(eventDir) {
132
- const path = journalFileNames.find((candidate) => existsSync(join(eventDir, candidate)));
133
- if (!path) return {
134
- value: [],
135
- diagnostics: []
136
- };
137
- const read = readSourceFile(join(eventDir, path), "journal", path);
138
- if (read.value === void 0) return {
139
- value: [],
140
- diagnostics: read.diagnostics
141
- };
142
- const out = [];
143
- let partial = false;
144
- for (const line of read.value.split("\n")) {
145
- const trimmed = line.trim();
146
- if (!trimmed) continue;
147
- try {
148
- const parsed = JSON.parse(trimmed);
149
- const events = parsed.kind === "event" || parsed.kind === "events" ? spawnJournalRecordEvents(parsed) : [parsed];
150
- for (const event of events) if (isSpawnEvent(event)) out.push(event);
151
- } catch {
152
- partial = true;
153
- }
154
- }
155
- return {
156
- value: out,
157
- diagnostics: partial ? [{
158
- source: "journal",
159
- path,
160
- reason: "partial-json"
161
- }] : []
162
- };
163
- }
164
- function buildSupervisorView(state, stateDir, events, progressTail, now, workerEventTails = /* @__PURE__ */ new Map(), accounting) {
165
- const workers = /* @__PURE__ */ new Map();
166
- let driverSpend = emptySpend;
167
- const journalRootId = events.find((event) => event.kind === "spawned" && !event.parent && event.label === "root")?.id;
168
- const isRoot = (id) => id === state.id || id === journalRootId;
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);
175
- if (event.kind === "spawned") {
176
- worker.label = event.label ?? worker.label;
177
- if (event.parent) worker.parent = event.parent;
178
- if (event.runtime) worker.runtime = event.runtime;
179
- worker.status = "running";
180
- if (event.at) worker.startedAt = event.at;
181
- const budget = parseBudget(event.budget);
182
- if (budget) worker.budget = budget;
183
- } else if (event.kind === "settled" || event.kind === "cancelled") {
184
- if (event.at) worker.endedAt = event.at;
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) {
196
- worker.spend = addSpend(worker.spend, parseSpend(event.spent));
197
- worker.metered = emptySpend;
198
- }
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;
207
- }
208
- }
209
- const workerViews = [...workers.values()].map((worker) => {
210
- const tail = workerEventTails.get(worker.label) ?? workerEventTails.get(safeWorkerFile(worker.label)) ?? workerEventTails.get(safeWorkerFile(worker.id)) ?? workerEventTails.get(worker.id);
211
- worker.liveTail = tail?.lines ?? [];
212
- if (tail?.file) worker.eventFile = tail.file;
213
- return finalizeWorker(worker, now);
214
- }).sort((a, b) => compareWorker(a, b));
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
- }
220
- return {
221
- id: state.id,
222
- stateDir,
223
- status: state.status,
224
- task: state.task,
225
- workspaceDir: state.workspaceDir,
226
- budget: state.budget,
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),
244
- ...state.result?.spentUsd !== void 0 ? { resultSpentUsd: state.result.spentUsd } : {},
245
- ...state.result?.spentTokens !== void 0 ? { resultSpentTokens: state.result.spentTokens } : {},
246
- workers: workerViews,
247
- progressTail: [...progressTail],
248
- journalTail: events.slice(-12),
249
- driverSpend,
250
- totals
251
- };
252
- }
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) {
259
- const existing = workers.get(id);
260
- if (existing) return existing;
261
- const created = {
262
- id,
263
- label: id,
264
- status: "running",
265
- spend: emptySpend,
266
- metered: emptySpend,
267
- liveTail: []
268
- };
269
- workers.set(id, created);
270
- return created;
271
- }
272
- function finalizeWorker(worker, now) {
273
- const startMs = parseTime(worker.startedAt);
274
- const endMs = parseTime(worker.endedAt) ?? (worker.status === "running" ? now : startMs);
275
- const latencyMs = startMs !== void 0 && endMs !== void 0 ? Math.max(0, endMs - startMs) : 0;
276
- return {
277
- ...worker,
278
- latencyMs
279
- };
280
- }
281
- function supervisorTotals(state, workers, driverSpend, now) {
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;
290
- const started = parseTime(state.startedAt);
291
- const completed = parseTime(state.completedAt);
292
- const latencyMs = started !== void 0 ? Math.max(0, (completed ?? now) - started) : 0;
293
- const latencies = workers.map((worker) => worker.latencyMs).filter((ms) => ms > 0);
294
- return {
295
- workers: workers.length,
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,
305
- latencyMs,
306
- workerLatency: distribution(latencies)
307
- };
308
- }
309
- function aggregateSnapshot(snapshot) {
310
- const complete = snapshot.completeness === "complete";
311
- return {
312
- usdKnown: complete && snapshot.supervisors.every((row) => row.totals.usdKnown !== false),
313
- tokensKnown: complete && snapshot.supervisors.every((row) => row.totals.tokensKnown !== false),
314
- supervisors: snapshot.supervisors.length,
315
- workers: sum(snapshot.supervisors.map((supervisor) => supervisor.totals.workers)),
316
- running: sum(snapshot.supervisors.map((supervisor) => supervisor.totals.running)),
317
- done: sum(snapshot.supervisors.map((supervisor) => supervisor.totals.done)),
318
- down: sum(snapshot.supervisors.map((supervisor) => supervisor.totals.down)),
319
- usd: sum(snapshot.supervisors.map((supervisor) => supervisor.totals.usd)),
320
- tokensInput: sum(snapshot.supervisors.map((supervisor) => supervisor.totals.tokensInput)),
321
- tokensOutput: sum(snapshot.supervisors.map((supervisor) => supervisor.totals.tokensOutput))
322
- };
323
- }
324
- function compareWorker(a, b) {
325
- const aStart = parseTime(a.startedAt) ?? 0;
326
- const bStart = parseTime(b.startedAt) ?? 0;
327
- if (a.status === "running" && b.status !== "running") return -1;
328
- if (b.status === "running" && a.status !== "running") return 1;
329
- return aStart - bStart || a.label.localeCompare(b.label);
330
- }
331
- function totalSpend(worker) {
332
- return addSpend(worker.spend, worker.metered);
333
- }
334
- function addSpend(a, b) {
335
- return {
336
- iterations: a.iterations + b.iterations,
337
- tokensInput: a.tokensInput + b.tokensInput,
338
- tokensOutput: a.tokensOutput + b.tokensOutput,
339
- usd: a.usd + b.usd,
340
- ms: a.ms + b.ms,
341
- ...a.usdKnown === false || b.usdKnown === false ? { usdKnown: false } : {},
342
- ...a.tokensKnown === false || b.tokensKnown === false ? { tokensKnown: false } : {}
343
- };
344
- }
345
- function parseSpend(value) {
346
- if (!isRecord(value)) return emptySpend;
347
- const tokens = isRecord(value.tokens) ? value.tokens : {};
348
- return {
349
- ...value.usdKnown === false ? { usdKnown: false } : {},
350
- ...value.tokensKnown === false || tokens.tokensKnown === false ? { tokensKnown: false } : {},
351
- iterations: numberValue(value.iterations),
352
- tokensInput: numberValue(tokens.input),
353
- tokensOutput: numberValue(tokens.output),
354
- usd: numberValue(value.usd),
355
- ms: numberValue(value.ms)
356
- };
357
- }
358
- function parseBudget(value) {
359
- if (!isRecord(value)) return void 0;
360
- const budget = {
361
- ...typeof value.maxIterations === "number" ? { maxIterations: value.maxIterations } : {},
362
- ...typeof value.maxTokens === "number" ? { maxTokens: value.maxTokens } : {},
363
- ...typeof value.maxUsd === "number" ? { maxUsd: value.maxUsd } : {}
364
- };
365
- return Object.keys(budget).length ? budget : void 0;
366
- }
367
- function describeVerdict(value) {
368
- if (!isRecord(value)) return void 0;
369
- if (typeof value.valid === "boolean") return value.valid ? "valid" : "invalid";
370
- if (typeof value.score === "number") return `score ${value.score.toFixed(2)}`;
371
- }
372
- function distribution(values) {
373
- const sorted = [...values].sort((a, b) => a - b);
374
- return {
375
- n: sorted.length,
376
- min: sorted[0] ?? 0,
377
- median: percentile(sorted, .5),
378
- p90: percentile(sorted, .9),
379
- max: sorted[sorted.length - 1] ?? 0
380
- };
381
- }
382
- function percentile(sorted, p) {
383
- if (sorted.length === 0) return 0;
384
- return sorted[Math.min(sorted.length - 1, Math.max(0, Math.ceil(sorted.length * p) - 1))] ?? 0;
385
- }
386
- /**
387
- * Read one source file under a run directory. An absent file is not a defect on its own — the
388
- * writer may not have reached it yet — so it reads as `undefined` with no diagnostic; only a
389
- * failed read raises one. `path` stays run-relative and never carries file contents.
390
- */
391
- function readSourceFile(file, source, path) {
392
- if (!existsSync(file)) return {
393
- value: void 0,
394
- diagnostics: []
395
- };
396
- try {
397
- return {
398
- value: readFileSync(file, "utf8"),
399
- diagnostics: []
400
- };
401
- } catch {
402
- return {
403
- value: void 0,
404
- diagnostics: [{
405
- source,
406
- path,
407
- reason: "unreadable"
408
- }]
409
- };
410
- }
411
- }
412
- function tailLines(raw, maxLines) {
413
- if (raw === void 0) return [];
414
- return raw.trim().split("\n").filter(Boolean).slice(-maxLines);
415
- }
416
- function readWorkerEventTails(dir, maxLines) {
417
- const out = /* @__PURE__ */ new Map();
418
- if (!existsSync(dir)) return {
419
- value: out,
420
- diagnostics: []
421
- };
422
- const workersDir = basename(dir);
423
- let entries;
424
- try {
425
- entries = readdirSync(dir);
426
- } catch {
427
- return {
428
- value: out,
429
- diagnostics: [{
430
- source: "worker-tail",
431
- path: workersDir,
432
- reason: "unreadable"
433
- }]
434
- };
435
- }
436
- const diagnostics = [];
437
- for (const entry of entries) {
438
- if (!entry.endsWith(".ndjson") || entry.endsWith(".inbox.ndjson")) continue;
439
- const file = join(dir, entry);
440
- const read = readSourceFile(file, "worker-tail", join(workersDir, entry));
441
- diagnostics.push(...read.diagnostics);
442
- const lines = tailLines(read.value, maxLines);
443
- out.set(entry.slice(0, -7), {
444
- file,
445
- lines
446
- });
447
- }
448
- return {
449
- value: out,
450
- diagnostics
451
- };
452
- }
453
- function readSupervisorState(dir) {
454
- const path = "state.json";
455
- const read = readSourceFile(join(dir, path), "supervisor-state", path);
456
- if (read.diagnostics.length > 0) return {
457
- value: void 0,
458
- diagnostics: read.diagnostics
459
- };
460
- const failed = (reason) => ({
461
- value: void 0,
462
- diagnostics: [{
463
- source: "supervisor-state",
464
- path,
465
- reason
466
- }]
467
- });
468
- if (read.value === void 0) return failed("missing");
469
- try {
470
- const parsed = JSON.parse(read.value);
471
- return isSupervisorState(parsed) ? {
472
- value: parsed,
473
- diagnostics: []
474
- } : failed("invalid-state");
475
- } catch {
476
- return failed("partial-json");
477
- }
478
- }
479
- function isSupervisorState(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);
487
- }
488
- function isSpawnEvent(value) {
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);
496
- }
497
- function isRecord(value) {
498
- return typeof value === "object" && value !== null;
499
- }
500
- function isDirectory(path) {
501
- try {
502
- return statSync(path).isDirectory();
503
- } catch {
504
- return false;
505
- }
506
- }
507
- function numberValue(value) {
508
- return typeof value === "number" && Number.isFinite(value) ? value : 0;
509
- }
510
- function parseTime(value) {
511
- if (!value) return void 0;
512
- const parsed = Date.parse(value);
513
- return Number.isFinite(parsed) ? parsed : void 0;
514
- }
515
- function sum(values) {
516
- return values.reduce((total, value) => total + value, 0);
517
- }
518
- export { parseTime as a, parseSpend as i, loadTopSnapshot as n, totalSpend as o, numberValue as r, aggregateSnapshot as t };
519
-
520
- //# sourceMappingURL=top-snapshot-DcV7VG4m.js.map
@@ -1 +0,0 @@
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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"}