@tangle-network/traces 0.23.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -1078
- package/dist/analyst-model-call-JVUOYZ5V.js +20 -0
- package/dist/ask-XLS3VANY.js +39 -0
- package/dist/check-YF6ZHPGG.js +322 -0
- package/dist/chunk-3I4PJ5Q7.js +25 -0
- package/dist/chunk-3T62R7ON.js +5695 -0
- package/dist/chunk-4VKPN432.js +138 -0
- package/dist/chunk-6CLC7DKP.js +492 -0
- package/dist/chunk-7CBV5RJ2.js +535 -0
- package/dist/chunk-B62DOFGI.js +273 -0
- package/dist/chunk-CL3OQOWX.js +407 -0
- package/dist/chunk-DLGAKCQJ.js +782 -0
- package/dist/chunk-DU534HAX.js +263 -0
- package/dist/chunk-GLUDGUGJ.js +232 -0
- package/dist/chunk-J2PM5SVN.js +503 -0
- package/dist/chunk-M3W6TZHQ.js +381 -0
- package/dist/chunk-NH7HCDLB.js +759 -0
- package/dist/chunk-NZ5Y7UEL.js +1217 -0
- package/dist/chunk-O52XK7OB.js +19 -0
- package/dist/chunk-PYH3PL3N.js +62 -0
- package/dist/chunk-RZL5GAWH.js +60 -0
- package/dist/chunk-TR6O4S4T.js +208 -0
- package/dist/chunk-TW43MR5D.js +259 -0
- package/dist/chunk-TYLFUX42.js +228 -0
- package/dist/chunk-UOLRCQHC.js +120 -0
- package/dist/chunk-UVE5ANVV.js +3921 -0
- package/dist/chunk-V2OCGX57.js +53 -0
- package/dist/cli.js +2086 -2050
- package/dist/diff-ZZ6KYBPP.js +16 -0
- package/dist/improvement-OJQ6365E.js +25 -0
- package/dist/index.d.ts +1235 -4357
- package/dist/index.js +53 -1204
- package/dist/live-Y64AJ6MA.js +14 -0
- package/dist/mcp-ZPGTJQYQ.js +85 -0
- package/dist/report-JAMXRTCW.js +338 -0
- package/dist/run-watch-PLWTIRSV.js +649 -0
- package/dist/supervisor-report-RMPLLBGZ.js +29 -0
- package/dist/supervisor-run-context-WO6VOTGV.js +30 -0
- package/dist/upload-R6NMKSGQ.js +20 -0
- package/dist/verify-safe-C5ZXZOZ2.js +8 -0
- package/docs/analyze.md +76 -0
- package/docs/ask.md +88 -0
- package/docs/bundle.md +40 -0
- package/docs/check.md +77 -0
- package/docs/convert.md +44 -0
- package/docs/develop.md +32 -0
- package/docs/diff.md +38 -0
- package/docs/facts.md +114 -0
- package/docs/mcp.md +36 -0
- package/docs/migrate-1.0.md +33 -0
- package/docs/parsers.md +66 -0
- package/docs/release-1.0.0.md +147 -0
- package/docs/sdk.md +77 -0
- package/docs/select.md +70 -0
- package/docs/skills.md +46 -0
- package/docs/upload.md +47 -0
- package/docs/watch-jsonl.v1.example.jsonl +5 -0
- package/docs/watch.md +66 -0
- package/examples/README.md +9 -0
- package/examples/custom-analyst.ts +65 -74
- package/install.sh +22 -2
- package/package.json +8 -7
- package/skills/inspect-agent-traces/SKILL.md +47 -110
- package/dist/chunk-COSWFESO.js +0 -20979
- package/docs/replay-verify.md +0 -123
- package/docs/stream-findings.svg +0 -39
- package/docs/trace-analysts.md +0 -643
- package/examples/custom-backend.ts +0 -21
- package/examples/external-engines.ts +0 -62
- package/examples/improvement-config.mjs +0 -63
- package/examples/observe-and-alert.ts +0 -19
- package/examples/register-harness.ts +0 -26
- package/skills/build-trace-analyst/SKILL.md +0 -76
- package/skills/build-trace-analyst/agents/openai.yaml +0 -4
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
// src/supervisor-run-context.ts
|
|
2
|
+
import { readFile, stat } from "fs/promises";
|
|
3
|
+
import { basename, join } from "path";
|
|
4
|
+
import { materializeTreeView } from "@tangle-network/agent-runtime/kernel";
|
|
5
|
+
import {
|
|
6
|
+
readRuntimeSupervisorRun
|
|
7
|
+
} from "@tangle-network/agent-eval/supervisor-run";
|
|
8
|
+
var SPAWN_JOURNAL_FILE = "spawn-journal.jsonl";
|
|
9
|
+
var COORDINATION_LOG_FILE = "coordination-log.jsonl";
|
|
10
|
+
var RESULT_FILE = "result.json";
|
|
11
|
+
async function readMaybe(path) {
|
|
12
|
+
return readFile(path, "utf8").catch(() => null);
|
|
13
|
+
}
|
|
14
|
+
function readJsonlLines(text) {
|
|
15
|
+
if (text === null) {
|
|
16
|
+
return { rows: [], invalidRows: 0, partialTail: false, present: false };
|
|
17
|
+
}
|
|
18
|
+
const lines = text.split("\n");
|
|
19
|
+
const partialTail = text.length > 0 && !text.endsWith("\n");
|
|
20
|
+
if (partialTail) lines.pop();
|
|
21
|
+
const rows = [];
|
|
22
|
+
let invalidRows = 0;
|
|
23
|
+
for (const line of lines) {
|
|
24
|
+
const trimmed = line.trim();
|
|
25
|
+
if (trimmed.length === 0) continue;
|
|
26
|
+
try {
|
|
27
|
+
const parsed = JSON.parse(trimmed);
|
|
28
|
+
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
29
|
+
rows.push(parsed);
|
|
30
|
+
} else invalidRows += 1;
|
|
31
|
+
} catch {
|
|
32
|
+
invalidRows += 1;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return { rows, invalidRows, partialTail, present: true };
|
|
36
|
+
}
|
|
37
|
+
function asRecord(v) {
|
|
38
|
+
return typeof v === "object" && v !== null && !Array.isArray(v) ? v : {};
|
|
39
|
+
}
|
|
40
|
+
function str(v) {
|
|
41
|
+
return typeof v === "string" && v.length > 0 ? v : null;
|
|
42
|
+
}
|
|
43
|
+
var RETIRED_WAIT_KINDS = /* @__PURE__ */ new Set(["waiting", "woken"]);
|
|
44
|
+
function readRunContextJournal(text) {
|
|
45
|
+
const parsed = readJsonlLines(text);
|
|
46
|
+
let root = null;
|
|
47
|
+
let begunAt = null;
|
|
48
|
+
const events = [];
|
|
49
|
+
let invalidRows = parsed.invalidRows;
|
|
50
|
+
let retiredWaitRows = 0;
|
|
51
|
+
for (const record of parsed.rows) {
|
|
52
|
+
const recordRoot = str(record.root);
|
|
53
|
+
if (root === null && recordRoot !== null) root = recordRoot;
|
|
54
|
+
if (record.kind === "begin") {
|
|
55
|
+
if (begunAt === null) begunAt = str(record.at);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (record.kind !== "event") {
|
|
59
|
+
invalidRows += 1;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const event = asRecord(record.event);
|
|
63
|
+
if (str(event.kind) === null || str(event.id) === null) {
|
|
64
|
+
invalidRows += 1;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (RETIRED_WAIT_KINDS.has(event.kind)) {
|
|
68
|
+
retiredWaitRows += 1;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
events.push(event);
|
|
72
|
+
}
|
|
73
|
+
const supervisorIds = /* @__PURE__ */ new Set();
|
|
74
|
+
for (const event of events) {
|
|
75
|
+
if (event.kind !== "spawned") continue;
|
|
76
|
+
const parent = event.parent;
|
|
77
|
+
if (typeof parent === "string" && parent.length > 0) supervisorIds.add(parent);
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
root,
|
|
81
|
+
begunAt,
|
|
82
|
+
events,
|
|
83
|
+
supervisorIds,
|
|
84
|
+
invalidRows,
|
|
85
|
+
retiredWaitRows,
|
|
86
|
+
partialTail: parsed.partialTail,
|
|
87
|
+
present: parsed.present
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function inferRole(id, parent, supervisorIds) {
|
|
91
|
+
if (parent === null || parent === void 0) return "supervisor";
|
|
92
|
+
return supervisorIds.has(id) ? "supervisor" : "worker";
|
|
93
|
+
}
|
|
94
|
+
var EMPTY_COORDINATION = {
|
|
95
|
+
present: false,
|
|
96
|
+
steers: [],
|
|
97
|
+
deliveries: [],
|
|
98
|
+
questions: [],
|
|
99
|
+
invalidRows: 0,
|
|
100
|
+
partialTail: false
|
|
101
|
+
};
|
|
102
|
+
function readCoordinationLog(text) {
|
|
103
|
+
const parsed = readJsonlLines(text);
|
|
104
|
+
if (!parsed.present) return EMPTY_COORDINATION;
|
|
105
|
+
const steers = [];
|
|
106
|
+
const deliveries = [];
|
|
107
|
+
const questions = [];
|
|
108
|
+
let invalidRows = parsed.invalidRows;
|
|
109
|
+
for (const row of parsed.rows) {
|
|
110
|
+
const record = asRecord(row.record);
|
|
111
|
+
const event = asRecord(Object.keys(record).length > 0 ? record.event : row.event);
|
|
112
|
+
const at = typeof record.at === "number" ? record.at : parseInstant(row.at);
|
|
113
|
+
switch (event.type) {
|
|
114
|
+
case "steer": {
|
|
115
|
+
const down = asRecord(event.down);
|
|
116
|
+
steers.push({
|
|
117
|
+
messageId: str(down.messageId),
|
|
118
|
+
toWorker: str(down.toWorker),
|
|
119
|
+
instruction: typeof down.instruction === "string" ? down.instruction : "",
|
|
120
|
+
deliveryMode: str(down.deliveryMode),
|
|
121
|
+
at
|
|
122
|
+
});
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
case "delivery": {
|
|
126
|
+
const receipt = asRecord(event.receipt);
|
|
127
|
+
deliveries.push({
|
|
128
|
+
messageId: str(receipt.messageId),
|
|
129
|
+
delivered: typeof receipt.delivered === "boolean" ? receipt.delivered : null
|
|
130
|
+
});
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
case "question": {
|
|
134
|
+
const q = asRecord(event.question);
|
|
135
|
+
const urgency = str(q.urgency);
|
|
136
|
+
questions.push({
|
|
137
|
+
id: str(q.id),
|
|
138
|
+
from: str(q.from),
|
|
139
|
+
question: typeof q.question === "string" ? q.question : "",
|
|
140
|
+
reason: str(q.reason),
|
|
141
|
+
urgency,
|
|
142
|
+
status: str(q.status),
|
|
143
|
+
blocking: urgency === "blocks-run",
|
|
144
|
+
at: typeof q.openedAt === "number" ? q.openedAt : at
|
|
145
|
+
});
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
case "settled":
|
|
149
|
+
break;
|
|
150
|
+
default:
|
|
151
|
+
if (str(event.type) === null) invalidRows += 1;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
present: true,
|
|
156
|
+
steers,
|
|
157
|
+
deliveries,
|
|
158
|
+
questions,
|
|
159
|
+
invalidRows,
|
|
160
|
+
partialTail: parsed.partialTail
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function parseInstant(v) {
|
|
164
|
+
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
165
|
+
if (typeof v !== "string") return null;
|
|
166
|
+
const t = Date.parse(v);
|
|
167
|
+
return Number.isFinite(t) ? t : null;
|
|
168
|
+
}
|
|
169
|
+
async function readFileRunContext(runDir, opts = {}) {
|
|
170
|
+
const sources = await readRuntimeSupervisorRun(runDir);
|
|
171
|
+
const coordination = readCoordinationLog(await readMaybe(join(runDir, COORDINATION_LOG_FILE)));
|
|
172
|
+
return {
|
|
173
|
+
...sources,
|
|
174
|
+
instanceId: opts.instanceId !== void 0 ? opts.instanceId : sources.instanceId,
|
|
175
|
+
arm: opts.arm !== void 0 ? opts.arm : basename(runDir),
|
|
176
|
+
workers: sources.workers !== null && coordination.present ? workerSources(sources.workers, coordination) : sources.workers,
|
|
177
|
+
...sources.journal !== null ? {
|
|
178
|
+
rootTranscriptRef: join(runDir, SPAWN_JOURNAL_FILE),
|
|
179
|
+
traceCommand: `traces watch ${runDir}`
|
|
180
|
+
} : {}
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function fileRunContextSupervisorRunReader(runDir, opts = {}) {
|
|
184
|
+
return { runRef: runDir, read: () => readFileRunContext(runDir, opts) };
|
|
185
|
+
}
|
|
186
|
+
async function isFileRunContextDir(runDir) {
|
|
187
|
+
return stat(join(runDir, SPAWN_JOURNAL_FILE)).then((s) => s.isFile()).catch(() => false);
|
|
188
|
+
}
|
|
189
|
+
function parseJsonObject(text) {
|
|
190
|
+
if (text === null) return null;
|
|
191
|
+
try {
|
|
192
|
+
const parsed = JSON.parse(text);
|
|
193
|
+
return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : null;
|
|
194
|
+
} catch {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function workerSources(workers, coordination) {
|
|
199
|
+
const deliveredById = /* @__PURE__ */ new Map();
|
|
200
|
+
for (const receipt of coordination.deliveries) {
|
|
201
|
+
if (receipt.messageId !== null) deliveredById.set(receipt.messageId, receipt.delivered);
|
|
202
|
+
}
|
|
203
|
+
return workers.map((worker) => {
|
|
204
|
+
const steers = coordination.steers.filter((steer) => steer.toWorker === worker.workerId);
|
|
205
|
+
const questions = coordination.questions.filter((question) => question.from === worker.workerId);
|
|
206
|
+
return {
|
|
207
|
+
...worker,
|
|
208
|
+
events: [
|
|
209
|
+
...steers.map((steer) => JSON.stringify({
|
|
210
|
+
kind: "message",
|
|
211
|
+
requestId: steer.messageId,
|
|
212
|
+
delivered: steer.messageId === null ? null : deliveredById.get(steer.messageId) ?? null
|
|
213
|
+
})),
|
|
214
|
+
...questions.map((question) => JSON.stringify({ kind: "message", direction: "up", id: question.id }))
|
|
215
|
+
].join("\n"),
|
|
216
|
+
inbox: steers.map((steer) => JSON.stringify({ id: steer.messageId, message: steer.instruction })).join("\n")
|
|
217
|
+
};
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
var ZERO_ROLL = {
|
|
221
|
+
records: 0,
|
|
222
|
+
iterations: 0,
|
|
223
|
+
tokensIn: 0,
|
|
224
|
+
tokensOut: 0,
|
|
225
|
+
usd: 0,
|
|
226
|
+
usdKnownRecords: 0,
|
|
227
|
+
usdUnknownRecords: 0
|
|
228
|
+
};
|
|
229
|
+
function addSpend(roll, spend) {
|
|
230
|
+
const known = spend.usdKnown !== false;
|
|
231
|
+
return {
|
|
232
|
+
records: roll.records + 1,
|
|
233
|
+
iterations: roll.iterations + (spend.iterations ?? 0),
|
|
234
|
+
tokensIn: roll.tokensIn + (spend.tokens?.input ?? 0),
|
|
235
|
+
tokensOut: roll.tokensOut + (spend.tokens?.output ?? 0),
|
|
236
|
+
usd: roll.usd + (known ? spend.usd ?? 0 : 0),
|
|
237
|
+
usdKnownRecords: roll.usdKnownRecords + (known ? 1 : 0),
|
|
238
|
+
usdUnknownRecords: roll.usdUnknownRecords + (known ? 0 : 1)
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
function mergeRolls(a, b) {
|
|
242
|
+
return {
|
|
243
|
+
records: a.records + b.records,
|
|
244
|
+
iterations: a.iterations + b.iterations,
|
|
245
|
+
tokensIn: a.tokensIn + b.tokensIn,
|
|
246
|
+
tokensOut: a.tokensOut + b.tokensOut,
|
|
247
|
+
usd: a.usd + b.usd,
|
|
248
|
+
usdKnownRecords: a.usdKnownRecords + b.usdKnownRecords,
|
|
249
|
+
usdUnknownRecords: a.usdUnknownRecords + b.usdUnknownRecords
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
async function readRunContextSnapshot(runDir) {
|
|
253
|
+
const journal = readRunContextJournal(await readMaybe(join(runDir, SPAWN_JOURNAL_FILE)));
|
|
254
|
+
const coordination = readCoordinationLog(await readMaybe(join(runDir, COORDINATION_LOG_FILE)));
|
|
255
|
+
const resultText = await readMaybe(join(runDir, RESULT_FILE));
|
|
256
|
+
const result = parseResult(resultText);
|
|
257
|
+
const view = safeTreeView(journal.events);
|
|
258
|
+
const nodes = view === null ? [] : orderNodes(view, journal);
|
|
259
|
+
return {
|
|
260
|
+
runDir,
|
|
261
|
+
runId: journal.root,
|
|
262
|
+
present: journal.present,
|
|
263
|
+
nodes,
|
|
264
|
+
maxDepth: nodes.reduce((max, n) => Math.max(max, n.depth), 0),
|
|
265
|
+
begunAt: parseInstant(journal.begunAt),
|
|
266
|
+
lastEventAt: journal.events.reduce((latest, event) => {
|
|
267
|
+
const at = parseInstant(event.at);
|
|
268
|
+
return at === null ? latest : latest === null ? at : Math.max(latest, at);
|
|
269
|
+
}, null),
|
|
270
|
+
questions: coordination.questions,
|
|
271
|
+
steers: coordination.steers,
|
|
272
|
+
result,
|
|
273
|
+
terminal: resultText !== null,
|
|
274
|
+
invalidJournalRows: journal.invalidRows,
|
|
275
|
+
retiredWaitRows: journal.retiredWaitRows,
|
|
276
|
+
invalidCoordinationRows: coordination.invalidRows,
|
|
277
|
+
partialTail: journal.partialTail || coordination.partialTail,
|
|
278
|
+
treeError: view === null && journal.present ? "spawn journal could not be folded into a tree (a settle or cancel names a node that was never spawned)" : null
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
function safeTreeView(events) {
|
|
282
|
+
if (events.length === 0) return null;
|
|
283
|
+
try {
|
|
284
|
+
return materializeTreeView([...events]);
|
|
285
|
+
} catch {
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
function orderNodes(view, journal) {
|
|
290
|
+
const driver = /* @__PURE__ */ new Map();
|
|
291
|
+
const settled = /* @__PURE__ */ new Map();
|
|
292
|
+
const childRoll = /* @__PURE__ */ new Map();
|
|
293
|
+
const spawnedAt = /* @__PURE__ */ new Map();
|
|
294
|
+
const settledAt = /* @__PURE__ */ new Map();
|
|
295
|
+
const cancelReason = /* @__PURE__ */ new Map();
|
|
296
|
+
const parentOf = new Map(view.nodes.map((n) => [n.id, n.parent]));
|
|
297
|
+
for (const event of journal.events) {
|
|
298
|
+
const at = parseInstant(event.at);
|
|
299
|
+
if (event.kind === "spawned") {
|
|
300
|
+
spawnedAt.set(event.id, at);
|
|
301
|
+
} else if (event.kind === "metered") {
|
|
302
|
+
driver.set(event.id, addSpend(driver.get(event.id) ?? ZERO_ROLL, event.spend));
|
|
303
|
+
} else if (event.kind === "settled") {
|
|
304
|
+
settled.set(event.id, addSpend(settled.get(event.id) ?? ZERO_ROLL, event.spent));
|
|
305
|
+
settledAt.set(event.id, at);
|
|
306
|
+
const parent = parentOf.get(event.id);
|
|
307
|
+
if (parent !== void 0) {
|
|
308
|
+
childRoll.set(parent, addSpend(childRoll.get(parent) ?? ZERO_ROLL, event.spent));
|
|
309
|
+
}
|
|
310
|
+
} else if (event.kind === "cancelled") {
|
|
311
|
+
settledAt.set(event.id, at);
|
|
312
|
+
cancelReason.set(event.id, event.reason);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
const byParent = /* @__PURE__ */ new Map();
|
|
316
|
+
for (const node of view.nodes) {
|
|
317
|
+
const key = node.parent ?? null;
|
|
318
|
+
const bucket = byParent.get(key);
|
|
319
|
+
if (bucket) bucket.push(node);
|
|
320
|
+
else byParent.set(key, [node]);
|
|
321
|
+
}
|
|
322
|
+
const out = [];
|
|
323
|
+
const seen = /* @__PURE__ */ new Set();
|
|
324
|
+
const walk = (id, depth) => {
|
|
325
|
+
if (seen.has(id)) return;
|
|
326
|
+
seen.add(id);
|
|
327
|
+
const node = view.nodes.find((n) => n.id === id);
|
|
328
|
+
if (node === void 0) return;
|
|
329
|
+
const spawned = spawnedAt.get(id) ?? null;
|
|
330
|
+
const closed = settledAt.get(id) ?? null;
|
|
331
|
+
out.push({
|
|
332
|
+
id: node.id,
|
|
333
|
+
parent: node.parent ?? null,
|
|
334
|
+
label: node.label,
|
|
335
|
+
depth,
|
|
336
|
+
role: inferRole(node.id, node.parent, journal.supervisorIds),
|
|
337
|
+
status: node.status,
|
|
338
|
+
runtime: node.runtime ?? null,
|
|
339
|
+
budget: node.budget,
|
|
340
|
+
driver: driver.get(id) ?? ZERO_ROLL,
|
|
341
|
+
children: childRoll.get(id) ?? ZERO_ROLL,
|
|
342
|
+
settled: settled.get(id) ?? ZERO_ROLL,
|
|
343
|
+
spawnedAt: spawned,
|
|
344
|
+
settledAt: closed,
|
|
345
|
+
wallMs: spawned !== null && closed !== null ? closed - spawned : null,
|
|
346
|
+
outRef: node.outRef ?? null,
|
|
347
|
+
cancelReason: cancelReason.get(id) ?? null
|
|
348
|
+
});
|
|
349
|
+
for (const child of byParent.get(id) ?? []) walk(child.id, depth + 1);
|
|
350
|
+
};
|
|
351
|
+
walk(view.root, 0);
|
|
352
|
+
for (const node of view.nodes) if (!seen.has(node.id)) walk(node.id, 0);
|
|
353
|
+
return out;
|
|
354
|
+
}
|
|
355
|
+
function parseResult(text) {
|
|
356
|
+
const result = parseJsonObject(text);
|
|
357
|
+
if (result === null) return null;
|
|
358
|
+
const error = asRecord(result.error);
|
|
359
|
+
return {
|
|
360
|
+
kind: str(result.kind),
|
|
361
|
+
reason: str(result.reason),
|
|
362
|
+
errorName: str(error.name),
|
|
363
|
+
errorMessage: str(error.message)
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
export {
|
|
368
|
+
SPAWN_JOURNAL_FILE,
|
|
369
|
+
COORDINATION_LOG_FILE,
|
|
370
|
+
RESULT_FILE,
|
|
371
|
+
readRunContextJournal,
|
|
372
|
+
inferRole,
|
|
373
|
+
readCoordinationLog,
|
|
374
|
+
readFileRunContext,
|
|
375
|
+
fileRunContextSupervisorRunReader,
|
|
376
|
+
isFileRunContextDir,
|
|
377
|
+
ZERO_ROLL,
|
|
378
|
+
addSpend,
|
|
379
|
+
mergeRolls,
|
|
380
|
+
readRunContextSnapshot
|
|
381
|
+
};
|