@tangle-network/agent-runtime 0.102.2 → 0.103.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -10
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +5 -5
- package/dist/analyst-loop.d.ts +1 -1
- package/dist/candidate-execution/index.d.ts +5 -41
- package/dist/candidate-execution/index.js +8 -6
- package/dist/{chunk-QCXD7NHM.js → chunk-3LJF5XSE.js} +79 -334
- package/dist/chunk-3LJF5XSE.js.map +1 -0
- package/dist/{chunk-3DW5DEKQ.js → chunk-5AITUUHO.js} +3 -3
- package/dist/{chunk-SQ3ZJH3Y.js → chunk-6WZZXQV5.js} +467 -23
- package/dist/chunk-6WZZXQV5.js.map +1 -0
- package/dist/{chunk-SCOHHMKU.js → chunk-AAN2MB2X.js} +3 -3
- package/dist/{chunk-KSM6GFHP.js → chunk-B7K7V22Y.js} +2 -2
- package/dist/{chunk-ZUCUAFVF.js → chunk-EAQ5YRRY.js} +1382 -62
- package/dist/chunk-EAQ5YRRY.js.map +1 -0
- package/dist/chunk-ISPWRSEC.js +408 -0
- package/dist/chunk-ISPWRSEC.js.map +1 -0
- package/dist/{chunk-7FJJUC73.js → chunk-LFM4JBRW.js} +29 -6
- package/dist/{chunk-7FJJUC73.js.map → chunk-LFM4JBRW.js.map} +1 -1
- package/dist/{chunk-ROILMKDL.js → chunk-QYCKIV6C.js} +3 -3
- package/dist/{chunk-LJLG734E.js → chunk-SBTWKPVR.js} +10 -11
- package/dist/{chunk-LJLG734E.js.map → chunk-SBTWKPVR.js.map} +1 -1
- package/dist/{chunk-CK76OZPM.js → chunk-SNSMRT6H.js} +56 -386
- package/dist/chunk-SNSMRT6H.js.map +1 -0
- package/dist/{chunk-EKUMRQNR.js → chunk-TUSOOIDV.js} +2 -2
- package/dist/{chunk-J6V6DWWS.js → chunk-ZOYN3JR5.js} +5 -5
- package/dist/{chunk-377GOJHJ.js → chunk-ZXICDSAK.js} +333 -4
- package/dist/chunk-ZXICDSAK.js.map +1 -0
- package/dist/{completion-gate-C6dhVN-N.d.ts → completion-gate-DLINnrkM.d.ts} +1 -1
- package/dist/{coordination-D9l_YmwW.d.ts → coordination-DTehA977.d.ts} +250 -8
- package/dist/environment-provider.d.ts +2 -2
- package/dist/index.d.ts +12 -12
- package/dist/index.js +17 -15
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +26 -8
- package/dist/intelligence.js +24 -7
- package/dist/intelligence.js.map +1 -1
- package/dist/knowledge.d.ts +6 -6
- package/dist/knowledge.js +9 -9
- package/dist/{loop-runner-bin-PnWslIw4.d.ts → loop-runner-bin-DhIXsLAd.d.ts} +2 -2
- package/dist/loop-runner-bin.d.ts +5 -5
- package/dist/loop-runner-bin.js +6 -6
- package/dist/loops.d.ts +305 -148
- package/dist/loops.js +82 -14
- package/dist/mcp/bin.js +3 -3
- package/dist/mcp/index.d.ts +6 -6
- package/dist/mcp/index.js +6 -6
- package/dist/profiles.d.ts +1 -1
- package/dist/{profile-DbfaMTdk.d.ts → protected-model-port-DzkUY3HQ.d.ts} +41 -3
- package/dist/{structural-rollout-D7xik9XR.d.ts → structural-rollout-BFPIy3iw.d.ts} +3 -3
- package/dist/supervise-Cp8bNcJi.d.ts +379 -0
- package/dist/testing.js +10 -10
- package/dist/testing.js.map +1 -1
- package/dist/{types-CWqfCO8s.d.ts → types-Cbp72qyu.d.ts} +1 -1
- package/dist/{types-CLat4bT9.d.ts → types-DK11_O4L.d.ts} +1 -1
- package/dist/types-lZTE_LBd.d.ts +957 -0
- package/dist/{worktree-fanout-DsIR4d6w.d.ts → worktree-fanout-DiiJWjJO.d.ts} +17 -5
- package/package.json +3 -2
- package/skills/build-with-agent-runtime/SKILL.md +7 -5
- package/skills/generate-eval/SKILL.md +45 -52
- package/skills/loop-writer/SKILL.md +79 -147
- package/skills/supervise/SKILL.md +33 -14
- package/dist/chunk-377GOJHJ.js.map +0 -1
- package/dist/chunk-CK76OZPM.js.map +0 -1
- package/dist/chunk-IMSNJSXH.js +0 -73
- package/dist/chunk-IMSNJSXH.js.map +0 -1
- package/dist/chunk-QCXD7NHM.js.map +0 -1
- package/dist/chunk-SQ3ZJH3Y.js.map +0 -1
- package/dist/chunk-ZUCUAFVF.js.map +0 -1
- package/dist/supervise-BQdNAXtK.d.ts +0 -131
- package/dist/types-D870JlH0.d.ts +0 -500
- /package/dist/{chunk-3DW5DEKQ.js.map → chunk-5AITUUHO.js.map} +0 -0
- /package/dist/{chunk-SCOHHMKU.js.map → chunk-AAN2MB2X.js.map} +0 -0
- /package/dist/{chunk-KSM6GFHP.js.map → chunk-B7K7V22Y.js.map} +0 -0
- /package/dist/{chunk-ROILMKDL.js.map → chunk-QYCKIV6C.js.map} +0 -0
- /package/dist/{chunk-EKUMRQNR.js.map → chunk-TUSOOIDV.js.map} +0 -0
- /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-
|
|
6
|
+
} from "./chunk-LFM4JBRW.js";
|
|
7
7
|
import {
|
|
8
8
|
canonicalCandidateDigest,
|
|
9
9
|
canonicalCandidateDocument,
|
|
10
10
|
immutableCandidateValue,
|
|
11
11
|
verifyCanonicalCandidateDocument
|
|
12
|
-
} from "./chunk-
|
|
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-
|
|
200
|
+
//# sourceMappingURL=chunk-5AITUUHO.js.map
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
-
contentAddress
|
|
3
|
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
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
|
|
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-
|
|
3526
|
+
//# sourceMappingURL=chunk-6WZZXQV5.js.map
|