@tangle-network/agent-runtime 0.293.4 → 0.295.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{activation-1BxDcwZs.d.ts → activation-DYCFEI_o.d.ts} +2 -2
- package/dist/{activation-BKz1t1Qb.js → activation-DbcZXadv.js} +3 -3
- package/dist/{activation-BKz1t1Qb.js.map → activation-DbcZXadv.js.map} +1 -1
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +2 -2
- package/dist/{bundle-BfW-32vB.js → bundle-CDR0caM4.js} +2 -2
- package/dist/{bundle-BfW-32vB.js.map → bundle-CDR0caM4.js.map} +1 -1
- package/dist/candidate-execution/index.d.ts +27 -3
- package/dist/candidate-execution/index.js +6 -6
- package/dist/{coordination-driver-BpEJv7GR.js → coordination-driver-Do3g6Qif.js} +2 -2
- package/dist/{coordination-driver-BpEJv7GR.js.map → coordination-driver-Do3g6Qif.js.map} +1 -1
- package/dist/{delegate-DEP51NR7.js → delegate-CCaU8M4O.js} +2 -2
- package/dist/{delegate-DEP51NR7.js.map → delegate-CCaU8M4O.js.map} +1 -1
- package/dist/durable.d.ts +1 -1
- package/dist/durable.js +3 -3
- package/dist/{graph-oFWfYVpn.js → graph-dNmpMnzl.js} +4 -4
- package/dist/{graph-oFWfYVpn.js.map → graph-dNmpMnzl.js.map} +1 -1
- package/dist/{improvement-cycle-CBAuTq3p.js → improvement-cycle-D4hoGlAe.js} +6 -6
- package/dist/{improvement-cycle-CBAuTq3p.js.map → improvement-cycle-D4hoGlAe.js.map} +1 -1
- package/dist/{index-DZqkIP6a.d.ts → index-nREMiWJP.d.ts} +108 -6
- package/dist/index.d.ts +5 -5
- package/dist/index.js +9 -9
- package/dist/intelligence.d.ts +4 -4
- package/dist/intelligence.js +8 -8
- package/dist/kernel.d.ts +3 -3
- package/dist/kernel.js +9 -9
- package/dist/{loop-runner-bin-D5lBiaf5.js → loop-runner-bin-DIf0bbQM.js} +3 -3
- package/dist/{loop-runner-bin-D5lBiaf5.js.map → loop-runner-bin-DIf0bbQM.js.map} +1 -1
- package/dist/{loop-runner-bin-BUldbpz8.d.ts → loop-runner-bin-cf1xZPC2.d.ts} +2 -2
- package/dist/loop-runner-bin.d.ts +1 -1
- package/dist/loop-runner-bin.js +1 -1
- package/dist/mcp/bin.js +3 -3
- package/dist/mcp/index.d.ts +2 -2
- package/dist/mcp/index.js +4 -4
- package/dist/{prepare-CxnyZ1fG.js → prepare-Dzkj4AGj.js} +3 -3
- package/dist/prepare-Dzkj4AGj.js.map +1 -0
- package/dist/{profile-C4NDjZyB.js → profile-BubsrYhR.js} +2 -2
- package/dist/{profile-C4NDjZyB.js.map → profile-BubsrYhR.js.map} +1 -1
- package/dist/{protected-model-port-DDnU39ul.d.ts → protected-model-port-CAa0t1MT.d.ts} +2 -2
- package/dist/{protected-model-port-BSsgmdhI.js → protected-model-port-_Daje74V.js} +4 -4
- package/dist/{protected-model-port-BSsgmdhI.js.map → protected-model-port-_Daje74V.js.map} +1 -1
- package/dist/{provision-supervisor-CIwZLCGR.js → provision-supervisor-B_3hmSz6.js} +3 -3
- package/dist/{provision-supervisor-CIwZLCGR.js.map → provision-supervisor-B_3hmSz6.js.map} +1 -1
- package/dist/{runtime-10G-vbmJ.js → runtime-CXKCdGTg.js} +575 -34
- package/dist/runtime-CXKCdGTg.js.map +1 -0
- package/dist/{search-method-3EtnGKdL.js → search-method-B0VM-hHV.js} +3 -3
- package/dist/{search-method-3EtnGKdL.js.map → search-method-B0VM-hHV.js.map} +1 -1
- package/dist/{server-DgEDz4Rn.js → server--GKA8T0f.js} +3 -3
- package/dist/{server-DgEDz4Rn.js.map → server--GKA8T0f.js.map} +1 -1
- package/dist/{stream-agent-turn-DsHYpI9p.d.ts → stream-agent-turn-CwqktoXW.d.ts} +2 -2
- package/dist/{supervise-Cu0yOTkc.js → supervise-BwfqpTVR.js} +3 -3
- package/dist/{supervise-Cu0yOTkc.js.map → supervise-BwfqpTVR.js.map} +1 -1
- package/dist/{supervisor-B-UbeBqD.js → supervisor-Da7iAPSw.js} +15 -6
- package/dist/supervisor-Da7iAPSw.js.map +1 -0
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +14 -14
- package/dist/tui/index.d.ts +1 -1
- package/dist/tui/index.js +1 -1
- package/dist/{workspace-archive-DpyZV2Cj.d.ts → workspace-archive-pz8YJ1fr.d.ts} +12 -1
- package/dist/{workspace-archive-MhowMCmp.js → workspace-streams-D4TMTrJV.js} +301 -15
- package/dist/workspace-streams-D4TMTrJV.js.map +1 -0
- package/package.json +1 -1
- package/dist/prepare-CxnyZ1fG.js.map +0 -1
- package/dist/runtime-10G-vbmJ.js.map +0 -1
- package/dist/supervisor-B-UbeBqD.js.map +0 -1
- package/dist/workspace-archive-MhowMCmp.js.map +0 -1
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
import { Ai as writeAllBytes, Da as zeroSpend, Dn as runBrainLoop, Dt as rollingDispatch, En as routerBrain, Fa as armDeadlineTimer, Fn as createPushTraceSource, Ft as createWorktreeCliExecutor, G as settledToIteration, Gn as assertContentAddress, Hn as InMemoryResultBlobStore, Kn as encodeResultBlob, M as withDriverExecutor, Mt as createExecutor, Nt as createExecutorRegistry, O as verdictFromJudgeScore, Oi as prepareJsonlAppend, Or as contentAddress, Qi as detachedSnapshot, Sa as stringifySafe, Tn as readPromptOptions, Un as InMemorySpawnJournal, Wn as SpawnEventIndex, Xi as executableAgentSpecSnapshot, Yi as executableAgentProfileSnapshot, Zi as detachedFrozen, _ as CheckUnavailableError, _a as hasCompleteCacheBreakdown, ba as randomSuffix, bn as probeSandboxCapabilities, er as isTraceAnalysisStore, gn as defaultSelectWinner, ha as cloneSpend, ki as readCommittedJsonLines, la as notifySandboxEventObserver, ma as chargedTokens, pa as addSpend, qn as insideCursorNamespace, r as createSupervisor, va as isAbortError, vn as runAgentRounds, wn as assertBoxlessPromptOptions, xa as sleep, yn as createSandboxLineage } from "./supervisor-
|
|
1
|
+
import { Ai as writeAllBytes, Da as zeroSpend, Dn as runBrainLoop, Dt as rollingDispatch, En as routerBrain, Fa as armDeadlineTimer, Fn as createPushTraceSource, Ft as createWorktreeCliExecutor, G as settledToIteration, Gn as assertContentAddress, Hn as InMemoryResultBlobStore, Kn as encodeResultBlob, M as withDriverExecutor, Mt as createExecutor, Nt as createExecutorRegistry, O as verdictFromJudgeScore, Oi as prepareJsonlAppend, Or as contentAddress, Qi as detachedSnapshot, Sa as stringifySafe, Tn as readPromptOptions, Un as InMemorySpawnJournal, Wn as SpawnEventIndex, Xi as executableAgentSpecSnapshot, Yi as executableAgentProfileSnapshot, Zi as detachedFrozen, _ as CheckUnavailableError, _a as hasCompleteCacheBreakdown, ba as randomSuffix, bn as probeSandboxCapabilities, er as isTraceAnalysisStore, gn as defaultSelectWinner, ha as cloneSpend, ki as readCommittedJsonLines, la as notifySandboxEventObserver, ma as chargedTokens, pa as addSpend, qn as insideCursorNamespace, r as createSupervisor, va as isAbortError, vn as runAgentRounds, wn as assertBoxlessPromptOptions, xa as sleep, yn as createSandboxLineage } from "./supervisor-Da7iAPSw.js";
|
|
2
2
|
import { i as ConfigError, m as ValidationError, n as AnalystError, s as PlannerError } from "./errors-DodWX-cb.js";
|
|
3
|
-
import { Q as sample, X as refine, Z as runAgentic, c as reconcileInterruptedSearchCalls, ct as strategyAuthorMethod, et as ObservationError, it as profileChatClient, nt as observe, o as dedicatedLane, r as runtimeShipDecision, rt as renderReport, u as searchExecutor } from "./search-method-
|
|
3
|
+
import { Q as sample, X as refine, Z as runAgentic, c as reconcileInterruptedSearchCalls, ct as strategyAuthorMethod, et as ObservationError, it as profileChatClient, nt as observe, o as dedicatedLane, r as runtimeShipDecision, rt as renderReport, u as searchExecutor } from "./search-method-B0VM-hHV.js";
|
|
4
4
|
import { c as profileModelExecutionSettings, i as concreteModelId, l as profileProviderModel, o as enforceTokenLimits, p as canonicalObservedModelParts, t as assertExecutableAgentProfile } from "./model-policy-DydyWTQg.js";
|
|
5
|
-
import {
|
|
5
|
+
import { D as canonicalCandidateDigest$1, N as sha256Bytes$1, h as WorkspaceScanLimitError, j as immutableCandidateValue, v as captureMaterializedWorkspace } from "./workspace-streams-D4TMTrJV.js";
|
|
6
6
|
import { i as notifyRuntimeHookEvent } from "./runtime-hooks-tXpAarhW.js";
|
|
7
7
|
import { i as redactProtectedValue, r as redactProtectedReason } from "./protected-redaction-DylCC_ot.js";
|
|
8
|
-
import { S as foldCoordinationRecords, y as createInMemoryRunContext } from "./coordination-driver-
|
|
9
|
-
import { C as gateOnDeliverable, r as supervise, w as mapExecutorResult } from "./supervise-
|
|
8
|
+
import { S as foldCoordinationRecords, y as createInMemoryRunContext } from "./coordination-driver-Do3g6Qif.js";
|
|
9
|
+
import { C as gateOnDeliverable, r as supervise, w as mapExecutorResult } from "./supervise-BwfqpTVR.js";
|
|
10
10
|
import "./run-layout-DSCWdbX2.js";
|
|
11
|
-
import "./provision-supervisor-
|
|
12
|
-
import "./delegate-
|
|
13
|
-
import "./graph-
|
|
11
|
+
import "./provision-supervisor-B_3hmSz6.js";
|
|
12
|
+
import "./delegate-CCaU8M4O.js";
|
|
13
|
+
import "./graph-dNmpMnzl.js";
|
|
14
14
|
import { agentProfileSchema, canonicalAgentProfileDigest, canonicalCandidateDigest, sha256Bytes, validateAgentProfileSecurity } from "@tangle-network/agent-interface";
|
|
15
15
|
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";
|
|
16
16
|
import { createAgentRunOutcomeTracker } from "@tangle-network/sandbox/runtime";
|
|
17
|
-
import { createHash, randomUUID } from "node:crypto";
|
|
17
|
+
import { createHash, createHmac, randomUUID } from "node:crypto";
|
|
18
18
|
import { execFile, execFileSync, spawn, spawnSync } from "node:child_process";
|
|
19
19
|
import { appendFileSync, chmodSync, constants, copyFileSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readlinkSync, renameSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
20
20
|
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
21
|
-
import { chmod, link, lstat, mkdir, mkdtemp, open, opendir, readFile, readdir, readlink, realpath, rm, stat, symlink, unlink, writeFile } from "node:fs/promises";
|
|
21
|
+
import { chmod, link, lstat, mkdir, mkdtemp, open, opendir, readFile, readdir, readlink, realpath, rename, rm, stat, symlink, unlink, writeFile } from "node:fs/promises";
|
|
22
22
|
import { tmpdir } from "node:os";
|
|
23
23
|
import { isDeepStrictEqual, promisify } from "node:util";
|
|
24
24
|
import { redact } from "@tangle-network/agent-eval/traces";
|
|
25
|
+
import { Readable } from "node:stream";
|
|
25
26
|
import { collectAgentResponseText } from "@tangle-network/sandbox";
|
|
26
27
|
import { SearchRecorder, asha, beam, createRunCostLedger, estimateNode, fsCampaignStorage, openSearchLedger, renderSearchSummary, runProfileMatrix, runSearch, searchClaimReserveUsd, searchModelIdentity, surfaceDiff } from "@tangle-network/agent-eval/campaign";
|
|
27
28
|
import { defineEvaluationClaim, summarizeEvaluationUnits } from "@tangle-network/agent-eval/experiment";
|
|
@@ -4960,8 +4961,12 @@ function requireSpend(rolled, id, root) {
|
|
|
4960
4961
|
}
|
|
4961
4962
|
//#endregion
|
|
4962
4963
|
//#region src/runtime/private-cas.ts
|
|
4963
|
-
const DIGEST = /^sha256:([0-9a-f]{64})$/u;
|
|
4964
|
+
const DIGEST$1 = /^sha256:([0-9a-f]{64})$/u;
|
|
4965
|
+
const HEX = /^[0-9a-f]{64}$/u;
|
|
4966
|
+
const SHARD = /^[0-9a-f]{2}$/u;
|
|
4964
4967
|
const SAFE_NAMESPACE = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/u;
|
|
4968
|
+
const RECEIPT_SCHEMA = "agent-runtime.private-cas-durable-receipt.v1";
|
|
4969
|
+
const DURABLE_ATTEMPTS = 3;
|
|
4965
4970
|
async function realDirectory(path) {
|
|
4966
4971
|
const entry = await lstat(path);
|
|
4967
4972
|
if (!entry.isDirectory() || entry.isSymbolicLink()) throw new Error(`private CAS directory is not a real directory: ${path}`);
|
|
@@ -4980,21 +4985,364 @@ async function checkDirectories(path, create) {
|
|
|
4980
4985
|
await realDirectory(current);
|
|
4981
4986
|
}
|
|
4982
4987
|
}
|
|
4983
|
-
|
|
4984
|
-
|
|
4988
|
+
const missing = (error) => error?.code === "ENOENT";
|
|
4989
|
+
const message = (error) => error instanceof Error ? error.message : String(error);
|
|
4990
|
+
const sha256 = (bytes) => `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
|
|
4991
|
+
async function syncDirectory(directory) {
|
|
4992
|
+
const handle = await open(directory, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
|
|
4993
|
+
try {
|
|
4994
|
+
await handle.sync();
|
|
4995
|
+
} finally {
|
|
4996
|
+
await handle.close();
|
|
4997
|
+
}
|
|
4998
|
+
}
|
|
4999
|
+
/** Read one local object, or undefined when the host no longer holds it. */
|
|
5000
|
+
async function readLocal(path) {
|
|
5001
|
+
let file;
|
|
5002
|
+
try {
|
|
5003
|
+
file = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
5004
|
+
} catch (error) {
|
|
5005
|
+
if (missing(error)) return void 0;
|
|
5006
|
+
throw error;
|
|
5007
|
+
}
|
|
5008
|
+
try {
|
|
5009
|
+
return await file.readFile();
|
|
5010
|
+
} finally {
|
|
5011
|
+
await file.close();
|
|
5012
|
+
}
|
|
5013
|
+
}
|
|
5014
|
+
/**
|
|
5015
|
+
* Private content-addressed storage scoped to one recorded run identity.
|
|
5016
|
+
*
|
|
5017
|
+
* Bytes are written to the host first. With a durable store, every object is also copied off the
|
|
5018
|
+
* host as it is written, and `localBudgetBytes` bounds what the host keeps: an object's local copy
|
|
5019
|
+
* is deleted only after its durable receipt exists, and reads fall back to the durable store.
|
|
5020
|
+
*/
|
|
5021
|
+
function createPrivateCasArtifactPort(root, namespace, options = {}) {
|
|
4985
5022
|
if (!isAbsolute(root)) throw new Error("private CAS root must be absolute");
|
|
4986
5023
|
if (!SAFE_NAMESPACE.test(namespace) || namespace === "." || namespace === "..") throw new Error("private CAS namespace must be one safe identifier");
|
|
5024
|
+
const { durable, localBudgetBytes } = options;
|
|
5025
|
+
if (localBudgetBytes !== void 0 && (durable === void 0 || !Number.isSafeInteger(localBudgetBytes) || localBudgetBytes < 0)) throw new Error("private CAS localBudgetBytes needs a durable store and a non-negative integer");
|
|
4987
5026
|
const store = join(resolve(root), "sha256");
|
|
4988
|
-
const
|
|
4989
|
-
|
|
5027
|
+
const receipts = join(resolve(root), "durable", "sha256");
|
|
5028
|
+
const hexOf = (digest) => {
|
|
5029
|
+
const match = DIGEST$1.exec(digest);
|
|
4990
5030
|
if (!match) throw new Error("private CAS digest must be sha256:<64 lowercase hex>");
|
|
4991
|
-
return
|
|
5031
|
+
return match[1];
|
|
5032
|
+
};
|
|
5033
|
+
const destination = (digest) => {
|
|
5034
|
+
const hex = hexOf(digest);
|
|
5035
|
+
return join(store, hex.slice(0, 2), hex);
|
|
5036
|
+
};
|
|
5037
|
+
const hasReceipt = async (hex) => {
|
|
5038
|
+
try {
|
|
5039
|
+
return (await lstat(join(receipts, hex))).isFile();
|
|
5040
|
+
} catch (error) {
|
|
5041
|
+
if (missing(error)) return false;
|
|
5042
|
+
throw error;
|
|
5043
|
+
}
|
|
5044
|
+
};
|
|
5045
|
+
const writeReceipt = async (digest, byteLength) => {
|
|
5046
|
+
await checkDirectories(receipts, true);
|
|
5047
|
+
const hex = hexOf(digest);
|
|
5048
|
+
const temporary = join(receipts, `.${hex}.${randomUUID()}.tmp`);
|
|
5049
|
+
const file = await open(temporary, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 384);
|
|
5050
|
+
try {
|
|
5051
|
+
await file.writeFile(`${JSON.stringify({
|
|
5052
|
+
schema: RECEIPT_SCHEMA,
|
|
5053
|
+
location: durable.location,
|
|
5054
|
+
namespace,
|
|
5055
|
+
digest,
|
|
5056
|
+
byteLength,
|
|
5057
|
+
storedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5058
|
+
})}\n`);
|
|
5059
|
+
await file.sync();
|
|
5060
|
+
} finally {
|
|
5061
|
+
await file.close();
|
|
5062
|
+
}
|
|
5063
|
+
await rename(temporary, join(receipts, hex));
|
|
5064
|
+
await syncDirectory(receipts);
|
|
5065
|
+
};
|
|
5066
|
+
const storeDurably = async (digest, bytes, signal) => {
|
|
5067
|
+
let failure;
|
|
5068
|
+
for (let attempt = 1; attempt <= DURABLE_ATTEMPTS; attempt++) {
|
|
5069
|
+
signal?.throwIfAborted();
|
|
5070
|
+
try {
|
|
5071
|
+
await durable.put({
|
|
5072
|
+
namespace,
|
|
5073
|
+
digest,
|
|
5074
|
+
bytes,
|
|
5075
|
+
...signal === void 0 ? {} : { signal }
|
|
5076
|
+
});
|
|
5077
|
+
await writeReceipt(digest, bytes.byteLength);
|
|
5078
|
+
return;
|
|
5079
|
+
} catch (error) {
|
|
5080
|
+
failure = error;
|
|
5081
|
+
if (signal?.aborted) throw error;
|
|
5082
|
+
if (attempt < DURABLE_ATTEMPTS) await new Promise((settle) => setTimeout(settle, 1e3 * 4 ** (attempt - 1)));
|
|
5083
|
+
}
|
|
5084
|
+
}
|
|
5085
|
+
throw failure;
|
|
4992
5086
|
};
|
|
5087
|
+
const localObjects = async () => {
|
|
5088
|
+
let shards;
|
|
5089
|
+
try {
|
|
5090
|
+
shards = await readdir(store);
|
|
5091
|
+
} catch (error) {
|
|
5092
|
+
if (missing(error)) return [];
|
|
5093
|
+
throw error;
|
|
5094
|
+
}
|
|
5095
|
+
const objects = [];
|
|
5096
|
+
for (const shard of shards.filter((name) => SHARD.test(name))) for (const hex of await readdir(join(store, shard))) {
|
|
5097
|
+
if (!HEX.test(hex) || hex.slice(0, 2) !== shard) continue;
|
|
5098
|
+
const path = join(store, shard, hex);
|
|
5099
|
+
try {
|
|
5100
|
+
const entry = await lstat(path);
|
|
5101
|
+
if (entry.isFile()) objects.push({
|
|
5102
|
+
hex,
|
|
5103
|
+
path,
|
|
5104
|
+
size: entry.size,
|
|
5105
|
+
modifiedMs: entry.mtimeMs
|
|
5106
|
+
});
|
|
5107
|
+
} catch (error) {
|
|
5108
|
+
if (!missing(error)) throw error;
|
|
5109
|
+
}
|
|
5110
|
+
}
|
|
5111
|
+
return objects;
|
|
5112
|
+
};
|
|
5113
|
+
const sweep = async (signal) => {
|
|
5114
|
+
const objects = await localObjects();
|
|
5115
|
+
const pending = [];
|
|
5116
|
+
let uploaded = 0;
|
|
5117
|
+
let refusal;
|
|
5118
|
+
const durableHex = /* @__PURE__ */ new Set();
|
|
5119
|
+
for (const object of objects) {
|
|
5120
|
+
if (await hasReceipt(object.hex)) {
|
|
5121
|
+
durableHex.add(object.hex);
|
|
5122
|
+
continue;
|
|
5123
|
+
}
|
|
5124
|
+
if (durable === void 0) continue;
|
|
5125
|
+
const digest = `sha256:${object.hex}`;
|
|
5126
|
+
if (refusal !== void 0) {
|
|
5127
|
+
pending.push({
|
|
5128
|
+
digest,
|
|
5129
|
+
error: `not attempted after an earlier refusal: ${refusal}`
|
|
5130
|
+
});
|
|
5131
|
+
continue;
|
|
5132
|
+
}
|
|
5133
|
+
try {
|
|
5134
|
+
if (durable.putStream && durable.getStream) {
|
|
5135
|
+
const ref = {
|
|
5136
|
+
locator: {
|
|
5137
|
+
kind: "private-cas",
|
|
5138
|
+
namespace,
|
|
5139
|
+
digest
|
|
5140
|
+
},
|
|
5141
|
+
sha256: digest,
|
|
5142
|
+
byteLength: object.size
|
|
5143
|
+
};
|
|
5144
|
+
let failure;
|
|
5145
|
+
for (let attempt = 1; attempt <= DURABLE_ATTEMPTS; attempt++) {
|
|
5146
|
+
signal?.throwIfAborted();
|
|
5147
|
+
const chunks = readObject(object.path, ref, signal);
|
|
5148
|
+
try {
|
|
5149
|
+
await durable.putStream({
|
|
5150
|
+
namespace,
|
|
5151
|
+
digest,
|
|
5152
|
+
byteLength: object.size,
|
|
5153
|
+
chunks,
|
|
5154
|
+
signal
|
|
5155
|
+
});
|
|
5156
|
+
await writeReceipt(digest, object.size);
|
|
5157
|
+
failure = void 0;
|
|
5158
|
+
break;
|
|
5159
|
+
} catch (error) {
|
|
5160
|
+
failure = error;
|
|
5161
|
+
if (signal?.aborted) throw error;
|
|
5162
|
+
if (attempt < DURABLE_ATTEMPTS) await new Promise((settle) => setTimeout(settle, 1e3 * 4 ** (attempt - 1)));
|
|
5163
|
+
} finally {
|
|
5164
|
+
await chunks.return(void 0);
|
|
5165
|
+
}
|
|
5166
|
+
}
|
|
5167
|
+
if (failure !== void 0) throw failure;
|
|
5168
|
+
} else {
|
|
5169
|
+
const bytes = await readLocal(object.path);
|
|
5170
|
+
if (bytes === void 0) continue;
|
|
5171
|
+
if (sha256(bytes) !== digest) {
|
|
5172
|
+
pending.push({
|
|
5173
|
+
digest,
|
|
5174
|
+
error: "local object failed digest verification; it stays on the host"
|
|
5175
|
+
});
|
|
5176
|
+
continue;
|
|
5177
|
+
}
|
|
5178
|
+
await storeDurably(digest, bytes, signal);
|
|
5179
|
+
}
|
|
5180
|
+
durableHex.add(object.hex);
|
|
5181
|
+
uploaded++;
|
|
5182
|
+
} catch (error) {
|
|
5183
|
+
if (signal?.aborted) throw error;
|
|
5184
|
+
refusal = message(error);
|
|
5185
|
+
pending.push({
|
|
5186
|
+
digest,
|
|
5187
|
+
error: refusal
|
|
5188
|
+
});
|
|
5189
|
+
}
|
|
5190
|
+
}
|
|
5191
|
+
let localBytes = objects.reduce((total, object) => total + object.size, 0);
|
|
5192
|
+
let evicted = 0;
|
|
5193
|
+
if (localBudgetBytes !== void 0) for (const object of [...objects].sort((a, b) => a.modifiedMs - b.modifiedMs)) {
|
|
5194
|
+
if (localBytes <= localBudgetBytes) break;
|
|
5195
|
+
if (!durableHex.has(object.hex) || !await hasReceipt(object.hex)) continue;
|
|
5196
|
+
try {
|
|
5197
|
+
await unlink(object.path);
|
|
5198
|
+
} catch (error) {
|
|
5199
|
+
if (!missing(error)) throw error;
|
|
5200
|
+
}
|
|
5201
|
+
localBytes -= object.size;
|
|
5202
|
+
evicted++;
|
|
5203
|
+
}
|
|
5204
|
+
let receiptCount = 0;
|
|
5205
|
+
try {
|
|
5206
|
+
receiptCount = (await readdir(receipts)).filter((name) => HEX.test(name)).length;
|
|
5207
|
+
} catch (error) {
|
|
5208
|
+
if (!missing(error)) throw error;
|
|
5209
|
+
}
|
|
5210
|
+
return {
|
|
5211
|
+
durable: receiptCount,
|
|
5212
|
+
uploaded,
|
|
5213
|
+
pending,
|
|
5214
|
+
evicted,
|
|
5215
|
+
localObjects: objects.length - evicted,
|
|
5216
|
+
localBytes
|
|
5217
|
+
};
|
|
5218
|
+
};
|
|
5219
|
+
let passes = Promise.resolve();
|
|
5220
|
+
const offload = (signal) => {
|
|
5221
|
+
const pass = passes.then(() => sweep(signal));
|
|
5222
|
+
passes = pass.catch(() => void 0);
|
|
5223
|
+
return pass;
|
|
5224
|
+
};
|
|
5225
|
+
const verified = (bytes, ref) => {
|
|
5226
|
+
if (sha256(bytes) !== ref.sha256 || bytes.byteLength !== ref.byteLength) throw new Error("private CAS object failed digest or length verification");
|
|
5227
|
+
return bytes;
|
|
5228
|
+
};
|
|
5229
|
+
async function* readStream(ref, options = {}) {
|
|
5230
|
+
const { signal } = options;
|
|
5231
|
+
signal?.throwIfAborted();
|
|
5232
|
+
if (ref.locator.kind !== "private-cas" || ref.locator.namespace !== namespace || ref.locator.digest !== ref.sha256) throw new Error("private CAS locator does not match its digest and namespace");
|
|
5233
|
+
const path = destination(ref.sha256);
|
|
5234
|
+
try {
|
|
5235
|
+
await checkDirectories(join(store, hexOf(ref.sha256).slice(0, 2)), false);
|
|
5236
|
+
yield* readObject(path, ref, signal);
|
|
5237
|
+
return;
|
|
5238
|
+
} catch (error) {
|
|
5239
|
+
if (!missing(error)) throw error;
|
|
5240
|
+
}
|
|
5241
|
+
if (!durable?.getStream) throw new Error(`private CAS object is not on this host; streaming durable reads are unavailable: ${ref.sha256}`);
|
|
5242
|
+
const chunks = await durable.getStream({
|
|
5243
|
+
namespace,
|
|
5244
|
+
digest: ref.sha256,
|
|
5245
|
+
signal
|
|
5246
|
+
});
|
|
5247
|
+
if (!chunks) throw new Error(`private CAS object is neither on this host nor in ${durable.location}: ${ref.sha256}`);
|
|
5248
|
+
yield* checkedChunks(chunks, ref, signal);
|
|
5249
|
+
}
|
|
5250
|
+
async function* readObject(path, ref, signal) {
|
|
5251
|
+
signal?.throwIfAborted();
|
|
5252
|
+
const file = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
5253
|
+
try {
|
|
5254
|
+
const stats = await file.stat();
|
|
5255
|
+
if (!stats.isFile() || stats.size !== ref.byteLength) throw new Error("private CAS object failed digest or length verification");
|
|
5256
|
+
yield* checkedChunks(file.createReadStream({
|
|
5257
|
+
autoClose: false,
|
|
5258
|
+
highWaterMark: 64 * 1024
|
|
5259
|
+
}), ref, signal);
|
|
5260
|
+
} finally {
|
|
5261
|
+
await file.close();
|
|
5262
|
+
}
|
|
5263
|
+
}
|
|
5264
|
+
async function* checkedChunks(chunks, ref, signal) {
|
|
5265
|
+
const hash = createHash("sha256");
|
|
5266
|
+
let byteLength = 0;
|
|
5267
|
+
for await (const chunk of chunks) {
|
|
5268
|
+
signal?.throwIfAborted();
|
|
5269
|
+
if (!(chunk instanceof Uint8Array)) throw new Error("private CAS emitted a non-byte chunk");
|
|
5270
|
+
byteLength += chunk.byteLength;
|
|
5271
|
+
if (byteLength > ref.byteLength) throw new Error("private CAS object failed digest or length verification");
|
|
5272
|
+
hash.update(chunk);
|
|
5273
|
+
yield chunk;
|
|
5274
|
+
}
|
|
5275
|
+
signal?.throwIfAborted();
|
|
5276
|
+
if (`sha256:${hash.digest("hex")}` !== ref.sha256 || byteLength !== ref.byteLength) throw new Error("private CAS object failed digest or length verification");
|
|
5277
|
+
}
|
|
5278
|
+
async function putStream(input) {
|
|
5279
|
+
const { signal } = input;
|
|
5280
|
+
signal?.throwIfAborted();
|
|
5281
|
+
await checkDirectories(store, true);
|
|
5282
|
+
const temporary = join(store, `.${randomUUID()}.tmp`);
|
|
5283
|
+
try {
|
|
5284
|
+
const file = await open(temporary, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 384);
|
|
5285
|
+
const hash = createHash("sha256");
|
|
5286
|
+
let byteLength = 0;
|
|
5287
|
+
try {
|
|
5288
|
+
for await (const chunk of input.chunks) {
|
|
5289
|
+
signal?.throwIfAborted();
|
|
5290
|
+
if (!(chunk instanceof Uint8Array)) throw new Error("private CAS received a non-byte chunk");
|
|
5291
|
+
hash.update(chunk);
|
|
5292
|
+
byteLength += chunk.byteLength;
|
|
5293
|
+
if (!Number.isSafeInteger(byteLength)) throw new Error("private CAS object is too large");
|
|
5294
|
+
await file.writeFile(chunk);
|
|
5295
|
+
}
|
|
5296
|
+
signal?.throwIfAborted();
|
|
5297
|
+
await file.sync();
|
|
5298
|
+
} finally {
|
|
5299
|
+
await file.close();
|
|
5300
|
+
}
|
|
5301
|
+
const sha = hash.digest("hex");
|
|
5302
|
+
const digest = `sha256:${sha}`;
|
|
5303
|
+
const ref = {
|
|
5304
|
+
locator: {
|
|
5305
|
+
kind: "private-cas",
|
|
5306
|
+
namespace,
|
|
5307
|
+
digest
|
|
5308
|
+
},
|
|
5309
|
+
sha256: digest,
|
|
5310
|
+
byteLength
|
|
5311
|
+
};
|
|
5312
|
+
for await (const _chunk of readObject(temporary, ref, signal));
|
|
5313
|
+
const path = destination(digest);
|
|
5314
|
+
const directory = join(store, sha.slice(0, 2));
|
|
5315
|
+
await checkDirectories(directory, true);
|
|
5316
|
+
signal?.throwIfAborted();
|
|
5317
|
+
try {
|
|
5318
|
+
await link(temporary, path);
|
|
5319
|
+
} catch (error) {
|
|
5320
|
+
if (error.code !== "EEXIST") throw error;
|
|
5321
|
+
for await (const _chunk of readStream(ref, { signal }));
|
|
5322
|
+
}
|
|
5323
|
+
const dir = await open(directory, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
|
|
5324
|
+
try {
|
|
5325
|
+
await dir.sync();
|
|
5326
|
+
} finally {
|
|
5327
|
+
await dir.close();
|
|
5328
|
+
}
|
|
5329
|
+
if (durable !== void 0) await offload(signal);
|
|
5330
|
+
return ref;
|
|
5331
|
+
} finally {
|
|
5332
|
+
await unlink(temporary).catch((error) => {
|
|
5333
|
+
if (error.code !== "ENOENT") throw error;
|
|
5334
|
+
});
|
|
5335
|
+
}
|
|
5336
|
+
}
|
|
4993
5337
|
const port = {
|
|
5338
|
+
...durable === void 0 || durable.putStream && durable.getStream ? {
|
|
5339
|
+
putStream,
|
|
5340
|
+
readStream
|
|
5341
|
+
} : {},
|
|
4994
5342
|
async put({ bytes, signal }) {
|
|
4995
5343
|
signal?.throwIfAborted();
|
|
4996
|
-
const
|
|
4997
|
-
const
|
|
5344
|
+
const digest = sha256(bytes);
|
|
5345
|
+
const sha = hexOf(digest);
|
|
4998
5346
|
const path = destination(digest);
|
|
4999
5347
|
const directory = join(store, sha.slice(0, 2));
|
|
5000
5348
|
await checkDirectories(directory, true);
|
|
@@ -5013,12 +5361,7 @@ function createPrivateCasArtifactPort(root, namespace) {
|
|
|
5013
5361
|
} catch (error) {
|
|
5014
5362
|
if (error.code !== "EEXIST") throw error;
|
|
5015
5363
|
}
|
|
5016
|
-
|
|
5017
|
-
try {
|
|
5018
|
-
await dir.sync();
|
|
5019
|
-
} finally {
|
|
5020
|
-
await dir.close();
|
|
5021
|
-
}
|
|
5364
|
+
await syncDirectory(directory);
|
|
5022
5365
|
} finally {
|
|
5023
5366
|
await unlink(temporary).catch(() => void 0);
|
|
5024
5367
|
}
|
|
@@ -5032,21 +5375,33 @@ function createPrivateCasArtifactPort(root, namespace) {
|
|
|
5032
5375
|
byteLength: bytes.byteLength
|
|
5033
5376
|
};
|
|
5034
5377
|
await port.read(ref);
|
|
5378
|
+
if (durable !== void 0) {
|
|
5379
|
+
if (!await hasReceipt(sha)) await storeDurably(digest, bytes, signal).catch(() => void 0);
|
|
5380
|
+
await offload(signal);
|
|
5381
|
+
}
|
|
5035
5382
|
return ref;
|
|
5036
5383
|
},
|
|
5037
5384
|
async read(ref) {
|
|
5038
5385
|
if (ref.locator.kind !== "private-cas" || ref.locator.namespace !== namespace || ref.locator.digest !== ref.sha256) throw new Error("private CAS locator does not match its digest and namespace");
|
|
5039
5386
|
const path = destination(ref.sha256);
|
|
5040
|
-
|
|
5041
|
-
|
|
5387
|
+
const shard = join(store, hexOf(ref.sha256).slice(0, 2));
|
|
5388
|
+
let local;
|
|
5042
5389
|
try {
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
await file.close();
|
|
5390
|
+
await checkDirectories(shard, false);
|
|
5391
|
+
local = await readLocal(path);
|
|
5392
|
+
} catch (error) {
|
|
5393
|
+
if (!missing(error)) throw error;
|
|
5048
5394
|
}
|
|
5049
|
-
|
|
5395
|
+
if (local !== void 0) return verified(local, ref);
|
|
5396
|
+
if (durable === void 0) throw new Error(`private CAS object is not on this host: ${ref.sha256}`);
|
|
5397
|
+
const stored = await durable.get({
|
|
5398
|
+
namespace,
|
|
5399
|
+
digest: ref.sha256
|
|
5400
|
+
});
|
|
5401
|
+
if (stored === void 0) throw new Error(`private CAS object is neither on this host nor in ${durable.location}: ${ref.sha256}`);
|
|
5402
|
+
return verified(stored, ref);
|
|
5403
|
+
},
|
|
5404
|
+
offload
|
|
5050
5405
|
};
|
|
5051
5406
|
return port;
|
|
5052
5407
|
}
|
|
@@ -5265,6 +5620,192 @@ function printBenchmarkReport(report) {
|
|
|
5265
5620
|
}
|
|
5266
5621
|
}
|
|
5267
5622
|
//#endregion
|
|
5623
|
+
//#region src/runtime/s3-private-cas-store.ts
|
|
5624
|
+
const DIGEST = /^sha256:([0-9a-f]{64})$/u;
|
|
5625
|
+
const BUCKET = /^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/u;
|
|
5626
|
+
const PREFIX = /^(?:[A-Za-z0-9._-]+\/)*$/u;
|
|
5627
|
+
const NAMESPACE = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/u;
|
|
5628
|
+
const EMPTY_PAYLOAD = createHash("sha256").update("").digest("hex");
|
|
5629
|
+
const CONTENT_TYPE = "application/octet-stream";
|
|
5630
|
+
const METADATA_DIGEST = "x-amz-meta-sha256";
|
|
5631
|
+
const hex = (value) => createHash("sha256").update(value).digest("hex");
|
|
5632
|
+
const hmac = (key, value) => createHmac("sha256", key).update(value).digest();
|
|
5633
|
+
const encode = (segment) => encodeURIComponent(segment).replace(/[!'()*]/gu, (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
5634
|
+
/**
|
|
5635
|
+
* Durable private CAS bytes in one S3-compatible bucket under `<prefix><namespace>/sha256/<hex>`.
|
|
5636
|
+
*
|
|
5637
|
+
* Every write declares its SHA-256 as the signed payload hash, so the store refuses bytes that
|
|
5638
|
+
* do not match the digest. A write is confirmed by reading back the object's length and digest
|
|
5639
|
+
* metadata. Reads return raw bytes; the private CAS port verifies them.
|
|
5640
|
+
*/
|
|
5641
|
+
function createS3PrivateCasStore(options) {
|
|
5642
|
+
const endpoint = new URL(options.endpoint);
|
|
5643
|
+
if (endpoint.protocol !== "https:" || endpoint.username || endpoint.password || endpoint.search || endpoint.hash || endpoint.pathname !== "/" && endpoint.pathname !== "") throw new Error("S3 private CAS endpoint must be a bare https origin");
|
|
5644
|
+
if (!BUCKET.test(options.bucket)) throw new Error("S3 private CAS bucket name is invalid");
|
|
5645
|
+
const prefix = options.prefix ?? "";
|
|
5646
|
+
if (!PREFIX.test(prefix)) throw new Error("S3 private CAS prefix must be empty or end in /");
|
|
5647
|
+
if (!options.accessKeyId || !options.secretAccessKey) throw new Error("S3 private CAS needs an access key id and secret");
|
|
5648
|
+
const region = options.region ?? "auto";
|
|
5649
|
+
const timeoutMs = options.timeoutMs ?? 12e4;
|
|
5650
|
+
const send = options.fetch ?? fetch;
|
|
5651
|
+
const key = (namespace, digest) => {
|
|
5652
|
+
if (!NAMESPACE.test(namespace)) throw new Error("S3 private CAS namespace is invalid");
|
|
5653
|
+
const match = DIGEST.exec(digest);
|
|
5654
|
+
if (!match) throw new Error("S3 private CAS digest must be sha256:<64 lowercase hex>");
|
|
5655
|
+
return `${prefix}${namespace}/sha256/${match[1]}`;
|
|
5656
|
+
};
|
|
5657
|
+
const request = async (method, objectKey, { body, byteLength, payloadHash = EMPTY_PAYLOAD, headers = {}, signal } = {}) => {
|
|
5658
|
+
const path = `/${[options.bucket, ...objectKey.split("/")].map(encode).join("/")}`;
|
|
5659
|
+
const url = new URL(path, endpoint);
|
|
5660
|
+
const amzDate = (/* @__PURE__ */ new Date()).toISOString().replace(/[:-]|\.\d{3}/gu, "");
|
|
5661
|
+
const day = amzDate.slice(0, 8);
|
|
5662
|
+
const signed = {
|
|
5663
|
+
host: url.host,
|
|
5664
|
+
"x-amz-content-sha256": payloadHash,
|
|
5665
|
+
"x-amz-date": amzDate,
|
|
5666
|
+
...Object.fromEntries(Object.entries(headers).map(([name, value]) => [name.toLowerCase(), value]))
|
|
5667
|
+
};
|
|
5668
|
+
const names = Object.keys(signed).sort();
|
|
5669
|
+
const canonical = [
|
|
5670
|
+
method,
|
|
5671
|
+
path,
|
|
5672
|
+
"",
|
|
5673
|
+
names.map((name) => `${name}:${signed[name].trim()}\n`).join(""),
|
|
5674
|
+
names.join(";"),
|
|
5675
|
+
payloadHash
|
|
5676
|
+
].join("\n");
|
|
5677
|
+
const scope = `${day}/${region}/s3/aws4_request`;
|
|
5678
|
+
const signature = createHmac("sha256", hmac(hmac(hmac(hmac(`AWS4${options.secretAccessKey}`, day), region), "s3"), "aws4_request")).update([
|
|
5679
|
+
"AWS4-HMAC-SHA256",
|
|
5680
|
+
amzDate,
|
|
5681
|
+
scope,
|
|
5682
|
+
hex(canonical)
|
|
5683
|
+
].join("\n")).digest("hex");
|
|
5684
|
+
const { host: _host, ...sent } = signed;
|
|
5685
|
+
const deadline = AbortSignal.timeout(timeoutMs + Math.ceil((byteLength ?? (body instanceof Uint8Array ? body.byteLength : 0)) / (1024 * 1024)) * 1e3);
|
|
5686
|
+
return await send(url, {
|
|
5687
|
+
method,
|
|
5688
|
+
headers: {
|
|
5689
|
+
...sent,
|
|
5690
|
+
authorization: `AWS4-HMAC-SHA256 Credential=${options.accessKeyId}/${scope}, SignedHeaders=${names.join(";")}, Signature=${signature}`
|
|
5691
|
+
},
|
|
5692
|
+
...body === void 0 ? {} : { body },
|
|
5693
|
+
...body instanceof ReadableStream ? { duplex: "half" } : {},
|
|
5694
|
+
signal: signal === void 0 ? deadline : AbortSignal.any([signal, deadline])
|
|
5695
|
+
});
|
|
5696
|
+
};
|
|
5697
|
+
const refusal = async (response, action) => {
|
|
5698
|
+
const reader = response.body?.getReader();
|
|
5699
|
+
let detail = "";
|
|
5700
|
+
try {
|
|
5701
|
+
while (reader && detail.length < 300) {
|
|
5702
|
+
const { done, value } = await reader.read();
|
|
5703
|
+
if (done) break;
|
|
5704
|
+
detail += new TextDecoder().decode(value.subarray(0, 300));
|
|
5705
|
+
}
|
|
5706
|
+
} catch {} finally {
|
|
5707
|
+
await reader?.cancel().catch(() => void 0);
|
|
5708
|
+
}
|
|
5709
|
+
detail = detail.replace(/\s+/gu, " ").slice(0, 300);
|
|
5710
|
+
return /* @__PURE__ */ new Error(`S3 private CAS ${action} returned ${response.status}${detail ? `: ${detail}` : ""}`);
|
|
5711
|
+
};
|
|
5712
|
+
/** Whether the bucket holds this exact object; refuses a same-key object of other bytes. */
|
|
5713
|
+
const holds = async (objectKey, digest, byteLength, signal) => {
|
|
5714
|
+
const response = await request("HEAD", objectKey, signal === void 0 ? {} : { signal });
|
|
5715
|
+
if (response.status === 404) return false;
|
|
5716
|
+
if (!response.ok) throw await refusal(response, "HEAD");
|
|
5717
|
+
const length = Number(response.headers.get("content-length"));
|
|
5718
|
+
const recorded = response.headers.get(METADATA_DIGEST);
|
|
5719
|
+
if (length !== byteLength || recorded !== null && recorded !== digest) throw new Error(`S3 private CAS object ${objectKey} has another length or digest`);
|
|
5720
|
+
return recorded === digest;
|
|
5721
|
+
};
|
|
5722
|
+
return {
|
|
5723
|
+
location: `s3://${options.bucket}/${prefix}`,
|
|
5724
|
+
async putStream({ namespace, digest, byteLength, chunks, signal }) {
|
|
5725
|
+
const objectKey = key(namespace, digest);
|
|
5726
|
+
if (await holds(objectKey, digest, byteLength, signal)) return;
|
|
5727
|
+
async function* checked() {
|
|
5728
|
+
const hash = createHash("sha256");
|
|
5729
|
+
let total = 0;
|
|
5730
|
+
for await (const chunk of chunks) {
|
|
5731
|
+
signal?.throwIfAborted();
|
|
5732
|
+
total += chunk.byteLength;
|
|
5733
|
+
if (total > byteLength) throw new Error("S3 private CAS stream exceeds its declared length");
|
|
5734
|
+
hash.update(chunk);
|
|
5735
|
+
yield chunk;
|
|
5736
|
+
}
|
|
5737
|
+
if (total !== byteLength || `sha256:${hash.digest("hex")}` !== digest) throw new Error("S3 private CAS stream failed digest or length verification");
|
|
5738
|
+
}
|
|
5739
|
+
const body = Readable.from(checked());
|
|
5740
|
+
try {
|
|
5741
|
+
const response = await request("PUT", objectKey, {
|
|
5742
|
+
body: Readable.toWeb(body),
|
|
5743
|
+
byteLength,
|
|
5744
|
+
payloadHash: DIGEST.exec(digest)[1],
|
|
5745
|
+
headers: {
|
|
5746
|
+
"content-type": CONTENT_TYPE,
|
|
5747
|
+
"content-length": String(byteLength),
|
|
5748
|
+
[METADATA_DIGEST]: digest
|
|
5749
|
+
},
|
|
5750
|
+
...signal === void 0 ? {} : { signal }
|
|
5751
|
+
});
|
|
5752
|
+
if (!response.ok) throw await refusal(response, "PUT");
|
|
5753
|
+
await response.body?.cancel().catch(() => void 0);
|
|
5754
|
+
if (!await holds(objectKey, digest, byteLength, signal)) throw new Error(`S3 private CAS object ${objectKey} is absent after its write`);
|
|
5755
|
+
} finally {
|
|
5756
|
+
body.destroy();
|
|
5757
|
+
}
|
|
5758
|
+
},
|
|
5759
|
+
async getStream({ namespace, digest, signal }) {
|
|
5760
|
+
const response = await request("GET", key(namespace, digest), signal === void 0 ? {} : { signal });
|
|
5761
|
+
if (response.status === 404) {
|
|
5762
|
+
await response.body?.cancel().catch(() => void 0);
|
|
5763
|
+
return;
|
|
5764
|
+
}
|
|
5765
|
+
if (!response.ok) throw await refusal(response, "GET");
|
|
5766
|
+
if (!response.body) throw new Error("S3 private CAS GET returned no body");
|
|
5767
|
+
return (async function* () {
|
|
5768
|
+
const reader = response.body.getReader();
|
|
5769
|
+
try {
|
|
5770
|
+
while (true) {
|
|
5771
|
+
signal?.throwIfAborted();
|
|
5772
|
+
const { done, value } = await reader.read();
|
|
5773
|
+
if (done) break;
|
|
5774
|
+
yield value;
|
|
5775
|
+
}
|
|
5776
|
+
} finally {
|
|
5777
|
+
await reader.cancel().catch(() => void 0);
|
|
5778
|
+
}
|
|
5779
|
+
})();
|
|
5780
|
+
},
|
|
5781
|
+
async put({ namespace, digest, bytes, signal }) {
|
|
5782
|
+
const objectKey = key(namespace, digest);
|
|
5783
|
+
if (await holds(objectKey, digest, bytes.byteLength, signal)) return;
|
|
5784
|
+
const response = await request("PUT", objectKey, {
|
|
5785
|
+
body: bytes,
|
|
5786
|
+
payloadHash: DIGEST.exec(digest)[1],
|
|
5787
|
+
headers: {
|
|
5788
|
+
"content-type": CONTENT_TYPE,
|
|
5789
|
+
[METADATA_DIGEST]: digest
|
|
5790
|
+
},
|
|
5791
|
+
...signal === void 0 ? {} : { signal }
|
|
5792
|
+
});
|
|
5793
|
+
if (!response.ok) throw await refusal(response, "PUT");
|
|
5794
|
+
await response.body?.cancel().catch(() => void 0);
|
|
5795
|
+
if (!await holds(objectKey, digest, bytes.byteLength, signal)) throw new Error(`S3 private CAS object ${objectKey} is absent after its write`);
|
|
5796
|
+
},
|
|
5797
|
+
async get({ namespace, digest, signal }) {
|
|
5798
|
+
const response = await request("GET", key(namespace, digest), signal === void 0 ? {} : { signal });
|
|
5799
|
+
if (response.status === 404) {
|
|
5800
|
+
await response.body?.cancel().catch(() => void 0);
|
|
5801
|
+
return;
|
|
5802
|
+
}
|
|
5803
|
+
if (!response.ok) throw await refusal(response, "GET");
|
|
5804
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
5805
|
+
}
|
|
5806
|
+
};
|
|
5807
|
+
}
|
|
5808
|
+
//#endregion
|
|
5268
5809
|
//#region src/runtime/box-read-retry.ts
|
|
5269
5810
|
/**
|
|
5270
5811
|
* One bounded-retry read over a sandbox box's filesystem, shared by every caller that reads a
|
|
@@ -8397,6 +8938,6 @@ function tail(s) {
|
|
|
8397
8938
|
return s.slice(-400);
|
|
8398
8939
|
}
|
|
8399
8940
|
//#endregion
|
|
8400
|
-
export {
|
|
8941
|
+
export { FileCorpus as $, envKeyProvider as $t, unsafeInProcessRunner as A, readDeclaredCheck as At, SandboxRunAbortError as B, renderLeaderboardSvg as Bt, withUntrackedArtifacts as C, loopDispatch as Ct, patchDelivered as D, declaredCheckDeliverable as Dt, createSqlRunContext as E, checkProgramDigest as Et, strategyTournament as F, stopSentinel as Ft, createPrivateCasArtifactPort as G, openSqlRunStore as Gt, createS3PrivateCasStore as H, auditIntent as Ht, assertStrategyContract as I, leaderboard as It, definePersona as J, McpSpawnFault as Jt, equalKOnCost as K, SqlResultBlobStore as Kt, authorStrategy as L, pairwiseSignificance as Lt, chatWorkerSeam as M, completionAuthorizes as Mt, createChatSessionStore as N, deterministicCompletion as Nt, runCoderChecks as O, declaredCheckDigest as Ot, runStrategyEvolution as P, sentinelCompletion as Pt, registerShape as Q, sanitizeMcpToolSchema as Qt, strategyAuthorContract as R, renderLeaderboardHtml as Rt, copyUntrackedIntoClone as S, loopCampaignDispatch as St, createFencedSqlRunContext as T, assertDeclaredCheck as Tt, printBenchmarkReport as U, defaultAuditorInstruction as Ut, openSandboxRun as V, renderPairwiseMarkdown as Vt, runBenchmark as W, SqlRunOwnershipError as Wt, builtinShapes as X, materializeLocalMcp as Xt, runPersonified as Y, connectStdioMcp as Yt, createShapeRegistry as Z, createMcpEnvironment as Zt, NOTE_MAX_CHARS as _, harvestCorpus as _t, localShell as a, panel as at, composeWorkerEvidence as b, localSandboxClient as bt, createVerifierEnvironment as c, verify as ct, harvestSurfaceDiffs as d, buildSteerContext as dt, mcpSecretEnvMetadataKey as en, InMemoryCorpus as et, analystsFromRegistry as f, createScopeAnalyst as ft, EVIDENCE_MAX_CHARS as g, HarvestError as gt, worktreeFanout as h, inProcessSandboxClient as ht, jjWorkspace as i, createTangleSandboxExactProcessProvider as in, loopUntil as it, chatTransportExecutor as j, runIsolatedCheck as jt, codeModeSupervisorTools as k, declaredCheckJudge as kt, boxSurfaceReader as l, widen as lt, superviseSurface as m, observationFromRegistry as mt, makeFinding$1 as n, resolveSecretEnv as nn, fanout as nt, runInWorkspace as o, pipeline as ot, failuresAnalyst as p, registryScopeAnalyst as pt, trajectoryReport as q, SqlSpawnJournal as qt, gitWorkspace as r, secretEnvOfMcpServer as rn, flatWidenGate as rt, createWaterfallCollector as s, selectValidWinner as st, computeFindingId$1 as t, resolveMcpServerLaunch as tn, renderCorpusToInstructions as tt, fsSurfaceReader as u, assertTraceDerivedFindings as ut, VERIFY_TAIL_CHARS as v, defineLeaderboard as vt, analyzeTrace as w, superviseDispatch as wt, settledWorkerOut as x, inlineSandboxClient as xt, closingWorkerNote as y, resolveSandboxClient as yt, strategyAuthorSystemPrompt as z, renderLeaderboardMarkdown as zt };
|
|
8401
8942
|
|
|
8402
|
-
//# sourceMappingURL=runtime-
|
|
8943
|
+
//# sourceMappingURL=runtime-CXKCdGTg.js.map
|