@tangle-network/agent-runtime 0.261.0 → 0.262.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.
Files changed (54) hide show
  1. package/dist/{activation-BwrMmguq.js → activation-C0AoYRgS.js} +2 -2
  2. package/dist/{activation-BwrMmguq.js.map → activation-C0AoYRgS.js.map} +1 -1
  3. package/dist/{activation-BpJ2CmXx.d.ts → activation-CozZXBTg.d.ts} +2 -2
  4. package/dist/agent.d.ts +2 -2
  5. package/dist/agent.js +2 -2
  6. package/dist/{coordination-driver-LmDxHvAO.js → coordination-driver-COGC8FK2.js} +302 -23
  7. package/dist/coordination-driver-COGC8FK2.js.map +1 -0
  8. package/dist/{delegate-rkhJf5w7.js → delegate-BC7Au73v.js} +2 -2
  9. package/dist/{delegate-rkhJf5w7.js.map → delegate-BC7Au73v.js.map} +1 -1
  10. package/dist/durable.d.ts +2 -2
  11. package/dist/durable.js +2 -2
  12. package/dist/{graph-Bn3wSH8-.js → graph-DgODOGWN.js} +3 -3
  13. package/dist/{graph-Bn3wSH8-.js.map → graph-DgODOGWN.js.map} +1 -1
  14. package/dist/{improvement-cycle-DYiwfjWY.js → improvement-cycle-DirqO-fX.js} +3 -3
  15. package/dist/{improvement-cycle-DYiwfjWY.js.map → improvement-cycle-DirqO-fX.js.map} +1 -1
  16. package/dist/{index-tubViIQJ.d.ts → index-B8tXCisZ.d.ts} +136 -288
  17. package/dist/index.d.ts +6 -6
  18. package/dist/index.js +7 -7
  19. package/dist/intelligence.d.ts +3 -3
  20. package/dist/intelligence.js +3 -3
  21. package/dist/kernel.d.ts +4 -4
  22. package/dist/kernel.js +9 -9
  23. package/dist/{loop-runner-bin-CL4W2pu1.d.ts → loop-runner-bin-BaZd1XIm.d.ts} +3 -3
  24. package/dist/{loop-runner-bin-Dxqxf91b.js → loop-runner-bin-C9P1ELVv.js} +3 -3
  25. package/dist/{loop-runner-bin-Dxqxf91b.js.map → loop-runner-bin-C9P1ELVv.js.map} +1 -1
  26. package/dist/loop-runner-bin.d.ts +1 -1
  27. package/dist/loop-runner-bin.js +1 -1
  28. package/dist/mcp/bin.js +3 -3
  29. package/dist/mcp/index.d.ts +6 -6
  30. package/dist/mcp/index.js +4 -4
  31. package/dist/{openai-tools-BlZHd0Nz.d.ts → openai-tools-CHwN_S24.d.ts} +2 -2
  32. package/dist/profiles.d.ts +2 -2
  33. package/dist/{provision-supervisor-By5oGk3t.js → provision-supervisor-9FMwo-Es.js} +3 -3
  34. package/dist/{provision-supervisor-By5oGk3t.js.map → provision-supervisor-9FMwo-Es.js.map} +1 -1
  35. package/dist/{runtime-BbQmK7qe.js → runtime-BXWVW51r.js} +8 -8
  36. package/dist/{runtime-BbQmK7qe.js.map → runtime-BXWVW51r.js.map} +1 -1
  37. package/dist/{server-CHlpLE22.js → server-6g6KFwUC.js} +3 -3
  38. package/dist/{server-CHlpLE22.js.map → server-6g6KFwUC.js.map} +1 -1
  39. package/dist/{stream-agent-turn-DTgxWXbR.d.ts → stream-agent-turn-u28hoxuR.d.ts} +2 -2
  40. package/dist/{structural-rollout-Dby60zHe.js → structural-rollout-WEfWpjub.js} +2 -2
  41. package/dist/{structural-rollout-Dby60zHe.js.map → structural-rollout-WEfWpjub.js.map} +1 -1
  42. package/dist/{substrate-CxwdhZri.d.ts → substrate-BeQiXkpa.d.ts} +2 -2
  43. package/dist/{supervise-1QzYAyS2.js → supervise-BeAI8-On.js} +221 -48
  44. package/dist/supervise-BeAI8-On.js.map +1 -0
  45. package/dist/{supervisor-yavsoQQo.js → supervisor-BGGvnXvV.js} +161 -17
  46. package/dist/{supervisor-yavsoQQo.js.map → supervisor-BGGvnXvV.js.map} +1 -1
  47. package/dist/testing.d.ts +2 -2
  48. package/dist/testing.js +12 -12
  49. package/dist/tui/index.d.ts +1 -1
  50. package/dist/tui/index.js +1 -1
  51. package/dist/{types-DNCNRu0E.d.ts → types-CP3iQ8Ji.d.ts} +354 -4
  52. package/package.json +2 -2
  53. package/dist/coordination-driver-LmDxHvAO.js.map +0 -1
  54. package/dist/supervise-1QzYAyS2.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { At as workerTraceAnalysisStore, Bi as chargedTokens, Ci as detachedFrozen, Gi as promptCacheTokenClasses, Mt as assertValidBudget, Qt as createPeerMailbox, S as meterRuntimeOwnedProviderAttempt, W as resolveSpawnResourcePaths, Zi as unmeteredSpend, Zn as resolveRedactor, _t as FileResultBlobStore, a as pickBestDelivered, bt as InMemorySpawnJournal, di as providerAttemptEvidence, dt as createExecutorRegistry, ea as addResourceSpend, ei as prepareJsonlAppend, g as withDriverExecutor, kt as parseWorkerToolTraceArtifact, na as withBudgetResources, ni as writeAllBytes, nn as isLiveNodeStatus, o as runFinalizer, qt as createInbox, r as bestDelivered, rn as isTerminalNodeStatus, rt as freeSlots, s as runTree, ti as readCommittedJsonLines, tt as errMessage, vt as FileSpawnJournal, wn as runBrainLoop, yt as InMemoryResultBlobStore, z as scopeRetainedOwnerResourceReader } from "./supervisor-yavsoQQo.js";
1
+ import { Ct as InMemorySpawnJournal, Dn as runBrainLoop, Ei as detachedFrozen, Ft as assertValidBudget, H as scopeRetainedOwnerResourceReader, Ji as promptCacheTokenClasses, Mt as parseWorkerToolTraceArtifact, Nt as workerTraceAnalysisStore, St as InMemoryResultBlobStore, Ui as chargedTokens, Xt as createInbox, a as pickBestDelivered, aa as withBudgetResources, ai as writeAllBytes, an as isLiveNodeStatus, bt as FileResultBlobStore, ea as unmeteredSpend, er as resolveRedactor, ii as readCommittedJsonLines, it as errMessage, mi as providerAttemptEvidence, mt as createExecutorRegistry, o as runFinalizer, on as isTerminalNodeStatus, ot as freeSlots, q as resolveSpawnResourcePaths, r as bestDelivered, ra as addResourceSpend, ri as prepareJsonlAppend, s as runTree, tn as createPeerMailbox, v as withDriverExecutor, w as meterRuntimeOwnedProviderAttempt, xt as FileSpawnJournal } from "./supervisor-BGGvnXvV.js";
2
2
  import { f as RuntimeRunStateError, m as ValidationError } from "./errors-DodWX-cb.js";
3
3
  import { A as writeWorkerCancellation, M as writeWorkerSteerAcknowledgement, b as workerCancellationsDir, c as readWorkerCancelRequests, d as readWorkerSteerRequests, k as writeRunCancellation, l as readWorkerCancellation, o as readRunCancelRequest, r as claimWorkerSteerDelivery, s as readRunCancellation, u as readWorkerSteerAcknowledgement } from "./run-layout-vwd4SwX_.js";
4
4
  import { agentProfileSchema, canonicalCandidateDigest } from "@tangle-network/agent-interface";
@@ -74,6 +74,12 @@ function createEventBus(now = Date.now) {
74
74
  }
75
75
  return best;
76
76
  };
77
+ const pullRecord = (kinds) => {
78
+ const i = bestIndex(kinds);
79
+ if (i < 0) return void 0;
80
+ pulled++;
81
+ return queue.splice(i, 1)[0];
82
+ };
77
83
  return {
78
84
  async publish(event, opts) {
79
85
  const record = staged.get(event) ?? {
@@ -92,10 +98,11 @@ function createEventBus(now = Date.now) {
92
98
  return record;
93
99
  },
94
100
  pull(kinds) {
95
- const i = bestIndex(kinds);
96
- if (i < 0) return void 0;
97
- pulled++;
98
- return queue.splice(i, 1)[0]?.event;
101
+ return pullRecord(kinds)?.event;
102
+ },
103
+ pullRecord,
104
+ queued(kinds) {
105
+ return queue.filter((r) => matches(r, kinds));
99
106
  },
100
107
  subscribe(handler) {
101
108
  subscribers.push(handler);
@@ -498,7 +505,8 @@ const journalEventKinds = [
498
505
  "delivery-attempt",
499
506
  "mail",
500
507
  "escalation",
501
- "analyst-defined"
508
+ "analyst-defined",
509
+ "acknowledgement"
502
510
  ];
503
511
  /** The reserved coordination verb names — the complete set `createCoordinationTools` can emit
504
512
  * (the analyst pair is conditional but still reserved). A driver's extra WORK tools must not
@@ -522,6 +530,7 @@ const coordinationVerbNames = [
522
530
  "ask_parent",
523
531
  "submit_result",
524
532
  "stop",
533
+ "report_blocked",
525
534
  "read_journal",
526
535
  "list_analysts",
527
536
  "run_analyst",
@@ -798,6 +807,7 @@ function createCoordinationToolsForManager(opts, lifetime) {
798
807
  let stopNotified = false;
799
808
  let submitted = priorSubmission === void 0 ? void 0 : detachedFrozen({ result: priorSubmission.event.result });
800
809
  let submissionInFlight;
810
+ let blockedEvidence;
801
811
  let questionSeq = 0;
802
812
  const ledger = [];
803
813
  const questions = [...opts.priorQuestions ?? []];
@@ -884,6 +894,27 @@ function createCoordinationToolsForManager(opts, lifetime) {
884
894
  });
885
895
  return readyInFlight;
886
896
  };
897
+ const deliveries = [];
898
+ let driverAttempt;
899
+ let journalReadTo = 0;
900
+ let lastRejection;
901
+ const flushedAnalystRuns = /* @__PURE__ */ new Set();
902
+ const eventWorker = (event) => event.type === "settled" ? event.worker.id : event.type === "finding" ? event.finding.fromWorker : event.type === "question" ? event.question.from : void 0;
903
+ const acknowledge = async (targets, by) => {
904
+ const fresh = targets.filter((delivery) => !delivery.acknowledged);
905
+ if (fresh.length === 0) return [];
906
+ const seqs = fresh.map((delivery) => delivery.record.seq);
907
+ await bus.publish({
908
+ type: "acknowledgement",
909
+ acknowledgement: detachedFrozen({
910
+ seqs,
911
+ by,
912
+ ...driverAttempt === void 0 ? {} : { attempt: driverAttempt }
913
+ })
914
+ }, { queue: false });
915
+ for (const delivery of fresh) delivery.acknowledged = true;
916
+ return seqs;
917
+ };
887
918
  const urgencyPriority = (u) => u === "blocks-run" ? 20 : u === "blocks-step" ? 10 : 0;
888
919
  const str = (v, field) => {
889
920
  if (typeof v !== "string" || v.length === 0) throw new Error(`coordination tools: "${field}" must be a non-empty string`);
@@ -1146,6 +1177,7 @@ function createCoordinationToolsForManager(opts, lifetime) {
1146
1177
  await bus.publish(pending.event);
1147
1178
  if (pending.analystRun) {
1148
1179
  analystRuns.delete(pending.worker.id);
1180
+ flushedAnalystRuns.add(pending.worker.id);
1149
1181
  unwatchWorker(pending.worker.id);
1150
1182
  pendingSettlement = void 0;
1151
1183
  const { route } = pending.analystRun;
@@ -1397,6 +1429,10 @@ function createCoordinationToolsForManager(opts, lifetime) {
1397
1429
  type: "analyst-defined",
1398
1430
  ...ev.analyst
1399
1431
  };
1432
+ if (ev.type === "acknowledgement") return {
1433
+ type: "acknowledgement",
1434
+ ...ev.acknowledgement
1435
+ };
1400
1436
  return {
1401
1437
  type: ev.type,
1402
1438
  ...ev.down
@@ -1607,9 +1643,11 @@ function createCoordinationToolsForManager(opts, lifetime) {
1607
1643
  usedBytes += bytes;
1608
1644
  }
1609
1645
  const last = entries[entries.length - 1];
1646
+ const nextRow = last === void 0 ? sinceRow : last.row + 1;
1647
+ journalReadTo = Math.max(journalReadTo, nextRow);
1610
1648
  return {
1611
1649
  entries,
1612
- nextRow: last === void 0 ? sinceRow : last.row + 1,
1650
+ nextRow,
1613
1651
  remaining: matching.length - index,
1614
1652
  truncated: bounded,
1615
1653
  bounds: {
@@ -1701,6 +1739,39 @@ function createCoordinationToolsForManager(opts, lifetime) {
1701
1739
  ...resumed ? { resumed: true } : {}
1702
1740
  });
1703
1741
  const liveSnapshot = () => opts.scope.view.nodes.filter((n) => isLiveNodeStatus(n.status)).map((n) => projectNodeEvidence(n));
1742
+ const openWork = () => {
1743
+ const received = new Set(ledger.map((worker) => worker.id));
1744
+ const nodes = opts.scope.view?.nodes ?? [];
1745
+ return {
1746
+ running: nodes.filter((node) => isLiveNodeStatus(node.status) && node.status !== "waiting"),
1747
+ unqueued: nodes.filter((node) => !isLiveNodeStatus(node.status) && !received.has(node.id) && !flushedAnalystRuns.has(node.id)),
1748
+ queued: bus.queued(["settled", "finding"])
1749
+ };
1750
+ };
1751
+ const openWorkRefusal = (verb) => {
1752
+ const { running, unqueued, queued } = openWork();
1753
+ if (running.length === 0 && unqueued.length === 0 && queued.length === 0) return void 0;
1754
+ const parts = [];
1755
+ if (running.length > 0) parts.push(`${running.length} worker${running.length === 1 ? " is" : "s are"} still running (${running.map((node) => node.id).join(", ")})`);
1756
+ const waiting = unqueued.length + queued.length;
1757
+ if (waiting > 0) parts.push(`${waiting} event${waiting === 1 ? " is" : "s are"} waiting for you in await_event`);
1758
+ return {
1759
+ error: "open-work",
1760
+ reason: `${parts.join(" and ")}. Call await_event until it returns idle, read each settled worker's output, and then call ${verb} again. Nothing was ${verb === "stop" ? "stopped" : "checked"}.`,
1761
+ running: running.map((node) => ({
1762
+ id: node.id,
1763
+ label: node.label,
1764
+ status: node.status
1765
+ })),
1766
+ waiting: [...queued.map((record) => ({
1767
+ type: record.event.type,
1768
+ ...eventWorker(record.event) === void 0 ? {} : { worker: eventWorker(record.event) }
1769
+ })), ...unqueued.map((node) => ({
1770
+ type: "settled",
1771
+ worker: node.id
1772
+ }))]
1773
+ };
1774
+ };
1704
1775
  const freeWorkerSlots = () => usesTreeWideLimit() ? sharedWorkerCapacity()?.freeSlots ?? null : freeSlots(localLiveWorkerCount(), maxLiveWorkers);
1705
1776
  const readProgress = (id) => {
1706
1777
  const scope = opts.scope;
@@ -2110,24 +2181,50 @@ function createCoordinationToolsForManager(opts, lifetime) {
2110
2181
  },
2111
2182
  {
2112
2183
  name: "await_event",
2113
- description: "Wait for and pull the next message a worker, sub-driver, or analyst sent up — the unified inbox. Read a settled artifact with the returned `outputRead` call; the receipt carries its reference, not its bytes. An event is one of: a settled worker output ('settled'), a question needing your answer ('question', from ask_parent / the worker's ask-user), or a trace-analyst finding ('finding', from analyze-on-settle). Pass kinds:['settled'] for just the next finished worker; omit `kinds` to also receive questions and findings. Returns { idle: true } when nothing is queued and no workers are live. If a worker is still running when the wait elapses, returns { pending: true, live: [...] } (the workers still in flight) instead of blocking indefinitely — call await_event again to keep waiting; the settlement is not lost. Every reply carries `freeSlots`: how many more workers you can start right now (`null` = uncapped). A settled worker frees its slot, so `freeSlots > 0` means capacity is sitting idle — spawn into it before waiting again.",
2184
+ description: "Wait for and pull the next message a worker, sub-driver, or analyst sent up — the unified inbox. Read a settled artifact with the returned `outputRead` call; the receipt carries its reference, not its bytes. An event is one of: a settled worker output ('settled'), a question needing your answer ('question', from ask_parent / the worker's ask-user), or a trace-analyst finding ('finding', from analyze-on-settle). Pass kinds:['settled'] for just the next finished worker; omit `kinds` to also receive questions and findings. Returns { idle: true } when nothing is queued and no workers are live. If a worker is still running when the wait elapses, returns { pending: true, live: [...] } (the workers still in flight) instead of blocking indefinitely — call await_event again to keep waiting; the settlement is not lost. Every reply carries `freeSlots`: how many more workers you can start right now (`null` = uncapped). A settled worker frees its slot, so `freeSlots > 0` means capacity is sitting idle — spawn into it before waiting again. Each event carries `eventSeq`; pass the ones you have processed in `acknowledge` on a later call. An event delivered to a turn that ends in failure is named again when you are re-entered, until it is acknowledged.",
2114
2185
  inputSchema: {
2115
2186
  type: "object",
2116
- properties: { kinds: {
2117
- type: "array",
2118
- items: {
2119
- type: "string",
2120
- enum: [...awaitableEventKinds]
2187
+ properties: {
2188
+ kinds: {
2189
+ type: "array",
2190
+ items: {
2191
+ type: "string",
2192
+ enum: [...awaitableEventKinds]
2193
+ },
2194
+ description: "Restrict to these event kinds (any if omitted)."
2121
2195
  },
2122
- description: "Restrict to these event kinds (any if omitted)."
2123
- } }
2196
+ acknowledge: {
2197
+ type: "array",
2198
+ items: {
2199
+ type: "integer",
2200
+ minimum: 0
2201
+ },
2202
+ description: "The eventSeq of each earlier event you have now processed."
2203
+ }
2204
+ }
2124
2205
  },
2125
2206
  handler: async (raw) => {
2126
- const k = obj(raw).kinds;
2207
+ const args = raw === void 0 ? {} : obj(raw);
2208
+ const k = args.kinds;
2127
2209
  const kinds = Array.isArray(k) ? k.filter(isAwaitableEventKind) : void 0;
2128
- let ev = bus.pull(kinds);
2210
+ if (Array.isArray(args.acknowledge)) {
2211
+ const named = new Set(args.acknowledge.filter((value) => typeof value === "number" && Number.isInteger(value)));
2212
+ await acknowledge(deliveries.filter((delivery) => named.has(delivery.record.seq)), "manager");
2213
+ }
2214
+ const deliver = (record) => {
2215
+ deliveries.push({
2216
+ record,
2217
+ attempt: driverAttempt,
2218
+ acknowledged: false
2219
+ });
2220
+ return {
2221
+ ...projectEvent(record.event),
2222
+ eventSeq: record.seq
2223
+ };
2224
+ };
2225
+ let ev = bus.pullRecord(kinds);
2129
2226
  if (ev) return {
2130
- ...projectEvent(ev),
2227
+ ...deliver(ev),
2131
2228
  freeSlots: freeWorkerSlots()
2132
2229
  };
2133
2230
  const raced = await raceDrainWithTimeout(ensureDrain());
@@ -2136,13 +2233,13 @@ function createCoordinationToolsForManager(opts, lifetime) {
2136
2233
  live: liveSnapshot(),
2137
2234
  freeSlots: freeWorkerSlots()
2138
2235
  };
2139
- ev = bus.pull(kinds);
2236
+ ev = bus.pullRecord(kinds);
2140
2237
  if (!ev) return {
2141
2238
  idle: !raced.drained,
2142
2239
  freeSlots: freeWorkerSlots()
2143
2240
  };
2144
2241
  return {
2145
- ...projectEvent(ev),
2242
+ ...deliver(ev),
2146
2243
  freeSlots: freeWorkerSlots()
2147
2244
  };
2148
2245
  }
@@ -2318,6 +2415,18 @@ function createCoordinationToolsForManager(opts, lifetime) {
2318
2415
  };
2319
2416
  const a = obj(raw);
2320
2417
  if (!Object.hasOwn(a, "result")) throw new Error("submit_result: \"result\" is required");
2418
+ const open = openWorkRefusal("submit_result");
2419
+ if (open !== void 0) {
2420
+ lastRejection = {
2421
+ at: Date.now(),
2422
+ reason: String(open.reason)
2423
+ };
2424
+ return {
2425
+ accepted: false,
2426
+ stop: false,
2427
+ ...open
2428
+ };
2429
+ }
2321
2430
  const result = structuredClone(a.result);
2322
2431
  let accepted = false;
2323
2432
  let thrown;
@@ -2336,10 +2445,15 @@ function createCoordinationToolsForManager(opts, lifetime) {
2336
2445
  } catch (error) {
2337
2446
  diagnosticError = error instanceof Error ? error.message : String(error);
2338
2447
  }
2448
+ const refusal = thrown === void 0 ? `the independent check did not pass on this result${explanation ? `. ${explanation}` : deliverable.describe ? `. Expected: ${deliverable.describe}` : ""}` : `the independent check THREW, so nothing was accepted: ${thrown}. This is a fault in the check, not necessarily in your result — report it rather than resubmitting unchanged`;
2449
+ lastRejection = {
2450
+ at: Date.now(),
2451
+ reason: refusal
2452
+ };
2339
2453
  return {
2340
2454
  accepted: false,
2341
2455
  stop: false,
2342
- reason: thrown === void 0 ? `the independent check did not pass on this result${explanation ? `. ${explanation}` : deliverable.describe ? `. Expected: ${deliverable.describe}` : ""}` : `the independent check THREW, so nothing was accepted: ${thrown}. This is a fault in the check, not necessarily in your result — report it rather than resubmitting unchanged`,
2456
+ reason: refusal,
2343
2457
  ...diagnosticError === void 0 ? {} : { diagnosticError }
2344
2458
  };
2345
2459
  }
@@ -2372,6 +2486,7 @@ function createCoordinationToolsForManager(opts, lifetime) {
2372
2486
  } finally {
2373
2487
  if (submissionInFlight === commit) submissionInFlight = void 0;
2374
2488
  }
2489
+ await acknowledge(deliveries, "result-accepted");
2375
2490
  return {
2376
2491
  accepted: true,
2377
2492
  retained: "this-result",
@@ -2401,6 +2516,11 @@ function createCoordinationToolsForManager(opts, lifetime) {
2401
2516
  ...unheard.length > 0 ? { unheardQuestionIds: unheard.map((q) => q.id) } : {}
2402
2517
  });
2403
2518
  }
2519
+ const open = openWorkRefusal("stop");
2520
+ if (open !== void 0) return Promise.resolve({
2521
+ stopped: false,
2522
+ ...open
2523
+ });
2404
2524
  stopped = true;
2405
2525
  const r = obj(raw).reason;
2406
2526
  reason = typeof r === "string" ? r : void 0;
@@ -2408,6 +2528,97 @@ function createCoordinationToolsForManager(opts, lifetime) {
2408
2528
  return Promise.resolve({ stopped: true });
2409
2529
  }
2410
2530
  },
2531
+ {
2532
+ name: "report_blocked",
2533
+ description: [
2534
+ "Report that a tool you need keeps failing, so the run cannot go on.",
2535
+ "Name the tool, the arguments you called it with, and the error you saw.",
2536
+ "The coordinator calls that tool again, with those arguments, under your identity.",
2537
+ "When the call succeeds you are not blocked: the reply carries its result, and you continue.",
2538
+ "When it fails again, the run ends as blocked and the record keeps both errors.",
2539
+ "submit_result, stop and report_blocked cannot be probed."
2540
+ ].join(" "),
2541
+ inputSchema: {
2542
+ type: "object",
2543
+ properties: {
2544
+ tool: {
2545
+ type: "string",
2546
+ description: "The tool that failed, as you called it."
2547
+ },
2548
+ arguments: {
2549
+ type: "object",
2550
+ description: "The arguments you called it with. Omit for none."
2551
+ },
2552
+ error: {
2553
+ type: "string",
2554
+ description: "The error the tool returned to you."
2555
+ }
2556
+ },
2557
+ required: ["tool", "error"],
2558
+ additionalProperties: false
2559
+ },
2560
+ handler: async (raw) => {
2561
+ const a = obj(raw);
2562
+ const named = str(a.tool, "tool");
2563
+ const reported = str(a.error, "error");
2564
+ const bare = named.replace(/^mcp__.+?__/u, "").replace(/^.*?coordination_+/u, "");
2565
+ if (unprobeableVerbs.has(bare)) return {
2566
+ blocked: false,
2567
+ error: "unprobeable",
2568
+ reason: `${bare} changes the run, so the coordinator does not call it for you`
2569
+ };
2570
+ const target = opts.resolveProbeTool?.(bare) ?? tools.find((tool) => tool.name === bare);
2571
+ if (target === void 0) return {
2572
+ blocked: false,
2573
+ error: "unknown-tool",
2574
+ reason: `no tool named ${JSON.stringify(bare)} is served to you, so there is nothing to probe; call the tools you were given`
2575
+ };
2576
+ const args = a.arguments === void 0 ? {} : typeof a.arguments === "object" && a.arguments !== null && !Array.isArray(a.arguments) ? a.arguments : void 0;
2577
+ if (args === void 0) return {
2578
+ blocked: false,
2579
+ error: "invalid-arguments",
2580
+ reason: "\"arguments\" must be an object"
2581
+ };
2582
+ let probe;
2583
+ try {
2584
+ probe = {
2585
+ ok: true,
2586
+ result: await runWithin(target.handler(structuredClone(args)), REPORT_BLOCKED_PROBE_MS, `the probe of ${bare} did not answer within ${REPORT_BLOCKED_PROBE_MS}ms`)
2587
+ };
2588
+ } catch (error) {
2589
+ probe = {
2590
+ ok: false,
2591
+ error: error instanceof Error ? error.message : String(error)
2592
+ };
2593
+ }
2594
+ if (probe.ok) return {
2595
+ blocked: false,
2596
+ probe: {
2597
+ tool: bare,
2598
+ ok: true,
2599
+ result: probe.result
2600
+ },
2601
+ guidance: "The call worked when the coordinator made it under your identity, so the tool is not blocked. Use this result and continue the objective."
2602
+ };
2603
+ blockedEvidence = Object.freeze({
2604
+ tool: bare,
2605
+ reported,
2606
+ probed: probe.error
2607
+ });
2608
+ stopped = true;
2609
+ reason = `blocked: ${bare} failed when the coordinator probed it: ${probe.error}`;
2610
+ notifyStop();
2611
+ return {
2612
+ blocked: true,
2613
+ stopped: true,
2614
+ probe: {
2615
+ tool: bare,
2616
+ ok: false,
2617
+ error: probe.error
2618
+ }
2619
+ };
2620
+ }
2621
+ },
2411
2622
  {
2412
2623
  name: "read_journal",
2413
2624
  description: [
@@ -2628,9 +2839,74 @@ function createCoordinationToolsForManager(opts, lifetime) {
2628
2839
  definedAnalysts: () => definedAnalysts,
2629
2840
  drainResolved,
2630
2841
  abortWorker,
2842
+ beginDriverAttempt: (attempt) => {
2843
+ driverAttempt = attempt;
2844
+ },
2845
+ endDriverAttempt: async (outcome) => {
2846
+ const attempt = driverAttempt;
2847
+ if (outcome === "completed") await acknowledge(deliveries.filter((delivery) => delivery.attempt === attempt), "turn-completed");
2848
+ },
2849
+ reentryState: () => {
2850
+ const { unqueued, queued } = openWork();
2851
+ const deliveredSettled = new Set(deliveries.flatMap((delivery) => delivery.record.event.type === "settled" ? [delivery.record.event.worker.id] : []));
2852
+ return detachedFrozen({
2853
+ journalRows: priorJournal.length + bus.history().length,
2854
+ journalReadTo,
2855
+ live: (opts.scope.view?.nodes ?? []).filter((node) => isLiveNodeStatus(node.status)).map((node) => ({
2856
+ id: node.id,
2857
+ label: node.label,
2858
+ status: node.status
2859
+ })),
2860
+ settled: [...ledger.map((worker) => ({
2861
+ id: worker.id,
2862
+ status: worker.status,
2863
+ ...worker.status === "done" && worker.valid !== void 0 ? { valid: worker.valid } : {},
2864
+ delivered: deliveredSettled.has(worker.id)
2865
+ })), ...unqueued.map((node) => ({
2866
+ id: node.id,
2867
+ status: node.status === "done" ? "done" : "down",
2868
+ delivered: false
2869
+ }))],
2870
+ waiting: [...queued.map((record) => ({
2871
+ type: record.event.type,
2872
+ ...eventWorker(record.event) === void 0 ? {} : { worker: eventWorker(record.event) }
2873
+ })), ...unqueued.map((node) => ({
2874
+ type: "settled",
2875
+ worker: node.id
2876
+ }))],
2877
+ unacknowledged: deliveries.filter((delivery) => !delivery.acknowledged).map((delivery) => ({
2878
+ seq: delivery.record.seq,
2879
+ type: delivery.record.event.type,
2880
+ ...eventWorker(delivery.record.event) === void 0 ? {} : { worker: eventWorker(delivery.record.event) },
2881
+ ...delivery.attempt === void 0 ? {} : { attempt: delivery.attempt }
2882
+ })),
2883
+ ...lastRejection === void 0 ? {} : { lastRejection }
2884
+ });
2885
+ },
2886
+ blocked: () => blockedEvidence,
2631
2887
  ...peerMail ? { peerMail } : {}
2632
2888
  };
2633
2889
  }
2890
+ /** The verbs `report_blocked` never calls on a manager's behalf: each one changes the run. */
2891
+ const unprobeableVerbs = /* @__PURE__ */ new Set([
2892
+ "submit_result",
2893
+ "stop",
2894
+ "report_blocked"
2895
+ ]);
2896
+ /** How long one `report_blocked` probe may run before it counts as a failure. */
2897
+ const REPORT_BLOCKED_PROBE_MS = 6e4;
2898
+ async function runWithin(work, ms, message) {
2899
+ let timer;
2900
+ const timeout = new Promise((_, reject) => {
2901
+ timer = setTimeout(() => reject(new Error(message)), ms);
2902
+ if (typeof timer?.unref === "function") timer.unref();
2903
+ });
2904
+ try {
2905
+ return await Promise.race([work, timeout]);
2906
+ } finally {
2907
+ if (timer) clearTimeout(timer);
2908
+ }
2909
+ }
2634
2910
  function nextUnkeyedAssignmentOrdinal(scope) {
2635
2911
  let next = 0;
2636
2912
  const views = [scope.resume?.view, scope.view];
@@ -3745,6 +4021,7 @@ function driverAgent(opts) {
3745
4021
  },
3746
4022
  async act(task, scope) {
3747
4023
  const ownerReader = opts.spawnResourceReader ?? (opts.spawnResourceRoot === void 0 ? scopeRetainedOwnerResourceReader(scope) : void 0);
4024
+ let probeableByName;
3748
4025
  const coord = createCoordinationTools({
3749
4026
  scope,
3750
4027
  blobs: opts.blobs,
@@ -3771,7 +4048,8 @@ function driverAgent(opts) {
3771
4048
  ...opts.priorCoordination?.questions.length ? { priorQuestions: opts.priorCoordination.questions } : {},
3772
4049
  ...opts.priorCoordination?.escalations?.length ? { priorEscalations: opts.priorCoordination.escalations } : {},
3773
4050
  ...opts.priorCoordination?.records.length ? { priorJournal: opts.priorCoordination.records } : {},
3774
- ...opts.priorCoordination?.analystDefinitions?.length ? { priorAnalystDefinitions: opts.priorCoordination.analystDefinitions } : {}
4051
+ ...opts.priorCoordination?.analystDefinitions?.length ? { priorAnalystDefinitions: opts.priorCoordination.analystDefinitions } : {},
4052
+ resolveProbeTool: (name) => probeableByName?.get(name)
3775
4053
  });
3776
4054
  await coord.ready();
3777
4055
  const availableTools = [...coord.tools, ...opts.nodeTools ?? []];
@@ -3791,6 +4069,7 @@ function driverAgent(opts) {
3791
4069
  };
3792
4070
  });
3793
4071
  const modelTools = selectedTools.flatMap((selected) => selected.kind === "descriptor" ? [selected.descriptor] : []);
4072
+ probeableByName = new Map(modelTools.map((tool) => [tool.name, tool]));
3794
4073
  const selectedExtraNames = new Set(selectedTools.flatMap((selected) => selected.kind === "extra" ? [selected.extra.name] : []));
3795
4074
  opts.onCoordinationTools?.(modelTools);
3796
4075
  const acknowledger = opts.controlDir === void 0 ? void 0 : createCancelAcknowledger({
@@ -4102,4 +4381,4 @@ function safeJson(v) {
4102
4381
  //#endregion
4103
4382
  export { downMessageRefusalReasons as A, ANALYST_DEFINITION_BOUNDS as C, coordinationVerbNames as D, canonicalFindingEvent as E, defaultToolDetectors as F, watchTrace as I, parseAuthoredAnalystDefinition as M, questionEscalationTargets as N, createCoordinationTools as O, createEventBus as P, watchRunCancellation as S, analystToolGroupNames as T, renderAnytimeTable as _, allOf as a, FileCoordinationLog as b, createProgressTracker as c, progressStop as d, sampleFromSettled as f, plateauLength as g, bestSoFar as h, finalizeBestDelivered as i, normalizeAnalyzeOnSettle as j, createCoordinationToolsForManager as k, noProgressFor as l, areaUnderCurve as m, createSteerAcknowledger as n, allWorkersStalled as o, anytimeReport as p, driverAgent as r, anyOf as s, createCancelAcknowledger as t, plateau as u, createFileRunContext as v, DEFAULT_AWAIT_EVENT_TIMEOUT_MS as w, applyRunCancellation as x, createInMemoryRunContext as y };
4104
4383
 
4105
- //# sourceMappingURL=coordination-driver-LmDxHvAO.js.map
4384
+ //# sourceMappingURL=coordination-driver-COGC8FK2.js.map