@tangle-network/agent-runtime 0.348.1 → 0.350.2
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/dist/{activation-BEGalhOL.js → activation-CfJMyzEs.js} +12 -14
- package/dist/{activation-BEGalhOL.js.map → activation-CfJMyzEs.js.map} +1 -1
- package/dist/{activation-NQZP_mdI.d.ts → activation-DyiHrTlS.d.ts} +2 -24
- package/dist/agent.d.ts +8 -12
- package/dist/agent.js +9 -12
- package/dist/agent.js.map +1 -1
- package/dist/{analyst-loop-DZw5QWT9.js → analyst-loop-BZvXCDKy.js} +2 -3
- package/dist/{analyst-loop-DZw5QWT9.js.map → analyst-loop-BZvXCDKy.js.map} +1 -1
- package/dist/analyst-loop.d.ts +3 -5
- package/dist/analyst-loop.js +1 -2
- package/dist/{bundle-DKQtOO9d.js → bundle-Ze8pd07a.js} +3 -4
- package/dist/{bundle-DKQtOO9d.js.map → bundle-Ze8pd07a.js.map} +1 -1
- package/dist/candidate-execution/index.d.ts +13 -33
- package/dist/candidate-execution/index.js +16 -18
- package/dist/candidate-execution/index.js.map +1 -1
- package/dist/{coordination-manager-Bm6leXc6.js → coordination-manager-BkVfWlMz.js} +101 -132
- package/dist/coordination-manager-BkVfWlMz.js.map +1 -0
- package/dist/{delegate-Cp5-PsaX.js → delegate-DgEie4ad.js} +19 -21
- package/dist/delegate-DgEie4ad.js.map +1 -0
- package/dist/durable.d.ts +13 -23
- package/dist/durable.js +48 -43
- package/dist/durable.js.map +1 -1
- package/dist/{errors-DodWX-cb.js → errors-wuhGvpE3.js} +2 -3
- package/dist/{errors-DodWX-cb.js.map → errors-wuhGvpE3.js.map} +1 -1
- package/dist/{graph-CE_pzU31.js → graph-Cx0FhKSE.js} +192 -15
- package/dist/graph-Cx0FhKSE.js.map +1 -0
- package/dist/{improve-wT11zteg.js → improve-i0HU1-aa.js} +35 -53
- package/dist/{improve-wT11zteg.js.map → improve-i0HU1-aa.js.map} +1 -1
- package/dist/{improvement-adapter-sIthWkcN.d.ts → improvement-adapter-D5GRU1eY.d.ts} +2 -6
- package/dist/index.d.ts +41 -89
- package/dist/index.js +43 -61
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +39 -59
- package/dist/intelligence.js +23 -33
- package/dist/intelligence.js.map +1 -1
- package/dist/kernel.d.ts +5 -5
- package/dist/kernel.js +11 -11
- package/dist/{loop-runner-CZzeeJTG.js → loop-runner-BwN9MhdP.js} +5 -6
- package/dist/{loop-runner-CZzeeJTG.js.map → loop-runner-BwN9MhdP.js.map} +1 -1
- package/dist/{loop-runner-CY5HHhtR.d.ts → loop-runner-DvfOXVx9.d.ts} +3 -5
- package/dist/loop-runner-bin.d.ts +5 -8
- package/dist/loop-runner-bin.js +2 -3
- package/dist/mcp/bin.js +6 -8
- package/dist/mcp/bin.js.map +1 -1
- package/dist/mcp/index.d.ts +8 -18
- package/dist/mcp/index.js +17 -25
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/memory-bin.js +4 -6
- package/dist/mcp/memory-bin.js.map +1 -1
- package/dist/{model-policy-CyCUwHed.js → model-policy-GSxWwP-b.js} +11 -13
- package/dist/model-policy-GSxWwP-b.js.map +1 -0
- package/dist/placement.d.ts +12 -14
- package/dist/placement.js +1 -2
- package/dist/platform.d.ts +7 -13
- package/dist/platform.js +3 -6
- package/dist/platform.js.map +1 -1
- package/dist/{prepare-TEEHSJwq.js → prepare-DE8TQnLu.js} +49 -69
- package/dist/{prepare-TEEHSJwq.js.map → prepare-DE8TQnLu.js.map} +1 -1
- package/dist/{profile-6OLpbjvV.js → profile-CAhZDW2T.js} +58 -92
- package/dist/profile-CAhZDW2T.js.map +1 -0
- package/dist/{profile-materialization-bPm0gGLO.d.ts → profile-materialization-BRY22Oh8.d.ts} +1 -3
- package/dist/profiles.d.ts +25 -12
- package/dist/profiles.js +52 -11
- package/dist/profiles.js.map +1 -1
- package/dist/{protected-model-port-DVVh-hEk.d.ts → protected-model-port-IKqhTypD.d.ts} +2 -14
- package/dist/{protected-redaction-DFCeo4vg.js → protected-redaction-DilFZch5.js} +2 -3
- package/dist/{protected-redaction-DFCeo4vg.js.map → protected-redaction-DilFZch5.js.map} +1 -1
- package/dist/{provision-supervisor-CC0HdOHo.js → provision-supervisor-Bde_FF0R.js} +11 -15
- package/dist/{provision-supervisor-CC0HdOHo.js.map → provision-supervisor-Bde_FF0R.js.map} +1 -1
- package/dist/{record-events-D93DkpAx.js → record-events-B2GUgYdz.js} +12 -14
- package/dist/{record-events-D93DkpAx.js.map → record-events-B2GUgYdz.js.map} +1 -1
- package/dist/{run-cancellation-CzFhQGMa.js → run-cancellation-BLy_Zz-w.js} +6 -7
- package/dist/{run-cancellation-CzFhQGMa.js.map → run-cancellation-BLy_Zz-w.js.map} +1 -1
- package/dist/{runtime-B_40dXlF.js → runtime-6Ec9sHRe.js} +833 -215
- package/dist/runtime-6Ec9sHRe.js.map +1 -0
- package/dist/{runtime-hooks-tXpAarhW.js → runtime-hooks-CsW2pfFk.js} +2 -3
- package/dist/{runtime-hooks-tXpAarhW.js.map → runtime-hooks-CsW2pfFk.js.map} +1 -1
- package/dist/{runtime-hooks-nsqxSUFL.d.ts → runtime-hooks-ZQqPw-0g.d.ts} +1 -3
- package/dist/{sandbox-profile-compat-_fEtHPCj.js → sandbox-profile-compat-BxMQ1VXv.js} +62 -44
- package/dist/sandbox-profile-compat-BxMQ1VXv.js.map +1 -0
- package/dist/{search-executor-COd2F2wp.js → search-executor-B7g_5Wjl.js} +12 -17
- package/dist/search-executor-B7g_5Wjl.js.map +1 -0
- package/dist/{server-BGB4R4wQ.js → server-fvEMwGMQ.js} +19 -30
- package/dist/{server-BGB4R4wQ.js.map → server-fvEMwGMQ.js.map} +1 -1
- package/dist/{structural-rollout-Wl_rCuzM.js → structural-rollout-B86bSixU.js} +69 -70
- package/dist/structural-rollout-B86bSixU.js.map +1 -0
- package/dist/{substrate-CGDFTSRh.js → substrate-Db2pp6y3.js} +2 -3
- package/dist/{substrate-CGDFTSRh.js.map → substrate-Db2pp6y3.js.map} +1 -1
- package/dist/{supervise-BUOeThuB.js → supervise-CaeZcgAW.js} +615 -203
- package/dist/supervise-CaeZcgAW.js.map +1 -0
- package/dist/{supervisor-DDy0aEtR.js → supervisor-C1OePYE-.js} +526 -642
- package/dist/supervisor-C1OePYE-.js.map +1 -0
- package/dist/{task-queue-0fKkoweu.d.ts → task-queue-kefGy79U.d.ts} +1 -3
- package/dist/task-queue.d.ts +1 -1
- package/dist/task-queue.js +1 -2
- package/dist/testing.d.ts +8 -16
- package/dist/testing.js +241 -244
- package/dist/testing.js.map +1 -1
- package/dist/tool-loop.d.ts +16 -19
- package/dist/tool-loop.js +2 -3
- package/dist/{tool-server-XV4aJwoQ.js → tool-server-CwuYeW_Z.js} +3 -4
- package/dist/{tool-server-XV4aJwoQ.js.map → tool-server-CwuYeW_Z.js.map} +1 -1
- package/dist/{top-snapshot-CflmaDgk.js → top-snapshot-ChwpTr7A.js} +4 -5
- package/dist/{top-snapshot-CflmaDgk.js.map → top-snapshot-ChwpTr7A.js.map} +1 -1
- package/dist/tui/bin.js +7 -9
- package/dist/tui/bin.js.map +1 -1
- package/dist/tui/index.d.ts +3 -5
- package/dist/tui/index.js +2 -2
- package/dist/{types-hc4cmSc7.d.ts → types-Fowuwdz2.d.ts} +555 -503
- package/dist/{types-Cwrea-bU.d.ts → types-qsqfyQoY.d.ts} +1 -3
- package/dist/workspace-store/index.d.ts +12 -22
- package/dist/workspace-store/index.js +4 -7
- package/dist/workspace-store/index.js.map +1 -1
- package/dist/{workspace-streams-BiS4ABah.d.ts → workspace-streams-Dq2Fzk3c.d.ts} +1 -11
- package/package.json +25 -25
- package/skills/agent-graphs/SKILL.md +19 -4
- package/skills/be-ambitious/SKILL.md +46 -0
- package/skills/graph-designer/SKILL.md +15 -2
- package/skills/profile-authoring/SKILL.md +1 -1
- package/dist/coordination-manager-Bm6leXc6.js.map +0 -1
- package/dist/delegate-Cp5-PsaX.js.map +0 -1
- package/dist/graph-CE_pzU31.js.map +0 -1
- package/dist/model-policy-CyCUwHed.js.map +0 -1
- package/dist/profile-6OLpbjvV.js.map +0 -1
- package/dist/runtime-B_40dXlF.js.map +0 -1
- package/dist/sandbox-profile-compat-_fEtHPCj.js.map +0 -1
- package/dist/search-executor-COd2F2wp.js.map +0 -1
- package/dist/structural-rollout-Wl_rCuzM.js.map +0 -1
- package/dist/supervise-BUOeThuB.js.map +0 -1
- package/dist/supervisor-DDy0aEtR.js.map +0 -1
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { s as writeAtomicDurableFile } from "./record-events-
|
|
2
|
-
import { At as createExecutor, Ct as readCommittedJsonLines, Dt as createExecutorRegistry, Et as insideCursorNamespace, Ft as assertBoxlessPromptOptions, I as coordinationProfileToolPrefix, It as readPromptOptions, Jt as routerBrain,
|
|
3
|
-
import { i as ConfigError, m as ValidationError, n as AnalystError, s as PlannerError } from "./errors-
|
|
4
|
-
import { D as runAgentic, E as refine, M as renderReport, N as profileChatClient, O as sample, j as observe, k as ObservationError, v as loadAuthoredStrategy, x as strategyAuthorContract, y as requestStrategySource } from "./structural-rollout-
|
|
5
|
-
import { $ as
|
|
6
|
-
import { c as profileModelExecutionSettings, i as concreteModelId, l as profileProviderModel, o as enforceTokenLimits, p as canonicalObservedModelParts, t as assertExecutableAgentProfile, v as harnessRunsAgent } from "./model-policy-
|
|
7
|
-
import { i as notifyRuntimeHookEvent } from "./runtime-hooks-
|
|
8
|
-
import { a as reconcileInterruptedSearchCalls, c as searchExecutor, r as dedicatedLane, x as runtimeShipDecision } from "./search-executor-
|
|
9
|
-
import {
|
|
10
|
-
import { A as
|
|
11
|
-
import "./run-cancellation-
|
|
12
|
-
import { i as redactProtectedValue, r as redactProtectedReason } from "./protected-redaction-
|
|
13
|
-
import "./provision-supervisor-
|
|
14
|
-
import "./delegate-
|
|
15
|
-
import "./graph-
|
|
1
|
+
import { s as writeAtomicDurableFile } from "./record-events-B2GUgYdz.js";
|
|
2
|
+
import { At as createExecutor, Bi as detachedSnapshot, Ci as executableAgentSpecSnapshot, Ct as readCommittedJsonLines, Di as runtimeFailureCauseSchema, Dt as createExecutorRegistry, Et as insideCursorNamespace, Ft as assertBoxlessPromptOptions, I as coordinationProfileToolPrefix, It as readPromptOptions, Jt as routerBrain, Pr as runAbortable, Pt as runAgentRounds, Rt as createSandboxLineage, Si as executableAgentProfileSnapshot, St as readCommittedJsonFile, Tt as withJsonlFileLock, Vi as contentAddress, Vt as defaultSelectWinner, W as rollingDispatch, _ as withDriverExecutor, _t as InMemorySpawnJournal, b as isTraceAnalysisStore, bt as isNoEntError, dr as CheckUnavailableError, gt as InMemoryResultBlobStore, hn as createWorktreeCliExecutor, hr as verdictFromJudgeScore, ia as createSandboxTurnEventCollector, mr as mapExecutorResult, n as createSupervisor, pr as gateOnDeliverable, sa as notifySandboxEventObserver, wt as upsertCommittedJsonLine, yt as appendCommittedJsonLine, z as settledToIteration, zi as detachedFrozen } from "./supervisor-C1OePYE-.js";
|
|
3
|
+
import { i as ConfigError, m as ValidationError, n as AnalystError, s as PlannerError } from "./errors-wuhGvpE3.js";
|
|
4
|
+
import { D as runAgentic, E as refine, M as renderReport, N as profileChatClient, O as sample, j as observe, k as ObservationError, v as loadAuthoredStrategy, x as strategyAuthorContract, y as requestStrategySource } from "./structural-rollout-B86bSixU.js";
|
|
5
|
+
import { $ as hasCompleteCacheBreakdown, B as sha256Bytes$1, C as WorkspaceScanLimitError, E as captureMaterializedWorkspace, G as addSpend, J as cloneSpend, P as canonicalCandidateDigest$1, Q as fnv1a32Hex, R as immutableCandidateValue, Z as errorMessage, ct as stringifySafe, et as isAbortError, h as markPutStreamVerified, it as randomSuffix, nt as mapWithConcurrency, pt as zeroSpend, q as chargedTokens, st as sleep, tt as isAsyncIterable, wt as armDeadlineTimer } from "./sandbox-profile-compat-BxMQ1VXv.js";
|
|
6
|
+
import { a as concreteProfileModel, c as profileModelExecutionSettings, i as concreteModelId, l as profileProviderModel, o as enforceTokenLimits, p as canonicalObservedModelParts, t as assertExecutableAgentProfile, v as harnessRunsAgent } from "./model-policy-GSxWwP-b.js";
|
|
7
|
+
import { i as notifyRuntimeHookEvent } from "./runtime-hooks-CsW2pfFk.js";
|
|
8
|
+
import { a as reconcileInterruptedSearchCalls, c as searchExecutor, r as dedicatedLane, x as runtimeShipDecision } from "./search-executor-B7g_5Wjl.js";
|
|
9
|
+
import { a as downMessageRefusalReasons, h as createInMemoryRunContext, v as foldCoordinationRecords } from "./coordination-manager-BkVfWlMz.js";
|
|
10
|
+
import { A as graphRouteWhenSchema, D as compileGraphParameters, E as bindGraphParameters, L as coordinationControlToolNames, O as graphTriggerBindingsSchema, T as assertGraphTriggerBindings, X as validateGraphTopology, f as graphDigest, h as graphRunsFor, k as graphFileSchema, m as graphRegistry, p as graphFromStored, q as validateFlowGraph, rt as kernelPromptRegistry, t as supervise, u as digestOfGraph, w as taskShapeDigest, x as recordGraphRun, y as lookupGraph, z as runBrainLoop } from "./supervise-CaeZcgAW.js";
|
|
11
|
+
import "./run-cancellation-BLy_Zz-w.js";
|
|
12
|
+
import { i as redactProtectedValue, r as redactProtectedReason } from "./protected-redaction-DilFZch5.js";
|
|
13
|
+
import "./provision-supervisor-Bde_FF0R.js";
|
|
14
|
+
import "./delegate-DgEie4ad.js";
|
|
15
|
+
import "./graph-Cx0FhKSE.js";
|
|
16
16
|
import { agentProfileSchema, canonicalAgentProfileDigest, canonicalCandidateDigest, sha256Bytes, validateAgentProfileSecurity } from "@tangle-network/agent-interface";
|
|
17
17
|
import { CODING_HARNESSES, DEFAULT_TRACE_ANALYST_KINDS, InMemoryTraceStore, OUTPUT_VALUE, benjaminiHochberg, buildTrajectory, computeFindingId as computeFindingId$1, confidenceInterval, createTraceAnalyst, expandProfileAxes, makeFinding as makeFinding$1, pairedBootstrap, paretoFrontier, wilcoxonSignedRank, wilson } from "@tangle-network/agent-eval";
|
|
18
18
|
import { createAgentRunOutcomeTracker } from "@tangle-network/sandbox/runtime";
|
|
19
19
|
import { collectAgentResponseText } from "@tangle-network/sandbox";
|
|
20
|
-
import { redact } from "@tangle-network/agent-eval/traces";
|
|
21
20
|
import { z } from "zod";
|
|
21
|
+
import { redact } from "@tangle-network/agent-eval/traces";
|
|
22
22
|
import { createHash, createHmac, randomUUID } from "node:crypto";
|
|
23
23
|
import { appendFileSync, chmodSync, constants, copyFileSync, lstatSync, mkdirSync, mkdtempSync, readlinkSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
24
|
-
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
24
|
+
import { dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
25
25
|
import { execFile, execFileSync, spawn, spawnSync } from "node:child_process";
|
|
26
26
|
import { chmod, link, lstat, mkdir, mkdtemp, open, opendir, readFile, readdir, readlink, realpath, rename, rm, stat, symlink, unlink, writeFile } from "node:fs/promises";
|
|
27
27
|
import { promisify } from "node:util";
|
|
@@ -32,9 +32,10 @@ import { defineEvaluationClaim, summarizeEvaluationUnits } from "@tangle-network
|
|
|
32
32
|
import { createInterface } from "node:readline";
|
|
33
33
|
import { Worker } from "node:worker_threads";
|
|
34
34
|
import { gzipSync } from "node:zlib";
|
|
35
|
+
import { parseDocument } from "yaml";
|
|
35
36
|
import { stuckLoopView, toolWasteView } from "@tangle-network/agent-eval/pipelines";
|
|
36
37
|
import { sha256Hex } from "@tangle-network/agent-core/node";
|
|
37
|
-
|
|
38
|
+
// src/durable/sql-run-store.ts
|
|
38
39
|
/** Refuses a competing or stale SQL run owner before it can publish new work. */
|
|
39
40
|
var SqlRunOwnershipError = class extends Error {
|
|
40
41
|
constructor(message) {
|
|
@@ -293,8 +294,7 @@ function wait(ms, signal) {
|
|
|
293
294
|
else signal?.addEventListener("abort", abort, { once: true });
|
|
294
295
|
});
|
|
295
296
|
}
|
|
296
|
-
|
|
297
|
-
//#region src/runtime/benchmark-report.ts
|
|
297
|
+
// src/runtime/benchmark-report.ts
|
|
298
298
|
/**
|
|
299
299
|
* benchmark-report — turn a fleet of `RunRecord`s into a publishable, multi-axis benchmark report:
|
|
300
300
|
* a ranked leaderboard, the full profile×axis score matrix, the cost/latency/token columns, and
|
|
@@ -623,9 +623,9 @@ function renderLeaderboardSvg(report) {
|
|
|
623
623
|
const x = labelW + c * cellW;
|
|
624
624
|
const s = r.perAxis[a];
|
|
625
625
|
if (s !== void 0) {
|
|
626
|
-
out.push(`<rect x="${x}" y="${y}" width="
|
|
627
|
-
out.push(`<text x="${x +
|
|
628
|
-
} else out.push(`<rect x="${x}" y="${y}" width="
|
|
626
|
+
out.push(`<rect x="${x}" y="${y}" width="51" height="22" fill="${ramp(s)}"/>`);
|
|
627
|
+
out.push(`<text x="${x + 51 / 2}" y="${y + 15}" text-anchor="middle" fill="white" font-size="10">${Math.round(100 * s)}</text>`);
|
|
628
|
+
} else out.push(`<rect x="${x}" y="${y}" width="51" height="22" fill="#f3f4f6"/>`);
|
|
629
629
|
});
|
|
630
630
|
});
|
|
631
631
|
out.push("</svg>");
|
|
@@ -658,8 +658,7 @@ ${rows}
|
|
|
658
658
|
</tbody></table>
|
|
659
659
|
</body></html>`;
|
|
660
660
|
}
|
|
661
|
-
|
|
662
|
-
//#region src/runtime/completion.ts
|
|
661
|
+
// src/runtime/completion.ts
|
|
663
662
|
/** Decide whether a `CompletionVerdict` may end the node under the policy: authority scales with the verdict's determinism, and probabilistic verdicts must clear `minConfidence`. */
|
|
664
663
|
function completionAuthorizes(v, policy) {
|
|
665
664
|
if (!v?.done) return false;
|
|
@@ -719,8 +718,7 @@ function deterministicCompletion(check) {
|
|
|
719
718
|
};
|
|
720
719
|
} };
|
|
721
720
|
}
|
|
722
|
-
|
|
723
|
-
//#region src/runtime/isolated-checker.ts
|
|
721
|
+
// src/runtime/isolated-checker.ts
|
|
724
722
|
const toolchains = [
|
|
725
723
|
"/usr",
|
|
726
724
|
"/bin",
|
|
@@ -856,7 +854,7 @@ var InputLimitError = class extends Error {};
|
|
|
856
854
|
async function copyBoundedTree(source, destination, maxBytes, maxEntries) {
|
|
857
855
|
let bytes = 0;
|
|
858
856
|
let entries = 0;
|
|
859
|
-
const buffer = Buffer.allocUnsafe(
|
|
857
|
+
const buffer = Buffer.allocUnsafe(1048576);
|
|
860
858
|
const visit = async (from, to, isRoot = false) => {
|
|
861
859
|
if (!isRoot && ++entries > (maxEntries ?? Number.MAX_SAFE_INTEGER)) throw new InputLimitError("Input tree exceeds maxInputEntries");
|
|
862
860
|
const info = await lstat(from);
|
|
@@ -1248,8 +1246,7 @@ async function removeScratch(path) {
|
|
|
1248
1246
|
throw new Error([permissionError, error].filter((value) => value !== void 0).map(String).join("; "));
|
|
1249
1247
|
}
|
|
1250
1248
|
}
|
|
1251
|
-
|
|
1252
|
-
//#region src/runtime/declared-check.ts
|
|
1249
|
+
// src/runtime/declared-check.ts
|
|
1253
1250
|
/**
|
|
1254
1251
|
* A declared check: the one frozen evaluator program that decides "done" for a run, named by
|
|
1255
1252
|
* digest, run by Runtime in a fresh box on the check account.
|
|
@@ -1282,7 +1279,7 @@ async function removeScratch(path) {
|
|
|
1282
1279
|
const INPUT_DIR = "_input";
|
|
1283
1280
|
const STATE_DIR = "state";
|
|
1284
1281
|
const SEALED_DIR = "_sealed";
|
|
1285
|
-
const DEFAULT_TIMEOUT_MS =
|
|
1282
|
+
const DEFAULT_TIMEOUT_MS = 9e5;
|
|
1286
1283
|
/** Refuse a malformed declaration before any compute. */
|
|
1287
1284
|
function assertDeclaredCheck(check, context) {
|
|
1288
1285
|
const fail = (message) => {
|
|
@@ -1489,8 +1486,7 @@ async function writeFiles(files, to) {
|
|
|
1489
1486
|
await writeFile(path, file.bytes, { mode: file.mode });
|
|
1490
1487
|
}
|
|
1491
1488
|
}
|
|
1492
|
-
|
|
1493
|
-
//#region src/runtime/loop-dispatch.ts
|
|
1489
|
+
// src/runtime/loop-dispatch.ts
|
|
1494
1490
|
/** Bridge a campaign `DispatchContext.trace` to a `LoopTraceEmitter` so every
|
|
1495
1491
|
* `loop.*` event lands as a span under the cell's scoped trace. */
|
|
1496
1492
|
function campaignTraceToLoopEmitter(trace) {
|
|
@@ -1737,8 +1733,7 @@ function loopCampaignDispatch(opts) {
|
|
|
1737
1733
|
function loopDispatch(opts) {
|
|
1738
1734
|
return (profile, scenario, ctx) => runLoopForCell(opts, scenario, profile, ctx);
|
|
1739
1735
|
}
|
|
1740
|
-
|
|
1741
|
-
//#region src/runtime/inline-sandbox-client.ts
|
|
1736
|
+
// src/runtime/inline-sandbox-client.ts
|
|
1742
1737
|
/**
|
|
1743
1738
|
* The ONE pseudo-box adapter: present any one-shot `Executor` (router / bridge /
|
|
1744
1739
|
* BYO) as a `SandboxClient` so the round-synchronous `runAgentRounds` can drive it
|
|
@@ -1782,8 +1777,10 @@ function inlineSandboxClient(factory, defaults = {}) {
|
|
|
1782
1777
|
const controller = new AbortController();
|
|
1783
1778
|
const callerSignal = opts?.signal;
|
|
1784
1779
|
const onAbort = () => controller.abort(callerSignal?.reason ?? /* @__PURE__ */ new Error("prompt aborted"));
|
|
1785
|
-
if (callerSignal)
|
|
1786
|
-
|
|
1780
|
+
if (callerSignal) {
|
|
1781
|
+
if (callerSignal.aborted) onAbort();
|
|
1782
|
+
else callerSignal.addEventListener("abort", onAbort, { once: true });
|
|
1783
|
+
}
|
|
1787
1784
|
const requestedProfile = (options?.backend && typeof options.backend === "object" ? options.backend.profile : void 0) ?? capturedDefaultProfile;
|
|
1788
1785
|
const parsedProfile = agentProfileSchema.safeParse(requestedProfile);
|
|
1789
1786
|
if (!parsedProfile.success) throw new Error("inlineSandboxClient: an exact AgentProfile is required; pass defaults.profile or create({ backend: { profile } })");
|
|
@@ -1852,8 +1849,7 @@ function inlineSandboxClient(factory, defaults = {}) {
|
|
|
1852
1849
|
};
|
|
1853
1850
|
} };
|
|
1854
1851
|
}
|
|
1855
|
-
|
|
1856
|
-
//#region src/runtime/http-mcp-client.ts
|
|
1852
|
+
// src/runtime/http-mcp-client.ts
|
|
1857
1853
|
/**
|
|
1858
1854
|
* `connectHttpMcp` — the remote (streamable HTTP) MCP client, sibling of
|
|
1859
1855
|
* `connectStdioMcp`. Same connection contract (`tools`, `callTool`, `close`),
|
|
@@ -2012,8 +2008,7 @@ async function connectHttpMcp(spec) {
|
|
|
2012
2008
|
throw error instanceof Error ? error : new Error(String(error));
|
|
2013
2009
|
}
|
|
2014
2010
|
}
|
|
2015
|
-
|
|
2016
|
-
//#region src/runtime/key-provider.ts
|
|
2011
|
+
// src/runtime/key-provider.ts
|
|
2017
2012
|
/** The env-backed provider: reads the (dotenvx-loaded) process env. Empty /
|
|
2018
2013
|
* whitespace-only values count as absent — fail loud, not with a blank key. */
|
|
2019
2014
|
function envKeyProvider(env = process.env) {
|
|
@@ -2112,8 +2107,7 @@ async function resolveMcpServerLaunch(server, keys, label) {
|
|
|
2112
2107
|
...Object.keys(protectedEnv).length > 0 ? { protectedEnv } : {}
|
|
2113
2108
|
};
|
|
2114
2109
|
}
|
|
2115
|
-
|
|
2116
|
-
//#region src/runtime/mcp-environment.ts
|
|
2110
|
+
// src/runtime/mcp-environment.ts
|
|
2117
2111
|
/** POST JSON-RPC and parse a JSON body OR the last `data:` line of an SSE stream.
|
|
2118
2112
|
* Retries thrown fetches (transient network) with linear backoff; HTTP status and
|
|
2119
2113
|
* JSON-RPC errors are returned to the caller, not retried. */
|
|
@@ -2217,8 +2211,7 @@ function createMcpEnvironment(opts) {
|
|
|
2217
2211
|
}
|
|
2218
2212
|
};
|
|
2219
2213
|
}
|
|
2220
|
-
|
|
2221
|
-
//#region src/runtime/stdio-mcp-client.ts
|
|
2214
|
+
// src/runtime/stdio-mcp-client.ts
|
|
2222
2215
|
/**
|
|
2223
2216
|
* Same-host stdio MCP: the ONE persistent newline-delimited JSON-RPC 2.0
|
|
2224
2217
|
* connection to a spawned MCP server child process. This is the handshake
|
|
@@ -2454,7 +2447,10 @@ async function resolveRemoteMcpHeaders(server, keys, label) {
|
|
|
2454
2447
|
*/
|
|
2455
2448
|
async function materializeLocalMcp(profile, opts = {}) {
|
|
2456
2449
|
const security = validateAgentProfileSecurity(profile, opts.profileSecurityPolicy);
|
|
2457
|
-
if (!security.ok)
|
|
2450
|
+
if (!security.ok) {
|
|
2451
|
+
const reasons = security.issues.filter((issue) => issue.level === "error").map((issue) => issue.message).join("; ");
|
|
2452
|
+
throw new ValidationError(`materializeLocalMcp: profile host execution refused: ${reasons}`);
|
|
2453
|
+
}
|
|
2458
2454
|
const maxResultChars = opts.maxResultChars ?? 2e3;
|
|
2459
2455
|
const connections = [];
|
|
2460
2456
|
const routes = /* @__PURE__ */ new Map();
|
|
@@ -2540,8 +2536,7 @@ async function materializeLocalMcp(profile, opts = {}) {
|
|
|
2540
2536
|
close
|
|
2541
2537
|
};
|
|
2542
2538
|
}
|
|
2543
|
-
|
|
2544
|
-
//#region src/runtime/local-sandbox-client.ts
|
|
2539
|
+
// src/runtime/local-sandbox-client.ts
|
|
2545
2540
|
/**
|
|
2546
2541
|
* `localSandboxClient` — the SAME-HOST pseudo-box: a `SandboxClient` whose
|
|
2547
2542
|
* `create()` MATERIALIZES the profile's stdio MCP servers as local child
|
|
@@ -2657,8 +2652,7 @@ function localSandboxClient(opts) {
|
|
|
2657
2652
|
};
|
|
2658
2653
|
} };
|
|
2659
2654
|
}
|
|
2660
|
-
|
|
2661
|
-
//#region src/runtime/resolve-sandbox-client.ts
|
|
2655
|
+
// src/runtime/resolve-sandbox-client.ts
|
|
2662
2656
|
/**
|
|
2663
2657
|
* The product-facing backend selector: one call picks the execution transport a
|
|
2664
2658
|
* `runAgentRounds` (or any consumer that drives a `SandboxClient`) runs on, from the
|
|
@@ -2719,8 +2713,7 @@ function resolveSandboxClient(opts) {
|
|
|
2719
2713
|
}
|
|
2720
2714
|
}
|
|
2721
2715
|
}
|
|
2722
|
-
|
|
2723
|
-
//#region src/runtime/define-leaderboard.ts
|
|
2716
|
+
// src/runtime/define-leaderboard.ts
|
|
2724
2717
|
/**
|
|
2725
2718
|
* `defineLeaderboard` — the declarative eval-leaderboard facade.
|
|
2726
2719
|
*
|
|
@@ -3069,8 +3062,7 @@ function defineLeaderboard(spec) {
|
|
|
3069
3062
|
toBenchmarkAdapter: () => leaderboardBenchmarkAdapter(spec)
|
|
3070
3063
|
};
|
|
3071
3064
|
}
|
|
3072
|
-
|
|
3073
|
-
//#region src/runtime/harvest-corpus.ts
|
|
3065
|
+
// src/runtime/harvest-corpus.ts
|
|
3074
3066
|
/**
|
|
3075
3067
|
* Analyze completed runs through the selected observer and retain findings in a corpus.
|
|
3076
3068
|
*
|
|
@@ -3167,8 +3159,7 @@ async function harvestCorpus(opts) {
|
|
|
3167
3159
|
if (report.runsObserved === 0 && report.failures.length > 0) throw new HarvestError(report);
|
|
3168
3160
|
return report;
|
|
3169
3161
|
}
|
|
3170
|
-
|
|
3171
|
-
//#region src/runtime/in-process-sandbox-client.ts
|
|
3162
|
+
// src/runtime/in-process-sandbox-client.ts
|
|
3172
3163
|
/**
|
|
3173
3164
|
* The ONE in-process pseudo-box: present a plain user callback as a
|
|
3174
3165
|
* `SandboxClient` so an example or test can drive `runAgentRounds` / `openSandboxRun`
|
|
@@ -3288,8 +3279,7 @@ function inProcessSandboxClient(options) {
|
|
|
3288
3279
|
};
|
|
3289
3280
|
} };
|
|
3290
3281
|
}
|
|
3291
|
-
|
|
3292
|
-
//#region src/runtime/observation-registry.ts
|
|
3282
|
+
// src/runtime/observation-registry.ts
|
|
3293
3283
|
/** Adapt any Eval analyst registry, including recursive engines, to observation and harvesting. */
|
|
3294
3284
|
function observationFromRegistry(registry, options) {
|
|
3295
3285
|
if (!["production", "search"].includes(options.proposalOrigin)) throw new TypeError("registry observation requires an explicit production or search origin");
|
|
@@ -3328,8 +3318,7 @@ function observationFromRegistry(registry, options) {
|
|
|
3328
3318
|
}
|
|
3329
3319
|
};
|
|
3330
3320
|
}
|
|
3331
|
-
|
|
3332
|
-
//#region src/runtime/personify/analyst.ts
|
|
3321
|
+
// src/runtime/personify/analyst.ts
|
|
3333
3322
|
/**
|
|
3334
3323
|
* The diagnosis a combinator steers from must be TRACE-derived, never JUDGE-derived. A finding
|
|
3335
3324
|
* whose evidence is a judge/verdict score (an `EvidenceRef` of `kind:'metric'` with a
|
|
@@ -3452,8 +3441,7 @@ function observedBestScore(settledSoFar) {
|
|
|
3452
3441
|
}
|
|
3453
3442
|
return best;
|
|
3454
3443
|
}
|
|
3455
|
-
|
|
3456
|
-
//#region src/runtime/personify/combinators.ts
|
|
3444
|
+
// src/runtime/personify/combinators.ts
|
|
3457
3445
|
/**
|
|
3458
3446
|
*
|
|
3459
3447
|
* The generic combinator library — the content-free act-bodies the wave's §1 contract froze.
|
|
@@ -3915,8 +3903,7 @@ function blocked(blockers) {
|
|
|
3915
3903
|
blockers
|
|
3916
3904
|
};
|
|
3917
3905
|
}
|
|
3918
|
-
|
|
3919
|
-
//#region src/runtime/personify/corpus.ts
|
|
3906
|
+
// src/runtime/personify/corpus.ts
|
|
3920
3907
|
const corpusSchemaVersion = "1.0.0";
|
|
3921
3908
|
/**
|
|
3922
3909
|
* Assert a value is a well-formed `CorpusRecord`. A PROVENANCE-and-shape check: every
|
|
@@ -4121,8 +4108,7 @@ async function renderCorpusToInstructions(opts) {
|
|
|
4121
4108
|
function renderLine(record) {
|
|
4122
4109
|
return record.rationale ? `${record.claim} (${record.rationale})` : record.claim;
|
|
4123
4110
|
}
|
|
4124
|
-
|
|
4125
|
-
//#region src/runtime/personify/registry.ts
|
|
4111
|
+
// src/runtime/personify/registry.ts
|
|
4126
4112
|
/**
|
|
4127
4113
|
*
|
|
4128
4114
|
* The loop-shape registry — the OPEN, content-free extension point for the personify layer.
|
|
@@ -4170,8 +4156,7 @@ function createShapeRegistry() {
|
|
|
4170
4156
|
/** The default registry `runPersonified` resolves a shape name against. Empty by construction —
|
|
4171
4157
|
* a caller registers its own composed shapes; the engine ships no domain shape. */
|
|
4172
4158
|
const builtinShapes = createShapeRegistry();
|
|
4173
|
-
|
|
4174
|
-
//#region src/runtime/personify/persona.ts
|
|
4159
|
+
// src/runtime/personify/persona.ts
|
|
4175
4160
|
/**
|
|
4176
4161
|
*
|
|
4177
4162
|
* The personify layer impl — `definePersona` (the thin builder) + `runPersonified` (composes
|
|
@@ -4353,8 +4338,7 @@ function mergeSeams(ctx, seams) {
|
|
|
4353
4338
|
}
|
|
4354
4339
|
};
|
|
4355
4340
|
}
|
|
4356
|
-
|
|
4357
|
-
//#region src/runtime/personify/trajectory.ts
|
|
4341
|
+
// src/runtime/personify/trajectory.ts
|
|
4358
4342
|
/**
|
|
4359
4343
|
*
|
|
4360
4344
|
* Trajectory trace + cost ledger — the post-hoc tree reconstructor (§4 of `wave-types`).
|
|
@@ -4581,12 +4565,11 @@ function requireSpend(rolled, id, root) {
|
|
|
4581
4565
|
if (!spend) throw new Error(`trajectoryReport: node '${id}' was never rolled up in tree '${root}' (unreachable from root)`);
|
|
4582
4566
|
return spend;
|
|
4583
4567
|
}
|
|
4584
|
-
|
|
4585
|
-
//#region src/runtime/durable-sync.ts
|
|
4568
|
+
// src/runtime/durable-sync.ts
|
|
4586
4569
|
/**
|
|
4587
4570
|
* Threads that run fsync for the private CAS. Node runs every fs call on libuv's pool of four
|
|
4588
4571
|
* threads, and an fsync on a busy disk holds its thread until the filesystem journal commits. On
|
|
4589
|
-
* drew-gtr-pro's USB disk
|
|
4572
|
+
* drew-gtr-pro's USB disk all four sat in jbd2_log_wait_commit and rq_qos_wait while
|
|
4590
4573
|
* a tree capture had 16 files in flight: four fsyncs shared each journal commit, and every open,
|
|
4591
4574
|
* read, lstat and link of the capture queued behind them, at about one file per second. On
|
|
4592
4575
|
* threads of their own, every fsync in flight waits on the same commit and the pool stays free
|
|
@@ -4710,8 +4693,7 @@ async function syncDirectory(directory) {
|
|
|
4710
4693
|
await handle.close();
|
|
4711
4694
|
}
|
|
4712
4695
|
}
|
|
4713
|
-
|
|
4714
|
-
//#region src/runtime/private-cas-objects.ts
|
|
4696
|
+
// src/runtime/private-cas-objects.ts
|
|
4715
4697
|
/**
|
|
4716
4698
|
* The local object store of a private CAS: where an object lives, how it is written, read back
|
|
4717
4699
|
* and verified, and how a locator is checked. An object's name is published only after its bytes
|
|
@@ -4784,7 +4766,7 @@ async function* readObject(path, ref, signal) {
|
|
|
4784
4766
|
if (!stats.isFile() || stats.size !== ref.byteLength) throw new Error("private CAS object failed digest or length verification");
|
|
4785
4767
|
yield* checkedChunks(file.createReadStream({
|
|
4786
4768
|
autoClose: false,
|
|
4787
|
-
highWaterMark:
|
|
4769
|
+
highWaterMark: 65536
|
|
4788
4770
|
}), ref, signal);
|
|
4789
4771
|
} finally {
|
|
4790
4772
|
await file.close();
|
|
@@ -4966,8 +4948,7 @@ async function putPrivateCasBuffered(layout, offload, object, signal) {
|
|
|
4966
4948
|
}, signal);
|
|
4967
4949
|
return ref;
|
|
4968
4950
|
}
|
|
4969
|
-
|
|
4970
|
-
//#region src/runtime/private-cas-offload.ts
|
|
4951
|
+
// src/runtime/private-cas-offload.ts
|
|
4971
4952
|
/**
|
|
4972
4953
|
* Durable copies of a private CAS, and the offload passes that make them: one object at a time to
|
|
4973
4954
|
* the off-host store, with a stall bound, retries, a receipt on the host once the store holds the
|
|
@@ -5170,7 +5151,8 @@ var PrivateCasOffload = class {
|
|
|
5170
5151
|
async copyObjects(objects) {
|
|
5171
5152
|
const { durable } = this.layout;
|
|
5172
5153
|
let refusal;
|
|
5173
|
-
|
|
5154
|
+
const streams = durable === void 0 || durable.putStream && durable.getStream;
|
|
5155
|
+
return mapWithConcurrency(objects, streams ? OFFLOAD_COPIES_AT_ONCE : 1, async ({ hex, path, size }) => {
|
|
5174
5156
|
await this.copier.waitForCopy(hex);
|
|
5175
5157
|
if (await hasReceipt(this.layout, hex)) return {
|
|
5176
5158
|
hex,
|
|
@@ -5333,7 +5315,7 @@ function streamDurably(layout, digest, path, byteLength, signal) {
|
|
|
5333
5315
|
* that finds its digest in flight waits for that copy, then reads the receipt. Copying it again
|
|
5334
5316
|
* doubles the upload and, for a buffered store, the archive in memory. Reporting it pending
|
|
5335
5317
|
* failed captures: a capture refuses on any pending object, so two captures sharing one store
|
|
5336
|
-
* refused each other (discovery-lab provider-retention, agent-runtime 0.325.6
|
|
5318
|
+
* refused each other (discovery-lab provider-retention, agent-runtime 0.325.6).
|
|
5337
5319
|
* A copy never waits for a pass, so a pass may wait for a copy.
|
|
5338
5320
|
*/
|
|
5339
5321
|
function createDurableCopier(layout) {
|
|
@@ -5364,8 +5346,7 @@ function createDurableCopier(layout) {
|
|
|
5364
5346
|
}
|
|
5365
5347
|
};
|
|
5366
5348
|
}
|
|
5367
|
-
|
|
5368
|
-
//#region src/runtime/private-cas.ts
|
|
5349
|
+
// src/runtime/private-cas.ts
|
|
5369
5350
|
const SAFE_NAMESPACE = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/u;
|
|
5370
5351
|
const DURABLE_STALL_MS = 12e4;
|
|
5371
5352
|
/**
|
|
@@ -5430,8 +5411,7 @@ function createPrivateCasArtifactPort(root, namespace, options = {}) {
|
|
|
5430
5411
|
if (durable === void 0) markPutStreamVerified(putStream, readStream);
|
|
5431
5412
|
return port;
|
|
5432
5413
|
}
|
|
5433
|
-
|
|
5434
|
-
//#region src/runtime/run-benchmark.ts
|
|
5414
|
+
// src/runtime/run-benchmark.ts
|
|
5435
5415
|
/**
|
|
5436
5416
|
* runBenchmark — the packaged optimization suite. Define a domain by implementing an
|
|
5437
5417
|
* `Environment` (open / tools / call / score / close); get the optimization strategies
|
|
@@ -5644,10 +5624,9 @@ function printBenchmarkReport(report) {
|
|
|
5644
5624
|
console.log(` refine − sample: ${pp(l.mean)} CI [${pp(l.low)}, ${pp(l.high)}] (${sig})`);
|
|
5645
5625
|
}
|
|
5646
5626
|
}
|
|
5647
|
-
|
|
5648
|
-
//#region src/runtime/s3-private-cas-namespace.ts
|
|
5627
|
+
// src/runtime/s3-private-cas-namespace.ts
|
|
5649
5628
|
const NAMESPACE$1 = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/u;
|
|
5650
|
-
const MAX_PAGE_BYTES =
|
|
5629
|
+
const MAX_PAGE_BYTES = 2097152;
|
|
5651
5630
|
const fingerprint = (namespace, location, storeIdentity, objects) => `sha256:${createHash("sha256").update(JSON.stringify({
|
|
5652
5631
|
namespace,
|
|
5653
5632
|
location,
|
|
@@ -5827,8 +5806,7 @@ function privateCasNamespaceOperations({ request, refusal, prefix, location, sto
|
|
|
5827
5806
|
}
|
|
5828
5807
|
};
|
|
5829
5808
|
}
|
|
5830
|
-
|
|
5831
|
-
//#region src/runtime/s3-private-cas-request.ts
|
|
5809
|
+
// src/runtime/s3-private-cas-request.ts
|
|
5832
5810
|
const EMPTY_PAYLOAD = createHash("sha256").update("").digest("hex");
|
|
5833
5811
|
const hex$1 = (value) => createHash("sha256").update(value).digest("hex");
|
|
5834
5812
|
const hmac = (key, value) => createHmac("sha256", key).update(value).digest();
|
|
@@ -5861,14 +5839,15 @@ function createPrivateCasS3Transport(options, endpoint) {
|
|
|
5861
5839
|
payloadHash
|
|
5862
5840
|
].join("\n");
|
|
5863
5841
|
const scope = `${day}/${region}/s3/aws4_request`;
|
|
5864
|
-
const
|
|
5842
|
+
const signingKey = hmac(hmac(hmac(hmac(`AWS4${options.secretAccessKey}`, day), region), "s3"), "aws4_request");
|
|
5843
|
+
const signature = createHmac("sha256", signingKey).update([
|
|
5865
5844
|
"AWS4-HMAC-SHA256",
|
|
5866
5845
|
amzDate,
|
|
5867
5846
|
scope,
|
|
5868
5847
|
hex$1(canonical)
|
|
5869
5848
|
].join("\n")).digest("hex");
|
|
5870
5849
|
const { host: _host, ...sent } = signed;
|
|
5871
|
-
const deadline = AbortSignal.timeout(timeoutMs + Math.ceil((byteLength ?? (body instanceof Uint8Array ? body.byteLength : 0)) /
|
|
5850
|
+
const deadline = AbortSignal.timeout(timeoutMs + Math.ceil((byteLength ?? (body instanceof Uint8Array ? body.byteLength : 0)) / 1048576) * 1e3);
|
|
5872
5851
|
return await send(url, {
|
|
5873
5852
|
method,
|
|
5874
5853
|
headers: {
|
|
@@ -5900,14 +5879,13 @@ function createPrivateCasS3Transport(options, endpoint) {
|
|
|
5900
5879
|
refusal
|
|
5901
5880
|
};
|
|
5902
5881
|
}
|
|
5903
|
-
|
|
5904
|
-
//#region src/runtime/s3-private-cas-store.ts
|
|
5882
|
+
// src/runtime/s3-private-cas-store.ts
|
|
5905
5883
|
const DIGEST = /^sha256:([0-9a-f]{64})$/u;
|
|
5906
5884
|
const BUCKET = /^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/u;
|
|
5907
5885
|
const PREFIX = /^(?:[A-Za-z0-9._-]+\/)*$/u;
|
|
5908
5886
|
const NAMESPACE = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/u;
|
|
5909
5887
|
const POINTER_NAME = /^(?!sha256\/)[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}(?:\/[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}){0,3}$/u;
|
|
5910
|
-
const POINTER_MAX_BYTES =
|
|
5888
|
+
const POINTER_MAX_BYTES = 1048576;
|
|
5911
5889
|
const CONTENT_TYPE = "application/octet-stream";
|
|
5912
5890
|
const METADATA_DIGEST = "x-amz-meta-sha256";
|
|
5913
5891
|
const hex = (value) => createHash("sha256").update(value).digest("hex");
|
|
@@ -6073,8 +6051,7 @@ function createS3PrivateCasStore(options) {
|
|
|
6073
6051
|
}
|
|
6074
6052
|
};
|
|
6075
6053
|
}
|
|
6076
|
-
|
|
6077
|
-
//#region src/runtime/box-read-retry.ts
|
|
6054
|
+
// src/runtime/box-read-retry.ts
|
|
6078
6055
|
/**
|
|
6079
6056
|
* One bounded-retry read over a sandbox box's filesystem, shared by every caller that reads a
|
|
6080
6057
|
* path the agent may have just written.
|
|
@@ -6117,8 +6094,7 @@ async function readBoxPathWithRetry(read, path, options) {
|
|
|
6117
6094
|
error: lastError
|
|
6118
6095
|
};
|
|
6119
6096
|
}
|
|
6120
|
-
|
|
6121
|
-
//#region src/runtime/sandbox-run.ts
|
|
6097
|
+
// src/runtime/sandbox-run.ts
|
|
6122
6098
|
/**
|
|
6123
6099
|
* Thrown when a turn is aborted/timed-out mid-settle. Carries the events drained
|
|
6124
6100
|
* BEFORE the abort fired (and any in-progress `readError`) so an aborted run is
|
|
@@ -6386,8 +6362,7 @@ function hashText(value) {
|
|
|
6386
6362
|
}
|
|
6387
6363
|
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
6388
6364
|
}
|
|
6389
|
-
|
|
6390
|
-
//#region src/runtime/strategy-evolution-cells.ts
|
|
6365
|
+
// src/runtime/strategy-evolution-cells.ts
|
|
6391
6366
|
/**
|
|
6392
6367
|
* Cells run in this process on one dedicated lane of Runtime's search executor, which
|
|
6393
6368
|
* records each finished attempt under its run id (a restarted search adopts it instead of
|
|
@@ -6543,7 +6518,8 @@ function unknownAccounting(reason) {
|
|
|
6543
6518
|
}
|
|
6544
6519
|
/** Free text as the ledger stores it: redacted with the share profile and bounded. */
|
|
6545
6520
|
function shareText(error) {
|
|
6546
|
-
|
|
6521
|
+
const text = error instanceof Error ? error.message : String(error);
|
|
6522
|
+
return redact(text, { profile: "share" }).value.slice(0, 300);
|
|
6547
6523
|
}
|
|
6548
6524
|
const STRATEGY_EVOLUTION_SOURCE = {
|
|
6549
6525
|
uri: "npm:@tangle-network/agent-runtime#runStrategyEvolution",
|
|
@@ -6560,10 +6536,10 @@ const STRATEGY_EVOLUTION_SOURCE = {
|
|
|
6560
6536
|
/** Check every option and derive the search's identity; throws `ConfigError` on a bad one. */
|
|
6561
6537
|
function planStrategyEvolution(cfg) {
|
|
6562
6538
|
const root = cfg.root ?? refine;
|
|
6563
|
-
const budget = positiveInteger("budget", cfg.budget ?? 3);
|
|
6564
|
-
const concurrency = positiveInteger("concurrency", cfg.concurrency ?? 3);
|
|
6539
|
+
const budget = positiveInteger$1("budget", cfg.budget ?? 3);
|
|
6540
|
+
const concurrency = positiveInteger$1("concurrency", cfg.concurrency ?? 3);
|
|
6565
6541
|
const maxExpansions = nonNegativeInteger("maxExpansions", cfg.maxExpansions ?? 4);
|
|
6566
|
-
const maxAttempts = positiveInteger("maxAttempts", cfg.maxAttempts ?? 3);
|
|
6542
|
+
const maxAttempts = positiveInteger$1("maxAttempts", cfg.maxAttempts ?? 3);
|
|
6567
6543
|
const seed = nonNegativeInteger("seed", cfg.seed ?? 42);
|
|
6568
6544
|
const cellUsd = dollars("cellUsd", cfg.cellUsd) ?? 0;
|
|
6569
6545
|
const maxUsd = dollars("maxUsd", cfg.maxUsd);
|
|
@@ -6686,7 +6662,7 @@ function searchTasks(claim, tasks) {
|
|
|
6686
6662
|
}
|
|
6687
6663
|
}));
|
|
6688
6664
|
}
|
|
6689
|
-
function positiveInteger(name, value) {
|
|
6665
|
+
function positiveInteger$1(name, value) {
|
|
6690
6666
|
if (!Number.isSafeInteger(value) || value < 1) throw new ConfigError(`evolution: ${name} must be a positive integer`);
|
|
6691
6667
|
return value;
|
|
6692
6668
|
}
|
|
@@ -6699,8 +6675,7 @@ function dollars(name, value) {
|
|
|
6699
6675
|
if (!Number.isFinite(value) || value < 0) throw new ConfigError(`evolution: ${name} must be a finite non-negative number`);
|
|
6700
6676
|
return value;
|
|
6701
6677
|
}
|
|
6702
|
-
|
|
6703
|
-
//#region src/runtime/strategy-evolution.ts
|
|
6678
|
+
// src/runtime/strategy-evolution.ts
|
|
6704
6679
|
/**
|
|
6705
6680
|
* runStrategyEvolution: strategy search on Eval's search kernel (`runSearch`).
|
|
6706
6681
|
*
|
|
@@ -7102,8 +7077,7 @@ function strategyNames(state, recorder, codec) {
|
|
|
7102
7077
|
}
|
|
7103
7078
|
return names;
|
|
7104
7079
|
}
|
|
7105
|
-
|
|
7106
|
-
//#region src/runtime/supervise/chat-transport-executor.ts
|
|
7080
|
+
// src/runtime/supervise/chat-transport-executor.ts
|
|
7107
7081
|
/**
|
|
7108
7082
|
* A session-owning composition over Runtime's canonical Router tool-loop executor.
|
|
7109
7083
|
*
|
|
@@ -7171,7 +7145,8 @@ function buildChatTransportExecutor(opts, context) {
|
|
|
7171
7145
|
profile,
|
|
7172
7146
|
harness: null
|
|
7173
7147
|
};
|
|
7174
|
-
|
|
7148
|
+
const inner = createExecutor(config)(spec, context);
|
|
7149
|
+
return mapExecutorResult(inner, (result) => {
|
|
7175
7150
|
const raw = result.out;
|
|
7176
7151
|
const content = typeof raw?.content === "string" ? raw.content : "";
|
|
7177
7152
|
return {
|
|
@@ -7224,8 +7199,7 @@ function chatWorkerSeam(opts) {
|
|
|
7224
7199
|
};
|
|
7225
7200
|
};
|
|
7226
7201
|
}
|
|
7227
|
-
|
|
7228
|
-
//#region src/runtime/supervise/designer-tools.ts
|
|
7202
|
+
// src/runtime/supervise/designer-tools.ts
|
|
7229
7203
|
/**
|
|
7230
7204
|
* `graphDesignerExtraTools` — the designer's toolset on the existing
|
|
7231
7205
|
* `RunGraphOptions.extraTools` seam.
|
|
@@ -7353,7 +7327,7 @@ function graphDesignerExtraTools(env) {
|
|
|
7353
7327
|
})();
|
|
7354
7328
|
if (name === "designer_history") return (async () => {
|
|
7355
7329
|
const args = asRecord(raw ?? {}, "designer_history");
|
|
7356
|
-
const { listGraphRuns } = await import("./supervise-
|
|
7330
|
+
const { listGraphRuns } = await import("./supervise-CaeZcgAW.js").then((n) => n.g);
|
|
7357
7331
|
const all = await listGraphRuns(registry);
|
|
7358
7332
|
return { runs: (args.taskShape === void 0 ? all : all.filter((row) => row.taskDigest === taskShapeDigest(asRecord(args.taskShape, "designer_history.taskShape")))).map(summarize) };
|
|
7359
7333
|
})();
|
|
@@ -7364,7 +7338,7 @@ function graphDesignerExtraTools(env) {
|
|
|
7364
7338
|
if (mode === "replay") {
|
|
7365
7339
|
const digest = args.graphDigest;
|
|
7366
7340
|
if (typeof digest !== "string" || digest.length === 0) throw new ValidationError("designer_run_graph: replay mode requires graphDigest from lookup");
|
|
7367
|
-
const { loadGraph } = await import("./supervise-
|
|
7341
|
+
const { loadGraph } = await import("./supervise-CaeZcgAW.js").then((n) => n.g);
|
|
7368
7342
|
const stored = await loadGraph(registry, digest);
|
|
7369
7343
|
if (!stored) throw new ValidationError(`designer_run_graph: no stored graph ${digest.slice(0, 12)} — re-lookup`);
|
|
7370
7344
|
const graph = env.bindCheck(graphFromStored(stored, () => {
|
|
@@ -7403,8 +7377,453 @@ function graphDesignerExtraTools(env) {
|
|
|
7403
7377
|
};
|
|
7404
7378
|
}
|
|
7405
7379
|
}
|
|
7406
|
-
|
|
7407
|
-
|
|
7380
|
+
// src/runtime/supervise/graph-file.ts
|
|
7381
|
+
/** A provider name in authored data needs an environment-owned canonical connection binding. */
|
|
7382
|
+
var GraphFileResolutionError = class extends Error {
|
|
7383
|
+
provider;
|
|
7384
|
+
node;
|
|
7385
|
+
code = "CONNECTION_REQUIRED";
|
|
7386
|
+
fixCommand = "tangle graph run --help";
|
|
7387
|
+
constructor(provider, node) {
|
|
7388
|
+
super(`loadGraphFile: node ${node} needs an environment binding for provider ${provider}`);
|
|
7389
|
+
this.provider = provider;
|
|
7390
|
+
this.node = node;
|
|
7391
|
+
this.name = "GraphFileResolutionError";
|
|
7392
|
+
}
|
|
7393
|
+
};
|
|
7394
|
+
function refuse$2(message) {
|
|
7395
|
+
throw new ValidationError(`loadGraphFile: ${message}`);
|
|
7396
|
+
}
|
|
7397
|
+
function jsonData(value, visiting = /* @__PURE__ */ new Set()) {
|
|
7398
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") return;
|
|
7399
|
+
if (typeof value === "number" && Number.isFinite(value)) return;
|
|
7400
|
+
if (!value || typeof value !== "object" || visiting.has(value)) refuse$2("definition must be finite, acyclic JSON data");
|
|
7401
|
+
visiting.add(value);
|
|
7402
|
+
for (const child of Object.values(value)) jsonData(child, visiting);
|
|
7403
|
+
visiting.delete(value);
|
|
7404
|
+
}
|
|
7405
|
+
function bindParameters(raw, supplied) {
|
|
7406
|
+
const definitions = graphFileSchema.shape.params.parse(raw.params) ?? {};
|
|
7407
|
+
for (const key of Object.keys(supplied ?? {})) if (!Object.hasOwn(definitions, key)) refuse$2(`unknown parameter ${key}`);
|
|
7408
|
+
return Object.fromEntries(Object.entries(definitions).map(([key, definition]) => {
|
|
7409
|
+
let value = supplied && Object.hasOwn(supplied, key) ? supplied[key] : definition.default;
|
|
7410
|
+
if (value === void 0) refuse$2(`missing parameter ${key}`);
|
|
7411
|
+
const type = definition.type;
|
|
7412
|
+
if (typeof value === "string" && type && type !== "string") try {
|
|
7413
|
+
value = JSON.parse(value);
|
|
7414
|
+
} catch {
|
|
7415
|
+
refuse$2(`parameter ${key} must be ${type}`);
|
|
7416
|
+
}
|
|
7417
|
+
if (type) {
|
|
7418
|
+
if (!(type === "integer" ? Number.isSafeInteger(value) : type === "null" ? value === null : type === "array" ? Array.isArray(value) : type === "object" ? value !== null && typeof value === "object" && !Array.isArray(value) : typeof value === type)) refuse$2(`parameter ${key} must be ${type}`);
|
|
7419
|
+
}
|
|
7420
|
+
jsonData(value);
|
|
7421
|
+
return [key, value];
|
|
7422
|
+
}));
|
|
7423
|
+
}
|
|
7424
|
+
async function expandProfile(node, options) {
|
|
7425
|
+
if (node.id === "params" || node.id === "trigger") refuse$2(`reserved node id ${node.id}`);
|
|
7426
|
+
const authored = options.seat ?? options.nodeSeats?.[node.id] ?? node.seat;
|
|
7427
|
+
const resolveSeat = options.resolveSeat;
|
|
7428
|
+
const context = {
|
|
7429
|
+
node: node.id,
|
|
7430
|
+
cwd: options.cwd,
|
|
7431
|
+
signal: options.signal
|
|
7432
|
+
};
|
|
7433
|
+
let selected;
|
|
7434
|
+
if (authored !== void 0) {
|
|
7435
|
+
if (!resolveSeat) refuse$2(`node ${node.id} has unresolved seat shorthand; supply resolveSeat from Bridge login inventory or a canonical profile`);
|
|
7436
|
+
const candidates = typeof authored === "string" ? [authored] : authored;
|
|
7437
|
+
if (!candidates.length) refuse$2(`node ${node.id} has an empty seat preference list`);
|
|
7438
|
+
for (const [index, candidate] of candidates.entries()) {
|
|
7439
|
+
selected = await resolveSeat(candidate, {
|
|
7440
|
+
...context,
|
|
7441
|
+
lastCandidate: index === candidates.length - 1
|
|
7442
|
+
});
|
|
7443
|
+
if (selected) break;
|
|
7444
|
+
}
|
|
7445
|
+
if (!selected) refuse$2(`node ${node.id} has no available Bridge seat; sign in through Bridge or choose another seat`);
|
|
7446
|
+
} else if (Array.isArray(node.profile?.seats)) {
|
|
7447
|
+
const parsed = agentProfileSchema.safeParse({
|
|
7448
|
+
...node.profile,
|
|
7449
|
+
name: node.id
|
|
7450
|
+
});
|
|
7451
|
+
if (!parsed.success) refuse$2(`node ${node.id} has an invalid profile: ${parsed.error.message}`);
|
|
7452
|
+
} else if (!node.profile?.harness || !concreteProfileModel(node.profile) || !node.profile.model?.provider) {
|
|
7453
|
+
selected = options.seats?.[0] ?? await resolveSeat?.(void 0, {
|
|
7454
|
+
...context,
|
|
7455
|
+
lastCandidate: true
|
|
7456
|
+
});
|
|
7457
|
+
if (!selected) refuse$2(`node ${node.id} needs a canonical profile or resolveSeat from Bridge login inventory`);
|
|
7458
|
+
}
|
|
7459
|
+
const connections = node.needs?.map((provider) => {
|
|
7460
|
+
if (!options.needs || !Object.hasOwn(options.needs, provider)) throw new GraphFileResolutionError(provider, node.id);
|
|
7461
|
+
return options.needs[provider];
|
|
7462
|
+
});
|
|
7463
|
+
const { seats: _authoredSeats, ...authoredProfile } = node.profile ?? {};
|
|
7464
|
+
const profile = {
|
|
7465
|
+
...selected ? authoredProfile : node.profile,
|
|
7466
|
+
name: node.id,
|
|
7467
|
+
...selected ? {
|
|
7468
|
+
harness: selected.harness,
|
|
7469
|
+
model: {
|
|
7470
|
+
...node.profile?.model,
|
|
7471
|
+
provider: selected.provider,
|
|
7472
|
+
default: selected.model,
|
|
7473
|
+
...selected.reasoningEffort === void 0 ? {} : { reasoningEffort: selected.reasoningEffort }
|
|
7474
|
+
}
|
|
7475
|
+
} : {},
|
|
7476
|
+
...connections ? { connections: [...node.profile?.connections ?? [], ...connections] } : {}
|
|
7477
|
+
};
|
|
7478
|
+
const parsed = agentProfileSchema.safeParse(profile);
|
|
7479
|
+
if (!parsed.success) refuse$2(`node ${node.id} has an invalid profile: ${parsed.error.message}`);
|
|
7480
|
+
assertExecutableAgentProfile(parsed.data, `loadGraphFile node ${node.id}`);
|
|
7481
|
+
return parsed.data;
|
|
7482
|
+
}
|
|
7483
|
+
/** Parse the canonical YAML/JSON file into content-addressed Runtime graph data, offline. */
|
|
7484
|
+
async function loadGraphFile(file, options = {}) {
|
|
7485
|
+
if (![
|
|
7486
|
+
".yaml",
|
|
7487
|
+
".yml",
|
|
7488
|
+
".json"
|
|
7489
|
+
].includes(extname(file).toLowerCase())) refuse$2("file must be YAML or JSON");
|
|
7490
|
+
const text = options.source ?? await readFile(file, "utf8");
|
|
7491
|
+
const document = parseDocument(text, {
|
|
7492
|
+
uniqueKeys: true,
|
|
7493
|
+
strict: true
|
|
7494
|
+
});
|
|
7495
|
+
if (document.errors.length) refuse$2(document.errors.map((error) => error.message).join("; "));
|
|
7496
|
+
if (document.warnings.length) refuse$2(document.warnings.map((warning) => warning.message).join("; "));
|
|
7497
|
+
const raw = extname(file).toLowerCase() === ".json" ? JSON.parse(text) : document.toJS({ maxAliasCount: 100 });
|
|
7498
|
+
jsonData(raw);
|
|
7499
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) refuse$2("definition must be an object");
|
|
7500
|
+
const source = raw;
|
|
7501
|
+
if (Array.isArray(source.nodes) && source.nodes.some((node) => node && typeof node === "object" && "call" in node)) refuse$2("call vertices are not supported by this loader");
|
|
7502
|
+
const params = bindParameters(source, options.params);
|
|
7503
|
+
const { params: _definitions, on, ...authored } = source;
|
|
7504
|
+
const bindings = {
|
|
7505
|
+
params,
|
|
7506
|
+
trigger: options.trigger
|
|
7507
|
+
};
|
|
7508
|
+
const bindingOptions = options.trigger === void 0 ? { defer: ["trigger"] } : {};
|
|
7509
|
+
const compiled = compileGraphParameters(authored, bindings, bindingOptions);
|
|
7510
|
+
const bound = graphFileSchema.parse(compiled.value);
|
|
7511
|
+
const boundOn = on === void 0 ? void 0 : bindGraphParameters(on, bindings, bindingOptions);
|
|
7512
|
+
if (bound.check && bound.deliverable) refuse$2("use check or deliverable, not both");
|
|
7513
|
+
let deliverable = bound.deliverable;
|
|
7514
|
+
if (bound.check) {
|
|
7515
|
+
if ("command" in bound.check) deliverable = {
|
|
7516
|
+
...(bound.check.describe ?? bound.describe) === void 0 ? {} : { describe: bound.check.describe ?? bound.describe },
|
|
7517
|
+
checkRef: "command",
|
|
7518
|
+
command: bound.check.command
|
|
7519
|
+
};
|
|
7520
|
+
else {
|
|
7521
|
+
const { describe, ...condition } = "describe" in bound.check ? bound.check : {
|
|
7522
|
+
...bound.check,
|
|
7523
|
+
describe: void 0
|
|
7524
|
+
};
|
|
7525
|
+
deliverable = {
|
|
7526
|
+
...(describe ?? bound.describe) === void 0 ? {} : { describe: describe ?? bound.describe },
|
|
7527
|
+
checkRef: "route",
|
|
7528
|
+
when: condition
|
|
7529
|
+
};
|
|
7530
|
+
}
|
|
7531
|
+
}
|
|
7532
|
+
if (!deliverable) refuse$2("check or deliverable is required");
|
|
7533
|
+
if (deliverable.checkRef === "route" && !deliverable.when) refuse$2("route deliverable requires when");
|
|
7534
|
+
if (deliverable.checkRef === "command" && !deliverable.command) refuse$2("command deliverable requires command");
|
|
7535
|
+
const nodes = await Promise.all(bound.nodes.map(async (node) => ({
|
|
7536
|
+
id: node.id,
|
|
7537
|
+
profile: await expandProfile(node, {
|
|
7538
|
+
...options,
|
|
7539
|
+
cwd: options.cwd ?? dirname(file)
|
|
7540
|
+
})
|
|
7541
|
+
})));
|
|
7542
|
+
const nodeIds = new Set(nodes.map((node) => node.id));
|
|
7543
|
+
for (const id of Object.keys(options.nodeSeats ?? {})) if (!nodeIds.has(id)) refuse$2(`seat override references unknown node ${id}`);
|
|
7544
|
+
if (deliverable.when) {
|
|
7545
|
+
for (const condition of "all" in deliverable.when ? deliverable.when.all : [deliverable.when]) if (condition.node !== void 0 && !nodeIds.has(condition.node)) refuse$2(`check references unknown node ${condition.node}`);
|
|
7546
|
+
}
|
|
7547
|
+
const topology = {
|
|
7548
|
+
nodes,
|
|
7549
|
+
edges: bound.edges,
|
|
7550
|
+
budget: bound.budget,
|
|
7551
|
+
deliverable,
|
|
7552
|
+
...bound.entry ? { entry: bound.entry.map((entry) => typeof entry === "string" ? {
|
|
7553
|
+
node: entry,
|
|
7554
|
+
task: {}
|
|
7555
|
+
} : entry) } : {},
|
|
7556
|
+
...bound.gates ? { gates: bound.gates } : {}
|
|
7557
|
+
};
|
|
7558
|
+
const triggerBindings = compiled.triggerBindings.flatMap((slot) => {
|
|
7559
|
+
const [top, index, field, ...tail] = slot.path;
|
|
7560
|
+
if (top === "nodes") {
|
|
7561
|
+
if (field === "id") return [slot, {
|
|
7562
|
+
...slot,
|
|
7563
|
+
path: [
|
|
7564
|
+
"nodes",
|
|
7565
|
+
index,
|
|
7566
|
+
"profile",
|
|
7567
|
+
"name"
|
|
7568
|
+
]
|
|
7569
|
+
}];
|
|
7570
|
+
if (field === "profile") {
|
|
7571
|
+
if (tail[0] === "name") return [];
|
|
7572
|
+
if (tail[0] === "harness" || tail[0] === "model" && [
|
|
7573
|
+
"provider",
|
|
7574
|
+
"default",
|
|
7575
|
+
"reasoningEffort"
|
|
7576
|
+
].includes(String(tail[1]))) {
|
|
7577
|
+
let before = bound.nodes[index].profile;
|
|
7578
|
+
let after = nodes[index].profile;
|
|
7579
|
+
for (const key of tail) {
|
|
7580
|
+
before = before?.[key];
|
|
7581
|
+
after = after?.[key];
|
|
7582
|
+
}
|
|
7583
|
+
if (before !== after) return [];
|
|
7584
|
+
}
|
|
7585
|
+
return [slot];
|
|
7586
|
+
}
|
|
7587
|
+
refuse$2("trigger slots in seat/needs must be supplied to loadGraphFile before profile resolution");
|
|
7588
|
+
}
|
|
7589
|
+
if (top === "check") {
|
|
7590
|
+
if (index === "describe") return [{
|
|
7591
|
+
...slot,
|
|
7592
|
+
path: ["deliverable", "describe"]
|
|
7593
|
+
}];
|
|
7594
|
+
return [{
|
|
7595
|
+
...slot,
|
|
7596
|
+
path: [
|
|
7597
|
+
"deliverable",
|
|
7598
|
+
index === "command" ? "command" : "when",
|
|
7599
|
+
...index === "command" ? slot.path.slice(2) : slot.path.slice(1)
|
|
7600
|
+
]
|
|
7601
|
+
}];
|
|
7602
|
+
}
|
|
7603
|
+
if (top === "describe") return bound.check?.describe !== void 0 || bound.deliverable ? [] : [{
|
|
7604
|
+
...slot,
|
|
7605
|
+
path: ["deliverable", "describe"]
|
|
7606
|
+
}];
|
|
7607
|
+
if (top === "entry" && slot.path.length === 2) return [{
|
|
7608
|
+
...slot,
|
|
7609
|
+
path: [
|
|
7610
|
+
"entry",
|
|
7611
|
+
index,
|
|
7612
|
+
"node"
|
|
7613
|
+
]
|
|
7614
|
+
}];
|
|
7615
|
+
return [
|
|
7616
|
+
"edges",
|
|
7617
|
+
"budget",
|
|
7618
|
+
"gates",
|
|
7619
|
+
"entry",
|
|
7620
|
+
"deliverable"
|
|
7621
|
+
].includes(String(top)) ? [slot] : [];
|
|
7622
|
+
});
|
|
7623
|
+
assertGraphTriggerBindings(topology, triggerBindings);
|
|
7624
|
+
const content = {
|
|
7625
|
+
...topology,
|
|
7626
|
+
triggerBindings
|
|
7627
|
+
};
|
|
7628
|
+
const registry = options.registry ?? kernelPromptRegistry();
|
|
7629
|
+
if (content.entry) validateFlowGraph(content, registry, options.analysts);
|
|
7630
|
+
else validateGraphTopology(content.nodes, content.edges, registry, options.analysts);
|
|
7631
|
+
const digest = graphDigest(content);
|
|
7632
|
+
if (bound.digest !== void 0 && bound.digest !== digest) refuse$2("supplied digest does not match the materialized graph");
|
|
7633
|
+
return {
|
|
7634
|
+
graph: {
|
|
7635
|
+
...content,
|
|
7636
|
+
digest
|
|
7637
|
+
},
|
|
7638
|
+
params,
|
|
7639
|
+
...boundOn === void 0 ? {} : { on: boundOn }
|
|
7640
|
+
};
|
|
7641
|
+
}
|
|
7642
|
+
// src/runtime/supervise/graph-session-observation.ts
|
|
7643
|
+
function measured(fact) {
|
|
7644
|
+
return fact && !fact.partial && fact.value !== null ? fact.value : void 0;
|
|
7645
|
+
}
|
|
7646
|
+
function recordedAt(fact) {
|
|
7647
|
+
const value = measured(fact);
|
|
7648
|
+
return value && Number.isFinite(Date.parse(value)) ? value : void 0;
|
|
7649
|
+
}
|
|
7650
|
+
/** Project an existing canonical span run tree into an observed graph design,
|
|
7651
|
+
* linked to its trace run. SessionFacts supplies exclusive accounting. No
|
|
7652
|
+
* execution tree, transcript, or source-specific traversal parser is stored. */
|
|
7653
|
+
function graphFromSessionFacts(facts, options) {
|
|
7654
|
+
if (!facts.length) throw new ValidationError("graphFromSessionFacts: no session facts");
|
|
7655
|
+
const unknowns = ["edge traversal accounting unavailable from canonical span relationships", "span containment does not establish graph edge semantics"];
|
|
7656
|
+
const spanNodes = options.spanRun?.present ? options.spanRun.nodes : [];
|
|
7657
|
+
const spanKey = (traceId, spanId) => JSON.stringify([traceId, spanId]);
|
|
7658
|
+
const identities = /* @__PURE__ */ new Set();
|
|
7659
|
+
const observations = facts.map((fact) => {
|
|
7660
|
+
const roots = spanNodes.filter((node) => node.traceId === fact.traceId && node.parentNodeId === null);
|
|
7661
|
+
const anchor = measured(fact.rootSpanId) ?? (roots.length === 1 ? roots[0].spanId : void 0);
|
|
7662
|
+
const boundary = fact.traceId && anchor ? `span:${spanKey(fact.traceId, anchor)}` : void 0;
|
|
7663
|
+
const sourceId = fact.sessionId ?? boundary;
|
|
7664
|
+
const identity = boundary ?? (fact.sessionId ? `session:${fact.sessionId}` : void 0);
|
|
7665
|
+
if (!identity || !sourceId || identities.has(identity)) throw new ValidationError("graphFromSessionFacts: every observation needs a unique recorded session or span identity");
|
|
7666
|
+
identities.add(identity);
|
|
7667
|
+
const humanCounts = measured(fact.typedTurnCounts)?.filter((entry) => entry.actor === "human");
|
|
7668
|
+
if (humanCounts?.some((entry) => !Number.isSafeInteger(entry.turns) || entry.turns < 0)) throw new ValidationError("graphFromSessionFacts: invalid human turn count");
|
|
7669
|
+
const humanMessages = fact.typedTurnCounts === void 0 ? measured(fact.humanTurns)?.length : humanCounts?.reduce((sum, entry) => sum + entry.turns, 0);
|
|
7670
|
+
const leadMessages = measured(fact.leadMessages);
|
|
7671
|
+
const inputTokens = fact.tokens.input ?? void 0;
|
|
7672
|
+
const outputTokens = fact.tokens.output ?? void 0;
|
|
7673
|
+
for (const [key, value] of Object.entries({
|
|
7674
|
+
inputTokens,
|
|
7675
|
+
outputTokens,
|
|
7676
|
+
humanMessages,
|
|
7677
|
+
leadMessages
|
|
7678
|
+
})) if (value === void 0) unknowns.push(`${sourceId}: ${key} unavailable`);
|
|
7679
|
+
else if (!Number.isSafeInteger(value) || value < 0) throw new ValidationError(`graphFromSessionFacts: invalid ${key}`);
|
|
7680
|
+
return {
|
|
7681
|
+
sourceId,
|
|
7682
|
+
startedAt: recordedAt(fact.firstRecordAt),
|
|
7683
|
+
lastRecordAt: recordedAt(fact.lastRecordAt),
|
|
7684
|
+
inputTokens,
|
|
7685
|
+
outputTokens,
|
|
7686
|
+
humanMessages,
|
|
7687
|
+
leadMessages
|
|
7688
|
+
};
|
|
7689
|
+
});
|
|
7690
|
+
const ids = /* @__PURE__ */ new Map();
|
|
7691
|
+
for (const [index, node] of spanNodes.entries()) {
|
|
7692
|
+
const key = spanKey(node.traceId, node.spanId);
|
|
7693
|
+
if (ids.has(key)) throw new ValidationError("graphFromSessionFacts: duplicate canonical span identity");
|
|
7694
|
+
ids.set(key, `n${index}`);
|
|
7695
|
+
}
|
|
7696
|
+
const nodes = spanNodes.map((node) => {
|
|
7697
|
+
const profile = { name: node.parentNodeId === null ? "observed-agent" : "observed-child" };
|
|
7698
|
+
if (node.runtime || node.kind) profile.metadata = {
|
|
7699
|
+
...node.runtime ? { runtime: node.runtime } : {},
|
|
7700
|
+
...node.kind ? { spanKind: node.kind } : {}
|
|
7701
|
+
};
|
|
7702
|
+
return {
|
|
7703
|
+
id: ids.get(spanKey(node.traceId, node.spanId)),
|
|
7704
|
+
profile
|
|
7705
|
+
};
|
|
7706
|
+
});
|
|
7707
|
+
const edges = [];
|
|
7708
|
+
for (const node of spanNodes) {
|
|
7709
|
+
if (node.parentNodeId === null) continue;
|
|
7710
|
+
const from = ids.get(spanKey(node.traceId, node.parentNodeId));
|
|
7711
|
+
if (from) edges.push({
|
|
7712
|
+
from,
|
|
7713
|
+
to: ids.get(spanKey(node.traceId, node.spanId))
|
|
7714
|
+
});
|
|
7715
|
+
else unknowns.push("canonical span run has an unresolved parent node");
|
|
7716
|
+
}
|
|
7717
|
+
edges.sort((a, b) => a.from.localeCompare(b.from) || a.to.localeCompare(b.to));
|
|
7718
|
+
const nodeUsage = [];
|
|
7719
|
+
const joinedNodes = /* @__PURE__ */ new Set();
|
|
7720
|
+
for (const [index, fact] of facts.entries()) {
|
|
7721
|
+
const anchor = measured(fact.rootSpanId);
|
|
7722
|
+
const matching = spanNodes.filter((node) => node.traceId === fact.traceId && (anchor === void 0 ? node.parentNodeId === null : node.spanId === anchor));
|
|
7723
|
+
if (matching.length !== 1 || joinedNodes.has(spanKey(matching[0].traceId, matching[0].spanId))) {
|
|
7724
|
+
unknowns.push(`${fact.sessionId}: session accounting cannot be joined to one canonical span node`);
|
|
7725
|
+
continue;
|
|
7726
|
+
}
|
|
7727
|
+
const key = spanKey(matching[0].traceId, matching[0].spanId);
|
|
7728
|
+
joinedNodes.add(key);
|
|
7729
|
+
const nodeId = ids.get(key);
|
|
7730
|
+
nodeUsage.push({
|
|
7731
|
+
nodeId,
|
|
7732
|
+
...observations[index]
|
|
7733
|
+
});
|
|
7734
|
+
const profile = nodes.find((node) => node.id === nodeId).profile;
|
|
7735
|
+
const identity = measured(fact.agent);
|
|
7736
|
+
const model = identity?.model;
|
|
7737
|
+
if (model) profile.model = { default: model };
|
|
7738
|
+
const harness = identity?.harness ?? fact.harness;
|
|
7739
|
+
if (harness) profile.metadata = {
|
|
7740
|
+
...profile.metadata,
|
|
7741
|
+
harness
|
|
7742
|
+
};
|
|
7743
|
+
}
|
|
7744
|
+
for (const node of spanNodes) {
|
|
7745
|
+
const key = spanKey(node.traceId, node.spanId);
|
|
7746
|
+
if (!joinedNodes.has(key)) {
|
|
7747
|
+
nodeUsage.push({ nodeId: ids.get(key) });
|
|
7748
|
+
unknowns.push(`${ids.get(key)}: canonical node accounting unavailable`);
|
|
7749
|
+
}
|
|
7750
|
+
}
|
|
7751
|
+
if (!spanNodes.length) unknowns.push("topology unavailable: no canonical span run tree was supplied");
|
|
7752
|
+
if (spanNodes.some((node) => node.kind == null)) unknowns.push("canonical span node kind unavailable");
|
|
7753
|
+
if (options.spanRun?.orphanSpans) unknowns.push("canonical span run contains orphan spans");
|
|
7754
|
+
if (!options.traceRunId) unknowns.push("trace run identity unavailable");
|
|
7755
|
+
for (const issue of options.issues ?? []) {
|
|
7756
|
+
const kind = issue && typeof issue === "object" && "kind" in issue ? issue.kind : void 0;
|
|
7757
|
+
const reason = issue && typeof issue === "object" && "reason" in issue ? issue.reason : void 0;
|
|
7758
|
+
if (typeof kind === "string") unknowns.push("workflow issue: " + kind + (kind === "source-coverage" && typeof reason === "string" ? `: ${reason.replace(/[\r\n]/g, " ").slice(0, 500)}` : ""));
|
|
7759
|
+
}
|
|
7760
|
+
const incompleteIssues = options.issues?.some((issue) => !issue || typeof issue !== "object" || !("kind" in issue) || issue.kind !== "source-coverage");
|
|
7761
|
+
const unread = facts.some((fact) => fact.unreadRecords?.partial || (fact.unreadRecords?.value ?? 0) > 0);
|
|
7762
|
+
if (unread) unknowns.push("source contains unread or partial records; total accounting unavailable");
|
|
7763
|
+
const complete = options.complete !== false && !incompleteIssues && !unread;
|
|
7764
|
+
if (!complete) unknowns.push("workflow selection incomplete; total accounting unavailable");
|
|
7765
|
+
if (!options.taskType) unknowns.push("task type not explicitly labeled");
|
|
7766
|
+
const starts = observations.flatMap((node) => node.startedAt ? [node.startedAt] : []).sort((a, b) => Date.parse(a) - Date.parse(b));
|
|
7767
|
+
const startedAt = options.startedAt ?? starts[0];
|
|
7768
|
+
if (!startedAt || !Number.isFinite(Date.parse(startedAt))) throw new ValidationError("graphFromSessionFacts: no recorded task start; supply an authoritative startedAt");
|
|
7769
|
+
const cost = {};
|
|
7770
|
+
for (const channel of [
|
|
7771
|
+
"inputTokens",
|
|
7772
|
+
"outputTokens",
|
|
7773
|
+
"humanMessages",
|
|
7774
|
+
"leadMessages"
|
|
7775
|
+
]) if (complete && observations.every((node) => node[channel] !== void 0)) cost[channel] = observations.reduce((sum, node) => sum + node[channel], 0);
|
|
7776
|
+
if (cost.inputTokens !== void 0 && cost.outputTokens !== void 0) cost.tokens = cost.inputTokens + cost.outputTokens;
|
|
7777
|
+
const outcome = options.outcome ?? {
|
|
7778
|
+
kind: "unknown",
|
|
7779
|
+
reason: "no independent delivery outcome was joined"
|
|
7780
|
+
};
|
|
7781
|
+
if ((outcome.kind === "delivered" || outcome.kind === "no-winner") && !options.finishedAt) throw new ValidationError("graphFromSessionFacts: terminal outcomes require authoritative finishedAt");
|
|
7782
|
+
if (!options.startedAt) unknowns.push("task start unconfirmed; startedAt is earliest observed activity");
|
|
7783
|
+
if (options.finishedAt) {
|
|
7784
|
+
const elapsed = Date.parse(options.finishedAt) - Date.parse(startedAt);
|
|
7785
|
+
if (!Number.isFinite(elapsed) || elapsed < 0) throw new ValidationError("graphFromSessionFacts: invalid finishedAt");
|
|
7786
|
+
if (options.startedAt) cost.ms = elapsed;
|
|
7787
|
+
}
|
|
7788
|
+
const merged = options.evidence?.filter((entry) => entry.kind === "pr-merged" && entry.at).map((entry) => Date.parse(entry.at)).filter(Number.isFinite).sort((a, b) => a - b)[0];
|
|
7789
|
+
if (options.startedAt && merged !== void 0 && merged >= Date.parse(startedAt)) cost.mergeMs = merged - Date.parse(startedAt);
|
|
7790
|
+
const content = {
|
|
7791
|
+
observed: true,
|
|
7792
|
+
nodes,
|
|
7793
|
+
edges,
|
|
7794
|
+
deliverable: {}
|
|
7795
|
+
};
|
|
7796
|
+
const graph = {
|
|
7797
|
+
digest: graphDigest(content),
|
|
7798
|
+
...content
|
|
7799
|
+
};
|
|
7800
|
+
return {
|
|
7801
|
+
graph,
|
|
7802
|
+
record: {
|
|
7803
|
+
graphDigest: graph.digest,
|
|
7804
|
+
...spanNodes.length ? { topologyDigest: taskShapeDigest({
|
|
7805
|
+
nodes: nodes.map((node, index) => ({
|
|
7806
|
+
id: node.id,
|
|
7807
|
+
kind: spanNodes[index].kind ?? null
|
|
7808
|
+
})),
|
|
7809
|
+
edges
|
|
7810
|
+
}) } : {},
|
|
7811
|
+
taskDigest: taskShapeDigest(options.taskShape ?? { taskType: options.taskType ?? "unknown" }),
|
|
7812
|
+
startedAt,
|
|
7813
|
+
...options.finishedAt ? { finishedAt: options.finishedAt } : {},
|
|
7814
|
+
outcome,
|
|
7815
|
+
cost,
|
|
7816
|
+
source: options.source,
|
|
7817
|
+
...options.traceRunId ? { traceRunId: options.traceRunId } : {},
|
|
7818
|
+
...options.observedAt ? { observedAt: options.observedAt } : {},
|
|
7819
|
+
...options.taskType ? { taskType: options.taskType } : {},
|
|
7820
|
+
...options.evidence ? { evidence: options.evidence } : {},
|
|
7821
|
+
...nodeUsage.length ? { nodeUsage } : {},
|
|
7822
|
+
unknowns
|
|
7823
|
+
}
|
|
7824
|
+
};
|
|
7825
|
+
}
|
|
7826
|
+
// src/runtime/supervise/profile-registry.ts
|
|
7408
7827
|
/**
|
|
7409
7828
|
* `profile-registry` — named AgentProfiles with run receipts: the missing
|
|
7410
7829
|
* bottom layer of the designer's memory.
|
|
@@ -7456,7 +7875,8 @@ async function recordProfileRun(reg, profile, record) {
|
|
|
7456
7875
|
await withJsonlFileLock(join(reg.root, RECORDS_FILE), async (canonicalPath) => {
|
|
7457
7876
|
const file = join(reg.root, PROFILES_DIR, `${digest}.json`);
|
|
7458
7877
|
try {
|
|
7459
|
-
|
|
7878
|
+
const existing = JSON.parse(await readFile(file, "utf8"));
|
|
7879
|
+
if (canonicalAgentProfileDigest(existing) !== digest) throw new ValidationError(`profile-registry: revision ${digest.slice(0, 12)} is immutable but its stored copy differs — refusing to overwrite`);
|
|
7460
7880
|
} catch (error) {
|
|
7461
7881
|
if (!isNoEntError(error)) throw error;
|
|
7462
7882
|
writeAtomicDurableFile(file, JSON.stringify(profile));
|
|
@@ -7504,14 +7924,14 @@ async function bestProfileFor(reg, name) {
|
|
|
7504
7924
|
record: best
|
|
7505
7925
|
} : void 0;
|
|
7506
7926
|
}
|
|
7507
|
-
|
|
7508
|
-
//#region src/runtime/supervise/remote-supervisor.ts
|
|
7927
|
+
// src/runtime/supervise/remote-supervisor.ts
|
|
7509
7928
|
const agentSchema = z.object({
|
|
7510
7929
|
id: z.string(),
|
|
7511
7930
|
parent: z.string().optional(),
|
|
7512
7931
|
label: z.string(),
|
|
7513
7932
|
status: z.string(),
|
|
7514
|
-
runtime: z.string()
|
|
7933
|
+
runtime: z.string(),
|
|
7934
|
+
failure: runtimeFailureCauseSchema.optional()
|
|
7515
7935
|
}).passthrough();
|
|
7516
7936
|
const treeSchema = z.object({
|
|
7517
7937
|
root: z.string(),
|
|
@@ -7537,38 +7957,98 @@ const eventPageSchema = z.discriminatedUnion("status", [z.object({
|
|
|
7537
7957
|
historyExpired: z.boolean(),
|
|
7538
7958
|
remaining: z.number().int().nonnegative()
|
|
7539
7959
|
})]);
|
|
7540
|
-
|
|
7541
|
-
|
|
7542
|
-
|
|
7543
|
-
|
|
7544
|
-
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7960
|
+
const steerSchema = z.discriminatedUnion("delivered", [z.object({
|
|
7961
|
+
delivered: z.literal(true),
|
|
7962
|
+
progress: z.record(z.string(), z.unknown()).nullable()
|
|
7963
|
+
}), z.object({
|
|
7964
|
+
delivered: z.literal(false),
|
|
7965
|
+
outcome: z.custom((value) => typeof value === "string" && value !== "delivered" && Object.hasOwn(downMessageRefusalReasons, value)),
|
|
7966
|
+
reason: z.string(),
|
|
7967
|
+
progress: z.record(z.string(), z.unknown()).nullable()
|
|
7968
|
+
})]);
|
|
7969
|
+
const workerCounts = {
|
|
7970
|
+
live: z.number().int().nonnegative(),
|
|
7971
|
+
queued: z.number().int().nonnegative()
|
|
7972
|
+
};
|
|
7973
|
+
const cancelSchema = z.union([
|
|
7974
|
+
z.object({
|
|
7975
|
+
cancelled: z.literal(true),
|
|
7976
|
+
workerId: z.string(),
|
|
7977
|
+
label: z.string(),
|
|
7978
|
+
...workerCounts
|
|
7979
|
+
}),
|
|
7980
|
+
z.object({
|
|
7981
|
+
released: z.literal(true),
|
|
7982
|
+
workerId: z.string(),
|
|
7983
|
+
...workerCounts
|
|
7984
|
+
}),
|
|
7985
|
+
z.object({
|
|
7986
|
+
error: z.literal("not-live"),
|
|
7987
|
+
reason: z.string(),
|
|
7988
|
+
...workerCounts
|
|
7989
|
+
})
|
|
7990
|
+
]);
|
|
7991
|
+
async function callRemoteSupervisor(connection, tool, args) {
|
|
7992
|
+
const text = await connection.callTool(tool, args);
|
|
7993
|
+
if (text.startsWith("ERROR:")) throw new ValidationError(text);
|
|
7994
|
+
return z.record(z.string(), z.unknown()).parse(JSON.parse(text));
|
|
7995
|
+
}
|
|
7996
|
+
function supervisorReader(connection) {
|
|
7997
|
+
const observe = async (args) => {
|
|
7998
|
+
const result = await callRemoteSupervisor(connection, "observe_agent", args);
|
|
7551
7999
|
if (result.error) throw new ValidationError(`remote supervisor refused observation: ${String(result.error)}`);
|
|
7552
8000
|
return result;
|
|
7553
8001
|
};
|
|
7554
8002
|
return {
|
|
7555
|
-
tree: async () => treeSchema.parse((await
|
|
8003
|
+
tree: async () => treeSchema.parse((await observe({ tree: true })).tree),
|
|
7556
8004
|
observe: async (workerId, cursor) => {
|
|
7557
|
-
const agent = await
|
|
8005
|
+
const agent = await observe({
|
|
7558
8006
|
workerId,
|
|
7559
8007
|
events: true,
|
|
7560
8008
|
...cursor ? { eventCursor: cursor } : {}
|
|
7561
8009
|
});
|
|
7562
8010
|
return {
|
|
7563
|
-
agent,
|
|
8011
|
+
agent: agentSchema.parse(agent),
|
|
7564
8012
|
events: eventPageSchema.parse(agent.events)
|
|
7565
8013
|
};
|
|
7566
8014
|
},
|
|
7567
8015
|
close: () => connection.close()
|
|
7568
8016
|
};
|
|
7569
8017
|
}
|
|
7570
|
-
|
|
7571
|
-
|
|
8018
|
+
/** Connect with the server's readOnly URL and protected headers; credentials never enter a profile. */
|
|
8019
|
+
async function connectRemoteSupervisor(spec) {
|
|
8020
|
+
const connection = await connectHttpMcp(spec);
|
|
8021
|
+
if (!connection.tools.some((tool) => tool.name === "observe_agent")) {
|
|
8022
|
+
await connection.close();
|
|
8023
|
+
throw new ValidationError("remote supervisor does not expose observe_agent");
|
|
8024
|
+
}
|
|
8025
|
+
return supervisorReader(connection);
|
|
8026
|
+
}
|
|
8027
|
+
/** Connect with the dedicated /control capability, keeping credentials on the protected transport. */
|
|
8028
|
+
async function connectRemoteSupervisorControl(access) {
|
|
8029
|
+
const connection = await connectHttpMcp({
|
|
8030
|
+
url: access.url,
|
|
8031
|
+
protectedHeaders: { ...access.headers }
|
|
8032
|
+
});
|
|
8033
|
+
const granted = new Set(connection.tools.map((tool) => tool.name));
|
|
8034
|
+
if (granted.size !== coordinationControlToolNames.length || !coordinationControlToolNames.every((tool) => granted.has(tool))) {
|
|
8035
|
+
await connection.close();
|
|
8036
|
+
throw new ValidationError("remote supervisor control requires the exact operator tool set");
|
|
8037
|
+
}
|
|
8038
|
+
return {
|
|
8039
|
+
...supervisorReader(connection),
|
|
8040
|
+
steer: async (workerId, instruction, options = {}) => steerSchema.parse(await callRemoteSupervisor(connection, "steer_agent", {
|
|
8041
|
+
workerId,
|
|
8042
|
+
instruction,
|
|
8043
|
+
...options.interrupt === void 0 ? {} : { interrupt: options.interrupt }
|
|
8044
|
+
})),
|
|
8045
|
+
cancel: async (workerId, reason) => cancelSchema.parse(await callRemoteSupervisor(connection, "cancel_worker", {
|
|
8046
|
+
workerId,
|
|
8047
|
+
...reason === void 0 ? {} : { reason }
|
|
8048
|
+
}))
|
|
8049
|
+
};
|
|
8050
|
+
}
|
|
8051
|
+
// src/runtime/supervise/search-spec.ts
|
|
7572
8052
|
/**
|
|
7573
8053
|
* SearchSpec: one data value for a multi-agent research configuration, and the compiler that maps
|
|
7574
8054
|
* it onto exactly one existing call, `supervise(profile, task, options)` or `runGraph(graph,
|
|
@@ -7588,32 +8068,32 @@ async function connectRemoteSupervisor(spec) {
|
|
|
7588
8068
|
* caller that supplies it is refused. */
|
|
7589
8069
|
const SEARCH_SPEC_CORRELATION_KEY = "searchSpecDigest";
|
|
7590
8070
|
const SPAWN_GRANT = `${coordinationProfileToolPrefix}spawn_worker`;
|
|
7591
|
-
function refuse(message) {
|
|
8071
|
+
function refuse$1(message) {
|
|
7592
8072
|
throw new ValidationError(`SearchSpec: ${message}`);
|
|
7593
8073
|
}
|
|
7594
8074
|
const quoted = (values) => values.map((v) => `'${v}'`).join(", ");
|
|
7595
8075
|
function record(value, where, required, optional = []) {
|
|
7596
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) refuse(`${where} must be an object`);
|
|
8076
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) refuse$1(`${where} must be an object`);
|
|
7597
8077
|
const fields = value;
|
|
7598
8078
|
const known = /* @__PURE__ */ new Set([...required, ...optional]);
|
|
7599
8079
|
const unknown = Object.keys(fields).filter((key) => !known.has(key));
|
|
7600
|
-
if (unknown.length > 0) refuse(`${where} has unknown ${unknown.length === 1 ? "key" : "keys"} ${quoted(unknown)}; it takes ${quoted([...required, ...optional])}`);
|
|
8080
|
+
if (unknown.length > 0) refuse$1(`${where} has unknown ${unknown.length === 1 ? "key" : "keys"} ${quoted(unknown)}; it takes ${quoted([...required, ...optional])}`);
|
|
7601
8081
|
const missing = required.filter((key) => fields[key] === void 0);
|
|
7602
|
-
if (missing.length > 0) refuse(`${where} is missing ${quoted(missing)}`);
|
|
8082
|
+
if (missing.length > 0) refuse$1(`${where} is missing ${quoted(missing)}`);
|
|
7603
8083
|
return fields;
|
|
7604
8084
|
}
|
|
7605
8085
|
function oneOf(value, where, values) {
|
|
7606
8086
|
if (typeof value === "string" && values.includes(value)) return value;
|
|
7607
|
-
return refuse(`${where} is ${JSON.stringify(value)}; it must be one of ${quoted(values)}`);
|
|
8087
|
+
return refuse$1(`${where} is ${JSON.stringify(value)}; it must be one of ${quoted(values)}`);
|
|
7608
8088
|
}
|
|
7609
8089
|
function names(value, where) {
|
|
7610
|
-
if (!Array.isArray(value) || value.length === 0 || !value.every((item) => typeof item === "string" && item.trim() !== "")) refuse(`${where} must be a non-empty list of non-empty strings`);
|
|
8090
|
+
if (!Array.isArray(value) || value.length === 0 || !value.every((item) => typeof item === "string" && item.trim() !== "")) refuse$1(`${where} must be a non-empty list of non-empty strings`);
|
|
7611
8091
|
const list = value;
|
|
7612
|
-
if (new Set(list).size !== list.length) refuse(`${where} lists a name twice`);
|
|
8092
|
+
if (new Set(list).size !== list.length) refuse$1(`${where} lists a name twice`);
|
|
7613
8093
|
return Object.freeze([...list].sort());
|
|
7614
8094
|
}
|
|
7615
8095
|
function integer(value, where, min) {
|
|
7616
|
-
if (!Number.isSafeInteger(value) || value < min) refuse(`${where} must be an integer >= ${min}`);
|
|
8096
|
+
if (!Number.isSafeInteger(value) || value < min) refuse$1(`${where} must be an integer >= ${min}`);
|
|
7617
8097
|
return value;
|
|
7618
8098
|
}
|
|
7619
8099
|
/**
|
|
@@ -7630,13 +8110,13 @@ function assertSearchSpec(spec) {
|
|
|
7630
8110
|
"evaluate",
|
|
7631
8111
|
"stop"
|
|
7632
8112
|
];
|
|
7633
|
-
if (typeof spec !== "object" || spec === null || Array.isArray(spec)) refuse("a spec must be an object with the axes state, context, select, workers, comms, evaluate and stop");
|
|
8113
|
+
if (typeof spec !== "object" || spec === null || Array.isArray(spec)) refuse$1("a spec must be an object with the axes state, context, select, workers, comms, evaluate and stop");
|
|
7634
8114
|
const top = spec;
|
|
7635
8115
|
const unknownAxes = Object.keys(top).filter((key) => !axes.includes(key));
|
|
7636
|
-
if (unknownAxes.length > 0) refuse(`unknown axis ${quoted(unknownAxes)}; the axes are ${quoted(axes)}`);
|
|
8116
|
+
if (unknownAxes.length > 0) refuse$1(`unknown axis ${quoted(unknownAxes)}; the axes are ${quoted(axes)}`);
|
|
7637
8117
|
const missingAxes = axes.filter((axis) => top[axis] === void 0);
|
|
7638
|
-
if (missingAxes.length > 0) refuse(`axis ${quoted(missingAxes)} is missing`);
|
|
7639
|
-
if (top.state === "conversation") refuse("state 'conversation' is not a value: research memory that lives only in a harness conversation cannot be checkpointed, inspected or ablated; it is always harness");
|
|
8118
|
+
if (missingAxes.length > 0) refuse$1(`axis ${quoted(missingAxes)} is missing`);
|
|
8119
|
+
if (top.state === "conversation") refuse$1("state 'conversation' is not a value: research memory that lives only in a harness conversation cannot be checkpointed, inspected or ablated; it is always harness");
|
|
7640
8120
|
const state = oneOf(top.state, "state", ["harness"]);
|
|
7641
8121
|
const context = oneOf(top.context, "context", ["fresh", "native"]);
|
|
7642
8122
|
const select = oneOf(top.select, "select", [
|
|
@@ -7665,21 +8145,21 @@ function assertSearchSpec(spec) {
|
|
|
7665
8145
|
if (stopIn.plateau !== void 0) {
|
|
7666
8146
|
const plateauIn = record(stopIn.plateau, "stop.plateau", ["window", "minDelta"]);
|
|
7667
8147
|
const minDelta = plateauIn.minDelta;
|
|
7668
|
-
if (typeof minDelta !== "number" || !Number.isFinite(minDelta) || minDelta < 0) refuse("stop.plateau.minDelta must be a finite number >= 0");
|
|
8148
|
+
if (typeof minDelta !== "number" || !Number.isFinite(minDelta) || minDelta < 0) refuse$1("stop.plateau.minDelta must be a finite number >= 0");
|
|
7669
8149
|
plateau = Object.freeze({
|
|
7670
8150
|
window: integer(plateauIn.window, "stop.plateau.window", 1),
|
|
7671
8151
|
minDelta
|
|
7672
8152
|
});
|
|
7673
8153
|
}
|
|
7674
|
-
if (select === "advisor" && context === "native") refuse("select 'advisor' sees each epoch only through the coordinator's projection, so it needs context 'fresh'; with 'native' its earlier turns would stay in its context");
|
|
7675
|
-
if (select === "code" && context === "fresh") refuse("select 'code' runs the root in your brain, in process; it has no harness session for context 'fresh' to renew");
|
|
7676
|
-
if (select === "advisor" && count === 0) refuse("select 'advisor' only assigns work, so workers.count must be at least 1");
|
|
7677
|
-
if (count === 0 && comms !== "none") refuse(`workers.count 0 runs the root alone, so comms must be 'none', not '${comms}'`);
|
|
7678
|
-
if (count > 0 && comms === "none") refuse(`comms 'none' leaves ${count} worker(s) with no channel; use 'assignments' or 'messages'`);
|
|
7679
|
-
if (comms === "messages" && count < 2) refuse(`comms 'messages' needs at least two peers to message each other; workers.count is ${count}`);
|
|
7680
|
-
if (select === "self" && comms !== "messages") refuse("select 'self' lets the peers divide the work by messages, so comms must be 'messages'; use select 'fixed' for independent attempts");
|
|
7681
|
-
if (count === 0 && isolation === "shared") refuse("workers.isolation 'shared' places workers in shared boxes, and workers.count is 0");
|
|
7682
|
-
if (count === 0 && models !== void 0) refuse("workers.models lists the models workers may use, and workers.count is 0");
|
|
8154
|
+
if (select === "advisor" && context === "native") refuse$1("select 'advisor' sees each epoch only through the coordinator's projection, so it needs context 'fresh'; with 'native' its earlier turns would stay in its context");
|
|
8155
|
+
if (select === "code" && context === "fresh") refuse$1("select 'code' runs the root in your brain, in process; it has no harness session for context 'fresh' to renew");
|
|
8156
|
+
if (select === "advisor" && count === 0) refuse$1("select 'advisor' only assigns work, so workers.count must be at least 1");
|
|
8157
|
+
if (count === 0 && comms !== "none") refuse$1(`workers.count 0 runs the root alone, so comms must be 'none', not '${comms}'`);
|
|
8158
|
+
if (count > 0 && comms === "none") refuse$1(`comms 'none' leaves ${count} worker(s) with no channel; use 'assignments' or 'messages'`);
|
|
8159
|
+
if (comms === "messages" && count < 2) refuse$1(`comms 'messages' needs at least two peers to message each other; workers.count is ${count}`);
|
|
8160
|
+
if (select === "self" && comms !== "messages") refuse$1("select 'self' lets the peers divide the work by messages, so comms must be 'messages'; use select 'fixed' for independent attempts");
|
|
8161
|
+
if (count === 0 && isolation === "shared") refuse$1("workers.isolation 'shared' places workers in shared boxes, and workers.count is 0");
|
|
8162
|
+
if (count === 0 && models !== void 0) refuse$1("workers.models lists the models workers may use, and workers.count is 0");
|
|
7683
8163
|
return Object.freeze({
|
|
7684
8164
|
state,
|
|
7685
8165
|
context,
|
|
@@ -7808,8 +8288,8 @@ function profileTable(entries) {
|
|
|
7808
8288
|
for (const item of entries) {
|
|
7809
8289
|
const entry = "profile" in item ? item : { profile: item };
|
|
7810
8290
|
const name = entry.profile.name;
|
|
7811
|
-
if (typeof name !== "string" || name.trim() === "") refuse("every profile in inputs.workers needs a name, which the root spawns it by");
|
|
7812
|
-
if (table.has(name)) refuse(`inputs.workers names profile '${name}' twice`);
|
|
8291
|
+
if (typeof name !== "string" || name.trim() === "") refuse$1("every profile in inputs.workers needs a name, which the root spawns it by");
|
|
8292
|
+
if (table.has(name)) refuse$1(`inputs.workers names profile '${name}' twice`);
|
|
7813
8293
|
table.set(name, entry);
|
|
7814
8294
|
}
|
|
7815
8295
|
const listed = Object.freeze([...table.keys()]);
|
|
@@ -7823,12 +8303,12 @@ function placedBackend(spec, inputs) {
|
|
|
7823
8303
|
const backend = inputs.options?.backend;
|
|
7824
8304
|
const sharedAlready = backend?.backend === "provider" && backend.shared !== void 0;
|
|
7825
8305
|
if (spec.workers.isolation === "isolated") {
|
|
7826
|
-
if (inputs.sharedPlacement !== void 0 || sharedAlready) refuse("workers.isolation 'isolated' gives every worker its own environment; drop the shared placement or use isolation 'shared'");
|
|
8306
|
+
if (inputs.sharedPlacement !== void 0 || sharedAlready) refuse$1("workers.isolation 'isolated' gives every worker its own environment; drop the shared placement or use isolation 'shared'");
|
|
7827
8307
|
return backend;
|
|
7828
8308
|
}
|
|
7829
8309
|
if (inputs.sharedPlacement === void 0) return backend;
|
|
7830
|
-
if (backend?.backend !== "provider") refuse(`inputs.sharedPlacement places workers through a 'provider' backend; options.backend is ${backend === void 0 ? "absent" : `'${backend.backend}'`}`);
|
|
7831
|
-
if (sharedAlready) refuse("options.backend already carries a shared placement; pass it once");
|
|
8310
|
+
if (backend?.backend !== "provider") refuse$1(`inputs.sharedPlacement places workers through a 'provider' backend; options.backend is ${backend === void 0 ? "absent" : `'${backend.backend}'`}`);
|
|
8311
|
+
if (sharedAlready) refuse$1("options.backend already carries a shared placement; pass it once");
|
|
7832
8312
|
return Object.freeze({
|
|
7833
8313
|
...backend,
|
|
7834
8314
|
shared: inputs.sharedPlacement
|
|
@@ -7857,10 +8337,10 @@ function compileSearchSpec(raw, inputs) {
|
|
|
7857
8337
|
const spec = assertSearchSpec(raw);
|
|
7858
8338
|
const digest = searchSpecDigest(spec);
|
|
7859
8339
|
const passed = inputs.options ?? {};
|
|
7860
|
-
for (const [key, axis] of Object.entries(ownedBy)) if (passed[key] !== void 0) refuse(`options.${key} is decided by ${axis}; change the spec or that input instead`);
|
|
7861
|
-
if (inputs.deliverable === void 0) refuse("inputs.deliverable is required: a spec run is sent back by its check");
|
|
8340
|
+
for (const [key, axis] of Object.entries(ownedBy)) if (passed[key] !== void 0) refuse$1(`options.${key} is decided by ${axis}; change the spec or that input instead`);
|
|
8341
|
+
if (inputs.deliverable === void 0) refuse$1("inputs.deliverable is required: a spec run is sent back by its check");
|
|
7862
8342
|
const correlation = passed.execution?.correlation ?? {};
|
|
7863
|
-
if (Object.hasOwn(correlation, "searchSpecDigest")) refuse(`options.execution.correlation cannot set ${SEARCH_SPEC_CORRELATION_KEY}; Runtime records it`);
|
|
8343
|
+
if (Object.hasOwn(correlation, "searchSpecDigest")) refuse$1(`options.execution.correlation cannot set ${SEARCH_SPEC_CORRELATION_KEY}; Runtime records it`);
|
|
7864
8344
|
const execution = Object.freeze({
|
|
7865
8345
|
...passed.execution,
|
|
7866
8346
|
correlation: Object.freeze({
|
|
@@ -7881,9 +8361,9 @@ function compileSearchSpec(raw, inputs) {
|
|
|
7881
8361
|
};
|
|
7882
8362
|
const backend = placedBackend(spec, inputs);
|
|
7883
8363
|
const callerOwnsLeaves = passed.makeLeafAgent !== void 0 || passed.makeWorkerAgent !== void 0;
|
|
7884
|
-
if (spec.comms === "messages" && backend !== void 0 && backend.backend !== "bridge" && backend.backend !== "provider" && !callerOwnsLeaves) refuse(`comms 'messages' needs workers that can call peer mail: Runtime mounts it on 'bridge' or capable 'provider' workers, and '${backend.backend}' workers run no client for it. Run the workers on a bridge, or mount WorkerSpawnContext.peerMailUrl through makeLeafAgent`);
|
|
8364
|
+
if (spec.comms === "messages" && backend !== void 0 && backend.backend !== "bridge" && backend.backend !== "provider" && !callerOwnsLeaves) refuse$1(`comms 'messages' needs workers that can call peer mail: Runtime mounts it on 'bridge' or capable 'provider' workers, and '${backend.backend}' workers run no client for it. Run the workers on a bridge, or mount WorkerSpawnContext.peerMailUrl through makeLeafAgent`);
|
|
7885
8365
|
const analystKinds = spec.evaluate.analysts ?? [];
|
|
7886
|
-
if (analystKinds.length > 0 && inputs.analysts === void 0) refuse("evaluate.analysts names analyst kinds, and inputs.analysts holds no registry to run them");
|
|
8366
|
+
if (analystKinds.length > 0 && inputs.analysts === void 0) refuse$1("evaluate.analysts names analyst kinds, and inputs.analysts holds no registry to run them");
|
|
7887
8367
|
const axisOptions = {
|
|
7888
8368
|
continuation,
|
|
7889
8369
|
execution,
|
|
@@ -7894,15 +8374,15 @@ function compileSearchSpec(raw, inputs) {
|
|
|
7894
8374
|
...backend === void 0 ? {} : { backend }
|
|
7895
8375
|
};
|
|
7896
8376
|
if (spec.select === "code" || spec.select === "fixed") {
|
|
7897
|
-
const graph = inputs.graph ?? refuse(`select '${spec.select}' needs inputs.graph`);
|
|
7898
|
-
if (inputs.profile !== void 0 || inputs.task !== void 0) refuse(`select '${spec.select}' runs inputs.graph, whose root is its own node and whose task is the deliverable's description; drop inputs.profile and inputs.task`);
|
|
7899
|
-
if (inputs.workers !== void 0) refuse(`select '${spec.select}' spawns the graph's nodes; drop inputs.workers`);
|
|
7900
|
-
if (analystKinds.length > 0) refuse(`select '${spec.select}' declares a graph's analysts as analyzes edges, not evaluate.analysts`);
|
|
7901
|
-
if (spec.workers.count === 0) refuse(`select '${spec.select}' runs a graph's worker nodes, so workers.count must be at least 1`);
|
|
7902
|
-
if (spec.select === "code" && inputs.brain === void 0) refuse("select 'code' needs inputs.brain, the caller's brain that drives the root");
|
|
7903
|
-
if (spec.select === "fixed" && inputs.brain !== void 0) refuse("select 'fixed' runs the graph's root profile; a brain is select 'code'");
|
|
7904
|
-
if (passed.registry !== void 0) refuse("options.registry is supervise's name table, which a graph cannot read; pass the graph's directive registry as inputs.directives");
|
|
7905
|
-
if (spec.context === "fresh" && !harnessRunsAgent(graphRoot(graph)?.harness)) refuse("context 'fresh' renews an external harness root's session at each re-entry, and the graph's root runs on the router brain");
|
|
8377
|
+
const graph = inputs.graph ?? refuse$1(`select '${spec.select}' needs inputs.graph`);
|
|
8378
|
+
if (inputs.profile !== void 0 || inputs.task !== void 0) refuse$1(`select '${spec.select}' runs inputs.graph, whose root is its own node and whose task is the deliverable's description; drop inputs.profile and inputs.task`);
|
|
8379
|
+
if (inputs.workers !== void 0) refuse$1(`select '${spec.select}' spawns the graph's nodes; drop inputs.workers`);
|
|
8380
|
+
if (analystKinds.length > 0) refuse$1(`select '${spec.select}' declares a graph's analysts as analyzes edges, not evaluate.analysts`);
|
|
8381
|
+
if (spec.workers.count === 0) refuse$1(`select '${spec.select}' runs a graph's worker nodes, so workers.count must be at least 1`);
|
|
8382
|
+
if (spec.select === "code" && inputs.brain === void 0) refuse$1("select 'code' needs inputs.brain, the caller's brain that drives the root");
|
|
8383
|
+
if (spec.select === "fixed" && inputs.brain !== void 0) refuse$1("select 'fixed' runs the graph's root profile; a brain is select 'code'");
|
|
8384
|
+
if (passed.registry !== void 0) refuse$1("options.registry is supervise's name table, which a graph cannot read; pass the graph's directive registry as inputs.directives");
|
|
8385
|
+
if (spec.context === "fresh" && !harnessRunsAgent(graphRoot(graph)?.harness)) refuse$1("context 'fresh' renews an external harness root's session at each re-entry, and the graph's root runs on the router brain");
|
|
7906
8386
|
return Object.freeze({
|
|
7907
8387
|
call: "runGraph",
|
|
7908
8388
|
spec,
|
|
@@ -7922,14 +8402,14 @@ function compileSearchSpec(raw, inputs) {
|
|
|
7922
8402
|
})
|
|
7923
8403
|
});
|
|
7924
8404
|
}
|
|
7925
|
-
const profile = inputs.profile ?? refuse(`select '${spec.select}' needs inputs.profile, the root`);
|
|
7926
|
-
if (inputs.task === void 0) refuse(`select '${spec.select}' needs inputs.task`);
|
|
7927
|
-
if (inputs.graph !== void 0 || inputs.brain !== void 0 || inputs.directives !== void 0) refuse(`select '${spec.select}' runs inputs.profile; a graph, brain or directives is select 'code' or 'fixed'`);
|
|
7928
|
-
if (!harnessRunsAgent(profile.harness)) refuse(`select '${spec.select}' runs the root under Runtime's continuation (context, evaluate and stop), which drives an external harness; profile '${profile.name}' runs on the router brain. Give it a harness such as claude-code or codex, or use select 'code'`);
|
|
7929
|
-
if (spec.workers.count === 0 && grantsSpawn(profile)) refuse(`workers.count 0 runs the root alone, but profile '${profile.name}' grants ${SPAWN_GRANT}`);
|
|
7930
|
-
if (spec.workers.count > 0 && !grantsSpawn(profile)) refuse(`workers.count ${spec.workers.count} needs a root that spawns, and profile '${profile.name}' does not grant ${SPAWN_GRANT}`);
|
|
7931
|
-
if (spec.select === "self" && inputs.workers?.length !== spec.workers.count) refuse(`select 'self' starts exactly workers.count peers; inputs.workers holds ${inputs.workers?.length ?? 0}, and workers.count is ${spec.workers.count}`);
|
|
7932
|
-
if (inputs.workers !== void 0 && passed.registry?.profiles !== void 0) refuse("inputs.workers and options.registry.profiles both name spawnable profiles; pass them once");
|
|
8405
|
+
const profile = inputs.profile ?? refuse$1(`select '${spec.select}' needs inputs.profile, the root`);
|
|
8406
|
+
if (inputs.task === void 0) refuse$1(`select '${spec.select}' needs inputs.task`);
|
|
8407
|
+
if (inputs.graph !== void 0 || inputs.brain !== void 0 || inputs.directives !== void 0) refuse$1(`select '${spec.select}' runs inputs.profile; a graph, brain or directives is select 'code' or 'fixed'`);
|
|
8408
|
+
if (!harnessRunsAgent(profile.harness)) refuse$1(`select '${spec.select}' runs the root under Runtime's continuation (context, evaluate and stop), which drives an external harness; profile '${profile.name}' runs on the router brain. Give it a harness such as claude-code or codex, or use select 'code'`);
|
|
8409
|
+
if (spec.workers.count === 0 && grantsSpawn(profile)) refuse$1(`workers.count 0 runs the root alone, but profile '${profile.name}' grants ${SPAWN_GRANT}`);
|
|
8410
|
+
if (spec.workers.count > 0 && !grantsSpawn(profile)) refuse$1(`workers.count ${spec.workers.count} needs a root that spawns, and profile '${profile.name}' does not grant ${SPAWN_GRANT}`);
|
|
8411
|
+
if (spec.select === "self" && inputs.workers?.length !== spec.workers.count) refuse$1(`select 'self' starts exactly workers.count peers; inputs.workers holds ${inputs.workers?.length ?? 0}, and workers.count is ${spec.workers.count}`);
|
|
8412
|
+
if (inputs.workers !== void 0 && passed.registry?.profiles !== void 0) refuse$1("inputs.workers and options.registry.profiles both name spawnable profiles; pass them once");
|
|
7933
8413
|
const registry = inputs.workers === void 0 ? passed.registry : Object.freeze({
|
|
7934
8414
|
...passed.registry,
|
|
7935
8415
|
profiles: profileTable(inputs.workers)
|
|
@@ -7955,8 +8435,7 @@ function compileSearchSpec(raw, inputs) {
|
|
|
7955
8435
|
})
|
|
7956
8436
|
});
|
|
7957
8437
|
}
|
|
7958
|
-
|
|
7959
|
-
//#region src/runtime/supervise/sql-run-context.ts
|
|
8438
|
+
// src/runtime/supervise/sql-run-context.ts
|
|
7960
8439
|
/**
|
|
7961
8440
|
* A cross-machine run context on the existing autocommit SqlAdapter. Reuse the same database,
|
|
7962
8441
|
* tablePrefix and runId on every host; no runDir or shared filesystem is required.
|
|
@@ -8129,8 +8608,158 @@ async function projection(entries) {
|
|
|
8129
8608
|
}
|
|
8130
8609
|
};
|
|
8131
8610
|
}
|
|
8132
|
-
|
|
8133
|
-
|
|
8611
|
+
// src/runtime/supervise/stored-graph-validation.ts
|
|
8612
|
+
const name = z.string().min(1);
|
|
8613
|
+
const positiveInteger = z.number().int().positive();
|
|
8614
|
+
const directive = z.strictObject({
|
|
8615
|
+
surface: name,
|
|
8616
|
+
version: z.number().int().nonnegative()
|
|
8617
|
+
});
|
|
8618
|
+
const node = z.strictObject({
|
|
8619
|
+
id: name,
|
|
8620
|
+
profile: agentProfileSchema
|
|
8621
|
+
});
|
|
8622
|
+
const entry = z.array(z.strictObject({
|
|
8623
|
+
node: name,
|
|
8624
|
+
task: z.unknown().refine((value) => value !== void 0, "task must be explicit JSON data")
|
|
8625
|
+
})).min(1);
|
|
8626
|
+
const gates = z.array(z.strictObject({
|
|
8627
|
+
id: name,
|
|
8628
|
+
question: name,
|
|
8629
|
+
choices: z.array(name).min(1)
|
|
8630
|
+
}));
|
|
8631
|
+
const continuity = z.enum(["fresh", "resume"]).optional();
|
|
8632
|
+
const topology = z.lazy(() => z.strictObject({
|
|
8633
|
+
nodes: z.array(node).min(1),
|
|
8634
|
+
edges: z.array(edge),
|
|
8635
|
+
entry: entry.optional(),
|
|
8636
|
+
gates: gates.optional()
|
|
8637
|
+
}));
|
|
8638
|
+
const edge = z.lazy(() => z.discriminatedUnion("kind", [
|
|
8639
|
+
z.strictObject({
|
|
8640
|
+
kind: z.literal("delegates"),
|
|
8641
|
+
from: name,
|
|
8642
|
+
to: name,
|
|
8643
|
+
directive,
|
|
8644
|
+
maxTraversals: positiveInteger.optional(),
|
|
8645
|
+
continuity
|
|
8646
|
+
}),
|
|
8647
|
+
z.strictObject({
|
|
8648
|
+
kind: z.literal("analyzes"),
|
|
8649
|
+
analyst: name,
|
|
8650
|
+
over: z.array(name).min(1),
|
|
8651
|
+
to: name,
|
|
8652
|
+
directive,
|
|
8653
|
+
maxTraversals: positiveInteger.optional()
|
|
8654
|
+
}),
|
|
8655
|
+
z.strictObject({
|
|
8656
|
+
kind: z.literal("maps"),
|
|
8657
|
+
from: name,
|
|
8658
|
+
pointer: z.string(),
|
|
8659
|
+
to: name.optional(),
|
|
8660
|
+
graph: topology.optional(),
|
|
8661
|
+
join: name,
|
|
8662
|
+
directive,
|
|
8663
|
+
maxItems: positiveInteger,
|
|
8664
|
+
concurrency: positiveInteger,
|
|
8665
|
+
onItemFailure: z.enum(["all-or-refuse", "settled-subset"]),
|
|
8666
|
+
itemBudget: graphFileSchema.shape.budget.partial().optional()
|
|
8667
|
+
}),
|
|
8668
|
+
z.strictObject({
|
|
8669
|
+
kind: z.literal("routes"),
|
|
8670
|
+
from: z.union([name, z.array(name).min(2)]),
|
|
8671
|
+
to: z.union([
|
|
8672
|
+
name,
|
|
8673
|
+
z.array(name).min(2),
|
|
8674
|
+
z.strictObject({ stop: name }),
|
|
8675
|
+
z.strictObject({ finish: name })
|
|
8676
|
+
]),
|
|
8677
|
+
directive,
|
|
8678
|
+
when: graphRouteWhenSchema.optional(),
|
|
8679
|
+
evidence: z.array(name).optional(),
|
|
8680
|
+
maxTraversals: positiveInteger.optional(),
|
|
8681
|
+
continuity
|
|
8682
|
+
})
|
|
8683
|
+
]));
|
|
8684
|
+
const storedGraphSchema = graphFileSchema.pick({
|
|
8685
|
+
digest: true,
|
|
8686
|
+
budget: true,
|
|
8687
|
+
deliverable: true
|
|
8688
|
+
}).required().extend({
|
|
8689
|
+
observed: z.literal(false).optional(),
|
|
8690
|
+
triggerBindings: graphTriggerBindingsSchema.optional(),
|
|
8691
|
+
nodes: z.array(node).min(1),
|
|
8692
|
+
edges: z.array(edge),
|
|
8693
|
+
entry: entry.optional(),
|
|
8694
|
+
gates: gates.optional()
|
|
8695
|
+
});
|
|
8696
|
+
function refuse(message) {
|
|
8697
|
+
throw new ValidationError(`validateStoredGraph: ${message}`);
|
|
8698
|
+
}
|
|
8699
|
+
/** Inspect descriptors instead of invoking accessors; JSON has no getters, symbols, prototypes,
|
|
8700
|
+
* sparse arrays, undefined, closures or cycles. Repeated non-cyclic references remain JSON data. */
|
|
8701
|
+
function assertJsonData(value, visiting = /* @__PURE__ */ new Set()) {
|
|
8702
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") return;
|
|
8703
|
+
if (typeof value === "number" && Number.isFinite(value)) return;
|
|
8704
|
+
if (!value || typeof value !== "object" || visiting.has(value)) refuse("expected finite, acyclic JSON data without executable values");
|
|
8705
|
+
const array = Array.isArray(value);
|
|
8706
|
+
const prototype = Object.getPrototypeOf(value);
|
|
8707
|
+
if (array ? prototype !== Array.prototype : prototype !== Object.prototype && prototype !== null) refuse("expected plain JSON objects and arrays");
|
|
8708
|
+
visiting.add(value);
|
|
8709
|
+
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
8710
|
+
const keys = Reflect.ownKeys(descriptors);
|
|
8711
|
+
if (array && keys.length !== value.length + 1) refuse("sparse arrays are not canonical JSON");
|
|
8712
|
+
for (const key of keys) {
|
|
8713
|
+
if (array && key === "length") continue;
|
|
8714
|
+
const property = typeof key === "string" ? descriptors[key] : void 0;
|
|
8715
|
+
if (!property || !property.enumerable || !("value" in property)) refuse("JSON data cannot contain symbols, hidden properties or accessors");
|
|
8716
|
+
if (array && (!/^(0|[1-9]\d*)$/.test(key) || Number(key) >= value.length)) refuse("arrays may contain only indexed JSON values");
|
|
8717
|
+
assertJsonData(property.value, visiting);
|
|
8718
|
+
}
|
|
8719
|
+
visiting.delete(value);
|
|
8720
|
+
}
|
|
8721
|
+
function assertExecutableNodes(graph) {
|
|
8722
|
+
for (const item of graph.nodes) assertExecutableAgentProfile(item.profile, `validateStoredGraph node ${item.id}`);
|
|
8723
|
+
for (const item of graph.edges) if (item.kind === "maps" && item.graph) assertExecutableNodes(item.graph);
|
|
8724
|
+
}
|
|
8725
|
+
/** Validate compiled, runnable StoredGraph data. Authored params/seats/on envelopes belong to
|
|
8726
|
+
* loadGraphFile; observations belong to the registry's observation importer, never this entry.
|
|
8727
|
+
* No check function or model call is executed while validating environment-owned references. */
|
|
8728
|
+
function validateStoredGraph(value, options = {}) {
|
|
8729
|
+
assertJsonData(value);
|
|
8730
|
+
const parsed = storedGraphSchema.safeParse(value);
|
|
8731
|
+
if (!parsed.success) refuse(parsed.error.message);
|
|
8732
|
+
const graph = parsed.data;
|
|
8733
|
+
if (graph.triggerBindings !== void 0) assertGraphTriggerBindings(graph, graph.triggerBindings);
|
|
8734
|
+
const check = graph.deliverable;
|
|
8735
|
+
if (check.checkRef === "command") {
|
|
8736
|
+
if (!check.command?.command.trim() || check.when) refuse("command check requires only command data");
|
|
8737
|
+
} else if (check.checkRef === "route") {
|
|
8738
|
+
if (!check.when || check.command) refuse("route check requires only when data");
|
|
8739
|
+
} else {
|
|
8740
|
+
if (check.command || check.when) refuse("custom checkRef cannot carry builtin command/route data");
|
|
8741
|
+
const selected = options.checks && Object.hasOwn(options.checks, check.checkRef) ? options.checks[check.checkRef] : void 0;
|
|
8742
|
+
if (selected === void 0) refuse(`unknown checkRef ${check.checkRef}; supply an environment checks binding`);
|
|
8743
|
+
if (typeof selected !== "function") {
|
|
8744
|
+
const command = graphFileSchema.shape.deliverable.unwrap().shape.command.unwrap().safeParse(selected);
|
|
8745
|
+
if (!command.success || !command.data.command.trim()) refuse(`invalid checks binding ${check.checkRef}`);
|
|
8746
|
+
}
|
|
8747
|
+
}
|
|
8748
|
+
if (check.when) {
|
|
8749
|
+
const ids = new Set(graph.nodes.map((item) => item.id));
|
|
8750
|
+
for (const condition of "all" in check.when ? check.when.all : [check.when]) if (condition.node !== void 0 && !ids.has(condition.node)) refuse(`check references unknown node ${condition.node}`);
|
|
8751
|
+
}
|
|
8752
|
+
assertExecutableNodes(graph);
|
|
8753
|
+
const registry = options.registry ?? kernelPromptRegistry();
|
|
8754
|
+
if (graph.entry) validateFlowGraph(graph, registry, options.analysts);
|
|
8755
|
+
else validateGraphTopology(graph.nodes, graph.edges, registry, options.analysts);
|
|
8756
|
+
const { digest: provided, ...rawContent } = value;
|
|
8757
|
+
if (graphDigest(rawContent) !== provided) refuse("supplied digest does not match the input graph");
|
|
8758
|
+
const { digest, ...content } = graph;
|
|
8759
|
+
if (graphDigest(content) !== digest) refuse("supplied digest does not match the canonical graph");
|
|
8760
|
+
return detachedSnapshot(graph, "validated stored graph");
|
|
8761
|
+
}
|
|
8762
|
+
// src/runtime/supervise/trajectory-recorder.ts
|
|
8134
8763
|
/**
|
|
8135
8764
|
*
|
|
8136
8765
|
* The SETTLE-time analyst: when a worker finishes, collect its tool spans from a `TraceSource` and run
|
|
@@ -8191,8 +8820,7 @@ async function analyzeTrace(source, runId = "worker") {
|
|
|
8191
8820
|
toolWaste
|
|
8192
8821
|
};
|
|
8193
8822
|
}
|
|
8194
|
-
|
|
8195
|
-
//#region src/runtime/supervise/untracked-clone.ts
|
|
8823
|
+
// src/runtime/supervise/untracked-clone.ts
|
|
8196
8824
|
/**
|
|
8197
8825
|
* Worker-clone preparation: make each worker's fresh clone a FAITHFUL copy of the
|
|
8198
8826
|
* shared workspace's working tree, not just of its git history.
|
|
@@ -8235,7 +8863,7 @@ const SKIPPED_TOP_LEVEL = /* @__PURE__ */ new Set([
|
|
|
8235
8863
|
".claude"
|
|
8236
8864
|
]);
|
|
8237
8865
|
/** Warn (and copy anyway) past this untracked payload size. */
|
|
8238
|
-
const DEFAULT_WARN_BYTES =
|
|
8866
|
+
const DEFAULT_WARN_BYTES = 2147483648;
|
|
8239
8867
|
/**
|
|
8240
8868
|
* Copy every untracked file of `sourceDir`'s working tree — including git-ignored
|
|
8241
8869
|
* build outputs (`git ls-files --others` with NO exclude flags lists both) — into
|
|
@@ -8256,7 +8884,7 @@ function copyUntrackedIntoClone(sourceDir, cloneDir, opts = {}) {
|
|
|
8256
8884
|
"-z"
|
|
8257
8885
|
], {
|
|
8258
8886
|
encoding: "utf8",
|
|
8259
|
-
maxBuffer:
|
|
8887
|
+
maxBuffer: 268435456
|
|
8260
8888
|
});
|
|
8261
8889
|
if (ls.status !== 0) throw new Error(`git ls-files --others failed in ${src}: ${(ls.stderr ?? "").trim() || `exit ${ls.status}`}`);
|
|
8262
8890
|
const plan = [];
|
|
@@ -8342,8 +8970,7 @@ function withUntrackedArtifacts(ws, sourceDir, log) {
|
|
|
8342
8970
|
head: () => ws.head()
|
|
8343
8971
|
};
|
|
8344
8972
|
}
|
|
8345
|
-
|
|
8346
|
-
//#region src/runtime/supervise/worker-evidence.ts
|
|
8973
|
+
// src/runtime/supervise/worker-evidence.ts
|
|
8347
8974
|
/**
|
|
8348
8975
|
* Evidence-rich worker settlement.
|
|
8349
8976
|
*
|
|
@@ -8418,8 +9045,7 @@ function diffSummary(patch) {
|
|
|
8418
9045
|
const omitted = lines.length - head.length;
|
|
8419
9046
|
return `${`--- diff: ${filesChanged} file(s) changed, ${Buffer.byteLength(patch)} bytes; first ${head.length} line(s) ---`}\n${head.join("\n")}${omitted > 0 ? `\n... (${omitted} more patch lines; full patch persisted per worker)` : ""}`;
|
|
8420
9047
|
}
|
|
8421
|
-
|
|
8422
|
-
//#region src/runtime/supervise/patch-checks.ts
|
|
9048
|
+
// src/runtime/supervise/patch-checks.ts
|
|
8423
9049
|
const DEFAULT_MAX_DIFF_LINES = 400;
|
|
8424
9050
|
/**
|
|
8425
9051
|
* Default-on credential-path floor: a patch that touches a credential-shaped path is rejected
|
|
@@ -8511,8 +9137,7 @@ function runCoderChecks(input, constraints = {}) {
|
|
|
8511
9137
|
if (notes.length > 0) verdict.notes = notes.join("; ");
|
|
8512
9138
|
return verdict;
|
|
8513
9139
|
}
|
|
8514
|
-
|
|
8515
|
-
//#region src/runtime/supervise/patch-deliverable.ts
|
|
9140
|
+
// src/runtime/supervise/patch-deliverable.ts
|
|
8516
9141
|
/**
|
|
8517
9142
|
* Build the `DeliverableSpec<WorktreePatchArtifact>`: `check(artifact)` runs the shared mechanical
|
|
8518
9143
|
* gate (`runCoderChecks`) over the captured patch + the worktree-derived pass signals and returns
|
|
@@ -8547,8 +9172,7 @@ function signalPass(value, required) {
|
|
|
8547
9172
|
if (value !== void 0) return value;
|
|
8548
9173
|
return !required;
|
|
8549
9174
|
}
|
|
8550
|
-
|
|
8551
|
-
//#region src/runtime/supervise/worktree-fanout.ts
|
|
9175
|
+
// src/runtime/supervise/worktree-fanout.ts
|
|
8552
9176
|
/**
|
|
8553
9177
|
* Build the worktree fanout combinator. Run it with `runPersonified({ persona, shape, task, budget })`
|
|
8554
9178
|
* — equal-k holds by construction (the conserved budget pool bounds the N leaves), and selection is
|
|
@@ -8600,8 +9224,7 @@ function worktreeFanout(options) {
|
|
|
8600
9224
|
selectWinner
|
|
8601
9225
|
});
|
|
8602
9226
|
}
|
|
8603
|
-
|
|
8604
|
-
//#region src/runtime/supervise-analysts.ts
|
|
9227
|
+
// src/runtime/supervise-analysts.ts
|
|
8605
9228
|
/**
|
|
8606
9229
|
* Analyst lenses a supervised manager reads: the agent-eval trace-analyst registry adapted to the
|
|
8607
9230
|
* `analysts` option (`analystsFromRegistry`), and `failuresAnalyst`, which reports the tests still
|
|
@@ -8788,8 +9411,7 @@ function allTestsPassed(report) {
|
|
|
8788
9411
|
function missingRunTestsEvidence() {
|
|
8789
9412
|
return { summary: "Missing structured run_tests span evidence. Refusing to infer failing-test names from worker prose." };
|
|
8790
9413
|
}
|
|
8791
|
-
|
|
8792
|
-
//#region src/runtime/surface-diff.ts
|
|
9414
|
+
// src/runtime/surface-diff.ts
|
|
8793
9415
|
/**
|
|
8794
9416
|
*
|
|
8795
9417
|
* Settle-time surface-diff harvest — the read-back dual of the mount manifest.
|
|
@@ -8986,8 +9608,7 @@ function fsSurfaceReader(root) {
|
|
|
8986
9608
|
}
|
|
8987
9609
|
};
|
|
8988
9610
|
}
|
|
8989
|
-
|
|
8990
|
-
//#region src/runtime/verifier-environment.ts
|
|
9611
|
+
// src/runtime/verifier-environment.ts
|
|
8991
9612
|
const submitTool = {
|
|
8992
9613
|
type: "function",
|
|
8993
9614
|
function: {
|
|
@@ -9065,8 +9686,7 @@ function createVerifierEnvironment(opts) {
|
|
|
9065
9686
|
}
|
|
9066
9687
|
};
|
|
9067
9688
|
}
|
|
9068
|
-
|
|
9069
|
-
//#region src/runtime/waterfall.ts
|
|
9689
|
+
// src/runtime/waterfall.ts
|
|
9070
9690
|
/** Build a `WaterfallCollector` that records agent spans and renders them as an ASCII timeline. */
|
|
9071
9691
|
function createWaterfallCollector() {
|
|
9072
9692
|
let spans = /* @__PURE__ */ new Map();
|
|
@@ -9185,8 +9805,7 @@ function createWaterfallCollector() {
|
|
|
9185
9805
|
}
|
|
9186
9806
|
};
|
|
9187
9807
|
}
|
|
9188
|
-
|
|
9189
|
-
//#region src/runtime/workspace.ts
|
|
9808
|
+
// src/runtime/workspace.ts
|
|
9190
9809
|
/** Host-process `Shell`: run a command via `execFile`, resolving `{ stdout, stderr, code }` (never throws on non-zero exit). */
|
|
9191
9810
|
function localShell() {
|
|
9192
9811
|
return async (args, cwd) => {
|
|
@@ -9196,7 +9815,7 @@ function localShell() {
|
|
|
9196
9815
|
execFile(bin ?? "", rest, {
|
|
9197
9816
|
cwd,
|
|
9198
9817
|
encoding: "utf-8",
|
|
9199
|
-
maxBuffer:
|
|
9818
|
+
maxBuffer: 67108864
|
|
9200
9819
|
}, (err, stdout, stderr) => {
|
|
9201
9820
|
resolve({
|
|
9202
9821
|
stdout: stdout ?? "",
|
|
@@ -9405,7 +10024,6 @@ async function runInWorkspace(ws, body, opts = {}) {
|
|
|
9405
10024
|
function tail(s) {
|
|
9406
10025
|
return s.slice(-400);
|
|
9407
10026
|
}
|
|
9408
|
-
|
|
9409
|
-
export { runPersonified as $, openSqlRunStore as $t, searchSpecDigest as A, secretEnvOfMcpServer as At, chatWorkerSeam as B, readDeclaredCheck as Bt, withUntrackedArtifacts as C, materializeLocalMcp as Ct, assertSearchSpec as D, mcpSecretEnvMetadataKey as Dt, SEARCH_SPEC_CORRELATION_KEY as E, envKeyProvider as Et, profileRegistry as F, assertDeclaredCheck as Ft, openSandboxRun as G, stopSentinel as Gt, runStrategyEvolution as H, completionAuthorizes as Ht, profileRunsForName as I, checkProgramDigest as It, runBenchmark as J, renderLeaderboardHtml as Jt, createS3PrivateCasStore as K, leaderboard as Kt, recordProfileRun as L, declaredCheckDeliverable as Lt, bestProfileFor as M, loopCampaignDispatch as Mt, loadProfile as N, loopDispatch as Nt, compileSearchSpec as O, resolveMcpServerLaunch as Ot, pickBestProfile as P, superviseDispatch as Pt, definePersona as Q, SqlRunOwnershipError as Qt, graphDesignerExtraTools as R, declaredCheckDigest as Rt, copyUntrackedIntoClone as S, connectStdioMcp as St, createFencedSqlRunContext as T, sanitizeMcpToolSchema as Tt, strategyTournament as U, deterministicCompletion as Ut, createChatSessionStore as V, runIsolatedCheck as Vt, SandboxRunAbortError as W, sentinelCompletion as Wt, equalKOnCost as X, renderLeaderboardSvg as Xt, createPrivateCasArtifactPort as Y, renderLeaderboardMarkdown as Yt, trajectoryReport as Z, renderPairwiseMarkdown as Zt, NOTE_MAX_CHARS as _, HarvestError as _t, localShell as a, loopUntil as at, composeWorkerEvidence as b, resolveSandboxClient as bt, createVerifierEnvironment as c, selectValidWinner as ct, harvestSurfaceDiffs as d, assertTraceDerivedFindings as dt, FileCorpus as et, analystsFromRegistry as f, buildSteerContext as ft, EVIDENCE_MAX_CHARS as g, inProcessSandboxClient as gt, runCoderChecks as h, observationFromRegistry as ht, jjWorkspace as i, flatWidenGate as it, connectRemoteSupervisor as j, inlineSandboxClient as jt, searchPresets as k, resolveSecretEnv as kt, boxSurfaceReader as l, verify as lt, worktreeFanout as m, registryScopeAnalyst as mt, makeFinding$1 as n, renderCorpusToInstructions as nt, runInWorkspace as o, panel as ot, failuresAnalyst as p, createScopeAnalyst as pt, printBenchmarkReport as q, pairwiseSignificance as qt, gitWorkspace as r, fanout as rt, createWaterfallCollector as s, pipeline as st, computeFindingId$1 as t, InMemoryCorpus as tt, fsSurfaceReader as u, widen as ut, VERIFY_TAIL_CHARS as v, harvestCorpus as vt, analyzeTrace as w, createMcpEnvironment as wt, settledWorkerOut as x, McpSpawnFault as xt, closingWorkerNote as y, defineLeaderboard as yt, chatTransportExecutor as z, declaredCheckJudge as zt };
|
|
10027
|
+
export { runBenchmark as $, renderLeaderboardHtml as $t, searchPresets as A, sanitizeMcpToolSchema as At, graphFromSessionFacts as B, assertDeclaredCheck as Bt, withUntrackedArtifacts as C, harvestCorpus as Ct, SEARCH_SPEC_CORRELATION_KEY as D, connectStdioMcp as Dt, createFencedSqlRunContext as E, McpSpawnFault as Et, loadProfile as F, secretEnvOfMcpServer as Ft, chatWorkerSeam as G, readDeclaredCheck as Gt, loadGraphFile as H, declaredCheckDeliverable as Ht, pickBestProfile as I, inlineSandboxClient as It, strategyTournament as J, deterministicCompletion as Jt, createChatSessionStore as K, runIsolatedCheck as Kt, profileRegistry as L, loopCampaignDispatch as Lt, connectRemoteSupervisor as M, mcpSecretEnvMetadataKey as Mt, connectRemoteSupervisorControl as N, resolveMcpServerLaunch as Nt, assertSearchSpec as O, materializeLocalMcp as Ot, bestProfileFor as P, resolveSecretEnv as Pt, printBenchmarkReport as Q, pairwiseSignificance as Qt, profileRunsForName as R, loopDispatch as Rt, copyUntrackedIntoClone as S, HarvestError as St, validateStoredGraph as T, resolveSandboxClient as Tt, graphDesignerExtraTools as U, declaredCheckDigest as Ut, GraphFileResolutionError as V, checkProgramDigest as Vt, chatTransportExecutor as W, declaredCheckJudge as Wt, openSandboxRun as X, stopSentinel as Xt, SandboxRunAbortError as Y, sentinelCompletion as Yt, createS3PrivateCasStore as Z, leaderboard as Zt, NOTE_MAX_CHARS as _, buildSteerContext as _t, localShell as a, FileCorpus as at, composeWorkerEvidence as b, observationFromRegistry as bt, createVerifierEnvironment as c, fanout as ct, harvestSurfaceDiffs as d, panel as dt, renderLeaderboardMarkdown as en, createPrivateCasArtifactPort as et, analystsFromRegistry as f, pipeline as ft, EVIDENCE_MAX_CHARS as g, assertTraceDerivedFindings as gt, runCoderChecks as h, widen as ht, jjWorkspace as i, openSqlRunStore as in, runPersonified as it, searchSpecDigest as j, envKeyProvider as jt, compileSearchSpec as k, createMcpEnvironment as kt, boxSurfaceReader as l, flatWidenGate as lt, worktreeFanout as m, verify as mt, makeFinding$1 as n, renderPairwiseMarkdown as nn, trajectoryReport as nt, runInWorkspace as o, InMemoryCorpus as ot, failuresAnalyst as p, selectValidWinner as pt, runStrategyEvolution as q, completionAuthorizes as qt, gitWorkspace as r, SqlRunOwnershipError as rn, definePersona as rt, createWaterfallCollector as s, renderCorpusToInstructions as st, computeFindingId$1 as t, renderLeaderboardSvg as tn, equalKOnCost as tt, fsSurfaceReader as u, loopUntil as ut, VERIFY_TAIL_CHARS as v, createScopeAnalyst as vt, analyzeTrace as w, defineLeaderboard as wt, settledWorkerOut as x, inProcessSandboxClient as xt, closingWorkerNote as y, registryScopeAnalyst as yt, recordProfileRun as z, superviseDispatch as zt };
|
|
9410
10028
|
|
|
9411
|
-
//# sourceMappingURL=runtime-
|
|
10029
|
+
//# sourceMappingURL=runtime-6Ec9sHRe.js.map
|