@tangle-network/agent-runtime 0.69.0 → 0.70.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 +81 -13
- package/dist/agent.d.ts +4 -5
- package/dist/agent.js +3 -6
- package/dist/agent.js.map +1 -1
- package/dist/chunk-BYZCXQHF.js +474 -0
- package/dist/chunk-BYZCXQHF.js.map +1 -0
- package/dist/{chunk-G6U3GVK2.js → chunk-EDCVUZZC.js} +2 -2
- package/dist/{chunk-RTDI2DHD.js → chunk-L5ZFBVT6.js} +6 -6
- package/dist/chunk-L5ZFBVT6.js.map +1 -0
- package/dist/{chunk-NLRA6434.js → chunk-QXWGSDAQ.js} +716 -535
- package/dist/chunk-QXWGSDAQ.js.map +1 -0
- package/dist/{chunk-QZ6FA5LM.js → chunk-ZNQVMMR5.js} +3 -3
- package/dist/{coordination-Curpzeyc.d.ts → coordination-C7WxwHXq.d.ts} +8 -1
- package/dist/{delegates-CLFNAKyi.d.ts → delegates-DqAgo32T.d.ts} +105 -10
- package/dist/{improvement-adapter-BC4HhuAR.d.ts → improvement-adapter-BVuMragr.d.ts} +1 -1
- package/dist/index.d.ts +439 -100
- package/dist/index.js +583 -125
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +2 -3
- package/dist/{loop-runner-bin-B6dzNZC8.d.ts → loop-runner-bin-B0NeLTRd.d.ts} +4 -4
- package/dist/loop-runner-bin.d.ts +7 -10
- package/dist/loop-runner-bin.js +4 -7
- package/dist/loops.d.ts +3149 -16
- package/dist/loops.js +34 -63
- package/dist/mcp/bin.js +14 -16
- package/dist/mcp/bin.js.map +1 -1
- package/dist/mcp/index.d.ts +8 -12
- package/dist/mcp/index.js +16 -19
- package/dist/mcp/index.js.map +1 -1
- package/dist/{openai-tools-CA2N3-Ak.d.ts → openai-tools-DPx9Gzvn.d.ts} +1 -1
- package/dist/profiles.d.ts +94 -6
- package/dist/profiles.js +320 -9
- package/dist/profiles.js.map +1 -1
- package/dist/{router-client-30Y_pca8.d.ts → router-client-C7kp_ECN.d.ts} +37 -1
- package/dist/{substrate-CUgk7F7s.d.ts → substrate-BoRXgvka.d.ts} +52 -1
- package/dist/{types-Crxftafi.d.ts → types-BYa2ZOAx.d.ts} +83 -2
- package/dist/{types-p8dWBIXL.d.ts → types-DJu6TBGp.d.ts} +2 -16
- package/dist/{worktree-fanout-DUiKPApb.d.ts → worktree-fanout-gNfl0Byj.d.ts} +9 -37
- package/package.json +9 -39
- package/dist/analyst-loop.d.ts +0 -52
- package/dist/analyst-loop.js +0 -11
- package/dist/analyst-loop.js.map +0 -1
- package/dist/audit.d.ts +0 -93
- package/dist/audit.js +0 -312
- package/dist/audit.js.map +0 -1
- package/dist/chunk-4B6U4CVQ.js +0 -15
- package/dist/chunk-4B6U4CVQ.js.map +0 -1
- package/dist/chunk-K4FQSEXQ.js +0 -214
- package/dist/chunk-K4FQSEXQ.js.map +0 -1
- package/dist/chunk-NLRA6434.js.map +0 -1
- package/dist/chunk-O2UPHN7X.js +0 -114
- package/dist/chunk-O2UPHN7X.js.map +0 -1
- package/dist/chunk-P5OKDSLB.js +0 -580
- package/dist/chunk-P5OKDSLB.js.map +0 -1
- package/dist/chunk-RTDI2DHD.js.map +0 -1
- package/dist/chunk-VLF5RHEQ.js +0 -143
- package/dist/chunk-VLF5RHEQ.js.map +0 -1
- package/dist/coder-2leJPOvC.d.ts +0 -52
- package/dist/improvement.d.ts +0 -208
- package/dist/improvement.js +0 -343
- package/dist/improvement.js.map +0 -1
- package/dist/local-harness-BE_h8szs.d.ts +0 -93
- package/dist/platform.d.ts +0 -255
- package/dist/platform.js +0 -229
- package/dist/platform.js.map +0 -1
- package/dist/run-loop-D3PwlG7J.d.ts +0 -112
- package/dist/runtime-hooks-C7JwKb9E.d.ts +0 -70
- package/dist/runtime.d.ts +0 -3120
- package/dist/runtime.js +0 -263
- package/dist/runtime.js.map +0 -1
- package/dist/topology.d.ts +0 -126
- package/dist/topology.js +0 -333
- package/dist/topology.js.map +0 -1
- package/dist/workflow.d.ts +0 -551
- package/dist/workflow.js +0 -1781
- package/dist/workflow.js.map +0 -1
- /package/dist/{chunk-G6U3GVK2.js.map → chunk-EDCVUZZC.js.map} +0 -0
- /package/dist/{chunk-QZ6FA5LM.js.map → chunk-ZNQVMMR5.js.map} +0 -0
|
@@ -1,22 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
UI_LENSES
|
|
3
|
-
} from "./chunk-WIR4HOOJ.js";
|
|
4
|
-
import {
|
|
5
|
-
AgentEvalError,
|
|
6
|
-
AnalystError,
|
|
7
|
-
NotFoundError,
|
|
8
|
-
PlannerError,
|
|
9
|
-
RuntimeRunStateError,
|
|
10
|
-
ValidationError,
|
|
11
|
-
extractLlmCallEvent
|
|
12
|
-
} from "./chunk-VLF5RHEQ.js";
|
|
13
|
-
import {
|
|
14
|
-
harnessInvocation,
|
|
15
|
-
runLocalHarness
|
|
16
|
-
} from "./chunk-O2UPHN7X.js";
|
|
17
1
|
import {
|
|
18
2
|
buildLoopSpanNodes
|
|
19
3
|
} from "./chunk-G3RGMA7C.js";
|
|
4
|
+
import {
|
|
5
|
+
UI_LENSES
|
|
6
|
+
} from "./chunk-WIR4HOOJ.js";
|
|
7
|
+
|
|
8
|
+
// src/runtime/index.ts
|
|
9
|
+
import { computeFindingId as computeFindingId2, makeFinding as makeFinding3 } from "@tangle-network/agent-eval";
|
|
20
10
|
|
|
21
11
|
// src/durable/spawn-journal.ts
|
|
22
12
|
import { createHash } from "crypto";
|
|
@@ -149,38 +139,6 @@ var InMemoryResultBlobStore = class {
|
|
|
149
139
|
return this.blobs.has(outRef) ? this.blobs.get(outRef) : void 0;
|
|
150
140
|
}
|
|
151
141
|
};
|
|
152
|
-
var FileResultBlobStore = class {
|
|
153
|
-
constructor(dir) {
|
|
154
|
-
this.dir = dir;
|
|
155
|
-
}
|
|
156
|
-
dir;
|
|
157
|
-
async put(outRef, artifact) {
|
|
158
|
-
assertContentAddress(outRef, artifact);
|
|
159
|
-
const fs = await import("fs/promises");
|
|
160
|
-
await fs.mkdir(this.dir, { recursive: true });
|
|
161
|
-
const fh = await fs.open(this.blobPath(outRef), "w");
|
|
162
|
-
try {
|
|
163
|
-
await fh.write(JSON.stringify(artifact));
|
|
164
|
-
await fh.sync();
|
|
165
|
-
} finally {
|
|
166
|
-
await fh.close();
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
async get(outRef) {
|
|
170
|
-
const fs = await import("fs/promises");
|
|
171
|
-
let text;
|
|
172
|
-
try {
|
|
173
|
-
text = await fs.readFile(this.blobPath(outRef), "utf8");
|
|
174
|
-
} catch (err) {
|
|
175
|
-
if (isNoEntError(err)) return void 0;
|
|
176
|
-
throw err;
|
|
177
|
-
}
|
|
178
|
-
return JSON.parse(text);
|
|
179
|
-
}
|
|
180
|
-
blobPath(outRef) {
|
|
181
|
-
return `${this.dir}/${outRef.replace(/:/g, "-")}.json`;
|
|
182
|
-
}
|
|
183
|
-
};
|
|
184
142
|
function assertContentAddress(outRef, artifact) {
|
|
185
143
|
const expected = contentAddress(artifact);
|
|
186
144
|
if (outRef !== expected) {
|
|
@@ -217,90 +175,6 @@ var InMemorySpawnJournal = class {
|
|
|
217
175
|
tree.events.push({ ...ev });
|
|
218
176
|
}
|
|
219
177
|
};
|
|
220
|
-
var FileSpawnJournal = class {
|
|
221
|
-
constructor(path2) {
|
|
222
|
-
this.path = path2;
|
|
223
|
-
}
|
|
224
|
-
path;
|
|
225
|
-
async loadTree(root) {
|
|
226
|
-
const fs = await import("fs/promises");
|
|
227
|
-
let text;
|
|
228
|
-
try {
|
|
229
|
-
text = await fs.readFile(this.path, "utf8");
|
|
230
|
-
} catch (err) {
|
|
231
|
-
if (isNoEntError(err)) return void 0;
|
|
232
|
-
throw err;
|
|
233
|
-
}
|
|
234
|
-
const lines = text.split("\n").filter((line) => line.length > 0);
|
|
235
|
-
let begun = false;
|
|
236
|
-
const events = [];
|
|
237
|
-
for (const line of lines) {
|
|
238
|
-
const record = JSON.parse(line);
|
|
239
|
-
if (record.root !== root) continue;
|
|
240
|
-
if (record.kind === "begin") {
|
|
241
|
-
begun = true;
|
|
242
|
-
} else {
|
|
243
|
-
if (!begun) {
|
|
244
|
-
throw new Error(
|
|
245
|
-
`spawn journal corrupted: event for tree '${root}' precedes its begin record`
|
|
246
|
-
);
|
|
247
|
-
}
|
|
248
|
-
assertSeqUnique(root, events, record.event);
|
|
249
|
-
events.push(record.event);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
return begun ? events : void 0;
|
|
253
|
-
}
|
|
254
|
-
async beginTree(root, at) {
|
|
255
|
-
const existing = await this.loadTreeBegin(root);
|
|
256
|
-
if (existing) {
|
|
257
|
-
if (existing !== at) {
|
|
258
|
-
throw new Error(
|
|
259
|
-
`spawn tree '${root}' already begun in ${this.path} at ${existing}; refusing to overwrite with ${at}`
|
|
260
|
-
);
|
|
261
|
-
}
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
await this.appendRecord({ kind: "begin", root, at });
|
|
265
|
-
}
|
|
266
|
-
async appendEvent(root, ev) {
|
|
267
|
-
const events = await this.loadTree(root);
|
|
268
|
-
if (events === void 0) {
|
|
269
|
-
throw new Error(`appendEvent called for unknown spawn tree '${root}'; call beginTree first`);
|
|
270
|
-
}
|
|
271
|
-
assertSeqUnique(root, events, ev);
|
|
272
|
-
await this.appendRecord({ kind: "event", root, event: ev });
|
|
273
|
-
}
|
|
274
|
-
async loadTreeBegin(root) {
|
|
275
|
-
const fs = await import("fs/promises");
|
|
276
|
-
let text;
|
|
277
|
-
try {
|
|
278
|
-
text = await fs.readFile(this.path, "utf8");
|
|
279
|
-
} catch (err) {
|
|
280
|
-
if (isNoEntError(err)) return void 0;
|
|
281
|
-
throw err;
|
|
282
|
-
}
|
|
283
|
-
const lines = text.split("\n").filter((line) => line.length > 0);
|
|
284
|
-
for (const line of lines) {
|
|
285
|
-
const record = JSON.parse(line);
|
|
286
|
-
if (record.root === root && record.kind === "begin") return record.at;
|
|
287
|
-
}
|
|
288
|
-
return void 0;
|
|
289
|
-
}
|
|
290
|
-
async appendRecord(record) {
|
|
291
|
-
const fs = await import("fs/promises");
|
|
292
|
-
const path2 = await import("path");
|
|
293
|
-
await fs.mkdir(path2.dirname(this.path), { recursive: true });
|
|
294
|
-
const fh = await fs.open(this.path, "a");
|
|
295
|
-
try {
|
|
296
|
-
await fh.write(`${JSON.stringify(record)}
|
|
297
|
-
`);
|
|
298
|
-
await fh.sync();
|
|
299
|
-
} finally {
|
|
300
|
-
await fh.close();
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
};
|
|
304
178
|
function assertSeqUnique(root, events, ev) {
|
|
305
179
|
if (ev.kind === "spawned" || ev.kind === "metered") return;
|
|
306
180
|
if (events.some((e) => e.kind !== "spawned" && e.kind !== "metered" && e.seq === ev.seq)) {
|
|
@@ -309,148 +183,6 @@ function assertSeqUnique(root, events, ev) {
|
|
|
309
183
|
);
|
|
310
184
|
}
|
|
311
185
|
}
|
|
312
|
-
async function replaySpawnTree(journal, blobs, root) {
|
|
313
|
-
const events = await journal.loadTree(root);
|
|
314
|
-
if (events === void 0) {
|
|
315
|
-
throw new Error(`replaySpawnTree: no journaled tree for root '${root}'`);
|
|
316
|
-
}
|
|
317
|
-
const ordered = [...events].sort((a, b) => a.seq - b.seq);
|
|
318
|
-
const labels = /* @__PURE__ */ new Map();
|
|
319
|
-
for (const ev of ordered) {
|
|
320
|
-
if (ev.kind === "spawned") labels.set(ev.id, ev.label);
|
|
321
|
-
}
|
|
322
|
-
const settled = [];
|
|
323
|
-
for (const ev of ordered) {
|
|
324
|
-
if (ev.kind === "spawned") continue;
|
|
325
|
-
if (ev.kind === "metered") continue;
|
|
326
|
-
if (ev.kind === "cancelled") {
|
|
327
|
-
settled.push({
|
|
328
|
-
kind: "down",
|
|
329
|
-
handle: replayHandle(ev.id, labels.get(ev.id) ?? ev.id, "cancelled"),
|
|
330
|
-
reason: ev.reason,
|
|
331
|
-
infra: false,
|
|
332
|
-
restartCount: 0,
|
|
333
|
-
seq: ev.seq
|
|
334
|
-
});
|
|
335
|
-
continue;
|
|
336
|
-
}
|
|
337
|
-
if (ev.status === "down") {
|
|
338
|
-
settled.push({
|
|
339
|
-
kind: "down",
|
|
340
|
-
handle: replayHandle(ev.id, labels.get(ev.id) ?? ev.id, "failed"),
|
|
341
|
-
reason: ev.verdict?.notes ?? "child down",
|
|
342
|
-
infra: ev.infra === true,
|
|
343
|
-
restartCount: 0,
|
|
344
|
-
seq: ev.seq
|
|
345
|
-
});
|
|
346
|
-
continue;
|
|
347
|
-
}
|
|
348
|
-
if (ev.outRef === void 0) {
|
|
349
|
-
throw new Error(
|
|
350
|
-
`replaySpawnTree: settled-done event for '${ev.id}' (seq ${ev.seq}) has no outRef; cannot rehydrate the result the driver branched on`
|
|
351
|
-
);
|
|
352
|
-
}
|
|
353
|
-
const out = await blobs.get(ev.outRef);
|
|
354
|
-
if (out === void 0) {
|
|
355
|
-
throw new Error(
|
|
356
|
-
`replaySpawnTree: blob store has no artifact for outRef '${ev.outRef}' (node '${ev.id}', seq ${ev.seq})`
|
|
357
|
-
);
|
|
358
|
-
}
|
|
359
|
-
settled.push({
|
|
360
|
-
kind: "done",
|
|
361
|
-
handle: replayHandle(ev.id, labels.get(ev.id) ?? ev.id, "done"),
|
|
362
|
-
out,
|
|
363
|
-
outRef: ev.outRef,
|
|
364
|
-
verdict: ev.verdict,
|
|
365
|
-
spent: ev.spent,
|
|
366
|
-
seq: ev.seq
|
|
367
|
-
});
|
|
368
|
-
}
|
|
369
|
-
return settled;
|
|
370
|
-
}
|
|
371
|
-
function replayHandle(id, label, status) {
|
|
372
|
-
return {
|
|
373
|
-
id,
|
|
374
|
-
label,
|
|
375
|
-
status,
|
|
376
|
-
abort() {
|
|
377
|
-
throw new Error(`cannot abort node '${id}': replayed handles are terminal, not live`);
|
|
378
|
-
}
|
|
379
|
-
};
|
|
380
|
-
}
|
|
381
|
-
function materializeTreeView(events) {
|
|
382
|
-
const nodes = /* @__PURE__ */ new Map();
|
|
383
|
-
let root;
|
|
384
|
-
const spawns = events.filter((ev) => ev.kind === "spawned").sort((a, b) => a.seq - b.seq);
|
|
385
|
-
const settlements = events.filter((ev) => ev.kind !== "spawned" && ev.kind !== "metered").sort((a, b) => a.seq - b.seq);
|
|
386
|
-
for (const ev of spawns) {
|
|
387
|
-
if (ev.parent === void 0 && root === void 0) root = ev.id;
|
|
388
|
-
nodes.set(ev.id, {
|
|
389
|
-
id: ev.id,
|
|
390
|
-
parent: ev.parent,
|
|
391
|
-
label: ev.label,
|
|
392
|
-
status: "pending",
|
|
393
|
-
runtime: ev.runtime,
|
|
394
|
-
budget: ev.budget,
|
|
395
|
-
spent: zeroSpend()
|
|
396
|
-
});
|
|
397
|
-
}
|
|
398
|
-
for (const ev of settlements) {
|
|
399
|
-
if (ev.kind === "settled") {
|
|
400
|
-
const node = requireNode(nodes, ev.id);
|
|
401
|
-
node.status = ev.status === "done" ? "done" : "failed";
|
|
402
|
-
node.spent = ev.spent;
|
|
403
|
-
node.outRef = ev.outRef;
|
|
404
|
-
} else {
|
|
405
|
-
const node = requireNode(nodes, ev.id);
|
|
406
|
-
node.status = "cancelled";
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
for (const ev of events) {
|
|
410
|
-
if (ev.kind !== "metered") continue;
|
|
411
|
-
const node = requireNode(nodes, ev.id);
|
|
412
|
-
node.spent = addJournalSpend(node.spent, ev.spend);
|
|
413
|
-
}
|
|
414
|
-
const snapshots = [...nodes.values()].map(freezeSnapshot);
|
|
415
|
-
return {
|
|
416
|
-
root: root ?? snapshots[0]?.id ?? "",
|
|
417
|
-
nodes: snapshots,
|
|
418
|
-
inFlight: snapshots.filter((n) => n.status === "running" || n.status === "acquiring").length
|
|
419
|
-
};
|
|
420
|
-
}
|
|
421
|
-
function zeroSpend() {
|
|
422
|
-
return { iterations: 0, tokens: zeroTokenUsage(), usd: 0, ms: 0 };
|
|
423
|
-
}
|
|
424
|
-
function addJournalSpend(a, b) {
|
|
425
|
-
return {
|
|
426
|
-
iterations: a.iterations + b.iterations,
|
|
427
|
-
tokens: { input: a.tokens.input + b.tokens.input, output: a.tokens.output + b.tokens.output },
|
|
428
|
-
usd: a.usd + b.usd,
|
|
429
|
-
ms: a.ms + b.ms
|
|
430
|
-
};
|
|
431
|
-
}
|
|
432
|
-
function requireNode(nodes, id) {
|
|
433
|
-
const node = nodes.get(id);
|
|
434
|
-
if (!node) {
|
|
435
|
-
throw new Error(`spawn journal corrupted: settle/cancel for node '${id}' with no prior spawn`);
|
|
436
|
-
}
|
|
437
|
-
return node;
|
|
438
|
-
}
|
|
439
|
-
function freezeSnapshot(node) {
|
|
440
|
-
return {
|
|
441
|
-
id: node.id,
|
|
442
|
-
parent: node.parent,
|
|
443
|
-
label: node.label,
|
|
444
|
-
status: node.status,
|
|
445
|
-
runtime: node.runtime,
|
|
446
|
-
budget: node.budget,
|
|
447
|
-
spent: node.spent,
|
|
448
|
-
outRef: node.outRef
|
|
449
|
-
};
|
|
450
|
-
}
|
|
451
|
-
function isNoEntError(err) {
|
|
452
|
-
return typeof err === "object" && err !== null && "code" in err && err.code === "ENOENT";
|
|
453
|
-
}
|
|
454
186
|
|
|
455
187
|
// src/runtime/anytime.ts
|
|
456
188
|
var median = (xs) => {
|
|
@@ -947,6 +679,61 @@ function reportLoopUsage(cost, result, source = "loop") {
|
|
|
947
679
|
cost.observeTokens(result.tokenUsage);
|
|
948
680
|
}
|
|
949
681
|
|
|
682
|
+
// src/errors.ts
|
|
683
|
+
import { AgentEvalError } from "@tangle-network/agent-eval";
|
|
684
|
+
import {
|
|
685
|
+
AgentEvalError as AgentEvalError2,
|
|
686
|
+
ConfigError,
|
|
687
|
+
JudgeError,
|
|
688
|
+
NotFoundError,
|
|
689
|
+
ValidationError
|
|
690
|
+
} from "@tangle-network/agent-eval";
|
|
691
|
+
var SessionMismatchError = class extends AgentEvalError {
|
|
692
|
+
sessionBackend;
|
|
693
|
+
requestedBackend;
|
|
694
|
+
constructor(sessionBackend, requestedBackend, options) {
|
|
695
|
+
super(
|
|
696
|
+
"validation",
|
|
697
|
+
`Cannot resume ${sessionBackend} session with ${requestedBackend} backend`,
|
|
698
|
+
options
|
|
699
|
+
);
|
|
700
|
+
this.sessionBackend = sessionBackend;
|
|
701
|
+
this.requestedBackend = requestedBackend;
|
|
702
|
+
}
|
|
703
|
+
};
|
|
704
|
+
var BackendTransportError = class extends AgentEvalError {
|
|
705
|
+
backend;
|
|
706
|
+
status;
|
|
707
|
+
/**
|
|
708
|
+
* Truncated upstream response body (≤2 KiB) when available. Diagnostic
|
|
709
|
+
* only — surfaces in `backend_error.error.body` and `final.error.body`
|
|
710
|
+
* so operators can see "free_tier_limit", "invalid_api_key", etc. without
|
|
711
|
+
* cracking the log line open.
|
|
712
|
+
*/
|
|
713
|
+
body;
|
|
714
|
+
constructor(backend, message, options) {
|
|
715
|
+
super("config", message, options);
|
|
716
|
+
this.backend = backend;
|
|
717
|
+
this.status = options?.status;
|
|
718
|
+
this.body = options?.body;
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
var RuntimeRunStateError = class extends AgentEvalError {
|
|
722
|
+
constructor(message, options) {
|
|
723
|
+
super("validation", message, options);
|
|
724
|
+
}
|
|
725
|
+
};
|
|
726
|
+
var PlannerError = class extends AgentEvalError {
|
|
727
|
+
constructor(message, options) {
|
|
728
|
+
super("validation", message, options);
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
var AnalystError = class extends AgentEvalError {
|
|
732
|
+
constructor(message, options) {
|
|
733
|
+
super("validation", message, options);
|
|
734
|
+
}
|
|
735
|
+
};
|
|
736
|
+
|
|
950
737
|
// src/runtime-hooks.ts
|
|
951
738
|
function defineRuntimeHooks(hooks) {
|
|
952
739
|
return hooks;
|
|
@@ -1175,6 +962,79 @@ async function resolveCapabilities(client) {
|
|
|
1175
962
|
}
|
|
1176
963
|
}
|
|
1177
964
|
|
|
965
|
+
// src/runtime/sandbox-events.ts
|
|
966
|
+
function extractLlmCallEvent(event, agentRunName) {
|
|
967
|
+
if (!event || typeof event !== "object") return void 0;
|
|
968
|
+
const type = String(event.type ?? "");
|
|
969
|
+
const data = event.data && typeof event.data === "object" ? event.data : {};
|
|
970
|
+
if (type === "llm_call" || type === "cost.usage" || type === "usage") {
|
|
971
|
+
return buildLlmCall(data, agentRunName);
|
|
972
|
+
}
|
|
973
|
+
if (type === "message.completed" || type === "result" || type === "final") {
|
|
974
|
+
const usage = data.usage;
|
|
975
|
+
if (!usage || typeof usage !== "object") return void 0;
|
|
976
|
+
return buildLlmCall({ ...usage, model: data.model ?? usage.model }, agentRunName);
|
|
977
|
+
}
|
|
978
|
+
if (type === "done") {
|
|
979
|
+
const usage = data.tokenUsage;
|
|
980
|
+
if (!usage || typeof usage !== "object") return void 0;
|
|
981
|
+
const out = pickFiniteNumber(usage, ["outputTokens", "completion_tokens", "tokensOut"]);
|
|
982
|
+
const reasoning = pickFiniteNumber(usage, ["reasoningTokens"]);
|
|
983
|
+
const mergedOut = out !== void 0 || reasoning !== void 0 ? (out ?? 0) + (reasoning ?? 0) : void 0;
|
|
984
|
+
return buildLlmCall(
|
|
985
|
+
{
|
|
986
|
+
inputTokens: usage.inputTokens,
|
|
987
|
+
outputTokens: mergedOut,
|
|
988
|
+
totalCostUsd: data.totalCostUsd,
|
|
989
|
+
model: data.model ?? usage.model
|
|
990
|
+
},
|
|
991
|
+
agentRunName
|
|
992
|
+
);
|
|
993
|
+
}
|
|
994
|
+
return void 0;
|
|
995
|
+
}
|
|
996
|
+
function buildLlmCall(data, agentRunName) {
|
|
997
|
+
const tokensIn = pickFiniteNumber(data, ["tokensIn", "inputTokens", "prompt_tokens"]);
|
|
998
|
+
const tokensOut = pickFiniteNumber(data, ["tokensOut", "outputTokens", "completion_tokens"]);
|
|
999
|
+
const costUsd = pickFiniteNumber(data, ["costUsd", "totalCostUsd", "cost_usd", "cost"]);
|
|
1000
|
+
if (tokensIn === void 0 && tokensOut === void 0 && costUsd === void 0) {
|
|
1001
|
+
return void 0;
|
|
1002
|
+
}
|
|
1003
|
+
const model = typeof data.model === "string" && data.model.length > 0 ? data.model : agentRunName;
|
|
1004
|
+
const event = {
|
|
1005
|
+
type: "llm_call",
|
|
1006
|
+
model
|
|
1007
|
+
};
|
|
1008
|
+
if (tokensIn !== void 0) event.tokensIn = tokensIn;
|
|
1009
|
+
if (tokensOut !== void 0) event.tokensOut = tokensOut;
|
|
1010
|
+
if (costUsd !== void 0) event.costUsd = costUsd;
|
|
1011
|
+
return event;
|
|
1012
|
+
}
|
|
1013
|
+
function pickFiniteNumber(data, keys) {
|
|
1014
|
+
for (const key of keys) {
|
|
1015
|
+
const value = data[key];
|
|
1016
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
1017
|
+
}
|
|
1018
|
+
return void 0;
|
|
1019
|
+
}
|
|
1020
|
+
function mapSandboxEvent(event, opts = {}) {
|
|
1021
|
+
if (!event || typeof event !== "object") return void 0;
|
|
1022
|
+
const type = String(event.type ?? "");
|
|
1023
|
+
const data = event.data && typeof event.data === "object" ? event.data : {};
|
|
1024
|
+
if (type === "message.part.updated") {
|
|
1025
|
+
const part = data.part && typeof data.part === "object" ? data.part : {};
|
|
1026
|
+
const partType = String(part.type ?? "");
|
|
1027
|
+
const delta = typeof data.delta === "string" ? data.delta : void 0;
|
|
1028
|
+
const text = delta ?? (typeof part.text === "string" ? part.text : void 0);
|
|
1029
|
+
if (text === void 0) return void 0;
|
|
1030
|
+
if (partType === "text") return { type: "text_delta", text };
|
|
1031
|
+
if (partType === "reasoning" || partType === "thinking")
|
|
1032
|
+
return { type: "reasoning_delta", text };
|
|
1033
|
+
return void 0;
|
|
1034
|
+
}
|
|
1035
|
+
return extractLlmCallEvent(event, opts.agentRunName ?? "agent");
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1178
1038
|
// src/runtime/sandbox-lineage.ts
|
|
1179
1039
|
var TEARDOWN_TIMEOUT_MS = 15e3;
|
|
1180
1040
|
var DEFAULT_FORK_CONCURRENCY = 4;
|
|
@@ -2143,7 +2003,7 @@ function createScope(args) {
|
|
|
2143
2003
|
let cursorSeq = 0;
|
|
2144
2004
|
let meterSeq = 0;
|
|
2145
2005
|
const now = args.now ?? Date.now;
|
|
2146
|
-
function
|
|
2006
|
+
function spawn5(agent, task, opts) {
|
|
2147
2007
|
if (args.maxDepth !== void 0 && args.depth >= args.maxDepth) {
|
|
2148
2008
|
return { ok: false, reason: "depth-exceeded" };
|
|
2149
2009
|
}
|
|
@@ -2185,7 +2045,7 @@ function createScope(args) {
|
|
|
2185
2045
|
runtime: executor.runtime,
|
|
2186
2046
|
budget: opts.budget,
|
|
2187
2047
|
label: opts.label,
|
|
2188
|
-
spent:
|
|
2048
|
+
spent: zeroSpend(),
|
|
2189
2049
|
settled: void 0,
|
|
2190
2050
|
delivered: false,
|
|
2191
2051
|
...executor.deliver ? { deliver: executor.deliver.bind(executor) } : {}
|
|
@@ -2239,7 +2099,7 @@ function createScope(args) {
|
|
|
2239
2099
|
live.settled = settled;
|
|
2240
2100
|
return { ok: true, handle };
|
|
2241
2101
|
} catch (err) {
|
|
2242
|
-
args.pool.reconcile(reservation.ticket,
|
|
2102
|
+
args.pool.reconcile(reservation.ticket, zeroSpend());
|
|
2243
2103
|
throw err;
|
|
2244
2104
|
}
|
|
2245
2105
|
}
|
|
@@ -2294,7 +2154,7 @@ function createScope(args) {
|
|
|
2294
2154
|
);
|
|
2295
2155
|
}
|
|
2296
2156
|
return {
|
|
2297
|
-
spawn:
|
|
2157
|
+
spawn: spawn5,
|
|
2298
2158
|
next,
|
|
2299
2159
|
send,
|
|
2300
2160
|
signal: args.signal,
|
|
@@ -2546,7 +2406,7 @@ async function teardownSafe(executor, grace) {
|
|
|
2546
2406
|
function downRecord(reason, infra, metered) {
|
|
2547
2407
|
return { kind: "down", reason, infra, restartCount: 0, ...metered ? { metered } : {} };
|
|
2548
2408
|
}
|
|
2549
|
-
function
|
|
2409
|
+
function zeroSpend() {
|
|
2550
2410
|
return { iterations: 0, tokens: { input: 0, output: 0 }, usd: 0, ms: 0 };
|
|
2551
2411
|
}
|
|
2552
2412
|
function isAsyncIterable2(value) {
|
|
@@ -3042,7 +2902,7 @@ var FileCorpus = class {
|
|
|
3042
2902
|
try {
|
|
3043
2903
|
text = await fs.readFile(this.path, "utf8");
|
|
3044
2904
|
} catch (err) {
|
|
3045
|
-
if (
|
|
2905
|
+
if (isNoEntError(err)) return /* @__PURE__ */ new Map();
|
|
3046
2906
|
throw err;
|
|
3047
2907
|
}
|
|
3048
2908
|
const lines = text.split("\n").filter((line) => line.length > 0);
|
|
@@ -3116,30 +2976,13 @@ function renderLine(record) {
|
|
|
3116
2976
|
function freeze(record) {
|
|
3117
2977
|
return Object.freeze({ ...record });
|
|
3118
2978
|
}
|
|
3119
|
-
function
|
|
2979
|
+
function isNoEntError(err) {
|
|
3120
2980
|
return typeof err === "object" && err !== null && "code" in err && err.code === "ENOENT";
|
|
3121
2981
|
}
|
|
3122
2982
|
|
|
3123
2983
|
// src/runtime/supervise/driver-executor.ts
|
|
3124
2984
|
var driverRuntime = "driver";
|
|
3125
2985
|
var driverRole = "driver";
|
|
3126
|
-
function driverChild(name, driver, journal) {
|
|
3127
|
-
const spec = {
|
|
3128
|
-
profile: { name, metadata: { role: driverRole } },
|
|
3129
|
-
harness: null,
|
|
3130
|
-
driver,
|
|
3131
|
-
journal
|
|
3132
|
-
};
|
|
3133
|
-
return {
|
|
3134
|
-
name,
|
|
3135
|
-
executorSpec: spec,
|
|
3136
|
-
act() {
|
|
3137
|
-
throw new ValidationError(
|
|
3138
|
-
`driverChild: "${name}" was run directly; a driver child runs through its nested-scope executor`
|
|
3139
|
-
);
|
|
3140
|
-
}
|
|
3141
|
-
};
|
|
3142
|
-
}
|
|
3143
2986
|
function isDriverSpec(spec) {
|
|
3144
2987
|
const role = spec.profile.metadata?.role;
|
|
3145
2988
|
if (role !== driverRole) return false;
|
|
@@ -3311,12 +3154,64 @@ function isAgent(value) {
|
|
|
3311
3154
|
}
|
|
3312
3155
|
|
|
3313
3156
|
// src/runtime/supervise/runtime.ts
|
|
3314
|
-
import { spawn as
|
|
3157
|
+
import { spawn as spawn4 } from "child_process";
|
|
3315
3158
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
3316
3159
|
import { estimateCost as estimateCost2, isModelPriced as isModelPriced2 } from "@tangle-network/agent-eval";
|
|
3317
3160
|
|
|
3318
3161
|
// src/runtime/router-client.ts
|
|
3319
3162
|
import { estimateCost, isModelPriced } from "@tangle-network/agent-eval";
|
|
3163
|
+
|
|
3164
|
+
// src/runtime/tool-loop.ts
|
|
3165
|
+
async function runBrainLoop(opts) {
|
|
3166
|
+
const maxTurns = opts.maxTurns ?? 4;
|
|
3167
|
+
const messages = [...opts.initialMessages];
|
|
3168
|
+
let toolCalls = 0;
|
|
3169
|
+
let lastText = "";
|
|
3170
|
+
const usage = { input: 0, output: 0 };
|
|
3171
|
+
const toolTrace = [];
|
|
3172
|
+
for (let turn = 1; turn <= maxTurns; turn += 1) {
|
|
3173
|
+
if (opts.hooks?.stopBefore?.(turn)) break;
|
|
3174
|
+
await opts.hooks?.beforeTurn?.(turn, messages);
|
|
3175
|
+
const r = await opts.chat(messages, opts.tools);
|
|
3176
|
+
if (r.usage) {
|
|
3177
|
+
usage.input += r.usage.input;
|
|
3178
|
+
usage.output += r.usage.output;
|
|
3179
|
+
opts.hooks?.onUsage?.(r.usage);
|
|
3180
|
+
}
|
|
3181
|
+
if (r.content) lastText = r.content;
|
|
3182
|
+
if (r.toolCalls.length === 0)
|
|
3183
|
+
return { final: lastText, turns: turn, toolCalls, toolTrace, usage, messages };
|
|
3184
|
+
messages.push({
|
|
3185
|
+
role: "assistant",
|
|
3186
|
+
content: r.content ?? "",
|
|
3187
|
+
tool_calls: r.toolCalls.map((tc) => ({
|
|
3188
|
+
id: tc.id,
|
|
3189
|
+
type: "function",
|
|
3190
|
+
function: { name: tc.name, arguments: tc.arguments }
|
|
3191
|
+
}))
|
|
3192
|
+
});
|
|
3193
|
+
for (const tc of r.toolCalls) {
|
|
3194
|
+
toolCalls += 1;
|
|
3195
|
+
let args = {};
|
|
3196
|
+
try {
|
|
3197
|
+
args = JSON.parse(tc.arguments);
|
|
3198
|
+
} catch {
|
|
3199
|
+
messages.push({
|
|
3200
|
+
role: "tool",
|
|
3201
|
+
tool_call_id: tc.id,
|
|
3202
|
+
content: `error: arguments were not valid JSON: ${tc.arguments.slice(0, 200)}`
|
|
3203
|
+
});
|
|
3204
|
+
continue;
|
|
3205
|
+
}
|
|
3206
|
+
const out = await opts.execute(tc.name, args);
|
|
3207
|
+
messages.push({ role: "tool", tool_call_id: tc.id, content: out });
|
|
3208
|
+
toolTrace.push({ name: tc.name, args: tc.arguments, result: out });
|
|
3209
|
+
}
|
|
3210
|
+
}
|
|
3211
|
+
return { final: lastText, turns: maxTurns, toolCalls, toolTrace, usage, messages };
|
|
3212
|
+
}
|
|
3213
|
+
|
|
3214
|
+
// src/runtime/router-client.ts
|
|
3320
3215
|
async function routerChatWithUsage(cfg, messages, opts) {
|
|
3321
3216
|
const url = `${cfg.routerBaseUrl.replace(/\/$/, "")}/chat/completions`;
|
|
3322
3217
|
const headers = { "content-type": "application/json", authorization: `Bearer ${cfg.routerKey}` };
|
|
@@ -3394,56 +3289,25 @@ async function routerChatWithTools(cfg, messages, tools, opts) {
|
|
|
3394
3289
|
};
|
|
3395
3290
|
}
|
|
3396
3291
|
async function routerToolLoop(cfg, system, user, tools, execute, opts) {
|
|
3397
|
-
const
|
|
3398
|
-
const messages = opts?.initialMessages ? [...opts.initialMessages] : [
|
|
3292
|
+
const initialMessages = opts?.initialMessages ?? [
|
|
3399
3293
|
{ role: "system", content: system },
|
|
3400
3294
|
{ role: "user", content: user }
|
|
3401
3295
|
];
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
const usage = { input: 0, output: 0 };
|
|
3405
|
-
const toolTrace = [];
|
|
3406
|
-
for (let turn = 1; turn <= maxTurns; turn += 1) {
|
|
3407
|
-
const r = await routerChatWithTools(cfg, messages, tools, {
|
|
3296
|
+
return runBrainLoop({
|
|
3297
|
+
chat: (messages, toolSpecs) => routerChatWithTools(cfg, messages, toolSpecs, {
|
|
3408
3298
|
...opts?.temperature !== void 0 ? { temperature: opts.temperature } : {},
|
|
3409
3299
|
...opts?.maxTokens ? { maxTokens: opts.maxTokens } : {},
|
|
3410
3300
|
...opts?.signal ? { signal: opts.signal } : {}
|
|
3411
|
-
})
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
content: r.content ?? "",
|
|
3422
|
-
tool_calls: r.toolCalls.map((tc) => ({
|
|
3423
|
-
id: tc.id,
|
|
3424
|
-
type: "function",
|
|
3425
|
-
function: { name: tc.name, arguments: tc.arguments }
|
|
3426
|
-
}))
|
|
3427
|
-
});
|
|
3428
|
-
for (const tc of r.toolCalls) {
|
|
3429
|
-
toolCalls += 1;
|
|
3430
|
-
let args = {};
|
|
3431
|
-
try {
|
|
3432
|
-
args = JSON.parse(tc.arguments);
|
|
3433
|
-
} catch {
|
|
3434
|
-
messages.push({
|
|
3435
|
-
role: "tool",
|
|
3436
|
-
tool_call_id: tc.id,
|
|
3437
|
-
content: `error: arguments were not valid JSON: ${tc.arguments.slice(0, 200)}`
|
|
3438
|
-
});
|
|
3439
|
-
continue;
|
|
3440
|
-
}
|
|
3441
|
-
const out = await execute(tc.name, args);
|
|
3442
|
-
messages.push({ role: "tool", tool_call_id: tc.id, content: out });
|
|
3443
|
-
toolTrace.push({ name: tc.name, args: tc.arguments, result: out });
|
|
3444
|
-
}
|
|
3445
|
-
}
|
|
3446
|
-
return { final: lastText, turns: maxTurns, toolCalls, toolTrace, usage, messages };
|
|
3301
|
+
}),
|
|
3302
|
+
tools,
|
|
3303
|
+
execute,
|
|
3304
|
+
initialMessages,
|
|
3305
|
+
maxTurns: opts?.maxTurns ?? 4
|
|
3306
|
+
});
|
|
3307
|
+
}
|
|
3308
|
+
function routerBrain(cfg, opts = {}) {
|
|
3309
|
+
const temperature = opts.temperature ?? 0.4;
|
|
3310
|
+
return (messages, tools) => routerChatWithTools(cfg, messages, tools, { temperature, toolChoice: "auto" });
|
|
3447
3311
|
}
|
|
3448
3312
|
|
|
3449
3313
|
// src/runtime/supervise/inbox.ts
|
|
@@ -3495,14 +3359,123 @@ ${lines.join("\n")}`;
|
|
|
3495
3359
|
import { randomUUID } from "crypto";
|
|
3496
3360
|
|
|
3497
3361
|
// src/mcp/worktree-harness.ts
|
|
3498
|
-
import { spawn as
|
|
3362
|
+
import { spawn as spawn3 } from "child_process";
|
|
3499
3363
|
|
|
3500
|
-
// src/mcp/
|
|
3364
|
+
// src/mcp/local-harness.ts
|
|
3501
3365
|
import { spawn } from "child_process";
|
|
3366
|
+
var HARNESS_INVOCATIONS = {
|
|
3367
|
+
claude: {
|
|
3368
|
+
command: "claude",
|
|
3369
|
+
buildArgs: (taskPrompt) => ["--headless", "-p", taskPrompt],
|
|
3370
|
+
modelArgs: (model) => ["-m", model]
|
|
3371
|
+
},
|
|
3372
|
+
codex: {
|
|
3373
|
+
command: "codex",
|
|
3374
|
+
buildArgs: (taskPrompt) => ["run", taskPrompt],
|
|
3375
|
+
modelArgs: (model) => ["-m", model]
|
|
3376
|
+
},
|
|
3377
|
+
opencode: {
|
|
3378
|
+
command: "opencode",
|
|
3379
|
+
buildArgs: (taskPrompt) => ["run", taskPrompt],
|
|
3380
|
+
modelArgs: (model) => ["-m", model]
|
|
3381
|
+
}
|
|
3382
|
+
};
|
|
3383
|
+
function harnessInvocation(harness, profile, taskPrompt) {
|
|
3384
|
+
const invocation = HARNESS_INVOCATIONS[harness];
|
|
3385
|
+
if (!invocation) {
|
|
3386
|
+
throw new Error(`harnessInvocation: unknown harness ${String(harness)}`);
|
|
3387
|
+
}
|
|
3388
|
+
const systemPrompt = profile.prompt?.systemPrompt;
|
|
3389
|
+
const composedPrompt = typeof systemPrompt === "string" && systemPrompt.trim().length > 0 ? `${systemPrompt}
|
|
3390
|
+
|
|
3391
|
+
${taskPrompt}` : taskPrompt;
|
|
3392
|
+
const args = invocation.buildArgs(composedPrompt);
|
|
3393
|
+
const model = profile.model?.default;
|
|
3394
|
+
if (typeof model === "string" && model.length > 0) {
|
|
3395
|
+
args.push(...invocation.modelArgs(model));
|
|
3396
|
+
}
|
|
3397
|
+
return { command: invocation.command, args };
|
|
3398
|
+
}
|
|
3399
|
+
var DEFAULT_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
3400
|
+
function runLocalHarness(options) {
|
|
3401
|
+
const { harness, cwd, taskPrompt } = options;
|
|
3402
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
3403
|
+
const env = options.env ?? process.env;
|
|
3404
|
+
const spawnImpl = options.spawn ?? spawn;
|
|
3405
|
+
const invocation = HARNESS_INVOCATIONS[harness];
|
|
3406
|
+
if (!invocation) {
|
|
3407
|
+
return Promise.reject(new Error(`runLocalHarness: unknown harness ${String(harness)}`));
|
|
3408
|
+
}
|
|
3409
|
+
const startedAt = Date.now();
|
|
3410
|
+
const command = options.invocation?.command ?? invocation.command;
|
|
3411
|
+
const args = options.invocation ? [...options.invocation.args] : invocation.buildArgs(taskPrompt);
|
|
3412
|
+
return new Promise((resolve, reject) => {
|
|
3413
|
+
let child;
|
|
3414
|
+
try {
|
|
3415
|
+
child = spawnImpl(command, args, { cwd, env, stdio: "pipe" });
|
|
3416
|
+
} catch (err) {
|
|
3417
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
3418
|
+
return;
|
|
3419
|
+
}
|
|
3420
|
+
child.stdin?.end();
|
|
3421
|
+
let stdout = "";
|
|
3422
|
+
let stderr = "";
|
|
3423
|
+
let timedOut = false;
|
|
3424
|
+
let settled = false;
|
|
3425
|
+
const timer = timeoutMs > 0 ? setTimeout(() => {
|
|
3426
|
+
timedOut = true;
|
|
3427
|
+
if (!child.killed) child.kill("SIGTERM");
|
|
3428
|
+
}, timeoutMs) : null;
|
|
3429
|
+
if (timer && typeof timer.unref === "function") {
|
|
3430
|
+
;
|
|
3431
|
+
timer.unref();
|
|
3432
|
+
}
|
|
3433
|
+
const onAbort = () => {
|
|
3434
|
+
if (!child.killed) child.kill("SIGTERM");
|
|
3435
|
+
};
|
|
3436
|
+
if (options.signal) {
|
|
3437
|
+
if (options.signal.aborted) onAbort();
|
|
3438
|
+
else options.signal.addEventListener("abort", onAbort, { once: true });
|
|
3439
|
+
}
|
|
3440
|
+
child.stdout?.on("data", (chunk) => {
|
|
3441
|
+
stdout += String(chunk);
|
|
3442
|
+
});
|
|
3443
|
+
child.stderr?.on("data", (chunk) => {
|
|
3444
|
+
stderr += String(chunk);
|
|
3445
|
+
});
|
|
3446
|
+
const finalize3 = (result) => {
|
|
3447
|
+
if (settled) return;
|
|
3448
|
+
settled = true;
|
|
3449
|
+
if (timer) clearTimeout(timer);
|
|
3450
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
3451
|
+
resolve(result);
|
|
3452
|
+
};
|
|
3453
|
+
child.on("error", (err) => {
|
|
3454
|
+
if (settled) return;
|
|
3455
|
+
settled = true;
|
|
3456
|
+
if (timer) clearTimeout(timer);
|
|
3457
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
3458
|
+
reject(err);
|
|
3459
|
+
});
|
|
3460
|
+
child.on("close", (code, signal) => {
|
|
3461
|
+
finalize3({
|
|
3462
|
+
exitCode: code,
|
|
3463
|
+
stdout,
|
|
3464
|
+
stderr,
|
|
3465
|
+
killedBySignal: signal,
|
|
3466
|
+
durationMs: Date.now() - startedAt,
|
|
3467
|
+
timedOut
|
|
3468
|
+
});
|
|
3469
|
+
});
|
|
3470
|
+
});
|
|
3471
|
+
}
|
|
3472
|
+
|
|
3473
|
+
// src/mcp/worktree.ts
|
|
3474
|
+
import { spawn as spawn2 } from "child_process";
|
|
3502
3475
|
async function runGitAsync(args, cwd, runner) {
|
|
3503
3476
|
if (runner) return runner(args, { cwd });
|
|
3504
3477
|
return new Promise((resolve, reject) => {
|
|
3505
|
-
const proc =
|
|
3478
|
+
const proc = spawn2("git", args, { cwd, stdio: "pipe" });
|
|
3506
3479
|
let stdout = "";
|
|
3507
3480
|
let stderr = "";
|
|
3508
3481
|
proc.stdout?.on("data", (c) => {
|
|
@@ -3668,7 +3641,7 @@ async function runChecks(opts) {
|
|
|
3668
3641
|
}
|
|
3669
3642
|
function defaultRunCommand(opts) {
|
|
3670
3643
|
return new Promise((resolve, reject) => {
|
|
3671
|
-
const child =
|
|
3644
|
+
const child = spawn3("/bin/sh", ["-c", opts.command], {
|
|
3672
3645
|
cwd: opts.cwd,
|
|
3673
3646
|
stdio: ["ignore", "pipe", "pipe"]
|
|
3674
3647
|
});
|
|
@@ -3791,7 +3764,7 @@ function contentRef(prefix, value) {
|
|
|
3791
3764
|
}
|
|
3792
3765
|
return `${prefix}:${(h >>> 0).toString(16).padStart(8, "0")}`;
|
|
3793
3766
|
}
|
|
3794
|
-
function
|
|
3767
|
+
function zeroSpend2() {
|
|
3795
3768
|
return { iterations: 0, tokens: zeroTokenUsage(), usd: 0, ms: 0 };
|
|
3796
3769
|
}
|
|
3797
3770
|
var routerInlineExecutor = (spec, ctx) => {
|
|
@@ -3963,15 +3936,24 @@ var routerToolsInlineExecutor = (spec, ctx) => {
|
|
|
3963
3936
|
const toolName = tc?.function?.name ?? "";
|
|
3964
3937
|
let result;
|
|
3965
3938
|
let status = "ok";
|
|
3939
|
+
const toolStartedAt = Date.now();
|
|
3966
3940
|
try {
|
|
3967
3941
|
result = await seam.executeToolCall(toolName, args, task);
|
|
3968
3942
|
} catch (e) {
|
|
3969
3943
|
status = "error";
|
|
3970
3944
|
result = `error: ${e instanceof Error ? e.message : String(e)}`;
|
|
3971
3945
|
}
|
|
3946
|
+
const toolEndedAt = Date.now();
|
|
3972
3947
|
messages.push({ role: "tool", tool_call_id: id, content: result });
|
|
3973
3948
|
try {
|
|
3974
|
-
seam.onToolStep?.({
|
|
3949
|
+
seam.onToolStep?.({
|
|
3950
|
+
toolName,
|
|
3951
|
+
args,
|
|
3952
|
+
status,
|
|
3953
|
+
startedAt: toolStartedAt,
|
|
3954
|
+
endedAt: toolEndedAt,
|
|
3955
|
+
durationMs: toolEndedAt - toolStartedAt
|
|
3956
|
+
});
|
|
3975
3957
|
} catch {
|
|
3976
3958
|
}
|
|
3977
3959
|
}
|
|
@@ -4151,7 +4133,7 @@ var cliExecutor = (_spec, ctx) => {
|
|
|
4151
4133
|
};
|
|
4152
4134
|
async function* streamCliLeaf(args) {
|
|
4153
4135
|
const prompt = taskToPrompt(args.task);
|
|
4154
|
-
const proc =
|
|
4136
|
+
const proc = spawn4(args.seam.bin, args.seam.args ?? [], {
|
|
4155
4137
|
...args.seam.cwd ? { cwd: args.seam.cwd } : {},
|
|
4156
4138
|
env: { ...process.env, ...args.seam.env ?? {} },
|
|
4157
4139
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -4188,7 +4170,7 @@ async function* streamCliLeaf(args) {
|
|
|
4188
4170
|
);
|
|
4189
4171
|
}
|
|
4190
4172
|
const out = { content: chunks.join("") };
|
|
4191
|
-
args.onArtifact({ outRef: contentRef("cli", out), out, spent:
|
|
4173
|
+
args.onArtifact({ outRef: contentRef("cli", out), out, spent: zeroSpend2() });
|
|
4192
4174
|
yield { kind: "iteration" };
|
|
4193
4175
|
}
|
|
4194
4176
|
function killWithGrace(proc, grace) {
|
|
@@ -4803,40 +4785,6 @@ function createSupervisor() {
|
|
|
4803
4785
|
return { run, attach };
|
|
4804
4786
|
}
|
|
4805
4787
|
var rootControls = /* @__PURE__ */ new WeakMap();
|
|
4806
|
-
function createRootHandle() {
|
|
4807
|
-
let binding;
|
|
4808
|
-
const handle = {
|
|
4809
|
-
view() {
|
|
4810
|
-
if (!binding) {
|
|
4811
|
-
throw new RuntimeRunStateError(
|
|
4812
|
-
"RootHandle.view: handle is not bound to a live run (attach it before run, read after run starts)"
|
|
4813
|
-
);
|
|
4814
|
-
}
|
|
4815
|
-
return binding.scope.view;
|
|
4816
|
-
},
|
|
4817
|
-
signal(msg) {
|
|
4818
|
-
if (!binding) {
|
|
4819
|
-
throw new RuntimeRunStateError("RootHandle.signal: handle is not bound to a live run");
|
|
4820
|
-
}
|
|
4821
|
-
binding.signal(msg);
|
|
4822
|
-
},
|
|
4823
|
-
abort(reason) {
|
|
4824
|
-
if (!binding) {
|
|
4825
|
-
throw new RuntimeRunStateError("RootHandle.abort: handle is not bound to a live run");
|
|
4826
|
-
}
|
|
4827
|
-
binding.cascadeAbort(reason ?? "root handle aborted");
|
|
4828
|
-
}
|
|
4829
|
-
};
|
|
4830
|
-
rootControls.set(handle, {
|
|
4831
|
-
bind(b) {
|
|
4832
|
-
binding = b;
|
|
4833
|
-
},
|
|
4834
|
-
unbind() {
|
|
4835
|
-
binding = void 0;
|
|
4836
|
-
}
|
|
4837
|
-
});
|
|
4838
|
-
return handle;
|
|
4839
|
-
}
|
|
4840
4788
|
function pushRootSignal(cascadeAbort) {
|
|
4841
4789
|
return (msg) => {
|
|
4842
4790
|
if (msg.kind === "cancel") cascadeAbort(msg.reason ?? "root signal: cancel");
|
|
@@ -5105,12 +5053,12 @@ async function trajectoryReport(journal, blobs, root, options = {}) {
|
|
|
5105
5053
|
label: ev.label,
|
|
5106
5054
|
runtime: ev.runtime,
|
|
5107
5055
|
status: "pending",
|
|
5108
|
-
ownSpend:
|
|
5056
|
+
ownSpend: zeroSpend3(),
|
|
5109
5057
|
children: []
|
|
5110
5058
|
});
|
|
5111
5059
|
}
|
|
5112
5060
|
for (const ev of closes) {
|
|
5113
|
-
const node =
|
|
5061
|
+
const node = requireNode(nodes, ev.id, root);
|
|
5114
5062
|
if (ev.kind === "cancelled") {
|
|
5115
5063
|
node.status = "cancelled";
|
|
5116
5064
|
continue;
|
|
@@ -5122,7 +5070,7 @@ async function trajectoryReport(journal, blobs, root, options = {}) {
|
|
|
5122
5070
|
}
|
|
5123
5071
|
for (const ev of events) {
|
|
5124
5072
|
if (ev.kind !== "metered") continue;
|
|
5125
|
-
const node =
|
|
5073
|
+
const node = requireNode(nodes, ev.id, root);
|
|
5126
5074
|
node.ownSpend = addNodeSpend(node.ownSpend, ev.spend);
|
|
5127
5075
|
}
|
|
5128
5076
|
if (!nodes.has(root)) {
|
|
@@ -5132,7 +5080,7 @@ async function trajectoryReport(journal, blobs, root, options = {}) {
|
|
|
5132
5080
|
}
|
|
5133
5081
|
for (const ev of spawns) {
|
|
5134
5082
|
if (ev.parent === void 0) continue;
|
|
5135
|
-
|
|
5083
|
+
requireNode(nodes, ev.parent, root).children.push(ev.id);
|
|
5136
5084
|
}
|
|
5137
5085
|
const rolledUp = rollUpSpend(nodes, root);
|
|
5138
5086
|
if (options.withOutputs) {
|
|
@@ -5180,7 +5128,7 @@ function rollUpSpend(nodes, root) {
|
|
|
5180
5128
|
while (stack.length > 0) {
|
|
5181
5129
|
const frame = stack.pop();
|
|
5182
5130
|
if (frame === void 0) continue;
|
|
5183
|
-
const node =
|
|
5131
|
+
const node = requireNode(nodes, frame.id, root);
|
|
5184
5132
|
if (!frame.expanded) {
|
|
5185
5133
|
stack.push({ id: frame.id, expanded: true });
|
|
5186
5134
|
for (const child of node.children) stack.push({ id: child, expanded: false });
|
|
@@ -5229,7 +5177,7 @@ function countStatuses(reported) {
|
|
|
5229
5177
|
for (const node of reported) counts[node.status] += 1;
|
|
5230
5178
|
return counts;
|
|
5231
5179
|
}
|
|
5232
|
-
function
|
|
5180
|
+
function zeroSpend3() {
|
|
5233
5181
|
return { iterations: 0, tokens: zeroTokenUsage(), usd: 0, ms: 0 };
|
|
5234
5182
|
}
|
|
5235
5183
|
function addNodeSpend(a, b) {
|
|
@@ -5289,7 +5237,7 @@ function isNode(node) {
|
|
|
5289
5237
|
function bySeq(a, b) {
|
|
5290
5238
|
return a.seq - b.seq;
|
|
5291
5239
|
}
|
|
5292
|
-
function
|
|
5240
|
+
function requireNode(nodes, id, root) {
|
|
5293
5241
|
const node = nodes.get(id);
|
|
5294
5242
|
if (!node) {
|
|
5295
5243
|
throw new Error(
|
|
@@ -5694,7 +5642,7 @@ var perChild = (innerTurns) => ({
|
|
|
5694
5642
|
maxIterations: innerTurns + 1,
|
|
5695
5643
|
maxTokens: 1e6
|
|
5696
5644
|
});
|
|
5697
|
-
function
|
|
5645
|
+
function depthStrategy(surface, task, opts, cfg) {
|
|
5698
5646
|
const innerTurns = opts.innerTurns ?? 4;
|
|
5699
5647
|
let pendingSteer;
|
|
5700
5648
|
return {
|
|
@@ -5757,7 +5705,7 @@ Address each with the tools, verify they took, then continue.`;
|
|
|
5757
5705
|
}
|
|
5758
5706
|
};
|
|
5759
5707
|
}
|
|
5760
|
-
function
|
|
5708
|
+
function breadthStrategy(_surface, task, opts, cfg) {
|
|
5761
5709
|
const innerTurns = opts.innerTurns ?? 4;
|
|
5762
5710
|
return {
|
|
5763
5711
|
name: "breadth",
|
|
@@ -5800,11 +5748,11 @@ function breadthDriver(_surface, task, opts, cfg) {
|
|
|
5800
5748
|
}
|
|
5801
5749
|
var sample = {
|
|
5802
5750
|
name: "sample",
|
|
5803
|
-
driver: (surface, task, opts, budget) =>
|
|
5751
|
+
driver: (surface, task, opts, budget) => breadthStrategy(surface, task, opts, { width: budget })
|
|
5804
5752
|
};
|
|
5805
5753
|
var refine = {
|
|
5806
5754
|
name: "refine",
|
|
5807
|
-
driver: (surface, task, opts, budget) =>
|
|
5755
|
+
driver: (surface, task, opts, budget) => depthStrategy(surface, task, opts, { maxShots: budget })
|
|
5808
5756
|
};
|
|
5809
5757
|
function defineStrategy(name, run) {
|
|
5810
5758
|
return {
|
|
@@ -6935,6 +6883,9 @@ ${summary}`,
|
|
|
6935
6883
|
};
|
|
6936
6884
|
}
|
|
6937
6885
|
|
|
6886
|
+
// src/runtime/supervise/authoring.ts
|
|
6887
|
+
import { computeFindingId, makeFinding as makeFinding2 } from "@tangle-network/agent-eval";
|
|
6888
|
+
|
|
6938
6889
|
// src/runtime/supervise/completion-gate.ts
|
|
6939
6890
|
function gateOnDeliverable(inner, deliverable) {
|
|
6940
6891
|
let gated;
|
|
@@ -6987,13 +6938,13 @@ function asAuthoredProfile(raw) {
|
|
|
6987
6938
|
...typeof p.model === "string" ? { model: p.model } : {}
|
|
6988
6939
|
};
|
|
6989
6940
|
}
|
|
6990
|
-
function
|
|
6941
|
+
function supervisorInstructions(opts) {
|
|
6991
6942
|
return [
|
|
6992
6943
|
"You are a SUPERVISOR. You do NOT do the work yourself \u2014 your job is to DESIGN and DRIVE specialist worker agents.",
|
|
6993
6944
|
"",
|
|
6994
6945
|
"For the task you are given:",
|
|
6995
6946
|
"1. DECOMPOSE it into the smallest set of sub-tasks a single focused worker can each deliver.",
|
|
6996
|
-
"2. For EACH sub-task, AUTHOR a worker by calling
|
|
6947
|
+
"2. For EACH sub-task, AUTHOR a worker by calling spawn_agent with a COMPLETE `profile`:",
|
|
6997
6948
|
" \u2022 name: a short id for the worker.",
|
|
6998
6949
|
' \u2022 systemPrompt: rich, specific instructions for THIS sub-task \u2014 tell the worker exactly what to produce, how to use its tools fully, and what "done" means. Never a one-liner; write the prompt a power-user would write.',
|
|
6999
6950
|
" \u2022 model: the model best suited to this sub-task (omit to use the default).",
|
|
@@ -7044,6 +6995,93 @@ function authoredWorker(profile, opts) {
|
|
|
7044
6995
|
};
|
|
7045
6996
|
return { name: profile.name, act: async () => "", executorSpec: spec };
|
|
7046
6997
|
}
|
|
6998
|
+
var defaultProfileRichnessThresholds = {
|
|
6999
|
+
minSystemPromptChars: 600,
|
|
7000
|
+
minSystemPromptLines: 6
|
|
7001
|
+
};
|
|
7002
|
+
function resolveSystemPrompt(profile) {
|
|
7003
|
+
const pr = profile.prompt;
|
|
7004
|
+
if (typeof pr === "string") return pr;
|
|
7005
|
+
if (pr && typeof pr === "object") {
|
|
7006
|
+
const o = pr;
|
|
7007
|
+
if (typeof o.systemPrompt === "string") return o.systemPrompt;
|
|
7008
|
+
if (typeof o.system === "string") return o.system;
|
|
7009
|
+
}
|
|
7010
|
+
return "";
|
|
7011
|
+
}
|
|
7012
|
+
function assessAuthoredProfile(profile, opts) {
|
|
7013
|
+
const th = { ...defaultProfileRichnessThresholds, ...opts?.thresholds ?? {} };
|
|
7014
|
+
const systemPrompt = resolveSystemPrompt(profile);
|
|
7015
|
+
const trimmed = systemPrompt.trim();
|
|
7016
|
+
const systemPromptChars = trimmed.length;
|
|
7017
|
+
const systemPromptLines = trimmed ? trimmed.split("\n").filter((l) => l.trim().length > 0).length : 0;
|
|
7018
|
+
const sentenceCount = trimmed ? (trimmed.match(/[.!?](\s|$)/g) ?? []).length || (trimmed ? 1 : 0) : 0;
|
|
7019
|
+
const hasDescription = typeof profile.description === "string" && profile.description.trim().length > 0;
|
|
7020
|
+
const tools = profile.tools;
|
|
7021
|
+
const hasTools = !!tools && Object.keys(tools).length > 0;
|
|
7022
|
+
const skills = profile.resources?.skills;
|
|
7023
|
+
const hasSkills = Array.isArray(skills) && skills.length > 0;
|
|
7024
|
+
const mcp = profile.mcp;
|
|
7025
|
+
const hasMcp = !!mcp && Object.keys(mcp).length > 0;
|
|
7026
|
+
const subagents = profile.subagents;
|
|
7027
|
+
const hasSubagents = !!subagents && Object.keys(subagents).length > 0;
|
|
7028
|
+
const reasons = [];
|
|
7029
|
+
const promptThin = systemPromptChars < th.minSystemPromptChars || systemPromptLines < th.minSystemPromptLines;
|
|
7030
|
+
if (promptThin)
|
|
7031
|
+
reasons.push(
|
|
7032
|
+
`system prompt is thin (${systemPromptChars} chars, ${systemPromptLines} lines; need \u2265${th.minSystemPromptChars} chars and \u2265${th.minSystemPromptLines} lines)`
|
|
7033
|
+
);
|
|
7034
|
+
if (!hasTools)
|
|
7035
|
+
reasons.push("no tools granted (a worker can only act through the tools you grant it)");
|
|
7036
|
+
if (!hasSkills) reasons.push("no skills attached (no reusable how-to notes injected)");
|
|
7037
|
+
if (opts?.needsMcp && !hasMcp) reasons.push("no MCP server, but the task needs data/tool access");
|
|
7038
|
+
const signals = [!promptThin, hasTools, hasSkills, hasDescription, opts?.needsMcp ? hasMcp : true];
|
|
7039
|
+
const richness = signals.filter(Boolean).length / signals.length;
|
|
7040
|
+
const thin = promptThin || !hasTools && !hasSkills && !hasMcp;
|
|
7041
|
+
return {
|
|
7042
|
+
name: profile.name ?? "worker",
|
|
7043
|
+
systemPrompt,
|
|
7044
|
+
systemPromptChars,
|
|
7045
|
+
systemPromptLines,
|
|
7046
|
+
sentenceCount,
|
|
7047
|
+
hasDescription,
|
|
7048
|
+
hasTools,
|
|
7049
|
+
hasSkills,
|
|
7050
|
+
hasMcp,
|
|
7051
|
+
hasSubagents,
|
|
7052
|
+
richness,
|
|
7053
|
+
thin,
|
|
7054
|
+
reasons
|
|
7055
|
+
};
|
|
7056
|
+
}
|
|
7057
|
+
function profileRichnessFinding(richness, opts) {
|
|
7058
|
+
const analyst_id = opts?.analystId ?? "profile-richness";
|
|
7059
|
+
const subject = richness.name;
|
|
7060
|
+
const claim = richness.thin ? `Worker "${richness.name}" was authored as a THIN profile: ${richness.reasons.join("; ")}.` : `Worker "${richness.name}" was authored as a rich profile (richness ${(richness.richness * 100).toFixed(0)}%).`;
|
|
7061
|
+
const severity = richness.thin ? richness.richness < 0.25 ? "high" : "medium" : "info";
|
|
7062
|
+
return makeFinding2({
|
|
7063
|
+
analyst_id,
|
|
7064
|
+
severity,
|
|
7065
|
+
area: "profile-quality",
|
|
7066
|
+
claim,
|
|
7067
|
+
subject,
|
|
7068
|
+
confidence: 0.9,
|
|
7069
|
+
evidence_refs: [
|
|
7070
|
+
{
|
|
7071
|
+
kind: "metric",
|
|
7072
|
+
uri: `profile:${subject}`,
|
|
7073
|
+
excerpt: `chars=${richness.systemPromptChars} lines=${richness.systemPromptLines} tools=${richness.hasTools} skills=${richness.hasSkills} mcp=${richness.hasMcp} richness=${richness.richness.toFixed(2)}`
|
|
7074
|
+
}
|
|
7075
|
+
],
|
|
7076
|
+
...richness.thin ? { recommended_action: `Re-author "${richness.name}" with: ${richness.reasons.join("; ")}.` } : {},
|
|
7077
|
+
id_basis: computeFindingId({
|
|
7078
|
+
analyst_id,
|
|
7079
|
+
area: "profile-quality",
|
|
7080
|
+
subject,
|
|
7081
|
+
claim: `richness:${richness.thin ? "thin" : "rich"}`
|
|
7082
|
+
})
|
|
7083
|
+
});
|
|
7084
|
+
}
|
|
7047
7085
|
|
|
7048
7086
|
// src/runtime/supervise/event-bus.ts
|
|
7049
7087
|
function createEventBus(now = Date.now) {
|
|
@@ -7102,7 +7140,19 @@ function createEventBus(now = Date.now) {
|
|
|
7102
7140
|
}
|
|
7103
7141
|
|
|
7104
7142
|
// src/mcp/tools/coordination.ts
|
|
7105
|
-
var
|
|
7143
|
+
var coordinationVerbNames = [
|
|
7144
|
+
"spawn_agent",
|
|
7145
|
+
"observe_agent",
|
|
7146
|
+
"steer_agent",
|
|
7147
|
+
"await_event",
|
|
7148
|
+
"list_questions",
|
|
7149
|
+
"answer_question",
|
|
7150
|
+
"ask_parent",
|
|
7151
|
+
"stop",
|
|
7152
|
+
"list_analysts",
|
|
7153
|
+
"run_analyst"
|
|
7154
|
+
];
|
|
7155
|
+
var idArg = { type: "string", description: "The workerId returned by spawn_agent." };
|
|
7106
7156
|
function createCoordinationTools(opts) {
|
|
7107
7157
|
let stopped = false;
|
|
7108
7158
|
let reason;
|
|
@@ -7126,6 +7176,28 @@ function createCoordinationTools(opts) {
|
|
|
7126
7176
|
throw new Error("coordination tools: arguments must be an object");
|
|
7127
7177
|
return raw;
|
|
7128
7178
|
};
|
|
7179
|
+
const mergeBudget = (base, raw) => {
|
|
7180
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
7181
|
+
throw new Error('coordination tools: "budget" must be an object');
|
|
7182
|
+
const o = raw;
|
|
7183
|
+
const field = (name) => {
|
|
7184
|
+
const v = o[name];
|
|
7185
|
+
if (v === void 0) return void 0;
|
|
7186
|
+
if (typeof v !== "number" || !Number.isFinite(v))
|
|
7187
|
+
throw new Error(`coordination tools: "budget.${name}" must be a finite number`);
|
|
7188
|
+
return v;
|
|
7189
|
+
};
|
|
7190
|
+
const maxIterations = field("maxIterations");
|
|
7191
|
+
const maxTokens = field("maxTokens");
|
|
7192
|
+
const maxUsd = field("maxUsd");
|
|
7193
|
+
const deadlineMs = field("deadlineMs");
|
|
7194
|
+
return {
|
|
7195
|
+
maxIterations: maxIterations ?? base.maxIterations,
|
|
7196
|
+
maxTokens: maxTokens ?? base.maxTokens,
|
|
7197
|
+
...(maxUsd ?? base.maxUsd) === void 0 ? {} : { maxUsd: maxUsd ?? base.maxUsd },
|
|
7198
|
+
...(deadlineMs ?? base.deadlineMs) === void 0 ? {} : { deadlineMs: deadlineMs ?? base.deadlineMs }
|
|
7199
|
+
};
|
|
7200
|
+
};
|
|
7129
7201
|
const level = (v) => {
|
|
7130
7202
|
if (v === "worker" || v === "driver" || v === "loop") return v;
|
|
7131
7203
|
throw new Error('coordination tools: "level" must be worker, driver, or loop');
|
|
@@ -7244,29 +7316,40 @@ function createCoordinationTools(opts) {
|
|
|
7244
7316
|
};
|
|
7245
7317
|
const tools = [
|
|
7246
7318
|
{
|
|
7247
|
-
name: "
|
|
7248
|
-
description: "Start a worker the driver will drive. `profile` is the worker or another driver; `task` is what it should do. Reserves budget from the conserved pool and fails closed.",
|
|
7319
|
+
name: "spawn_agent",
|
|
7320
|
+
description: "Start a worker the driver will drive. `profile` is the worker or another driver; `task` is what it should do. Reserves budget from the conserved pool and fails closed. Pass an optional `budget` (per-field) to give a hard sub-task more than the default \u2014 it merges over the per-worker default; the conserved pool is still the hard fence.",
|
|
7249
7321
|
inputSchema: {
|
|
7250
7322
|
type: "object",
|
|
7251
7323
|
properties: {
|
|
7252
7324
|
profile: { description: "The worker/driver profile to run." },
|
|
7253
7325
|
task: { description: "The task the worker should perform." },
|
|
7254
|
-
label: { type: "string", description: "Optional trace label." }
|
|
7326
|
+
label: { type: "string", description: "Optional trace label." },
|
|
7327
|
+
budget: {
|
|
7328
|
+
type: "object",
|
|
7329
|
+
description: "Optional per-spawn budget that merges over the per-worker default (per field). Only set the ceilings this sub-task needs raised; the conserved pool still fences.",
|
|
7330
|
+
properties: {
|
|
7331
|
+
maxIterations: { type: "number" },
|
|
7332
|
+
maxTokens: { type: "number" },
|
|
7333
|
+
maxUsd: { type: "number" },
|
|
7334
|
+
deadlineMs: { type: "number" }
|
|
7335
|
+
}
|
|
7336
|
+
}
|
|
7255
7337
|
},
|
|
7256
7338
|
required: ["profile", "task"]
|
|
7257
7339
|
},
|
|
7258
7340
|
handler: (raw) => {
|
|
7259
7341
|
const a = obj2(raw);
|
|
7260
7342
|
const agent = opts.makeWorkerAgent(a.profile);
|
|
7343
|
+
const budget = a.budget === void 0 ? opts.perWorker : mergeBudget(opts.perWorker, a.budget);
|
|
7261
7344
|
const res = opts.scope.spawn(agent, a.task, {
|
|
7262
|
-
budget
|
|
7345
|
+
budget,
|
|
7263
7346
|
label: typeof a.label === "string" ? a.label : "worker"
|
|
7264
7347
|
});
|
|
7265
7348
|
return Promise.resolve(res.ok ? { workerId: res.handle.id } : { error: res.reason });
|
|
7266
7349
|
}
|
|
7267
7350
|
},
|
|
7268
7351
|
{
|
|
7269
|
-
name: "
|
|
7352
|
+
name: "observe_agent",
|
|
7270
7353
|
description: "Inspect a worker status, spend, and settled output artifact when available.",
|
|
7271
7354
|
inputSchema: { type: "object", properties: { workerId: idArg }, required: ["workerId"] },
|
|
7272
7355
|
handler: async (raw) => {
|
|
@@ -7283,7 +7366,7 @@ function createCoordinationTools(opts) {
|
|
|
7283
7366
|
}
|
|
7284
7367
|
},
|
|
7285
7368
|
{
|
|
7286
|
-
name: "
|
|
7369
|
+
name: "steer_agent",
|
|
7287
7370
|
description: "Send a message DOWN to a still-LIVE worker (parent\u2192child): a new instruction, a course correction, or a continuation. The worker drains it at its next step boundary \u2014 and before it may settle, so it cannot finish while a message it never read is pending. A worker that already settled is gone (returns delivered:false) \u2014 spawn a fresh one instead.",
|
|
7288
7371
|
inputSchema: {
|
|
7289
7372
|
type: "object",
|
|
@@ -7504,13 +7587,26 @@ function deadlinePassed(scope, now) {
|
|
|
7504
7587
|
const b = scope.budget;
|
|
7505
7588
|
return b.deadlineMs > 0 && now() >= b.deadlineMs;
|
|
7506
7589
|
}
|
|
7507
|
-
function
|
|
7508
|
-
if (typeof opts.
|
|
7509
|
-
throw new ValidationError("
|
|
7590
|
+
function driverAgent(opts) {
|
|
7591
|
+
if (typeof opts.brain !== "function") {
|
|
7592
|
+
throw new ValidationError("driverAgent: opts.brain must be a function");
|
|
7593
|
+
}
|
|
7594
|
+
if ((opts.extraTools?.length ?? 0) > 0 && typeof opts.executeExtraTool !== "function") {
|
|
7595
|
+
throw new ValidationError(
|
|
7596
|
+
"driverAgent: extraTools requires executeExtraTool (how to run a work-tool call)"
|
|
7597
|
+
);
|
|
7598
|
+
}
|
|
7599
|
+
const reserved = new Set(coordinationVerbNames);
|
|
7600
|
+
for (const t of opts.extraTools ?? []) {
|
|
7601
|
+
if (reserved.has(t.name)) {
|
|
7602
|
+
throw new ValidationError(
|
|
7603
|
+
`driverAgent: extra work tool "${t.name}" collides with a coordination verb`
|
|
7604
|
+
);
|
|
7605
|
+
}
|
|
7510
7606
|
}
|
|
7511
7607
|
if (opts.maxTurns !== void 0 && opts.maxTurns < 0) {
|
|
7512
7608
|
throw new ValidationError(
|
|
7513
|
-
"
|
|
7609
|
+
"driverAgent: maxTurns must be >= 0 (0 lifts the turn cap; bounds become the conserved pool + deadline + abort)"
|
|
7514
7610
|
);
|
|
7515
7611
|
}
|
|
7516
7612
|
const maxTurns = opts.maxTurns === 0 ? runawayTripwireTurns : opts.maxTurns ?? 16;
|
|
@@ -7525,24 +7621,23 @@ function coordinationDriverAgent(opts) {
|
|
|
7525
7621
|
perWorker: opts.perWorker
|
|
7526
7622
|
});
|
|
7527
7623
|
const byName = new Map(coord.tools.map((t) => [t.name, t]));
|
|
7528
|
-
const toolSpecs =
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
|
|
7624
|
+
const toolSpecs = [
|
|
7625
|
+
...coord.tools.map((t) => ({
|
|
7626
|
+
type: "function",
|
|
7627
|
+
function: { name: t.name, description: t.description, parameters: t.inputSchema }
|
|
7628
|
+
})),
|
|
7629
|
+
// Work tools the driver calls DIRECTLY — so it can ACT, not only delegate.
|
|
7630
|
+
...(opts.extraTools ?? []).map((t) => ({
|
|
7631
|
+
type: "function",
|
|
7632
|
+
function: { name: t.name, description: t.description, parameters: t.parameters }
|
|
7633
|
+
}))
|
|
7634
|
+
];
|
|
7533
7635
|
const system = typeof opts.systemPrompt === "function" ? opts.systemPrompt(task) : opts.systemPrompt;
|
|
7534
|
-
|
|
7535
|
-
|
|
7536
|
-
|
|
7537
|
-
if (poolStarved(scope, opts.perWorker) || deadlinePassed(scope, now)) break;
|
|
7538
|
-
const res = await opts.chat.next({ system, messages, tools: toolSpecs });
|
|
7539
|
-
const calls = res.toolCalls ?? [];
|
|
7636
|
+
let turn = 0;
|
|
7637
|
+
const chat = async (messages, tools) => {
|
|
7638
|
+
const res = await opts.brain(messages, tools);
|
|
7540
7639
|
if (res.usage || res.costUsd !== void 0) {
|
|
7541
7640
|
const turnSpend = {
|
|
7542
|
-
// iterations:0 — the conserved iteration channel (`maxIterations`) budgets CHILD rounds,
|
|
7543
|
-
// not driver turns; counting turns there would conflate the two AND make a driver arm's
|
|
7544
|
-
// iteration count diverge from a blind arm's. The driver is bounded by maxTurns + the
|
|
7545
|
-
// token/usd pool; its turn COUNT stays observable via the per-turn `agent.turn` events.
|
|
7546
7641
|
iterations: 0,
|
|
7547
7642
|
tokens: { input: res.usage?.input ?? 0, output: res.usage?.output ?? 0 },
|
|
7548
7643
|
usd: res.costUsd ?? 0,
|
|
@@ -7552,28 +7647,47 @@ function coordinationDriverAgent(opts) {
|
|
|
7552
7647
|
kind: "driver-inference",
|
|
7553
7648
|
driver: opts.name,
|
|
7554
7649
|
turn,
|
|
7555
|
-
toolCalls:
|
|
7650
|
+
toolCalls: (res.toolCalls ?? []).map((c) => c.name)
|
|
7556
7651
|
});
|
|
7557
7652
|
}
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
|
|
7564
|
-
|
|
7565
|
-
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
}
|
|
7653
|
+
turn += 1;
|
|
7654
|
+
return res;
|
|
7655
|
+
};
|
|
7656
|
+
await runBrainLoop({
|
|
7657
|
+
chat,
|
|
7658
|
+
tools: toolSpecs,
|
|
7659
|
+
execute: async (name, args) => {
|
|
7660
|
+
if (opts.executeExtraTool) {
|
|
7661
|
+
const worked = await runExtraTool(opts.executeExtraTool, name, args);
|
|
7662
|
+
if (worked !== null && worked !== void 0) return worked;
|
|
7663
|
+
}
|
|
7664
|
+
const tool = byName.get(name);
|
|
7665
|
+
const result = tool ? await runTool(tool, args) : { error: `unknown tool: ${name}` };
|
|
7666
|
+
return safeJson(result);
|
|
7667
|
+
},
|
|
7668
|
+
initialMessages: [
|
|
7669
|
+
{ role: "system", content: system },
|
|
7670
|
+
{ role: "user", content: stringifyTask(task) }
|
|
7671
|
+
],
|
|
7672
|
+
maxTurns,
|
|
7673
|
+
// The conserved-pool + deadline + external-stop bound (what maxTurns=0 relies on): a driver
|
|
7674
|
+
// that can no longer spawn (pool starved) or has run past the deadline stops here instead of
|
|
7675
|
+
// burning turns. Checked before each inference turn.
|
|
7676
|
+
hooks: {
|
|
7677
|
+
stopBefore: () => coord.isStopped() || scope.signal.aborted || poolStarved(scope, opts.perWorker) || deadlinePassed(scope, now)
|
|
7571
7678
|
}
|
|
7572
|
-
}
|
|
7679
|
+
});
|
|
7573
7680
|
return finalize2(coord, opts.blobs);
|
|
7574
7681
|
}
|
|
7575
7682
|
};
|
|
7576
7683
|
}
|
|
7684
|
+
async function runExtraTool(execute, name, args) {
|
|
7685
|
+
try {
|
|
7686
|
+
return await execute(name, args);
|
|
7687
|
+
} catch (e) {
|
|
7688
|
+
return `error: ${e instanceof Error ? e.message : String(e)}`;
|
|
7689
|
+
}
|
|
7690
|
+
}
|
|
7577
7691
|
async function runTool(tool, args) {
|
|
7578
7692
|
try {
|
|
7579
7693
|
return await tool.handler(args);
|
|
@@ -7581,13 +7695,16 @@ async function runTool(tool, args) {
|
|
|
7581
7695
|
return { error: e instanceof Error ? e.message : String(e) };
|
|
7582
7696
|
}
|
|
7583
7697
|
}
|
|
7584
|
-
async function
|
|
7585
|
-
const delivered =
|
|
7698
|
+
async function finalizeBestDelivered(settled, blobs) {
|
|
7699
|
+
const delivered = settled.filter((w) => w.status === "done" && w.valid === true);
|
|
7586
7700
|
if (delivered.length === 0) return void 0;
|
|
7587
7701
|
let best = delivered[0];
|
|
7588
7702
|
for (const w of delivered) if ((w.score ?? 0) > (best.score ?? 0)) best = w;
|
|
7589
7703
|
return best.outRef ? await blobs.get(best.outRef) : void 0;
|
|
7590
7704
|
}
|
|
7705
|
+
async function finalize2(coord, blobs) {
|
|
7706
|
+
return finalizeBestDelivered(coord.settled(), blobs);
|
|
7707
|
+
}
|
|
7591
7708
|
function stringifyTask(task) {
|
|
7592
7709
|
return typeof task === "string" ? task : safeJson(task);
|
|
7593
7710
|
}
|
|
@@ -7638,12 +7755,12 @@ function eventToSnapshot(event) {
|
|
|
7638
7755
|
// src/mcp/delegation-store.ts
|
|
7639
7756
|
import { mkdir, readFile, rename, writeFile } from "fs/promises";
|
|
7640
7757
|
import { dirname } from "path";
|
|
7641
|
-
var DelegationStateCorruptError = class extends
|
|
7758
|
+
var DelegationStateCorruptError = class extends AgentEvalError2 {
|
|
7642
7759
|
constructor(message, options) {
|
|
7643
7760
|
super("validation", message, options);
|
|
7644
7761
|
}
|
|
7645
7762
|
};
|
|
7646
|
-
var DelegationPersistenceError = class extends
|
|
7763
|
+
var DelegationPersistenceError = class extends AgentEvalError2 {
|
|
7647
7764
|
constructor(message, options) {
|
|
7648
7765
|
super("config", message, options);
|
|
7649
7766
|
}
|
|
@@ -8549,7 +8666,7 @@ function createDetachedTurnTrace(options) {
|
|
|
8549
8666
|
function detachedRunningPhase(elapsedMs) {
|
|
8550
8667
|
return elapsedMs === void 0 ? "detached-running" : `detached-running ${Math.round(elapsedMs / 1e3)}s`;
|
|
8551
8668
|
}
|
|
8552
|
-
function
|
|
8669
|
+
function createDetachedTurnResumeDriver(options) {
|
|
8553
8670
|
const cancelHooked = /* @__PURE__ */ new Set();
|
|
8554
8671
|
return {
|
|
8555
8672
|
intervalMs: options.intervalMs ?? DEFAULT_TICK_INTERVAL_MS,
|
|
@@ -9811,6 +9928,16 @@ function watchTrace(source, opts = {}) {
|
|
|
9811
9928
|
});
|
|
9812
9929
|
}
|
|
9813
9930
|
|
|
9931
|
+
// src/runtime/supervise/model-policy.ts
|
|
9932
|
+
function assertModelAllowed(model, allowed) {
|
|
9933
|
+
if (!allowed || model === void 0) return;
|
|
9934
|
+
if (!allowed.includes(model)) {
|
|
9935
|
+
throw new ConfigError(
|
|
9936
|
+
`model ${JSON.stringify(model)} is not in the allowed set ${JSON.stringify([...allowed])}`
|
|
9937
|
+
);
|
|
9938
|
+
}
|
|
9939
|
+
}
|
|
9940
|
+
|
|
9814
9941
|
// src/runtime/supervise/patch-checks.ts
|
|
9815
9942
|
var DEFAULT_MAX_DIFF_LINES = 400;
|
|
9816
9943
|
var secretPathPattern = /(^|\/)(\.env(\.|$)|.*\.(pem|key|p12|pfx|keystore|wallet)|id_rsa|id_ed25519|secrets?\.json|credentials?\.json)$/i;
|
|
@@ -9835,12 +9962,6 @@ function countDiffLines(patch) {
|
|
|
9835
9962
|
}
|
|
9836
9963
|
return count;
|
|
9837
9964
|
}
|
|
9838
|
-
function isNonEmptyPatch(patch) {
|
|
9839
|
-
return touchedPathsFromPatch(patch).length > 0 && patch.trim().length > 0;
|
|
9840
|
-
}
|
|
9841
|
-
function touchesSecretPath(patch) {
|
|
9842
|
-
return touchedPathsFromPatch(patch).filter((p) => secretPathPattern.test(p));
|
|
9843
|
-
}
|
|
9844
9965
|
function runCoderChecks(input, constraints = {}) {
|
|
9845
9966
|
const maxDiff = constraints.maxDiffLines ?? DEFAULT_MAX_DIFF_LINES;
|
|
9846
9967
|
const forbidden = constraints.forbiddenPaths ?? [];
|
|
@@ -9927,72 +10048,132 @@ function signalPass(value, required) {
|
|
|
9927
10048
|
return !required;
|
|
9928
10049
|
}
|
|
9929
10050
|
|
|
9930
|
-
// src/runtime/supervise/
|
|
9931
|
-
function
|
|
9932
|
-
const
|
|
10051
|
+
// src/runtime/supervise/run-context.ts
|
|
10052
|
+
function createInMemoryRunContext(opts = {}) {
|
|
10053
|
+
const base = createExecutorRegistry();
|
|
9933
10054
|
return {
|
|
9934
|
-
|
|
9935
|
-
|
|
9936
|
-
|
|
9937
|
-
...messages.map(toOpenAI)
|
|
9938
|
-
];
|
|
9939
|
-
const oaTools = tools.map((t) => ({
|
|
9940
|
-
type: "function",
|
|
9941
|
-
function: { name: t.name, description: t.description, parameters: t.parameters }
|
|
9942
|
-
}));
|
|
9943
|
-
const r = await routerChatWithTools(c, oa, oaTools, { temperature, toolChoice: "auto" });
|
|
9944
|
-
return {
|
|
9945
|
-
...r.content ? { content: r.content } : {},
|
|
9946
|
-
// Forward the router's REAL usage + cost so the driver meters its own inference against the
|
|
9947
|
-
// conserved pool (the integrity hole: these were dropped on the floor before).
|
|
9948
|
-
...r.usage ? { usage: r.usage } : {},
|
|
9949
|
-
...typeof r.costUsd === "number" ? { costUsd: r.costUsd } : {},
|
|
9950
|
-
toolCalls: r.toolCalls.map((tc) => ({
|
|
9951
|
-
id: tc.id,
|
|
9952
|
-
name: tc.name,
|
|
9953
|
-
arguments: safeParse(tc.arguments)
|
|
9954
|
-
}))
|
|
9955
|
-
};
|
|
9956
|
-
}
|
|
10055
|
+
journal: new InMemorySpawnJournal(),
|
|
10056
|
+
blobs: new InMemoryResultBlobStore(),
|
|
10057
|
+
executors: opts.withDriver ? withDriverExecutor(base) : base
|
|
9957
10058
|
};
|
|
9958
10059
|
}
|
|
9959
|
-
|
|
9960
|
-
|
|
9961
|
-
|
|
9962
|
-
|
|
9963
|
-
|
|
9964
|
-
|
|
9965
|
-
|
|
9966
|
-
|
|
9967
|
-
|
|
9968
|
-
|
|
9969
|
-
|
|
10060
|
+
|
|
10061
|
+
// src/runtime/supervise/supervisor-agent.ts
|
|
10062
|
+
function supervisorAgent(profile, deps) {
|
|
10063
|
+
const name = profile.name ?? "supervisor";
|
|
10064
|
+
const systemPrompt = profile.systemPrompt ?? "";
|
|
10065
|
+
const harness = profile.harness ?? null;
|
|
10066
|
+
if (harness === null) {
|
|
10067
|
+
const brain = deps.brain ?? routerBrainFromProfile(profile, deps);
|
|
10068
|
+
return driverAgent({
|
|
10069
|
+
name,
|
|
10070
|
+
brain,
|
|
10071
|
+
blobs: deps.blobs,
|
|
10072
|
+
makeWorkerAgent: deps.makeWorkerAgent,
|
|
10073
|
+
perWorker: deps.perWorker,
|
|
10074
|
+
systemPrompt,
|
|
10075
|
+
...deps.extraTools ? { extraTools: deps.extraTools } : {},
|
|
10076
|
+
...deps.executeExtraTool ? { executeExtraTool: deps.executeExtraTool } : {},
|
|
10077
|
+
...deps.maxTurns !== void 0 ? { maxTurns: deps.maxTurns } : {}
|
|
10078
|
+
});
|
|
9970
10079
|
}
|
|
9971
|
-
|
|
9972
|
-
|
|
10080
|
+
const driveHarness = deps.driveHarness;
|
|
10081
|
+
if (!driveHarness) {
|
|
10082
|
+
throw new ValidationError(
|
|
10083
|
+
`supervisorAgent: profile.harness="${harness}" needs deps.driveHarness (how to run the harness with the coordination MCP mounted)`
|
|
10084
|
+
);
|
|
9973
10085
|
}
|
|
9974
|
-
return {
|
|
10086
|
+
return {
|
|
10087
|
+
name,
|
|
10088
|
+
async act(task, scope) {
|
|
10089
|
+
const mcp = await serveCoordinationMcp({
|
|
10090
|
+
scope,
|
|
10091
|
+
blobs: deps.blobs,
|
|
10092
|
+
makeWorkerAgent: deps.makeWorkerAgent,
|
|
10093
|
+
perWorker: deps.perWorker
|
|
10094
|
+
});
|
|
10095
|
+
try {
|
|
10096
|
+
await driveHarness({ profile, task, scope, coordinationMcpUrl: mcp.url });
|
|
10097
|
+
return await finalizeBestDelivered(mcp.settled(), deps.blobs);
|
|
10098
|
+
} finally {
|
|
10099
|
+
await mcp.close();
|
|
10100
|
+
}
|
|
10101
|
+
}
|
|
10102
|
+
};
|
|
9975
10103
|
}
|
|
9976
|
-
function
|
|
9977
|
-
|
|
9978
|
-
|
|
9979
|
-
|
|
9980
|
-
|
|
10104
|
+
function routerBrainFromProfile(profile, deps) {
|
|
10105
|
+
if (!deps.router) {
|
|
10106
|
+
throw new ValidationError(
|
|
10107
|
+
"supervisorAgent: a router-brained supervisor (harness null) needs deps.router (or deps.brain)"
|
|
10108
|
+
);
|
|
9981
10109
|
}
|
|
10110
|
+
return routerBrain({ ...deps.router, model: profile.model ?? deps.router.model });
|
|
9982
10111
|
}
|
|
9983
10112
|
|
|
9984
|
-
// src/runtime/supervise/
|
|
9985
|
-
function
|
|
9986
|
-
|
|
10113
|
+
// src/runtime/supervise/supervise.ts
|
|
10114
|
+
function workerFromBackend(backend, deliverable) {
|
|
10115
|
+
return (rawProfile) => {
|
|
10116
|
+
const p = rawProfile ?? {};
|
|
10117
|
+
const name = typeof p.name === "string" && p.name.length > 0 ? p.name : "worker";
|
|
10118
|
+
const spec = { profile: rawProfile, harness: null };
|
|
10119
|
+
const ctx = { signal: new AbortController().signal, seams: {} };
|
|
10120
|
+
const built = createExecutor(backend)(spec, ctx);
|
|
10121
|
+
const executor = deliverable ? gateOnDeliverable(built, deliverable) : built;
|
|
10122
|
+
return { name, act: async () => "", executorSpec: { ...spec, executor } };
|
|
10123
|
+
};
|
|
10124
|
+
}
|
|
10125
|
+
function defaultPerWorker(budget) {
|
|
9987
10126
|
return {
|
|
9988
|
-
|
|
9989
|
-
|
|
9990
|
-
executors: opts.withDriver ? withDriverExecutor(base) : base
|
|
10127
|
+
maxIterations: budget.maxIterations,
|
|
10128
|
+
maxTokens: Math.max(1, Math.floor(budget.maxTokens / 4))
|
|
9991
10129
|
};
|
|
9992
10130
|
}
|
|
10131
|
+
function supervise(profile, task, opts) {
|
|
10132
|
+
const backendModel = opts.backend?.model;
|
|
10133
|
+
assertModelAllowed(opts.router?.model, opts.allowedModels);
|
|
10134
|
+
assertModelAllowed(profile.model, opts.allowedModels);
|
|
10135
|
+
assertModelAllowed(
|
|
10136
|
+
typeof backendModel === "string" ? backendModel : void 0,
|
|
10137
|
+
opts.allowedModels
|
|
10138
|
+
);
|
|
10139
|
+
const ctx = createInMemoryRunContext({ withDriver: true });
|
|
10140
|
+
const blobs = opts.blobs ?? ctx.blobs;
|
|
10141
|
+
const perWorker = opts.perWorker ?? defaultPerWorker(opts.budget);
|
|
10142
|
+
let makeWorkerAgent = opts.makeWorkerAgent;
|
|
10143
|
+
if (!makeWorkerAgent) {
|
|
10144
|
+
if (!opts.backend) {
|
|
10145
|
+
throw new ValidationError(
|
|
10146
|
+
"supervise: provide opts.backend (where workers run) or opts.makeWorkerAgent"
|
|
10147
|
+
);
|
|
10148
|
+
}
|
|
10149
|
+
makeWorkerAgent = workerFromBackend(opts.backend, opts.deliverable);
|
|
10150
|
+
}
|
|
10151
|
+
const agent = supervisorAgent(profile, {
|
|
10152
|
+
blobs,
|
|
10153
|
+
makeWorkerAgent,
|
|
10154
|
+
perWorker,
|
|
10155
|
+
...opts.router ? { router: opts.router } : {},
|
|
10156
|
+
...opts.brain ? { brain: opts.brain } : {},
|
|
10157
|
+
...opts.driveHarness ? { driveHarness: opts.driveHarness } : {},
|
|
10158
|
+
...opts.extraTools ? { extraTools: opts.extraTools } : {},
|
|
10159
|
+
...opts.executeExtraTool ? { executeExtraTool: opts.executeExtraTool } : {},
|
|
10160
|
+
...opts.maxTurns !== void 0 ? { maxTurns: opts.maxTurns } : {}
|
|
10161
|
+
});
|
|
10162
|
+
return createSupervisor().run(agent, task, {
|
|
10163
|
+
budget: opts.budget,
|
|
10164
|
+
runId: opts.runId ?? "supervise",
|
|
10165
|
+
journal: ctx.journal,
|
|
10166
|
+
blobs,
|
|
10167
|
+
executors: ctx.executors,
|
|
10168
|
+
maxDepth: opts.maxDepth ?? 8,
|
|
10169
|
+
...opts.now ? { now: opts.now } : {}
|
|
10170
|
+
});
|
|
10171
|
+
}
|
|
9993
10172
|
|
|
9994
10173
|
// src/runtime/supervise/trace-source.ts
|
|
9995
10174
|
function toToolSpan(input, runId, seq, at) {
|
|
10175
|
+
const startedAt = typeof input.startedAt === "number" ? input.startedAt : at;
|
|
10176
|
+
const endedAt = typeof input.endedAt === "number" ? input.endedAt : startedAt;
|
|
9996
10177
|
return {
|
|
9997
10178
|
spanId: `${runId}-t${seq}`,
|
|
9998
10179
|
runId,
|
|
@@ -10001,8 +10182,8 @@ function toToolSpan(input, runId, seq, at) {
|
|
|
10001
10182
|
toolName: input.toolName,
|
|
10002
10183
|
args: input.args,
|
|
10003
10184
|
status: input.status ?? "ok",
|
|
10004
|
-
startedAt
|
|
10005
|
-
endedAt
|
|
10185
|
+
startedAt,
|
|
10186
|
+
endedAt,
|
|
10006
10187
|
...input.result !== void 0 ? { result: input.result } : {}
|
|
10007
10188
|
};
|
|
10008
10189
|
}
|
|
@@ -10042,7 +10223,7 @@ var decodeOpenAiPart = (p) => {
|
|
|
10042
10223
|
const rawArgs = fn?.arguments ?? p.arguments;
|
|
10043
10224
|
return {
|
|
10044
10225
|
toolName: name,
|
|
10045
|
-
args: typeof rawArgs === "string" ?
|
|
10226
|
+
args: typeof rawArgs === "string" ? safeParse(rawArgs) : rawArgs ?? {},
|
|
10046
10227
|
...str(p.id) ? { callId: p.id } : str(fn?.id) ? { callId: fn?.id } : {}
|
|
10047
10228
|
};
|
|
10048
10229
|
};
|
|
@@ -10066,7 +10247,7 @@ function decodeToolPart(part, harness) {
|
|
|
10066
10247
|
}
|
|
10067
10248
|
return void 0;
|
|
10068
10249
|
}
|
|
10069
|
-
function
|
|
10250
|
+
function safeParse(s) {
|
|
10070
10251
|
try {
|
|
10071
10252
|
return JSON.parse(s);
|
|
10072
10253
|
} catch {
|
|
@@ -10512,13 +10693,22 @@ function tail(s) {
|
|
|
10512
10693
|
}
|
|
10513
10694
|
|
|
10514
10695
|
export {
|
|
10696
|
+
SessionMismatchError,
|
|
10697
|
+
BackendTransportError,
|
|
10698
|
+
RuntimeRunStateError,
|
|
10699
|
+
PlannerError,
|
|
10700
|
+
AgentEvalError2 as AgentEvalError,
|
|
10701
|
+
ConfigError,
|
|
10702
|
+
JudgeError,
|
|
10703
|
+
NotFoundError,
|
|
10704
|
+
ValidationError,
|
|
10705
|
+
runLocalHarness,
|
|
10706
|
+
assertModelAllowed,
|
|
10707
|
+
extractLlmCallEvent,
|
|
10708
|
+
mapSandboxEvent,
|
|
10515
10709
|
contentAddress,
|
|
10516
10710
|
InMemoryResultBlobStore,
|
|
10517
|
-
FileResultBlobStore,
|
|
10518
10711
|
InMemorySpawnJournal,
|
|
10519
|
-
FileSpawnJournal,
|
|
10520
|
-
replaySpawnTree,
|
|
10521
|
-
materializeTreeView,
|
|
10522
10712
|
anytimeReport,
|
|
10523
10713
|
renderAnytimeTable,
|
|
10524
10714
|
defaultAuditorInstruction,
|
|
@@ -10541,7 +10731,6 @@ export {
|
|
|
10541
10731
|
probeSandboxCapabilities,
|
|
10542
10732
|
createSandboxLineage,
|
|
10543
10733
|
runLoop,
|
|
10544
|
-
describeSandboxPlacement,
|
|
10545
10734
|
createSandboxForSpec,
|
|
10546
10735
|
defaultSelectWinner,
|
|
10547
10736
|
loopDispatch,
|
|
@@ -10550,7 +10739,6 @@ export {
|
|
|
10550
10739
|
createScopeAnalyst,
|
|
10551
10740
|
registryScopeAnalyst,
|
|
10552
10741
|
buildSteerContext,
|
|
10553
|
-
nestedScopeSeamKey,
|
|
10554
10742
|
createScope,
|
|
10555
10743
|
settledToIteration,
|
|
10556
10744
|
selectValidWinner,
|
|
@@ -10564,14 +10752,10 @@ export {
|
|
|
10564
10752
|
InMemoryCorpus,
|
|
10565
10753
|
FileCorpus,
|
|
10566
10754
|
renderCorpusToInstructions,
|
|
10567
|
-
driverRuntime,
|
|
10568
|
-
driverChild,
|
|
10569
|
-
isDriverSpec,
|
|
10570
|
-
driverExecutorFactory,
|
|
10571
|
-
withDriverExecutor,
|
|
10572
10755
|
routerChatWithUsage,
|
|
10573
10756
|
routerChatWithTools,
|
|
10574
10757
|
routerToolLoop,
|
|
10758
|
+
routerBrain,
|
|
10575
10759
|
createInbox,
|
|
10576
10760
|
createWorktree,
|
|
10577
10761
|
captureWorktreeDiff,
|
|
@@ -10584,7 +10768,6 @@ export {
|
|
|
10584
10768
|
spendFromUsageEvents,
|
|
10585
10769
|
createBudgetPool,
|
|
10586
10770
|
createSupervisor,
|
|
10587
|
-
createRootHandle,
|
|
10588
10771
|
createShapeRegistry,
|
|
10589
10772
|
builtinShapes,
|
|
10590
10773
|
registerShape,
|
|
@@ -10593,8 +10776,8 @@ export {
|
|
|
10593
10776
|
trajectoryReport,
|
|
10594
10777
|
equalKOnCost,
|
|
10595
10778
|
promotionGate,
|
|
10596
|
-
|
|
10597
|
-
|
|
10779
|
+
depthStrategy,
|
|
10780
|
+
breadthStrategy,
|
|
10598
10781
|
sample,
|
|
10599
10782
|
refine,
|
|
10600
10783
|
defineStrategy,
|
|
@@ -10613,11 +10796,15 @@ export {
|
|
|
10613
10796
|
runStrategyEvolution,
|
|
10614
10797
|
gateOnDeliverable,
|
|
10615
10798
|
asAuthoredProfile,
|
|
10616
|
-
|
|
10799
|
+
supervisorInstructions,
|
|
10617
10800
|
authoredWorker,
|
|
10801
|
+
defaultProfileRichnessThresholds,
|
|
10802
|
+
assessAuthoredProfile,
|
|
10803
|
+
profileRichnessFinding,
|
|
10618
10804
|
createEventBus,
|
|
10619
10805
|
createCoordinationTools,
|
|
10620
|
-
|
|
10806
|
+
driverAgent,
|
|
10807
|
+
finalizeBestDelivered,
|
|
10621
10808
|
InMemoryFeedbackStore,
|
|
10622
10809
|
eventToSnapshot,
|
|
10623
10810
|
DelegationStateCorruptError,
|
|
@@ -10636,7 +10823,7 @@ export {
|
|
|
10636
10823
|
parseDetachedSessionRef,
|
|
10637
10824
|
detachedTurnEvents,
|
|
10638
10825
|
runDetachedTurn,
|
|
10639
|
-
|
|
10826
|
+
createDetachedTurnResumeDriver,
|
|
10640
10827
|
DELEGATE_CODE_TOOL_NAME,
|
|
10641
10828
|
DELEGATE_CODE_DESCRIPTION,
|
|
10642
10829
|
DELEGATE_CODE_INPUT_SCHEMA,
|
|
@@ -10672,22 +10859,14 @@ export {
|
|
|
10672
10859
|
serveCoordinationMcp,
|
|
10673
10860
|
defaultToolDetectors,
|
|
10674
10861
|
watchTrace,
|
|
10675
|
-
touchedPathsFromPatch,
|
|
10676
|
-
countDiffLines,
|
|
10677
|
-
isNonEmptyPatch,
|
|
10678
|
-
touchesSecretPath,
|
|
10679
10862
|
runCoderChecks,
|
|
10680
10863
|
patchDelivered,
|
|
10681
|
-
routerDriverChat,
|
|
10682
10864
|
createInMemoryRunContext,
|
|
10683
|
-
|
|
10684
|
-
|
|
10685
|
-
|
|
10686
|
-
decodeOpenAiPart,
|
|
10687
|
-
toolPartDecoders,
|
|
10865
|
+
supervisorAgent,
|
|
10866
|
+
workerFromBackend,
|
|
10867
|
+
supervise,
|
|
10688
10868
|
decodeToolPart,
|
|
10689
10869
|
createPushTraceSource,
|
|
10690
|
-
createPartsTraceSource,
|
|
10691
10870
|
sandboxSessionTraceSource,
|
|
10692
10871
|
analyzeTrace,
|
|
10693
10872
|
worktreeFanout,
|
|
@@ -10696,6 +10875,8 @@ export {
|
|
|
10696
10875
|
localShell,
|
|
10697
10876
|
gitWorkspace,
|
|
10698
10877
|
jjWorkspace,
|
|
10699
|
-
runInWorkspace
|
|
10878
|
+
runInWorkspace,
|
|
10879
|
+
computeFindingId2 as computeFindingId,
|
|
10880
|
+
makeFinding3 as makeFinding
|
|
10700
10881
|
};
|
|
10701
|
-
//# sourceMappingURL=chunk-
|
|
10882
|
+
//# sourceMappingURL=chunk-QXWGSDAQ.js.map
|