@tangle-network/agent-runtime 0.69.0 → 0.70.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +81 -13
  2. package/dist/agent.d.ts +4 -5
  3. package/dist/agent.js +3 -4
  4. package/dist/agent.js.map +1 -1
  5. package/dist/analyst-loop.d.ts +3 -4
  6. package/dist/{chunk-K4FQSEXQ.js → chunk-BGOLR66M.js} +6 -6
  7. package/dist/{chunk-G6U3GVK2.js → chunk-CRAH5EY2.js} +2 -2
  8. package/dist/{chunk-RTDI2DHD.js → chunk-HY4YOQM2.js} +6 -6
  9. package/dist/chunk-HY4YOQM2.js.map +1 -0
  10. package/dist/{chunk-QZ6FA5LM.js → chunk-LJZ5GC6C.js} +3 -3
  11. package/dist/{chunk-NLRA6434.js → chunk-YFOPWG74.js} +577 -525
  12. package/dist/chunk-YFOPWG74.js.map +1 -0
  13. package/dist/{coordination-Curpzeyc.d.ts → coordination-C7WxwHXq.d.ts} +8 -1
  14. package/dist/{delegates-CLFNAKyi.d.ts → delegates-DqAgo32T.d.ts} +105 -10
  15. package/dist/{improvement-adapter-BC4HhuAR.d.ts → improvement-adapter-CioiEE2z.d.ts} +1 -1
  16. package/dist/index.d.ts +439 -100
  17. package/dist/index.js +591 -130
  18. package/dist/index.js.map +1 -1
  19. package/dist/intelligence.d.ts +2 -3
  20. package/dist/{loop-runner-bin-B6dzNZC8.d.ts → loop-runner-bin-a8bu4O5-.d.ts} +4 -4
  21. package/dist/loop-runner-bin.d.ts +7 -10
  22. package/dist/loop-runner-bin.js +6 -7
  23. package/dist/loops.d.ts +3149 -16
  24. package/dist/loops.js +33 -60
  25. package/dist/mcp/bin.js +13 -14
  26. package/dist/mcp/bin.js.map +1 -1
  27. package/dist/mcp/index.d.ts +8 -12
  28. package/dist/mcp/index.js +10 -12
  29. package/dist/mcp/index.js.map +1 -1
  30. package/dist/{openai-tools-CA2N3-Ak.d.ts → openai-tools-DPx9Gzvn.d.ts} +1 -1
  31. package/dist/profiles.d.ts +94 -6
  32. package/dist/profiles.js +320 -9
  33. package/dist/profiles.js.map +1 -1
  34. package/dist/{router-client-30Y_pca8.d.ts → router-client-C7kp_ECN.d.ts} +37 -1
  35. package/dist/{substrate-CUgk7F7s.d.ts → substrate-BoRXgvka.d.ts} +52 -1
  36. package/dist/{types-p8dWBIXL.d.ts → types-BC3bZpH0.d.ts} +1 -1
  37. package/dist/{types-Crxftafi.d.ts → types-BYa2ZOAx.d.ts} +83 -2
  38. package/dist/{worktree-fanout-DUiKPApb.d.ts → worktree-fanout-gNfl0Byj.d.ts} +9 -37
  39. package/package.json +17 -37
  40. package/dist/audit.d.ts +0 -93
  41. package/dist/audit.js +0 -312
  42. package/dist/audit.js.map +0 -1
  43. package/dist/chunk-4B6U4CVQ.js +0 -15
  44. package/dist/chunk-4B6U4CVQ.js.map +0 -1
  45. package/dist/chunk-NLRA6434.js.map +0 -1
  46. package/dist/chunk-O2UPHN7X.js +0 -114
  47. package/dist/chunk-O2UPHN7X.js.map +0 -1
  48. package/dist/chunk-RTDI2DHD.js.map +0 -1
  49. package/dist/coder-2leJPOvC.d.ts +0 -52
  50. package/dist/improvement.d.ts +0 -208
  51. package/dist/improvement.js +0 -343
  52. package/dist/improvement.js.map +0 -1
  53. package/dist/local-harness-BE_h8szs.d.ts +0 -93
  54. package/dist/run-loop-D3PwlG7J.d.ts +0 -112
  55. package/dist/runtime-hooks-C7JwKb9E.d.ts +0 -70
  56. package/dist/runtime.d.ts +0 -3120
  57. package/dist/runtime.js +0 -263
  58. package/dist/runtime.js.map +0 -1
  59. package/dist/topology.d.ts +0 -126
  60. package/dist/topology.js +0 -333
  61. package/dist/topology.js.map +0 -1
  62. package/dist/workflow.d.ts +0 -551
  63. package/dist/workflow.js +0 -1781
  64. package/dist/workflow.js.map +0 -1
  65. /package/dist/{chunk-K4FQSEXQ.js.map → chunk-BGOLR66M.js.map} +0 -0
  66. /package/dist/{chunk-G6U3GVK2.js.map → chunk-CRAH5EY2.js.map} +0 -0
  67. /package/dist/{chunk-QZ6FA5LM.js.map → chunk-LJZ5GC6C.js.map} +0 -0
@@ -1,9 +1,10 @@
1
1
  import {
2
- UI_LENSES
3
- } from "./chunk-WIR4HOOJ.js";
2
+ buildLoopSpanNodes
3
+ } from "./chunk-G3RGMA7C.js";
4
4
  import {
5
5
  AgentEvalError,
6
6
  AnalystError,
7
+ ConfigError,
7
8
  NotFoundError,
8
9
  PlannerError,
9
10
  RuntimeRunStateError,
@@ -11,12 +12,11 @@ import {
11
12
  extractLlmCallEvent
12
13
  } from "./chunk-VLF5RHEQ.js";
13
14
  import {
14
- harnessInvocation,
15
- runLocalHarness
16
- } from "./chunk-O2UPHN7X.js";
17
- import {
18
- buildLoopSpanNodes
19
- } from "./chunk-G3RGMA7C.js";
15
+ UI_LENSES
16
+ } from "./chunk-WIR4HOOJ.js";
17
+
18
+ // src/runtime/index.ts
19
+ import { computeFindingId as computeFindingId2, makeFinding as makeFinding3 } from "@tangle-network/agent-eval";
20
20
 
21
21
  // src/durable/spawn-journal.ts
22
22
  import { createHash } from "crypto";
@@ -149,38 +149,6 @@ var InMemoryResultBlobStore = class {
149
149
  return this.blobs.has(outRef) ? this.blobs.get(outRef) : void 0;
150
150
  }
151
151
  };
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
152
  function assertContentAddress(outRef, artifact) {
185
153
  const expected = contentAddress(artifact);
186
154
  if (outRef !== expected) {
@@ -217,90 +185,6 @@ var InMemorySpawnJournal = class {
217
185
  tree.events.push({ ...ev });
218
186
  }
219
187
  };
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
188
  function assertSeqUnique(root, events, ev) {
305
189
  if (ev.kind === "spawned" || ev.kind === "metered") return;
306
190
  if (events.some((e) => e.kind !== "spawned" && e.kind !== "metered" && e.seq === ev.seq)) {
@@ -309,148 +193,6 @@ function assertSeqUnique(root, events, ev) {
309
193
  );
310
194
  }
311
195
  }
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
196
 
455
197
  // src/runtime/anytime.ts
456
198
  var median = (xs) => {
@@ -2143,7 +1885,7 @@ function createScope(args) {
2143
1885
  let cursorSeq = 0;
2144
1886
  let meterSeq = 0;
2145
1887
  const now = args.now ?? Date.now;
2146
- function spawn4(agent, task, opts) {
1888
+ function spawn5(agent, task, opts) {
2147
1889
  if (args.maxDepth !== void 0 && args.depth >= args.maxDepth) {
2148
1890
  return { ok: false, reason: "depth-exceeded" };
2149
1891
  }
@@ -2185,7 +1927,7 @@ function createScope(args) {
2185
1927
  runtime: executor.runtime,
2186
1928
  budget: opts.budget,
2187
1929
  label: opts.label,
2188
- spent: zeroSpend2(),
1930
+ spent: zeroSpend(),
2189
1931
  settled: void 0,
2190
1932
  delivered: false,
2191
1933
  ...executor.deliver ? { deliver: executor.deliver.bind(executor) } : {}
@@ -2239,7 +1981,7 @@ function createScope(args) {
2239
1981
  live.settled = settled;
2240
1982
  return { ok: true, handle };
2241
1983
  } catch (err) {
2242
- args.pool.reconcile(reservation.ticket, zeroSpend2());
1984
+ args.pool.reconcile(reservation.ticket, zeroSpend());
2243
1985
  throw err;
2244
1986
  }
2245
1987
  }
@@ -2294,7 +2036,7 @@ function createScope(args) {
2294
2036
  );
2295
2037
  }
2296
2038
  return {
2297
- spawn: spawn4,
2039
+ spawn: spawn5,
2298
2040
  next,
2299
2041
  send,
2300
2042
  signal: args.signal,
@@ -2546,7 +2288,7 @@ async function teardownSafe(executor, grace) {
2546
2288
  function downRecord(reason, infra, metered) {
2547
2289
  return { kind: "down", reason, infra, restartCount: 0, ...metered ? { metered } : {} };
2548
2290
  }
2549
- function zeroSpend2() {
2291
+ function zeroSpend() {
2550
2292
  return { iterations: 0, tokens: { input: 0, output: 0 }, usd: 0, ms: 0 };
2551
2293
  }
2552
2294
  function isAsyncIterable2(value) {
@@ -3042,7 +2784,7 @@ var FileCorpus = class {
3042
2784
  try {
3043
2785
  text = await fs.readFile(this.path, "utf8");
3044
2786
  } catch (err) {
3045
- if (isNoEntError2(err)) return /* @__PURE__ */ new Map();
2787
+ if (isNoEntError(err)) return /* @__PURE__ */ new Map();
3046
2788
  throw err;
3047
2789
  }
3048
2790
  const lines = text.split("\n").filter((line) => line.length > 0);
@@ -3116,30 +2858,13 @@ function renderLine(record) {
3116
2858
  function freeze(record) {
3117
2859
  return Object.freeze({ ...record });
3118
2860
  }
3119
- function isNoEntError2(err) {
2861
+ function isNoEntError(err) {
3120
2862
  return typeof err === "object" && err !== null && "code" in err && err.code === "ENOENT";
3121
2863
  }
3122
2864
 
3123
2865
  // src/runtime/supervise/driver-executor.ts
3124
2866
  var driverRuntime = "driver";
3125
2867
  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
2868
  function isDriverSpec(spec) {
3144
2869
  const role = spec.profile.metadata?.role;
3145
2870
  if (role !== driverRole) return false;
@@ -3311,12 +3036,64 @@ function isAgent(value) {
3311
3036
  }
3312
3037
 
3313
3038
  // src/runtime/supervise/runtime.ts
3314
- import { spawn as spawn3 } from "child_process";
3039
+ import { spawn as spawn4 } from "child_process";
3315
3040
  import { randomUUID as randomUUID2 } from "crypto";
3316
3041
  import { estimateCost as estimateCost2, isModelPriced as isModelPriced2 } from "@tangle-network/agent-eval";
3317
3042
 
3318
3043
  // src/runtime/router-client.ts
3319
3044
  import { estimateCost, isModelPriced } from "@tangle-network/agent-eval";
3045
+
3046
+ // src/runtime/tool-loop.ts
3047
+ async function runBrainLoop(opts) {
3048
+ const maxTurns = opts.maxTurns ?? 4;
3049
+ const messages = [...opts.initialMessages];
3050
+ let toolCalls = 0;
3051
+ let lastText = "";
3052
+ const usage = { input: 0, output: 0 };
3053
+ const toolTrace = [];
3054
+ for (let turn = 1; turn <= maxTurns; turn += 1) {
3055
+ if (opts.hooks?.stopBefore?.(turn)) break;
3056
+ await opts.hooks?.beforeTurn?.(turn, messages);
3057
+ const r = await opts.chat(messages, opts.tools);
3058
+ if (r.usage) {
3059
+ usage.input += r.usage.input;
3060
+ usage.output += r.usage.output;
3061
+ opts.hooks?.onUsage?.(r.usage);
3062
+ }
3063
+ if (r.content) lastText = r.content;
3064
+ if (r.toolCalls.length === 0)
3065
+ return { final: lastText, turns: turn, toolCalls, toolTrace, usage, messages };
3066
+ messages.push({
3067
+ role: "assistant",
3068
+ content: r.content ?? "",
3069
+ tool_calls: r.toolCalls.map((tc) => ({
3070
+ id: tc.id,
3071
+ type: "function",
3072
+ function: { name: tc.name, arguments: tc.arguments }
3073
+ }))
3074
+ });
3075
+ for (const tc of r.toolCalls) {
3076
+ toolCalls += 1;
3077
+ let args = {};
3078
+ try {
3079
+ args = JSON.parse(tc.arguments);
3080
+ } catch {
3081
+ messages.push({
3082
+ role: "tool",
3083
+ tool_call_id: tc.id,
3084
+ content: `error: arguments were not valid JSON: ${tc.arguments.slice(0, 200)}`
3085
+ });
3086
+ continue;
3087
+ }
3088
+ const out = await opts.execute(tc.name, args);
3089
+ messages.push({ role: "tool", tool_call_id: tc.id, content: out });
3090
+ toolTrace.push({ name: tc.name, args: tc.arguments, result: out });
3091
+ }
3092
+ }
3093
+ return { final: lastText, turns: maxTurns, toolCalls, toolTrace, usage, messages };
3094
+ }
3095
+
3096
+ // src/runtime/router-client.ts
3320
3097
  async function routerChatWithUsage(cfg, messages, opts) {
3321
3098
  const url = `${cfg.routerBaseUrl.replace(/\/$/, "")}/chat/completions`;
3322
3099
  const headers = { "content-type": "application/json", authorization: `Bearer ${cfg.routerKey}` };
@@ -3394,56 +3171,25 @@ async function routerChatWithTools(cfg, messages, tools, opts) {
3394
3171
  };
3395
3172
  }
3396
3173
  async function routerToolLoop(cfg, system, user, tools, execute, opts) {
3397
- const maxTurns = opts?.maxTurns ?? 4;
3398
- const messages = opts?.initialMessages ? [...opts.initialMessages] : [
3174
+ const initialMessages = opts?.initialMessages ?? [
3399
3175
  { role: "system", content: system },
3400
3176
  { role: "user", content: user }
3401
3177
  ];
3402
- let toolCalls = 0;
3403
- let lastText = "";
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, {
3178
+ return runBrainLoop({
3179
+ chat: (messages, toolSpecs) => routerChatWithTools(cfg, messages, toolSpecs, {
3408
3180
  ...opts?.temperature !== void 0 ? { temperature: opts.temperature } : {},
3409
3181
  ...opts?.maxTokens ? { maxTokens: opts.maxTokens } : {},
3410
3182
  ...opts?.signal ? { signal: opts.signal } : {}
3411
- });
3412
- if (r.usage) {
3413
- usage.input += r.usage.input;
3414
- usage.output += r.usage.output;
3415
- }
3416
- if (r.content) lastText = r.content;
3417
- if (r.toolCalls.length === 0)
3418
- return { final: lastText, turns: turn, toolCalls, toolTrace, usage, messages };
3419
- messages.push({
3420
- role: "assistant",
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 };
3183
+ }),
3184
+ tools,
3185
+ execute,
3186
+ initialMessages,
3187
+ maxTurns: opts?.maxTurns ?? 4
3188
+ });
3189
+ }
3190
+ function routerBrain(cfg, opts = {}) {
3191
+ const temperature = opts.temperature ?? 0.4;
3192
+ return (messages, tools) => routerChatWithTools(cfg, messages, tools, { temperature, toolChoice: "auto" });
3447
3193
  }
3448
3194
 
3449
3195
  // src/runtime/supervise/inbox.ts
@@ -3495,14 +3241,123 @@ ${lines.join("\n")}`;
3495
3241
  import { randomUUID } from "crypto";
3496
3242
 
3497
3243
  // src/mcp/worktree-harness.ts
3498
- import { spawn as spawn2 } from "child_process";
3244
+ import { spawn as spawn3 } from "child_process";
3499
3245
 
3500
- // src/mcp/worktree.ts
3246
+ // src/mcp/local-harness.ts
3501
3247
  import { spawn } from "child_process";
3248
+ var HARNESS_INVOCATIONS = {
3249
+ claude: {
3250
+ command: "claude",
3251
+ buildArgs: (taskPrompt) => ["--headless", "-p", taskPrompt],
3252
+ modelArgs: (model) => ["-m", model]
3253
+ },
3254
+ codex: {
3255
+ command: "codex",
3256
+ buildArgs: (taskPrompt) => ["run", taskPrompt],
3257
+ modelArgs: (model) => ["-m", model]
3258
+ },
3259
+ opencode: {
3260
+ command: "opencode",
3261
+ buildArgs: (taskPrompt) => ["run", taskPrompt],
3262
+ modelArgs: (model) => ["-m", model]
3263
+ }
3264
+ };
3265
+ function harnessInvocation(harness, profile, taskPrompt) {
3266
+ const invocation = HARNESS_INVOCATIONS[harness];
3267
+ if (!invocation) {
3268
+ throw new Error(`harnessInvocation: unknown harness ${String(harness)}`);
3269
+ }
3270
+ const systemPrompt = profile.prompt?.systemPrompt;
3271
+ const composedPrompt = typeof systemPrompt === "string" && systemPrompt.trim().length > 0 ? `${systemPrompt}
3272
+
3273
+ ${taskPrompt}` : taskPrompt;
3274
+ const args = invocation.buildArgs(composedPrompt);
3275
+ const model = profile.model?.default;
3276
+ if (typeof model === "string" && model.length > 0) {
3277
+ args.push(...invocation.modelArgs(model));
3278
+ }
3279
+ return { command: invocation.command, args };
3280
+ }
3281
+ var DEFAULT_TIMEOUT_MS = 5 * 60 * 1e3;
3282
+ function runLocalHarness(options) {
3283
+ const { harness, cwd, taskPrompt } = options;
3284
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
3285
+ const env = options.env ?? process.env;
3286
+ const spawnImpl = options.spawn ?? spawn;
3287
+ const invocation = HARNESS_INVOCATIONS[harness];
3288
+ if (!invocation) {
3289
+ return Promise.reject(new Error(`runLocalHarness: unknown harness ${String(harness)}`));
3290
+ }
3291
+ const startedAt = Date.now();
3292
+ const command = options.invocation?.command ?? invocation.command;
3293
+ const args = options.invocation ? [...options.invocation.args] : invocation.buildArgs(taskPrompt);
3294
+ return new Promise((resolve, reject) => {
3295
+ let child;
3296
+ try {
3297
+ child = spawnImpl(command, args, { cwd, env, stdio: "pipe" });
3298
+ } catch (err) {
3299
+ reject(err instanceof Error ? err : new Error(String(err)));
3300
+ return;
3301
+ }
3302
+ child.stdin?.end();
3303
+ let stdout = "";
3304
+ let stderr = "";
3305
+ let timedOut = false;
3306
+ let settled = false;
3307
+ const timer = timeoutMs > 0 ? setTimeout(() => {
3308
+ timedOut = true;
3309
+ if (!child.killed) child.kill("SIGTERM");
3310
+ }, timeoutMs) : null;
3311
+ if (timer && typeof timer.unref === "function") {
3312
+ ;
3313
+ timer.unref();
3314
+ }
3315
+ const onAbort = () => {
3316
+ if (!child.killed) child.kill("SIGTERM");
3317
+ };
3318
+ if (options.signal) {
3319
+ if (options.signal.aborted) onAbort();
3320
+ else options.signal.addEventListener("abort", onAbort, { once: true });
3321
+ }
3322
+ child.stdout?.on("data", (chunk) => {
3323
+ stdout += String(chunk);
3324
+ });
3325
+ child.stderr?.on("data", (chunk) => {
3326
+ stderr += String(chunk);
3327
+ });
3328
+ const finalize3 = (result) => {
3329
+ if (settled) return;
3330
+ settled = true;
3331
+ if (timer) clearTimeout(timer);
3332
+ options.signal?.removeEventListener("abort", onAbort);
3333
+ resolve(result);
3334
+ };
3335
+ child.on("error", (err) => {
3336
+ if (settled) return;
3337
+ settled = true;
3338
+ if (timer) clearTimeout(timer);
3339
+ options.signal?.removeEventListener("abort", onAbort);
3340
+ reject(err);
3341
+ });
3342
+ child.on("close", (code, signal) => {
3343
+ finalize3({
3344
+ exitCode: code,
3345
+ stdout,
3346
+ stderr,
3347
+ killedBySignal: signal,
3348
+ durationMs: Date.now() - startedAt,
3349
+ timedOut
3350
+ });
3351
+ });
3352
+ });
3353
+ }
3354
+
3355
+ // src/mcp/worktree.ts
3356
+ import { spawn as spawn2 } from "child_process";
3502
3357
  async function runGitAsync(args, cwd, runner) {
3503
3358
  if (runner) return runner(args, { cwd });
3504
3359
  return new Promise((resolve, reject) => {
3505
- const proc = spawn("git", args, { cwd, stdio: "pipe" });
3360
+ const proc = spawn2("git", args, { cwd, stdio: "pipe" });
3506
3361
  let stdout = "";
3507
3362
  let stderr = "";
3508
3363
  proc.stdout?.on("data", (c) => {
@@ -3668,7 +3523,7 @@ async function runChecks(opts) {
3668
3523
  }
3669
3524
  function defaultRunCommand(opts) {
3670
3525
  return new Promise((resolve, reject) => {
3671
- const child = spawn2("/bin/sh", ["-c", opts.command], {
3526
+ const child = spawn3("/bin/sh", ["-c", opts.command], {
3672
3527
  cwd: opts.cwd,
3673
3528
  stdio: ["ignore", "pipe", "pipe"]
3674
3529
  });
@@ -3791,7 +3646,7 @@ function contentRef(prefix, value) {
3791
3646
  }
3792
3647
  return `${prefix}:${(h >>> 0).toString(16).padStart(8, "0")}`;
3793
3648
  }
3794
- function zeroSpend3() {
3649
+ function zeroSpend2() {
3795
3650
  return { iterations: 0, tokens: zeroTokenUsage(), usd: 0, ms: 0 };
3796
3651
  }
3797
3652
  var routerInlineExecutor = (spec, ctx) => {
@@ -3963,15 +3818,24 @@ var routerToolsInlineExecutor = (spec, ctx) => {
3963
3818
  const toolName = tc?.function?.name ?? "";
3964
3819
  let result;
3965
3820
  let status = "ok";
3821
+ const toolStartedAt = Date.now();
3966
3822
  try {
3967
3823
  result = await seam.executeToolCall(toolName, args, task);
3968
3824
  } catch (e) {
3969
3825
  status = "error";
3970
3826
  result = `error: ${e instanceof Error ? e.message : String(e)}`;
3971
3827
  }
3828
+ const toolEndedAt = Date.now();
3972
3829
  messages.push({ role: "tool", tool_call_id: id, content: result });
3973
3830
  try {
3974
- seam.onToolStep?.({ toolName, args, status });
3831
+ seam.onToolStep?.({
3832
+ toolName,
3833
+ args,
3834
+ status,
3835
+ startedAt: toolStartedAt,
3836
+ endedAt: toolEndedAt,
3837
+ durationMs: toolEndedAt - toolStartedAt
3838
+ });
3975
3839
  } catch {
3976
3840
  }
3977
3841
  }
@@ -4151,7 +4015,7 @@ var cliExecutor = (_spec, ctx) => {
4151
4015
  };
4152
4016
  async function* streamCliLeaf(args) {
4153
4017
  const prompt = taskToPrompt(args.task);
4154
- const proc = spawn3(args.seam.bin, args.seam.args ?? [], {
4018
+ const proc = spawn4(args.seam.bin, args.seam.args ?? [], {
4155
4019
  ...args.seam.cwd ? { cwd: args.seam.cwd } : {},
4156
4020
  env: { ...process.env, ...args.seam.env ?? {} },
4157
4021
  stdio: ["pipe", "pipe", "pipe"]
@@ -4188,7 +4052,7 @@ async function* streamCliLeaf(args) {
4188
4052
  );
4189
4053
  }
4190
4054
  const out = { content: chunks.join("") };
4191
- args.onArtifact({ outRef: contentRef("cli", out), out, spent: zeroSpend3() });
4055
+ args.onArtifact({ outRef: contentRef("cli", out), out, spent: zeroSpend2() });
4192
4056
  yield { kind: "iteration" };
4193
4057
  }
4194
4058
  function killWithGrace(proc, grace) {
@@ -4803,40 +4667,6 @@ function createSupervisor() {
4803
4667
  return { run, attach };
4804
4668
  }
4805
4669
  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
4670
  function pushRootSignal(cascadeAbort) {
4841
4671
  return (msg) => {
4842
4672
  if (msg.kind === "cancel") cascadeAbort(msg.reason ?? "root signal: cancel");
@@ -5105,12 +4935,12 @@ async function trajectoryReport(journal, blobs, root, options = {}) {
5105
4935
  label: ev.label,
5106
4936
  runtime: ev.runtime,
5107
4937
  status: "pending",
5108
- ownSpend: zeroSpend4(),
4938
+ ownSpend: zeroSpend3(),
5109
4939
  children: []
5110
4940
  });
5111
4941
  }
5112
4942
  for (const ev of closes) {
5113
- const node = requireNode2(nodes, ev.id, root);
4943
+ const node = requireNode(nodes, ev.id, root);
5114
4944
  if (ev.kind === "cancelled") {
5115
4945
  node.status = "cancelled";
5116
4946
  continue;
@@ -5122,7 +4952,7 @@ async function trajectoryReport(journal, blobs, root, options = {}) {
5122
4952
  }
5123
4953
  for (const ev of events) {
5124
4954
  if (ev.kind !== "metered") continue;
5125
- const node = requireNode2(nodes, ev.id, root);
4955
+ const node = requireNode(nodes, ev.id, root);
5126
4956
  node.ownSpend = addNodeSpend(node.ownSpend, ev.spend);
5127
4957
  }
5128
4958
  if (!nodes.has(root)) {
@@ -5132,7 +4962,7 @@ async function trajectoryReport(journal, blobs, root, options = {}) {
5132
4962
  }
5133
4963
  for (const ev of spawns) {
5134
4964
  if (ev.parent === void 0) continue;
5135
- requireNode2(nodes, ev.parent, root).children.push(ev.id);
4965
+ requireNode(nodes, ev.parent, root).children.push(ev.id);
5136
4966
  }
5137
4967
  const rolledUp = rollUpSpend(nodes, root);
5138
4968
  if (options.withOutputs) {
@@ -5180,7 +5010,7 @@ function rollUpSpend(nodes, root) {
5180
5010
  while (stack.length > 0) {
5181
5011
  const frame = stack.pop();
5182
5012
  if (frame === void 0) continue;
5183
- const node = requireNode2(nodes, frame.id, root);
5013
+ const node = requireNode(nodes, frame.id, root);
5184
5014
  if (!frame.expanded) {
5185
5015
  stack.push({ id: frame.id, expanded: true });
5186
5016
  for (const child of node.children) stack.push({ id: child, expanded: false });
@@ -5229,7 +5059,7 @@ function countStatuses(reported) {
5229
5059
  for (const node of reported) counts[node.status] += 1;
5230
5060
  return counts;
5231
5061
  }
5232
- function zeroSpend4() {
5062
+ function zeroSpend3() {
5233
5063
  return { iterations: 0, tokens: zeroTokenUsage(), usd: 0, ms: 0 };
5234
5064
  }
5235
5065
  function addNodeSpend(a, b) {
@@ -5289,7 +5119,7 @@ function isNode(node) {
5289
5119
  function bySeq(a, b) {
5290
5120
  return a.seq - b.seq;
5291
5121
  }
5292
- function requireNode2(nodes, id, root) {
5122
+ function requireNode(nodes, id, root) {
5293
5123
  const node = nodes.get(id);
5294
5124
  if (!node) {
5295
5125
  throw new Error(
@@ -5694,7 +5524,7 @@ var perChild = (innerTurns) => ({
5694
5524
  maxIterations: innerTurns + 1,
5695
5525
  maxTokens: 1e6
5696
5526
  });
5697
- function depthDriver(surface, task, opts, cfg) {
5527
+ function depthStrategy(surface, task, opts, cfg) {
5698
5528
  const innerTurns = opts.innerTurns ?? 4;
5699
5529
  let pendingSteer;
5700
5530
  return {
@@ -5757,7 +5587,7 @@ Address each with the tools, verify they took, then continue.`;
5757
5587
  }
5758
5588
  };
5759
5589
  }
5760
- function breadthDriver(_surface, task, opts, cfg) {
5590
+ function breadthStrategy(_surface, task, opts, cfg) {
5761
5591
  const innerTurns = opts.innerTurns ?? 4;
5762
5592
  return {
5763
5593
  name: "breadth",
@@ -5800,11 +5630,11 @@ function breadthDriver(_surface, task, opts, cfg) {
5800
5630
  }
5801
5631
  var sample = {
5802
5632
  name: "sample",
5803
- driver: (surface, task, opts, budget) => breadthDriver(surface, task, opts, { width: budget })
5633
+ driver: (surface, task, opts, budget) => breadthStrategy(surface, task, opts, { width: budget })
5804
5634
  };
5805
5635
  var refine = {
5806
5636
  name: "refine",
5807
- driver: (surface, task, opts, budget) => depthDriver(surface, task, opts, { maxShots: budget })
5637
+ driver: (surface, task, opts, budget) => depthStrategy(surface, task, opts, { maxShots: budget })
5808
5638
  };
5809
5639
  function defineStrategy(name, run) {
5810
5640
  return {
@@ -6935,6 +6765,9 @@ ${summary}`,
6935
6765
  };
6936
6766
  }
6937
6767
 
6768
+ // src/runtime/supervise/authoring.ts
6769
+ import { computeFindingId, makeFinding as makeFinding2 } from "@tangle-network/agent-eval";
6770
+
6938
6771
  // src/runtime/supervise/completion-gate.ts
6939
6772
  function gateOnDeliverable(inner, deliverable) {
6940
6773
  let gated;
@@ -6987,13 +6820,13 @@ function asAuthoredProfile(raw) {
6987
6820
  ...typeof p.model === "string" ? { model: p.model } : {}
6988
6821
  };
6989
6822
  }
6990
- function supervisorSkill(opts) {
6823
+ function supervisorInstructions(opts) {
6991
6824
  return [
6992
6825
  "You are a SUPERVISOR. You do NOT do the work yourself \u2014 your job is to DESIGN and DRIVE specialist worker agents.",
6993
6826
  "",
6994
6827
  "For the task you are given:",
6995
6828
  "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 spawn_worker with a COMPLETE `profile`:",
6829
+ "2. For EACH sub-task, AUTHOR a worker by calling spawn_agent with a COMPLETE `profile`:",
6997
6830
  " \u2022 name: a short id for the worker.",
6998
6831
  ' \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
6832
  " \u2022 model: the model best suited to this sub-task (omit to use the default).",
@@ -7044,6 +6877,93 @@ function authoredWorker(profile, opts) {
7044
6877
  };
7045
6878
  return { name: profile.name, act: async () => "", executorSpec: spec };
7046
6879
  }
6880
+ var defaultProfileRichnessThresholds = {
6881
+ minSystemPromptChars: 600,
6882
+ minSystemPromptLines: 6
6883
+ };
6884
+ function resolveSystemPrompt(profile) {
6885
+ const pr = profile.prompt;
6886
+ if (typeof pr === "string") return pr;
6887
+ if (pr && typeof pr === "object") {
6888
+ const o = pr;
6889
+ if (typeof o.systemPrompt === "string") return o.systemPrompt;
6890
+ if (typeof o.system === "string") return o.system;
6891
+ }
6892
+ return "";
6893
+ }
6894
+ function assessAuthoredProfile(profile, opts) {
6895
+ const th = { ...defaultProfileRichnessThresholds, ...opts?.thresholds ?? {} };
6896
+ const systemPrompt = resolveSystemPrompt(profile);
6897
+ const trimmed = systemPrompt.trim();
6898
+ const systemPromptChars = trimmed.length;
6899
+ const systemPromptLines = trimmed ? trimmed.split("\n").filter((l) => l.trim().length > 0).length : 0;
6900
+ const sentenceCount = trimmed ? (trimmed.match(/[.!?](\s|$)/g) ?? []).length || (trimmed ? 1 : 0) : 0;
6901
+ const hasDescription = typeof profile.description === "string" && profile.description.trim().length > 0;
6902
+ const tools = profile.tools;
6903
+ const hasTools = !!tools && Object.keys(tools).length > 0;
6904
+ const skills = profile.resources?.skills;
6905
+ const hasSkills = Array.isArray(skills) && skills.length > 0;
6906
+ const mcp = profile.mcp;
6907
+ const hasMcp = !!mcp && Object.keys(mcp).length > 0;
6908
+ const subagents = profile.subagents;
6909
+ const hasSubagents = !!subagents && Object.keys(subagents).length > 0;
6910
+ const reasons = [];
6911
+ const promptThin = systemPromptChars < th.minSystemPromptChars || systemPromptLines < th.minSystemPromptLines;
6912
+ if (promptThin)
6913
+ reasons.push(
6914
+ `system prompt is thin (${systemPromptChars} chars, ${systemPromptLines} lines; need \u2265${th.minSystemPromptChars} chars and \u2265${th.minSystemPromptLines} lines)`
6915
+ );
6916
+ if (!hasTools)
6917
+ reasons.push("no tools granted (a worker can only act through the tools you grant it)");
6918
+ if (!hasSkills) reasons.push("no skills attached (no reusable how-to notes injected)");
6919
+ if (opts?.needsMcp && !hasMcp) reasons.push("no MCP server, but the task needs data/tool access");
6920
+ const signals = [!promptThin, hasTools, hasSkills, hasDescription, opts?.needsMcp ? hasMcp : true];
6921
+ const richness = signals.filter(Boolean).length / signals.length;
6922
+ const thin = promptThin || !hasTools && !hasSkills && !hasMcp;
6923
+ return {
6924
+ name: profile.name ?? "worker",
6925
+ systemPrompt,
6926
+ systemPromptChars,
6927
+ systemPromptLines,
6928
+ sentenceCount,
6929
+ hasDescription,
6930
+ hasTools,
6931
+ hasSkills,
6932
+ hasMcp,
6933
+ hasSubagents,
6934
+ richness,
6935
+ thin,
6936
+ reasons
6937
+ };
6938
+ }
6939
+ function profileRichnessFinding(richness, opts) {
6940
+ const analyst_id = opts?.analystId ?? "profile-richness";
6941
+ const subject = richness.name;
6942
+ 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)}%).`;
6943
+ const severity = richness.thin ? richness.richness < 0.25 ? "high" : "medium" : "info";
6944
+ return makeFinding2({
6945
+ analyst_id,
6946
+ severity,
6947
+ area: "profile-quality",
6948
+ claim,
6949
+ subject,
6950
+ confidence: 0.9,
6951
+ evidence_refs: [
6952
+ {
6953
+ kind: "metric",
6954
+ uri: `profile:${subject}`,
6955
+ excerpt: `chars=${richness.systemPromptChars} lines=${richness.systemPromptLines} tools=${richness.hasTools} skills=${richness.hasSkills} mcp=${richness.hasMcp} richness=${richness.richness.toFixed(2)}`
6956
+ }
6957
+ ],
6958
+ ...richness.thin ? { recommended_action: `Re-author "${richness.name}" with: ${richness.reasons.join("; ")}.` } : {},
6959
+ id_basis: computeFindingId({
6960
+ analyst_id,
6961
+ area: "profile-quality",
6962
+ subject,
6963
+ claim: `richness:${richness.thin ? "thin" : "rich"}`
6964
+ })
6965
+ });
6966
+ }
7047
6967
 
7048
6968
  // src/runtime/supervise/event-bus.ts
7049
6969
  function createEventBus(now = Date.now) {
@@ -7102,7 +7022,19 @@ function createEventBus(now = Date.now) {
7102
7022
  }
7103
7023
 
7104
7024
  // src/mcp/tools/coordination.ts
7105
- var idArg = { type: "string", description: "The workerId returned by spawn_worker." };
7025
+ var coordinationVerbNames = [
7026
+ "spawn_agent",
7027
+ "observe_agent",
7028
+ "steer_agent",
7029
+ "await_event",
7030
+ "list_questions",
7031
+ "answer_question",
7032
+ "ask_parent",
7033
+ "stop",
7034
+ "list_analysts",
7035
+ "run_analyst"
7036
+ ];
7037
+ var idArg = { type: "string", description: "The workerId returned by spawn_agent." };
7106
7038
  function createCoordinationTools(opts) {
7107
7039
  let stopped = false;
7108
7040
  let reason;
@@ -7126,6 +7058,28 @@ function createCoordinationTools(opts) {
7126
7058
  throw new Error("coordination tools: arguments must be an object");
7127
7059
  return raw;
7128
7060
  };
7061
+ const mergeBudget = (base, raw) => {
7062
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
7063
+ throw new Error('coordination tools: "budget" must be an object');
7064
+ const o = raw;
7065
+ const field = (name) => {
7066
+ const v = o[name];
7067
+ if (v === void 0) return void 0;
7068
+ if (typeof v !== "number" || !Number.isFinite(v))
7069
+ throw new Error(`coordination tools: "budget.${name}" must be a finite number`);
7070
+ return v;
7071
+ };
7072
+ const maxIterations = field("maxIterations");
7073
+ const maxTokens = field("maxTokens");
7074
+ const maxUsd = field("maxUsd");
7075
+ const deadlineMs = field("deadlineMs");
7076
+ return {
7077
+ maxIterations: maxIterations ?? base.maxIterations,
7078
+ maxTokens: maxTokens ?? base.maxTokens,
7079
+ ...(maxUsd ?? base.maxUsd) === void 0 ? {} : { maxUsd: maxUsd ?? base.maxUsd },
7080
+ ...(deadlineMs ?? base.deadlineMs) === void 0 ? {} : { deadlineMs: deadlineMs ?? base.deadlineMs }
7081
+ };
7082
+ };
7129
7083
  const level = (v) => {
7130
7084
  if (v === "worker" || v === "driver" || v === "loop") return v;
7131
7085
  throw new Error('coordination tools: "level" must be worker, driver, or loop');
@@ -7244,29 +7198,40 @@ function createCoordinationTools(opts) {
7244
7198
  };
7245
7199
  const tools = [
7246
7200
  {
7247
- name: "spawn_worker",
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.",
7201
+ name: "spawn_agent",
7202
+ 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
7203
  inputSchema: {
7250
7204
  type: "object",
7251
7205
  properties: {
7252
7206
  profile: { description: "The worker/driver profile to run." },
7253
7207
  task: { description: "The task the worker should perform." },
7254
- label: { type: "string", description: "Optional trace label." }
7208
+ label: { type: "string", description: "Optional trace label." },
7209
+ budget: {
7210
+ type: "object",
7211
+ 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.",
7212
+ properties: {
7213
+ maxIterations: { type: "number" },
7214
+ maxTokens: { type: "number" },
7215
+ maxUsd: { type: "number" },
7216
+ deadlineMs: { type: "number" }
7217
+ }
7218
+ }
7255
7219
  },
7256
7220
  required: ["profile", "task"]
7257
7221
  },
7258
7222
  handler: (raw) => {
7259
7223
  const a = obj2(raw);
7260
7224
  const agent = opts.makeWorkerAgent(a.profile);
7225
+ const budget = a.budget === void 0 ? opts.perWorker : mergeBudget(opts.perWorker, a.budget);
7261
7226
  const res = opts.scope.spawn(agent, a.task, {
7262
- budget: opts.perWorker,
7227
+ budget,
7263
7228
  label: typeof a.label === "string" ? a.label : "worker"
7264
7229
  });
7265
7230
  return Promise.resolve(res.ok ? { workerId: res.handle.id } : { error: res.reason });
7266
7231
  }
7267
7232
  },
7268
7233
  {
7269
- name: "observe_worker",
7234
+ name: "observe_agent",
7270
7235
  description: "Inspect a worker status, spend, and settled output artifact when available.",
7271
7236
  inputSchema: { type: "object", properties: { workerId: idArg }, required: ["workerId"] },
7272
7237
  handler: async (raw) => {
@@ -7283,7 +7248,7 @@ function createCoordinationTools(opts) {
7283
7248
  }
7284
7249
  },
7285
7250
  {
7286
- name: "steer_worker",
7251
+ name: "steer_agent",
7287
7252
  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
7253
  inputSchema: {
7289
7254
  type: "object",
@@ -7504,13 +7469,26 @@ function deadlinePassed(scope, now) {
7504
7469
  const b = scope.budget;
7505
7470
  return b.deadlineMs > 0 && now() >= b.deadlineMs;
7506
7471
  }
7507
- function coordinationDriverAgent(opts) {
7508
- if (typeof opts.chat?.next !== "function") {
7509
- throw new ValidationError("coordinationDriverAgent: opts.chat.next must be a function");
7472
+ function driverAgent(opts) {
7473
+ if (typeof opts.brain !== "function") {
7474
+ throw new ValidationError("driverAgent: opts.brain must be a function");
7475
+ }
7476
+ if ((opts.extraTools?.length ?? 0) > 0 && typeof opts.executeExtraTool !== "function") {
7477
+ throw new ValidationError(
7478
+ "driverAgent: extraTools requires executeExtraTool (how to run a work-tool call)"
7479
+ );
7480
+ }
7481
+ const reserved = new Set(coordinationVerbNames);
7482
+ for (const t of opts.extraTools ?? []) {
7483
+ if (reserved.has(t.name)) {
7484
+ throw new ValidationError(
7485
+ `driverAgent: extra work tool "${t.name}" collides with a coordination verb`
7486
+ );
7487
+ }
7510
7488
  }
7511
7489
  if (opts.maxTurns !== void 0 && opts.maxTurns < 0) {
7512
7490
  throw new ValidationError(
7513
- "coordinationDriverAgent: maxTurns must be >= 0 (0 lifts the turn cap; bounds become the conserved pool + deadline + abort)"
7491
+ "driverAgent: maxTurns must be >= 0 (0 lifts the turn cap; bounds become the conserved pool + deadline + abort)"
7514
7492
  );
7515
7493
  }
7516
7494
  const maxTurns = opts.maxTurns === 0 ? runawayTripwireTurns : opts.maxTurns ?? 16;
@@ -7525,24 +7503,23 @@ function coordinationDriverAgent(opts) {
7525
7503
  perWorker: opts.perWorker
7526
7504
  });
7527
7505
  const byName = new Map(coord.tools.map((t) => [t.name, t]));
7528
- const toolSpecs = coord.tools.map((t) => ({
7529
- name: t.name,
7530
- description: t.description,
7531
- parameters: t.inputSchema
7532
- }));
7506
+ const toolSpecs = [
7507
+ ...coord.tools.map((t) => ({
7508
+ type: "function",
7509
+ function: { name: t.name, description: t.description, parameters: t.inputSchema }
7510
+ })),
7511
+ // Work tools the driver calls DIRECTLY — so it can ACT, not only delegate.
7512
+ ...(opts.extraTools ?? []).map((t) => ({
7513
+ type: "function",
7514
+ function: { name: t.name, description: t.description, parameters: t.parameters }
7515
+ }))
7516
+ ];
7533
7517
  const system = typeof opts.systemPrompt === "function" ? opts.systemPrompt(task) : opts.systemPrompt;
7534
- const messages = [{ role: "user", content: stringifyTask(task) }];
7535
- for (let turn = 0; turn < maxTurns; turn += 1) {
7536
- if (coord.isStopped() || scope.signal.aborted) break;
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 ?? [];
7518
+ let turn = 0;
7519
+ const chat = async (messages, tools) => {
7520
+ const res = await opts.brain(messages, tools);
7540
7521
  if (res.usage || res.costUsd !== void 0) {
7541
7522
  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
7523
  iterations: 0,
7547
7524
  tokens: { input: res.usage?.input ?? 0, output: res.usage?.output ?? 0 },
7548
7525
  usd: res.costUsd ?? 0,
@@ -7552,28 +7529,47 @@ function coordinationDriverAgent(opts) {
7552
7529
  kind: "driver-inference",
7553
7530
  driver: opts.name,
7554
7531
  turn,
7555
- toolCalls: calls.map((c) => c.name)
7532
+ toolCalls: (res.toolCalls ?? []).map((c) => c.name)
7556
7533
  });
7557
7534
  }
7558
- if (calls.length === 0) {
7559
- return finalize2(coord, opts.blobs);
7560
- }
7561
- messages.push({ role: "assistant", content: res.content ?? "", toolCalls: calls });
7562
- for (const tc of calls) {
7563
- const tool = byName.get(tc.name);
7564
- const result = tool ? await runTool(tool, tc.arguments) : { error: `unknown tool: ${tc.name}` };
7565
- messages.push({
7566
- role: "tool",
7567
- ...tc.id ? { toolCallId: tc.id } : {},
7568
- name: tc.name,
7569
- content: safeJson(result)
7570
- });
7535
+ turn += 1;
7536
+ return res;
7537
+ };
7538
+ await runBrainLoop({
7539
+ chat,
7540
+ tools: toolSpecs,
7541
+ execute: async (name, args) => {
7542
+ if (opts.executeExtraTool) {
7543
+ const worked = await runExtraTool(opts.executeExtraTool, name, args);
7544
+ if (worked !== null && worked !== void 0) return worked;
7545
+ }
7546
+ const tool = byName.get(name);
7547
+ const result = tool ? await runTool(tool, args) : { error: `unknown tool: ${name}` };
7548
+ return safeJson(result);
7549
+ },
7550
+ initialMessages: [
7551
+ { role: "system", content: system },
7552
+ { role: "user", content: stringifyTask(task) }
7553
+ ],
7554
+ maxTurns,
7555
+ // The conserved-pool + deadline + external-stop bound (what maxTurns=0 relies on): a driver
7556
+ // that can no longer spawn (pool starved) or has run past the deadline stops here instead of
7557
+ // burning turns. Checked before each inference turn.
7558
+ hooks: {
7559
+ stopBefore: () => coord.isStopped() || scope.signal.aborted || poolStarved(scope, opts.perWorker) || deadlinePassed(scope, now)
7571
7560
  }
7572
- }
7561
+ });
7573
7562
  return finalize2(coord, opts.blobs);
7574
7563
  }
7575
7564
  };
7576
7565
  }
7566
+ async function runExtraTool(execute, name, args) {
7567
+ try {
7568
+ return await execute(name, args);
7569
+ } catch (e) {
7570
+ return `error: ${e instanceof Error ? e.message : String(e)}`;
7571
+ }
7572
+ }
7577
7573
  async function runTool(tool, args) {
7578
7574
  try {
7579
7575
  return await tool.handler(args);
@@ -7581,13 +7577,16 @@ async function runTool(tool, args) {
7581
7577
  return { error: e instanceof Error ? e.message : String(e) };
7582
7578
  }
7583
7579
  }
7584
- async function finalize2(coord, blobs) {
7585
- const delivered = coord.settled().filter((w) => w.status === "done" && w.valid === true);
7580
+ async function finalizeBestDelivered(settled, blobs) {
7581
+ const delivered = settled.filter((w) => w.status === "done" && w.valid === true);
7586
7582
  if (delivered.length === 0) return void 0;
7587
7583
  let best = delivered[0];
7588
7584
  for (const w of delivered) if ((w.score ?? 0) > (best.score ?? 0)) best = w;
7589
7585
  return best.outRef ? await blobs.get(best.outRef) : void 0;
7590
7586
  }
7587
+ async function finalize2(coord, blobs) {
7588
+ return finalizeBestDelivered(coord.settled(), blobs);
7589
+ }
7591
7590
  function stringifyTask(task) {
7592
7591
  return typeof task === "string" ? task : safeJson(task);
7593
7592
  }
@@ -8549,7 +8548,7 @@ function createDetachedTurnTrace(options) {
8549
8548
  function detachedRunningPhase(elapsedMs) {
8550
8549
  return elapsedMs === void 0 ? "detached-running" : `detached-running ${Math.round(elapsedMs / 1e3)}s`;
8551
8550
  }
8552
- function createDriveTurnResumeDriver(options) {
8551
+ function createDetachedTurnResumeDriver(options) {
8553
8552
  const cancelHooked = /* @__PURE__ */ new Set();
8554
8553
  return {
8555
8554
  intervalMs: options.intervalMs ?? DEFAULT_TICK_INTERVAL_MS,
@@ -9811,6 +9810,16 @@ function watchTrace(source, opts = {}) {
9811
9810
  });
9812
9811
  }
9813
9812
 
9813
+ // src/runtime/supervise/model-policy.ts
9814
+ function assertModelAllowed(model, allowed) {
9815
+ if (!allowed || model === void 0) return;
9816
+ if (!allowed.includes(model)) {
9817
+ throw new ConfigError(
9818
+ `model ${JSON.stringify(model)} is not in the allowed set ${JSON.stringify([...allowed])}`
9819
+ );
9820
+ }
9821
+ }
9822
+
9814
9823
  // src/runtime/supervise/patch-checks.ts
9815
9824
  var DEFAULT_MAX_DIFF_LINES = 400;
9816
9825
  var secretPathPattern = /(^|\/)(\.env(\.|$)|.*\.(pem|key|p12|pfx|keystore|wallet)|id_rsa|id_ed25519|secrets?\.json|credentials?\.json)$/i;
@@ -9835,12 +9844,6 @@ function countDiffLines(patch) {
9835
9844
  }
9836
9845
  return count;
9837
9846
  }
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
9847
  function runCoderChecks(input, constraints = {}) {
9845
9848
  const maxDiff = constraints.maxDiffLines ?? DEFAULT_MAX_DIFF_LINES;
9846
9849
  const forbidden = constraints.forbiddenPaths ?? [];
@@ -9927,72 +9930,132 @@ function signalPass(value, required) {
9927
9930
  return !required;
9928
9931
  }
9929
9932
 
9930
- // src/runtime/supervise/router-driver-chat.ts
9931
- function routerDriverChat(c, opts = {}) {
9932
- const temperature = opts.temperature ?? 0.4;
9933
+ // src/runtime/supervise/run-context.ts
9934
+ function createInMemoryRunContext(opts = {}) {
9935
+ const base = createExecutorRegistry();
9933
9936
  return {
9934
- next: async ({ system, messages, tools }) => {
9935
- const oa = [
9936
- { role: "system", content: system },
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
- }
9937
+ journal: new InMemorySpawnJournal(),
9938
+ blobs: new InMemoryResultBlobStore(),
9939
+ executors: opts.withDriver ? withDriverExecutor(base) : base
9957
9940
  };
9958
9941
  }
9959
- function toOpenAI(m) {
9960
- if (m.role === "assistant" && m.toolCalls?.length) {
9961
- return {
9962
- role: "assistant",
9963
- content: m.content ?? "",
9964
- tool_calls: m.toolCalls.map((tc) => ({
9965
- id: tc.id ?? tc.name,
9966
- type: "function",
9967
- function: { name: tc.name, arguments: JSON.stringify(tc.arguments) }
9968
- }))
9969
- };
9942
+
9943
+ // src/runtime/supervise/supervisor-agent.ts
9944
+ function supervisorAgent(profile, deps) {
9945
+ const name = profile.name ?? "supervisor";
9946
+ const systemPrompt = profile.systemPrompt ?? "";
9947
+ const harness = profile.harness ?? null;
9948
+ if (harness === null) {
9949
+ const brain = deps.brain ?? routerBrainFromProfile(profile, deps);
9950
+ return driverAgent({
9951
+ name,
9952
+ brain,
9953
+ blobs: deps.blobs,
9954
+ makeWorkerAgent: deps.makeWorkerAgent,
9955
+ perWorker: deps.perWorker,
9956
+ systemPrompt,
9957
+ ...deps.extraTools ? { extraTools: deps.extraTools } : {},
9958
+ ...deps.executeExtraTool ? { executeExtraTool: deps.executeExtraTool } : {},
9959
+ ...deps.maxTurns !== void 0 ? { maxTurns: deps.maxTurns } : {}
9960
+ });
9970
9961
  }
9971
- if (m.role === "tool") {
9972
- return { role: "tool", tool_call_id: m.toolCallId ?? m.name ?? "call", content: m.content };
9962
+ const driveHarness = deps.driveHarness;
9963
+ if (!driveHarness) {
9964
+ throw new ValidationError(
9965
+ `supervisorAgent: profile.harness="${harness}" needs deps.driveHarness (how to run the harness with the coordination MCP mounted)`
9966
+ );
9973
9967
  }
9974
- return { role: m.role, content: m.content };
9968
+ return {
9969
+ name,
9970
+ async act(task, scope) {
9971
+ const mcp = await serveCoordinationMcp({
9972
+ scope,
9973
+ blobs: deps.blobs,
9974
+ makeWorkerAgent: deps.makeWorkerAgent,
9975
+ perWorker: deps.perWorker
9976
+ });
9977
+ try {
9978
+ await driveHarness({ profile, task, scope, coordinationMcpUrl: mcp.url });
9979
+ return await finalizeBestDelivered(mcp.settled(), deps.blobs);
9980
+ } finally {
9981
+ await mcp.close();
9982
+ }
9983
+ }
9984
+ };
9975
9985
  }
9976
- function safeParse(s) {
9977
- try {
9978
- return JSON.parse(s);
9979
- } catch {
9980
- return {};
9986
+ function routerBrainFromProfile(profile, deps) {
9987
+ if (!deps.router) {
9988
+ throw new ValidationError(
9989
+ "supervisorAgent: a router-brained supervisor (harness null) needs deps.router (or deps.brain)"
9990
+ );
9981
9991
  }
9992
+ return routerBrain({ ...deps.router, model: profile.model ?? deps.router.model });
9982
9993
  }
9983
9994
 
9984
- // src/runtime/supervise/run-context.ts
9985
- function createInMemoryRunContext(opts = {}) {
9986
- const base = createExecutorRegistry();
9995
+ // src/runtime/supervise/supervise.ts
9996
+ function workerFromBackend(backend, deliverable) {
9997
+ return (rawProfile) => {
9998
+ const p = rawProfile ?? {};
9999
+ const name = typeof p.name === "string" && p.name.length > 0 ? p.name : "worker";
10000
+ const spec = { profile: rawProfile, harness: null };
10001
+ const ctx = { signal: new AbortController().signal, seams: {} };
10002
+ const built = createExecutor(backend)(spec, ctx);
10003
+ const executor = deliverable ? gateOnDeliverable(built, deliverable) : built;
10004
+ return { name, act: async () => "", executorSpec: { ...spec, executor } };
10005
+ };
10006
+ }
10007
+ function defaultPerWorker(budget) {
9987
10008
  return {
9988
- journal: new InMemorySpawnJournal(),
9989
- blobs: new InMemoryResultBlobStore(),
9990
- executors: opts.withDriver ? withDriverExecutor(base) : base
10009
+ maxIterations: budget.maxIterations,
10010
+ maxTokens: Math.max(1, Math.floor(budget.maxTokens / 4))
9991
10011
  };
9992
10012
  }
10013
+ function supervise(profile, task, opts) {
10014
+ const backendModel = opts.backend?.model;
10015
+ assertModelAllowed(opts.router?.model, opts.allowedModels);
10016
+ assertModelAllowed(profile.model, opts.allowedModels);
10017
+ assertModelAllowed(
10018
+ typeof backendModel === "string" ? backendModel : void 0,
10019
+ opts.allowedModels
10020
+ );
10021
+ const ctx = createInMemoryRunContext({ withDriver: true });
10022
+ const blobs = opts.blobs ?? ctx.blobs;
10023
+ const perWorker = opts.perWorker ?? defaultPerWorker(opts.budget);
10024
+ let makeWorkerAgent = opts.makeWorkerAgent;
10025
+ if (!makeWorkerAgent) {
10026
+ if (!opts.backend) {
10027
+ throw new ValidationError(
10028
+ "supervise: provide opts.backend (where workers run) or opts.makeWorkerAgent"
10029
+ );
10030
+ }
10031
+ makeWorkerAgent = workerFromBackend(opts.backend, opts.deliverable);
10032
+ }
10033
+ const agent = supervisorAgent(profile, {
10034
+ blobs,
10035
+ makeWorkerAgent,
10036
+ perWorker,
10037
+ ...opts.router ? { router: opts.router } : {},
10038
+ ...opts.brain ? { brain: opts.brain } : {},
10039
+ ...opts.driveHarness ? { driveHarness: opts.driveHarness } : {},
10040
+ ...opts.extraTools ? { extraTools: opts.extraTools } : {},
10041
+ ...opts.executeExtraTool ? { executeExtraTool: opts.executeExtraTool } : {},
10042
+ ...opts.maxTurns !== void 0 ? { maxTurns: opts.maxTurns } : {}
10043
+ });
10044
+ return createSupervisor().run(agent, task, {
10045
+ budget: opts.budget,
10046
+ runId: opts.runId ?? "supervise",
10047
+ journal: ctx.journal,
10048
+ blobs,
10049
+ executors: ctx.executors,
10050
+ maxDepth: opts.maxDepth ?? 8,
10051
+ ...opts.now ? { now: opts.now } : {}
10052
+ });
10053
+ }
9993
10054
 
9994
10055
  // src/runtime/supervise/trace-source.ts
9995
10056
  function toToolSpan(input, runId, seq, at) {
10057
+ const startedAt = typeof input.startedAt === "number" ? input.startedAt : at;
10058
+ const endedAt = typeof input.endedAt === "number" ? input.endedAt : startedAt;
9996
10059
  return {
9997
10060
  spanId: `${runId}-t${seq}`,
9998
10061
  runId,
@@ -10001,8 +10064,8 @@ function toToolSpan(input, runId, seq, at) {
10001
10064
  toolName: input.toolName,
10002
10065
  args: input.args,
10003
10066
  status: input.status ?? "ok",
10004
- startedAt: at,
10005
- endedAt: at,
10067
+ startedAt,
10068
+ endedAt,
10006
10069
  ...input.result !== void 0 ? { result: input.result } : {}
10007
10070
  };
10008
10071
  }
@@ -10042,7 +10105,7 @@ var decodeOpenAiPart = (p) => {
10042
10105
  const rawArgs = fn?.arguments ?? p.arguments;
10043
10106
  return {
10044
10107
  toolName: name,
10045
- args: typeof rawArgs === "string" ? safeParse2(rawArgs) : rawArgs ?? {},
10108
+ args: typeof rawArgs === "string" ? safeParse(rawArgs) : rawArgs ?? {},
10046
10109
  ...str(p.id) ? { callId: p.id } : str(fn?.id) ? { callId: fn?.id } : {}
10047
10110
  };
10048
10111
  };
@@ -10066,7 +10129,7 @@ function decodeToolPart(part, harness) {
10066
10129
  }
10067
10130
  return void 0;
10068
10131
  }
10069
- function safeParse2(s) {
10132
+ function safeParse(s) {
10070
10133
  try {
10071
10134
  return JSON.parse(s);
10072
10135
  } catch {
@@ -10512,13 +10575,11 @@ function tail(s) {
10512
10575
  }
10513
10576
 
10514
10577
  export {
10578
+ runLocalHarness,
10579
+ assertModelAllowed,
10515
10580
  contentAddress,
10516
10581
  InMemoryResultBlobStore,
10517
- FileResultBlobStore,
10518
10582
  InMemorySpawnJournal,
10519
- FileSpawnJournal,
10520
- replaySpawnTree,
10521
- materializeTreeView,
10522
10583
  anytimeReport,
10523
10584
  renderAnytimeTable,
10524
10585
  defaultAuditorInstruction,
@@ -10541,7 +10602,6 @@ export {
10541
10602
  probeSandboxCapabilities,
10542
10603
  createSandboxLineage,
10543
10604
  runLoop,
10544
- describeSandboxPlacement,
10545
10605
  createSandboxForSpec,
10546
10606
  defaultSelectWinner,
10547
10607
  loopDispatch,
@@ -10550,7 +10610,6 @@ export {
10550
10610
  createScopeAnalyst,
10551
10611
  registryScopeAnalyst,
10552
10612
  buildSteerContext,
10553
- nestedScopeSeamKey,
10554
10613
  createScope,
10555
10614
  settledToIteration,
10556
10615
  selectValidWinner,
@@ -10564,14 +10623,10 @@ export {
10564
10623
  InMemoryCorpus,
10565
10624
  FileCorpus,
10566
10625
  renderCorpusToInstructions,
10567
- driverRuntime,
10568
- driverChild,
10569
- isDriverSpec,
10570
- driverExecutorFactory,
10571
- withDriverExecutor,
10572
10626
  routerChatWithUsage,
10573
10627
  routerChatWithTools,
10574
10628
  routerToolLoop,
10629
+ routerBrain,
10575
10630
  createInbox,
10576
10631
  createWorktree,
10577
10632
  captureWorktreeDiff,
@@ -10584,7 +10639,6 @@ export {
10584
10639
  spendFromUsageEvents,
10585
10640
  createBudgetPool,
10586
10641
  createSupervisor,
10587
- createRootHandle,
10588
10642
  createShapeRegistry,
10589
10643
  builtinShapes,
10590
10644
  registerShape,
@@ -10593,8 +10647,8 @@ export {
10593
10647
  trajectoryReport,
10594
10648
  equalKOnCost,
10595
10649
  promotionGate,
10596
- depthDriver,
10597
- breadthDriver,
10650
+ depthStrategy,
10651
+ breadthStrategy,
10598
10652
  sample,
10599
10653
  refine,
10600
10654
  defineStrategy,
@@ -10613,11 +10667,15 @@ export {
10613
10667
  runStrategyEvolution,
10614
10668
  gateOnDeliverable,
10615
10669
  asAuthoredProfile,
10616
- supervisorSkill,
10670
+ supervisorInstructions,
10617
10671
  authoredWorker,
10672
+ defaultProfileRichnessThresholds,
10673
+ assessAuthoredProfile,
10674
+ profileRichnessFinding,
10618
10675
  createEventBus,
10619
10676
  createCoordinationTools,
10620
- coordinationDriverAgent,
10677
+ driverAgent,
10678
+ finalizeBestDelivered,
10621
10679
  InMemoryFeedbackStore,
10622
10680
  eventToSnapshot,
10623
10681
  DelegationStateCorruptError,
@@ -10636,7 +10694,7 @@ export {
10636
10694
  parseDetachedSessionRef,
10637
10695
  detachedTurnEvents,
10638
10696
  runDetachedTurn,
10639
- createDriveTurnResumeDriver,
10697
+ createDetachedTurnResumeDriver,
10640
10698
  DELEGATE_CODE_TOOL_NAME,
10641
10699
  DELEGATE_CODE_DESCRIPTION,
10642
10700
  DELEGATE_CODE_INPUT_SCHEMA,
@@ -10672,22 +10730,14 @@ export {
10672
10730
  serveCoordinationMcp,
10673
10731
  defaultToolDetectors,
10674
10732
  watchTrace,
10675
- touchedPathsFromPatch,
10676
- countDiffLines,
10677
- isNonEmptyPatch,
10678
- touchesSecretPath,
10679
10733
  runCoderChecks,
10680
10734
  patchDelivered,
10681
- routerDriverChat,
10682
10735
  createInMemoryRunContext,
10683
- toToolSpan,
10684
- decodeOpencodePart,
10685
- decodeAnthropicPart,
10686
- decodeOpenAiPart,
10687
- toolPartDecoders,
10736
+ supervisorAgent,
10737
+ workerFromBackend,
10738
+ supervise,
10688
10739
  decodeToolPart,
10689
10740
  createPushTraceSource,
10690
- createPartsTraceSource,
10691
10741
  sandboxSessionTraceSource,
10692
10742
  analyzeTrace,
10693
10743
  worktreeFanout,
@@ -10696,6 +10746,8 @@ export {
10696
10746
  localShell,
10697
10747
  gitWorkspace,
10698
10748
  jjWorkspace,
10699
- runInWorkspace
10749
+ runInWorkspace,
10750
+ computeFindingId2 as computeFindingId,
10751
+ makeFinding3 as makeFinding
10700
10752
  };
10701
- //# sourceMappingURL=chunk-NLRA6434.js.map
10753
+ //# sourceMappingURL=chunk-YFOPWG74.js.map