@tangle-network/agent-runtime 0.102.2 → 0.103.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 (77) hide show
  1. package/README.md +73 -10
  2. package/dist/agent.d.ts +1 -1
  3. package/dist/agent.js +5 -5
  4. package/dist/analyst-loop.d.ts +1 -1
  5. package/dist/candidate-execution/index.d.ts +5 -41
  6. package/dist/candidate-execution/index.js +8 -6
  7. package/dist/{chunk-QCXD7NHM.js → chunk-3LJF5XSE.js} +79 -334
  8. package/dist/chunk-3LJF5XSE.js.map +1 -0
  9. package/dist/{chunk-3DW5DEKQ.js → chunk-5AITUUHO.js} +3 -3
  10. package/dist/{chunk-SQ3ZJH3Y.js → chunk-6WZZXQV5.js} +467 -23
  11. package/dist/chunk-6WZZXQV5.js.map +1 -0
  12. package/dist/{chunk-SCOHHMKU.js → chunk-AAN2MB2X.js} +3 -3
  13. package/dist/{chunk-KSM6GFHP.js → chunk-B7K7V22Y.js} +2 -2
  14. package/dist/{chunk-ZUCUAFVF.js → chunk-EAQ5YRRY.js} +1382 -62
  15. package/dist/chunk-EAQ5YRRY.js.map +1 -0
  16. package/dist/chunk-ISPWRSEC.js +408 -0
  17. package/dist/chunk-ISPWRSEC.js.map +1 -0
  18. package/dist/{chunk-7FJJUC73.js → chunk-LFM4JBRW.js} +29 -6
  19. package/dist/{chunk-7FJJUC73.js.map → chunk-LFM4JBRW.js.map} +1 -1
  20. package/dist/{chunk-ROILMKDL.js → chunk-QYCKIV6C.js} +3 -3
  21. package/dist/{chunk-LJLG734E.js → chunk-SBTWKPVR.js} +10 -11
  22. package/dist/{chunk-LJLG734E.js.map → chunk-SBTWKPVR.js.map} +1 -1
  23. package/dist/{chunk-CK76OZPM.js → chunk-SNSMRT6H.js} +56 -386
  24. package/dist/chunk-SNSMRT6H.js.map +1 -0
  25. package/dist/{chunk-EKUMRQNR.js → chunk-TUSOOIDV.js} +2 -2
  26. package/dist/{chunk-J6V6DWWS.js → chunk-ZOYN3JR5.js} +5 -5
  27. package/dist/{chunk-377GOJHJ.js → chunk-ZXICDSAK.js} +333 -4
  28. package/dist/chunk-ZXICDSAK.js.map +1 -0
  29. package/dist/{completion-gate-C6dhVN-N.d.ts → completion-gate-DLINnrkM.d.ts} +1 -1
  30. package/dist/{coordination-D9l_YmwW.d.ts → coordination-DTehA977.d.ts} +250 -8
  31. package/dist/environment-provider.d.ts +2 -2
  32. package/dist/index.d.ts +12 -12
  33. package/dist/index.js +17 -15
  34. package/dist/index.js.map +1 -1
  35. package/dist/intelligence.d.ts +26 -8
  36. package/dist/intelligence.js +24 -7
  37. package/dist/intelligence.js.map +1 -1
  38. package/dist/knowledge.d.ts +6 -6
  39. package/dist/knowledge.js +9 -9
  40. package/dist/{loop-runner-bin-PnWslIw4.d.ts → loop-runner-bin-DhIXsLAd.d.ts} +2 -2
  41. package/dist/loop-runner-bin.d.ts +5 -5
  42. package/dist/loop-runner-bin.js +6 -6
  43. package/dist/loops.d.ts +305 -148
  44. package/dist/loops.js +82 -14
  45. package/dist/mcp/bin.js +3 -3
  46. package/dist/mcp/index.d.ts +6 -6
  47. package/dist/mcp/index.js +6 -6
  48. package/dist/profiles.d.ts +1 -1
  49. package/dist/{profile-DbfaMTdk.d.ts → protected-model-port-DzkUY3HQ.d.ts} +41 -3
  50. package/dist/{structural-rollout-D7xik9XR.d.ts → structural-rollout-BFPIy3iw.d.ts} +3 -3
  51. package/dist/supervise-Cp8bNcJi.d.ts +379 -0
  52. package/dist/testing.js +10 -10
  53. package/dist/testing.js.map +1 -1
  54. package/dist/{types-CWqfCO8s.d.ts → types-Cbp72qyu.d.ts} +1 -1
  55. package/dist/{types-CLat4bT9.d.ts → types-DK11_O4L.d.ts} +1 -1
  56. package/dist/types-lZTE_LBd.d.ts +957 -0
  57. package/dist/{worktree-fanout-DsIR4d6w.d.ts → worktree-fanout-DiiJWjJO.d.ts} +17 -5
  58. package/package.json +5 -4
  59. package/skills/build-with-agent-runtime/SKILL.md +7 -5
  60. package/skills/generate-eval/SKILL.md +45 -52
  61. package/skills/loop-writer/SKILL.md +79 -147
  62. package/skills/supervise/SKILL.md +33 -14
  63. package/dist/chunk-377GOJHJ.js.map +0 -1
  64. package/dist/chunk-CK76OZPM.js.map +0 -1
  65. package/dist/chunk-IMSNJSXH.js +0 -73
  66. package/dist/chunk-IMSNJSXH.js.map +0 -1
  67. package/dist/chunk-QCXD7NHM.js.map +0 -1
  68. package/dist/chunk-SQ3ZJH3Y.js.map +0 -1
  69. package/dist/chunk-ZUCUAFVF.js.map +0 -1
  70. package/dist/supervise-BQdNAXtK.d.ts +0 -131
  71. package/dist/types-D870JlH0.d.ts +0 -500
  72. /package/dist/{chunk-3DW5DEKQ.js.map → chunk-5AITUUHO.js.map} +0 -0
  73. /package/dist/{chunk-SCOHHMKU.js.map → chunk-AAN2MB2X.js.map} +0 -0
  74. /package/dist/{chunk-KSM6GFHP.js.map → chunk-B7K7V22Y.js.map} +0 -0
  75. /package/dist/{chunk-ROILMKDL.js.map → chunk-QYCKIV6C.js.map} +0 -0
  76. /package/dist/{chunk-EKUMRQNR.js.map → chunk-TUSOOIDV.js.map} +0 -0
  77. /package/dist/{chunk-J6V6DWWS.js.map → chunk-ZOYN3JR5.js.map} +0 -0
@@ -3,13 +3,13 @@ import {
3
3
  agentImprovementTargetInput,
4
4
  verifyAgentImprovementActivation,
5
5
  verifyAgentImprovementProposal
6
- } from "./chunk-7FJJUC73.js";
6
+ } from "./chunk-LFM4JBRW.js";
7
7
  import {
8
8
  canonicalCandidateDigest,
9
9
  canonicalCandidateDocument,
10
10
  immutableCandidateValue,
11
11
  verifyCanonicalCandidateDocument
12
- } from "./chunk-LJLG734E.js";
12
+ } from "./chunk-SBTWKPVR.js";
13
13
 
14
14
  // src/intelligence/activation.ts
15
15
  import {
@@ -197,4 +197,4 @@ export {
197
197
  verifyAgentImprovementActivationResult,
198
198
  executeAgentImprovementActivation
199
199
  };
200
- //# sourceMappingURL=chunk-3DW5DEKQ.js.map
200
+ //# sourceMappingURL=chunk-5AITUUHO.js.map
@@ -1,6 +1,9 @@
1
1
  import {
2
- contentAddress
3
- } from "./chunk-IMSNJSXH.js";
2
+ contentAddress,
3
+ materializeTreeView,
4
+ pendingWaits,
5
+ replaySpawnTree
6
+ } from "./chunk-ISPWRSEC.js";
4
7
  import {
5
8
  addTokenUsage,
6
9
  zeroTokenUsage
@@ -1684,6 +1687,186 @@ function toError(error) {
1684
1687
  return error instanceof Error ? error : new Error(String(error));
1685
1688
  }
1686
1689
 
1690
+ // src/runtime/supervise/progress.ts
1691
+ var DEFAULT_STALL_AFTER_MS = 18e4;
1692
+ function createActivityLog(limit = 12) {
1693
+ const notes = [];
1694
+ const cap = Math.max(1, Math.floor(limit));
1695
+ return {
1696
+ push(note) {
1697
+ notes.push(note);
1698
+ if (notes.length > cap) notes.splice(0, notes.length - cap);
1699
+ },
1700
+ read: () => [...notes],
1701
+ last: () => notes[notes.length - 1],
1702
+ size: () => notes.length
1703
+ };
1704
+ }
1705
+ function readWorkerProgress(scope, executor, now, stallAfterMs = DEFAULT_STALL_AFTER_MS) {
1706
+ const live = scope.status !== "done" && scope.status !== "failed" && scope.status !== "cancelled";
1707
+ const executorActivityAt = executor?.recentActivity?.length ? executor.recentActivity[executor.recentActivity.length - 1].at : 0;
1708
+ const lastActivityAt = Math.max(scope.lastActivityAt, executorActivityAt);
1709
+ const idleMs = Math.max(0, now - lastActivityAt);
1710
+ const note = executor?.note;
1711
+ return {
1712
+ id: scope.id,
1713
+ status: scope.status,
1714
+ live,
1715
+ steerable: scope.steerable,
1716
+ startedAt: scope.startedAt,
1717
+ lastActivityAt,
1718
+ idleMs,
1719
+ // Only a LIVE worker can stall; a settled one is simply finished.
1720
+ stalled: live && idleMs > stallAfterMs,
1721
+ stallAfterMs,
1722
+ turns: executor?.turns ?? scope.turns,
1723
+ tokens: scope.tokens,
1724
+ usd: scope.usd,
1725
+ pendingMessages: executor?.pendingMessages ?? 0,
1726
+ recentActivity: executor?.recentActivity ?? [],
1727
+ ...note ? { note } : {}
1728
+ };
1729
+ }
1730
+
1731
+ // src/runtime/supervise/wait.ts
1732
+ function timerAt(ms, now) {
1733
+ return { kind: "timer", untilMs: now + ms };
1734
+ }
1735
+ function pollFor(probe, opts, now) {
1736
+ return {
1737
+ kind: "poll",
1738
+ probe,
1739
+ intervalMs: opts.intervalMs,
1740
+ ...opts.timeoutMs !== void 0 ? { timeoutAtMs: now + opts.timeoutMs } : {},
1741
+ ...opts.args ? { args: opts.args } : {}
1742
+ };
1743
+ }
1744
+ function createWaitProbes(entries) {
1745
+ const map = new Map(Object.entries(entries));
1746
+ return { resolve: (name) => map.get(name) };
1747
+ }
1748
+ function isWaitOutcome(value) {
1749
+ return typeof value === "object" && value !== null && value.waitOutcome === true;
1750
+ }
1751
+ function waitUntil(spec) {
1752
+ return spec.kind === "timer" ? spec.untilMs : spec.timeoutAtMs;
1753
+ }
1754
+ function validateWaitSpec(spec) {
1755
+ if (spec.kind === "timer") {
1756
+ return Number.isFinite(spec.untilMs) ? null : "timer.untilMs must be a finite epoch-ms instant";
1757
+ }
1758
+ if (typeof spec.probe !== "string" || spec.probe.length === 0) {
1759
+ return "poll.probe must be a non-empty probe name";
1760
+ }
1761
+ if (!Number.isFinite(spec.intervalMs) || spec.intervalMs <= 0) {
1762
+ return "poll.intervalMs must be > 0";
1763
+ }
1764
+ if (spec.timeoutAtMs !== void 0 && !Number.isFinite(spec.timeoutAtMs)) {
1765
+ return "poll.timeoutAtMs must be a finite epoch-ms instant";
1766
+ }
1767
+ return null;
1768
+ }
1769
+ function assertWaitWithinDeadline(spec, deadlineMs) {
1770
+ if (deadlineMs <= 0) return true;
1771
+ const until = waitUntil(spec);
1772
+ if (until === void 0) return false;
1773
+ return until <= deadlineMs;
1774
+ }
1775
+ async function runWait(args) {
1776
+ const { spec, label, armedAt, resumed, signal, now } = args;
1777
+ const sleep = args.sleep ?? defaultSleep;
1778
+ if (signal.aborted) return { kind: "cancelled", reason: "aborted before arming" };
1779
+ if (spec.kind === "timer") {
1780
+ const remaining = spec.untilMs - now();
1781
+ if (remaining > 0) await sleep(remaining, signal);
1782
+ if (signal.aborted) return { kind: "cancelled", reason: "wait aborted" };
1783
+ return {
1784
+ kind: "woke",
1785
+ outcome: outcome("timer", "fired", label, spec.untilMs, armedAt, now(), 0, 0, resumed)
1786
+ };
1787
+ }
1788
+ const probe = args.probes?.resolve(spec.probe);
1789
+ if (!probe) {
1790
+ throw new ValidationError(
1791
+ `wait '${label}': poll probe '${spec.probe}' is not registered in this run's WaitProbeRegistry`
1792
+ );
1793
+ }
1794
+ let polls = 0;
1795
+ let probeErrors = 0;
1796
+ for (; ; ) {
1797
+ if (signal.aborted) return { kind: "cancelled", reason: "wait aborted" };
1798
+ polls += 1;
1799
+ let fired = false;
1800
+ try {
1801
+ fired = await probe(spec.args, signal);
1802
+ } catch {
1803
+ probeErrors += 1;
1804
+ }
1805
+ if (fired) {
1806
+ return {
1807
+ kind: "woke",
1808
+ outcome: outcome(
1809
+ "poll",
1810
+ "fired",
1811
+ label,
1812
+ spec.timeoutAtMs,
1813
+ armedAt,
1814
+ now(),
1815
+ polls,
1816
+ probeErrors,
1817
+ resumed
1818
+ )
1819
+ };
1820
+ }
1821
+ if (spec.timeoutAtMs !== void 0 && now() >= spec.timeoutAtMs) {
1822
+ return {
1823
+ kind: "woke",
1824
+ outcome: outcome(
1825
+ "poll",
1826
+ "timeout",
1827
+ label,
1828
+ spec.timeoutAtMs,
1829
+ armedAt,
1830
+ now(),
1831
+ polls,
1832
+ probeErrors,
1833
+ resumed
1834
+ )
1835
+ };
1836
+ }
1837
+ const nextCheck = spec.timeoutAtMs === void 0 ? spec.intervalMs : Math.min(spec.intervalMs, Math.max(0, spec.timeoutAtMs - now()));
1838
+ await sleep(nextCheck, signal);
1839
+ }
1840
+ }
1841
+ function outcome(kind, settled, label, untilMs, armedAt, wokenAt, polls, probeErrors, resumed) {
1842
+ return {
1843
+ waitOutcome: true,
1844
+ kind,
1845
+ settled,
1846
+ label,
1847
+ ...untilMs !== void 0 ? { untilMs } : {},
1848
+ armedAt,
1849
+ wokenAt,
1850
+ polls,
1851
+ probeErrors,
1852
+ resumed
1853
+ };
1854
+ }
1855
+ function defaultSleep(ms, signal) {
1856
+ if (ms <= 0 || signal.aborted) return Promise.resolve();
1857
+ return new Promise((resolve2) => {
1858
+ const timer = setTimeout(() => {
1859
+ signal.removeEventListener("abort", onAbort);
1860
+ resolve2();
1861
+ }, ms);
1862
+ function onAbort() {
1863
+ clearTimeout(timer);
1864
+ resolve2();
1865
+ }
1866
+ signal.addEventListener("abort", onAbort, { once: true });
1867
+ });
1868
+ }
1869
+
1687
1870
  // src/runtime/supervise/scope.ts
1688
1871
  var nestedScopeSeamKey = "nested-scope";
1689
1872
  function makeNestedScopeSeam(args, childNodeId) {
@@ -1713,10 +1896,14 @@ function makeNestedScopeSeam(args, childNodeId) {
1713
1896
  }
1714
1897
  function createScope(args) {
1715
1898
  const children = /* @__PURE__ */ new Map();
1716
- let spawnOrdinal = 0;
1717
- let cursorSeq = 0;
1899
+ let spawnOrdinal = args.resumeFrom ? args.resumeFrom.maxSpawnOrdinal + 1 : 0;
1900
+ let cursorSeq = args.resumeFrom ? args.resumeFrom.maxCursorSeq + 1 : 0;
1901
+ let waitOrdinal = args.resumeFrom ? args.resumeFrom.maxWaitOrdinal + 1 : 0;
1718
1902
  let meterSeq = 0;
1719
1903
  const now = args.now ?? Date.now;
1904
+ const unclaimedWaits = new Map(
1905
+ (args.resumeFrom?.waits ?? []).map((w) => [w.label, w])
1906
+ );
1720
1907
  function spawn4(agent, task, opts) {
1721
1908
  if (args.maxDepth !== void 0 && args.depth >= args.maxDepth) {
1722
1909
  return { ok: false, reason: "depth-exceeded" };
@@ -1763,7 +1950,11 @@ function createScope(args) {
1763
1950
  settled: void 0,
1764
1951
  delivered: false,
1765
1952
  executorDone: false,
1766
- ...executor.deliver ? { deliver: executor.deliver.bind(executor) } : {}
1953
+ startedAt: now(),
1954
+ lastActivityAt: now(),
1955
+ ...executor.deliver ? { deliver: executor.deliver.bind(executor) } : {},
1956
+ ...executor.progress ? { readProgress: executor.progress.bind(executor) } : {},
1957
+ ...executor.traceSource ? { readTraceSource: executor.traceSource.bind(executor) } : {}
1767
1958
  };
1768
1959
  children.set(id, live);
1769
1960
  void args.journal.appendEvent(args.root, {
@@ -1804,7 +1995,8 @@ function createScope(args) {
1804
1995
  opts,
1805
1996
  args.pool,
1806
1997
  reservation.ticket,
1807
- args.blobs
1998
+ args.blobs,
1999
+ now
1808
2000
  ).then((s) => {
1809
2001
  live.resolved = s;
1810
2002
  return s;
@@ -1854,8 +2046,152 @@ function createScope(args) {
1854
2046
  const child = children.get(nodeId);
1855
2047
  if (!child || child.delivered || !child.deliver) return false;
1856
2048
  child.deliver(msg);
2049
+ child.lastActivityAt = now();
1857
2050
  return true;
1858
2051
  }
2052
+ function wait(spec, opts) {
2053
+ if (validateWaitSpec(spec) !== null) return { ok: false, reason: "invalid-spec" };
2054
+ if (spec.kind === "poll" && args.probes?.resolve(spec.probe) === void 0) {
2055
+ return { ok: false, reason: "unknown-probe" };
2056
+ }
2057
+ const adopted = unclaimedWaits.get(opts.label);
2058
+ if (adopted) unclaimedWaits.delete(opts.label);
2059
+ const effectiveSpec = adopted?.spec ?? spec;
2060
+ const armedAt = adopted?.armedAt ?? now();
2061
+ if (!assertWaitWithinDeadline(effectiveSpec, args.pool.readout().deadlineMs)) {
2062
+ return { ok: false, reason: "deadline-exceeded" };
2063
+ }
2064
+ const id = adopted ? adopted.id : `${args.parentId}:w${waitOrdinal}`;
2065
+ const ordinal = adopted ? adopted.ordinal : waitOrdinal;
2066
+ if (!adopted) waitOrdinal += 1;
2067
+ const waitAbort = new AbortController();
2068
+ const cascadeAbort = () => waitAbort.abort();
2069
+ if (args.signal.aborted) waitAbort.abort();
2070
+ else args.signal.addEventListener("abort", cascadeAbort, { once: true });
2071
+ const handle = {
2072
+ id,
2073
+ label: opts.label,
2074
+ get status() {
2075
+ return children.get(id)?.status ?? "cancelled";
2076
+ },
2077
+ abort(reason) {
2078
+ waitAbort.abort(reason);
2079
+ }
2080
+ };
2081
+ const live = {
2082
+ id,
2083
+ status: "waiting",
2084
+ runtime: "wait",
2085
+ // A wait's recorded budget is zero on every channel — nothing was reserved, so nothing may
2086
+ // be reconciled, and a journal reader sums it as the zero it truly is.
2087
+ budget: { maxIterations: 0, maxTokens: 0 },
2088
+ label: opts.label,
2089
+ spent: zeroSpend(),
2090
+ settled: void 0,
2091
+ delivered: false,
2092
+ executorDone: false,
2093
+ startedAt: armedAt,
2094
+ lastActivityAt: now(),
2095
+ wait: { spec: effectiveSpec, armedAt, label: opts.label }
2096
+ };
2097
+ children.set(id, live);
2098
+ if (!adopted) {
2099
+ void args.journal.appendEvent(args.root, {
2100
+ kind: "waiting",
2101
+ id,
2102
+ parent: args.parentId,
2103
+ label: opts.label,
2104
+ spec: effectiveSpec,
2105
+ armedAt,
2106
+ seq: ordinal,
2107
+ at: new Date(now()).toISOString()
2108
+ });
2109
+ }
2110
+ notifyRuntimeHookEvent(
2111
+ args.hooks,
2112
+ {
2113
+ id: `${id}:waiting`,
2114
+ runId: args.root,
2115
+ target: "agent.spawn",
2116
+ phase: "after",
2117
+ timestamp: now(),
2118
+ stepIndex: ordinal,
2119
+ parentId: args.parentId,
2120
+ payload: {
2121
+ childId: id,
2122
+ label: opts.label,
2123
+ runtime: "wait",
2124
+ wait: effectiveSpec,
2125
+ armedAt,
2126
+ resumed: adopted !== void 0
2127
+ }
2128
+ },
2129
+ { signal: args.signal }
2130
+ );
2131
+ const settled = runWait({
2132
+ spec: effectiveSpec,
2133
+ label: opts.label,
2134
+ armedAt,
2135
+ resumed: adopted !== void 0,
2136
+ signal: waitAbort.signal,
2137
+ ...args.probes ? { probes: args.probes } : {},
2138
+ now,
2139
+ ...args.waitSleep ? { sleep: args.waitSleep } : {}
2140
+ }).then(async (resolution) => {
2141
+ live.executorDone = true;
2142
+ live.lastActivityAt = now();
2143
+ if (resolution.kind === "cancelled") {
2144
+ return { kind: "down", reason: resolution.reason, infra: false, restartCount: 0 };
2145
+ }
2146
+ const outRef = contentAddress(resolution.outcome);
2147
+ await args.blobs.put(outRef, resolution.outcome);
2148
+ return { kind: "done", out: resolution.outcome, outRef, spent: zeroSpend() };
2149
+ }).catch((err) => {
2150
+ live.executorDone = true;
2151
+ return { kind: "down", reason: errMessage(err), infra: true, restartCount: 0 };
2152
+ }).then((s) => {
2153
+ live.resolved = s;
2154
+ return s;
2155
+ }).finally(() => {
2156
+ args.signal.removeEventListener("abort", cascadeAbort);
2157
+ });
2158
+ live.settled = settled;
2159
+ return { ok: true, handle };
2160
+ }
2161
+ function progress(nodeId, opts = {}) {
2162
+ const child = children.get(nodeId);
2163
+ if (!child) return void 0;
2164
+ let fromExecutor;
2165
+ try {
2166
+ fromExecutor = child.readProgress?.();
2167
+ } catch {
2168
+ fromExecutor = void 0;
2169
+ }
2170
+ return readWorkerProgress(
2171
+ {
2172
+ id: child.id,
2173
+ status: child.status,
2174
+ steerable: child.deliver !== void 0 && !child.delivered,
2175
+ startedAt: child.startedAt,
2176
+ lastActivityAt: child.lastActivityAt,
2177
+ turns: child.spent.iterations,
2178
+ tokens: child.spent.tokens,
2179
+ usd: child.spent.usd
2180
+ },
2181
+ fromExecutor,
2182
+ opts.now ?? now(),
2183
+ opts.stallAfterMs ?? DEFAULT_STALL_AFTER_MS
2184
+ );
2185
+ }
2186
+ function traceSource(nodeId) {
2187
+ const child = children.get(nodeId);
2188
+ if (!child) return void 0;
2189
+ try {
2190
+ return child.readTraceSource?.();
2191
+ } catch {
2192
+ return void 0;
2193
+ }
2194
+ }
1859
2195
  async function meter(spend, detail) {
1860
2196
  const seq = meterSeq++;
1861
2197
  args.pool.observe(spend);
@@ -1880,13 +2216,22 @@ function createScope(args) {
1880
2216
  { signal: args.signal }
1881
2217
  );
1882
2218
  }
2219
+ const resume = args.resumeFrom ? {
2220
+ settled: args.resumeFrom.settled,
2221
+ view: args.resumeFrom.view,
2222
+ waits: args.resumeFrom.waits
2223
+ } : void 0;
1883
2224
  return {
1884
2225
  spawn: spawn4,
1885
2226
  next,
1886
2227
  nextResolved,
1887
2228
  send,
2229
+ wait,
2230
+ progress,
2231
+ traceSource,
1888
2232
  signal: args.signal,
1889
2233
  meter,
2234
+ ...resume ? { resume } : {},
1890
2235
  get view() {
1891
2236
  return makeTreeView(args.parentId, children);
1892
2237
  },
@@ -1900,6 +2245,7 @@ async function raceFirstSettled(pending) {
1900
2245
  }
1901
2246
  async function finalizeSettlement(child, settlement, seq, args, now) {
1902
2247
  const handle = frozenHandle(child);
2248
+ if (child.wait) return finalizeWait(child, settlement, seq, args, now, handle);
1903
2249
  if (settlement.kind === "down") {
1904
2250
  child.status = "failed";
1905
2251
  await args.journal.appendEvent(args.root, {
@@ -2002,7 +2348,61 @@ async function finalizeSettlement(child, settlement, seq, args, now) {
2002
2348
  seq
2003
2349
  };
2004
2350
  }
2005
- async function runChild(live, executor, childAbort, task, opts, pool, ticket, blobs) {
2351
+ async function finalizeWait(child, settlement, seq, args, now, handle) {
2352
+ const at = new Date(now()).toISOString();
2353
+ if (settlement.kind === "down") {
2354
+ child.status = "cancelled";
2355
+ await args.journal.appendEvent(args.root, {
2356
+ kind: "woken",
2357
+ id: child.id,
2358
+ by: "cancelled",
2359
+ seq,
2360
+ at
2361
+ });
2362
+ return {
2363
+ kind: "down",
2364
+ handle,
2365
+ reason: settlement.reason,
2366
+ infra: settlement.infra,
2367
+ restartCount: settlement.restartCount,
2368
+ seq
2369
+ };
2370
+ }
2371
+ child.status = "done";
2372
+ child.outRef = settlement.outRef;
2373
+ const out = settlement.out;
2374
+ await args.journal.appendEvent(args.root, {
2375
+ kind: "woken",
2376
+ id: child.id,
2377
+ by: out.settled,
2378
+ outRef: settlement.outRef,
2379
+ seq,
2380
+ at
2381
+ });
2382
+ notifyRuntimeHookEvent(
2383
+ args.hooks,
2384
+ {
2385
+ id: `${child.id}:woken`,
2386
+ runId: args.root,
2387
+ target: "agent.child",
2388
+ phase: "after",
2389
+ timestamp: now(),
2390
+ stepIndex: seq,
2391
+ parentId: args.parentId,
2392
+ payload: { childId: child.id, status: "done", wait: out }
2393
+ },
2394
+ { signal: args.signal }
2395
+ );
2396
+ return {
2397
+ kind: "done",
2398
+ handle,
2399
+ out: settlement.out,
2400
+ outRef: settlement.outRef,
2401
+ spent: settlement.spent,
2402
+ seq
2403
+ };
2404
+ }
2405
+ async function runChild(live, executor, childAbort, task, opts, pool, ticket, blobs, now) {
2006
2406
  let reconciled = false;
2007
2407
  const reconcileOnce = (spend) => {
2008
2408
  if (reconciled) return;
@@ -2014,7 +2414,10 @@ async function runChild(live, executor, childAbort, task, opts, pool, ticket, bl
2014
2414
  const ran = executor.execute(task, childAbort.signal);
2015
2415
  let artifact;
2016
2416
  if (isAsyncIterable(ran)) {
2017
- const spend = await foldStream(ran);
2417
+ const spend = await foldStream(ran, (running) => {
2418
+ live.spent = running;
2419
+ live.lastActivityAt = now();
2420
+ });
2018
2421
  live.spent = spend;
2019
2422
  artifact = executor.resultArtifact();
2020
2423
  reconcileOnce(spend);
@@ -2082,7 +2485,8 @@ function makeTreeView(root, children) {
2082
2485
  return {
2083
2486
  root,
2084
2487
  nodes,
2085
- inFlight: nodes.filter((n) => n.status === "running" || n.status === "acquiring").length
2488
+ inFlight: nodes.filter((n) => n.status === "running" || n.status === "acquiring").length,
2489
+ waiting: nodes.filter((n) => n.status === "waiting").length
2086
2490
  };
2087
2491
  }
2088
2492
  function frozenHandle(child) {
@@ -2094,7 +2498,7 @@ function frozenHandle(child) {
2094
2498
  }
2095
2499
  };
2096
2500
  }
2097
- async function foldStream(stream) {
2501
+ async function foldStream(stream, onProgress) {
2098
2502
  const tokens = { input: 0, output: 0 };
2099
2503
  let usd = 0;
2100
2504
  let iterations = 0;
@@ -2107,6 +2511,7 @@ async function foldStream(stream) {
2107
2511
  } else {
2108
2512
  iterations += 1;
2109
2513
  }
2514
+ onProgress?.({ iterations, tokens: { ...tokens }, usd, ms: 0 });
2110
2515
  }
2111
2516
  return { iterations, tokens, usd, ms: 0 };
2112
2517
  }
@@ -2312,22 +2717,49 @@ function createBudgetPool(root, now = Date.now) {
2312
2717
  }
2313
2718
 
2314
2719
  // src/runtime/supervise/supervisor.ts
2720
+ function maxSeqOf(events, pred) {
2721
+ let max = -1;
2722
+ for (const ev of events) if (pred(ev) && ev.seq > max) max = ev.seq;
2723
+ return max;
2724
+ }
2315
2725
  var defaultMaxDepth = 4;
2316
2726
  function createSupervisor() {
2317
2727
  let attached;
2318
2728
  async function run(root, task, opts) {
2319
2729
  const now = opts.now ?? Date.now;
2320
2730
  const pool = createBudgetPool(opts.budget, now);
2321
- await opts.journal.beginTree(opts.runId, new Date(now()).toISOString());
2322
- await opts.journal.appendEvent(opts.runId, {
2323
- kind: "spawned",
2324
- id: opts.runId,
2325
- label: "root",
2326
- budget: opts.budget,
2327
- runtime: "inline",
2328
- seq: 0,
2329
- at: new Date(now()).toISOString()
2330
- });
2731
+ const prior = opts.resume === true ? await opts.journal.loadTree(opts.runId) : void 0;
2732
+ const resuming = prior !== void 0 && prior.length > 0;
2733
+ let resumeFrom;
2734
+ if (resuming) {
2735
+ const settled = await replaySpawnTree(opts.journal, opts.blobs, opts.runId);
2736
+ const view = materializeTreeView(prior);
2737
+ resumeFrom = {
2738
+ settled,
2739
+ view,
2740
+ maxSpawnOrdinal: maxSeqOf(prior, (ev) => ev.kind === "spawned"),
2741
+ maxCursorSeq: maxSeqOf(
2742
+ prior,
2743
+ (ev) => ev.kind === "settled" || ev.kind === "cancelled" || ev.kind === "woken"
2744
+ ),
2745
+ maxWaitOrdinal: maxSeqOf(prior, (ev) => ev.kind === "waiting"),
2746
+ // Waits armed but never woken: the run died mid-wait. They ride onto `Scope.resume.waits`,
2747
+ // and re-arming the same label adopts the ORIGINAL absolute deadline rather than
2748
+ // restarting the countdown from this process's clock.
2749
+ waits: pendingWaits(prior)
2750
+ };
2751
+ } else {
2752
+ await opts.journal.beginTree(opts.runId, new Date(now()).toISOString());
2753
+ await opts.journal.appendEvent(opts.runId, {
2754
+ kind: "spawned",
2755
+ id: opts.runId,
2756
+ label: "root",
2757
+ budget: opts.budget,
2758
+ runtime: "inline",
2759
+ seq: 0,
2760
+ at: new Date(now()).toISOString()
2761
+ });
2762
+ }
2331
2763
  const controller = new AbortController();
2332
2764
  const cascadeAbort = (reason) => {
2333
2765
  if (controller.signal.aborted) return;
@@ -2352,7 +2784,9 @@ function createSupervisor() {
2352
2784
  maxDepth: opts.maxDepth ?? defaultMaxDepth,
2353
2785
  signal: controller.signal,
2354
2786
  now,
2355
- hooks: opts.hooks
2787
+ hooks: opts.hooks,
2788
+ ...opts.probes ? { probes: opts.probes } : {},
2789
+ ...resumeFrom ? { resumeFrom } : {}
2356
2790
  });
2357
2791
  const openScope = scope;
2358
2792
  if (attached) {
@@ -2455,7 +2889,8 @@ function wrapJournalForBreaker(journal, breaker) {
2455
2889
  };
2456
2890
  }
2457
2891
  async function drainLiveChildren(scope, controller) {
2458
- const hasLive = scope.view.inFlight > 0;
2892
+ const view = scope.view;
2893
+ const hasLive = view.inFlight > 0 || view.waiting > 0;
2459
2894
  if (!hasLive) return;
2460
2895
  if (!controller.signal.aborted) controller.abort();
2461
2896
  await Promise.allSettled([drainCursor(scope)]);
@@ -3072,6 +3507,15 @@ export {
3072
3507
  composeRuntimeHooks,
3073
3508
  notifyRuntimeHookEvent,
3074
3509
  notifyRuntimeDecisionPoint,
3510
+ DEFAULT_STALL_AFTER_MS,
3511
+ createActivityLog,
3512
+ readWorkerProgress,
3513
+ timerAt,
3514
+ pollFor,
3515
+ createWaitProbes,
3516
+ isWaitOutcome,
3517
+ waitUntil,
3518
+ validateWaitSpec,
3075
3519
  createScope,
3076
3520
  settledToIteration,
3077
3521
  withDriverExecutor,
@@ -3079,4 +3523,4 @@ export {
3079
3523
  createBudgetPool,
3080
3524
  createSupervisor
3081
3525
  };
3082
- //# sourceMappingURL=chunk-SQ3ZJH3Y.js.map
3526
+ //# sourceMappingURL=chunk-6WZZXQV5.js.map