@tangle-network/agent-runtime 0.94.13 → 0.95.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/agent.d.ts +2 -25
- package/dist/agent.js +9 -12
- package/dist/agent.js.map +1 -1
- package/dist/{agentic-generator-DDMM45kZ.d.ts → agentic-generator-hCaQRAes.d.ts} +0 -1
- package/dist/analyst-loop.d.ts +1 -1
- package/dist/candidate-execution/index.d.ts +43 -16
- package/dist/candidate-execution/index.js +18 -8
- package/dist/{chunk-VYA2YEKA.js → chunk-2KGAN2HM.js} +83 -14
- package/dist/chunk-2KGAN2HM.js.map +1 -0
- package/dist/{chunk-TVJQAYQM.js → chunk-6YBA64Z2.js} +120 -716
- package/dist/chunk-6YBA64Z2.js.map +1 -0
- package/dist/{chunk-HGRW27YY.js → chunk-AP7CPGMZ.js} +139 -19
- package/dist/chunk-AP7CPGMZ.js.map +1 -0
- package/dist/{chunk-XP5KDM3R.js → chunk-BPGXIKK7.js} +3 -3
- package/dist/{chunk-D3H7F6L2.js → chunk-DHCHL6OG.js} +2 -3
- package/dist/chunk-DHCHL6OG.js.map +1 -0
- package/dist/{chunk-PCURO3DL.js → chunk-G55QE4IQ.js} +512 -36
- package/dist/chunk-G55QE4IQ.js.map +1 -0
- package/dist/{chunk-C3UKLQ54.js → chunk-IADLKE7I.js} +14 -4
- package/dist/chunk-IADLKE7I.js.map +1 -0
- package/dist/{chunk-WIPGQ4GT.js → chunk-IMSNJSXH.js} +1 -1
- package/dist/{chunk-WIPGQ4GT.js.map → chunk-IMSNJSXH.js.map} +1 -1
- package/dist/{chunk-VSWBYWFK.js → chunk-M6MD6JBS.js} +20 -27
- package/dist/chunk-M6MD6JBS.js.map +1 -0
- package/dist/chunk-MKGRLDWB.js +684 -0
- package/dist/chunk-MKGRLDWB.js.map +1 -0
- package/dist/{chunk-AEG3NGJ2.js → chunk-Q2JSAVQ3.js} +34 -2
- package/dist/chunk-Q2JSAVQ3.js.map +1 -0
- package/dist/{chunk-CNH7DF7Z.js → chunk-WTZ37EQY.js} +922 -504
- package/dist/chunk-WTZ37EQY.js.map +1 -0
- package/dist/{chunk-U33YZ7B2.js → chunk-YLUOTX6U.js} +4 -4
- package/dist/{chunk-33OG2NN3.js → chunk-Z5I642SY.js} +2 -2
- package/dist/{completion-gate-D1gX1-hg.d.ts → completion-gate-C80jiRfN.d.ts} +1 -1
- package/dist/conversation.d.ts +12 -1
- package/dist/conversation.js +2 -2
- package/dist/{coordination-Dr_axlAf.d.ts → coordination-BFE3Den7.d.ts} +10 -11
- package/dist/environment-provider.d.ts +2 -2
- package/dist/environment-provider.js +1 -1
- package/dist/{improve-BN3HyXIO.d.ts → improve-B-UYaEH5.d.ts} +3 -3
- package/dist/index.d.ts +22 -25
- package/dist/index.js +45 -50
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +177 -119
- package/dist/intelligence.js +501 -342
- package/dist/intelligence.js.map +1 -1
- package/dist/knowledge.d.ts +22 -11
- package/dist/knowledge.js +9 -4
- package/dist/lifecycle.d.ts +2 -2
- package/dist/lifecycle.js +1 -1
- package/dist/{loop-runner-bin-BRQSQdHa.d.ts → loop-runner-bin-BIQldFS8.d.ts} +2 -2
- package/dist/loop-runner-bin.d.ts +5 -5
- package/dist/loop-runner-bin.js +6 -6
- package/dist/loops.d.ts +12 -12
- package/dist/loops.js +5 -5
- package/dist/mcp/bin.js +3 -3
- package/dist/mcp/index.d.ts +6 -6
- package/dist/mcp/index.js +6 -6
- package/dist/{mcp-serve-verifier-DQQDbuyz.d.ts → mcp-serve-verifier-Bs_n0xPc.d.ts} +1 -1
- package/dist/primeintellect/index.js +1 -1
- package/dist/profile-DbfaMTdk.d.ts +233 -0
- package/dist/profiles.d.ts +1 -1
- package/dist/{supervise-DmYOug5f.d.ts → supervise-BLPI50-w.d.ts} +3 -3
- package/dist/{types-ByAYqlVb.d.ts → types-B3vAW0Oq.d.ts} +1 -1
- package/dist/{prepare-CtdtsFNG.d.ts → types-CWqfCO8s.d.ts} +67 -298
- package/dist/{types-1d5QGK3t.d.ts → types-CmnA2iL3.d.ts} +3 -3
- package/dist/{worktree-fanout-CPprU-qI.d.ts → worktree-fanout-DCA3G4bO.d.ts} +3 -3
- package/package.json +13 -10
- package/dist/chunk-AEG3NGJ2.js.map +0 -1
- package/dist/chunk-C3UKLQ54.js.map +0 -1
- package/dist/chunk-CNH7DF7Z.js.map +0 -1
- package/dist/chunk-D3H7F6L2.js.map +0 -1
- package/dist/chunk-HGRW27YY.js.map +0 -1
- package/dist/chunk-PCURO3DL.js.map +0 -1
- package/dist/chunk-TVJQAYQM.js.map +0 -1
- package/dist/chunk-VSWBYWFK.js.map +0 -1
- package/dist/chunk-VYA2YEKA.js.map +0 -1
- /package/dist/{chunk-XP5KDM3R.js.map → chunk-BPGXIKK7.js.map} +0 -0
- /package/dist/{chunk-U33YZ7B2.js.map → chunk-YLUOTX6U.js.map} +0 -0
- /package/dist/{chunk-33OG2NN3.js.map → chunk-Z5I642SY.js.map} +0 -0
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
contentAddress
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-IMSNJSXH.js";
|
|
4
4
|
|
|
5
|
-
// src/candidate-execution/
|
|
6
|
-
import {
|
|
5
|
+
// src/candidate-execution/profile.ts
|
|
6
|
+
import {
|
|
7
|
+
agentCandidateProfileActivationSchema,
|
|
8
|
+
agentCandidateProfileSchema,
|
|
9
|
+
agentProfileDiffSchema,
|
|
10
|
+
agentProfileSchema,
|
|
11
|
+
applyAgentProfileDiff
|
|
12
|
+
} from "@tangle-network/agent-interface";
|
|
7
13
|
|
|
8
14
|
// src/candidate-execution/digest.ts
|
|
9
15
|
import { createHash } from "crypto";
|
|
@@ -38,6 +44,12 @@ function canonicalCandidateDocument(valueWithoutDigest) {
|
|
|
38
44
|
digest
|
|
39
45
|
});
|
|
40
46
|
}
|
|
47
|
+
function verifyCanonicalCandidateDocument(value, label) {
|
|
48
|
+
if (canonicalCandidateDigest(omitTopLevelDigest(value)) !== value.digest) {
|
|
49
|
+
throw new Error(`${label} digest does not match`);
|
|
50
|
+
}
|
|
51
|
+
return immutableCandidateValue(value);
|
|
52
|
+
}
|
|
41
53
|
function embeddedCandidateArtifact(bytes) {
|
|
42
54
|
return {
|
|
43
55
|
encoding: "base64",
|
|
@@ -61,24 +73,69 @@ function deepFreezeCandidate(value, seen = /* @__PURE__ */ new Set()) {
|
|
|
61
73
|
return Object.freeze(value);
|
|
62
74
|
}
|
|
63
75
|
|
|
64
|
-
// src/candidate-execution/
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
76
|
+
// src/candidate-execution/profile.ts
|
|
77
|
+
var MATERIALIZER_HARNESSES = /* @__PURE__ */ new Set([
|
|
78
|
+
"claude-code",
|
|
79
|
+
"claude",
|
|
80
|
+
"claudish",
|
|
81
|
+
"nanoclaw",
|
|
82
|
+
"codex",
|
|
83
|
+
"opencode",
|
|
84
|
+
"kimi-code",
|
|
85
|
+
"kimi",
|
|
86
|
+
"pi",
|
|
87
|
+
"gemini",
|
|
88
|
+
"hermes",
|
|
89
|
+
"openclaw"
|
|
90
|
+
]);
|
|
91
|
+
function candidateMaterializerHarness(harness) {
|
|
92
|
+
if (!MATERIALIZER_HARNESSES.has(harness)) {
|
|
93
|
+
throw new Error(
|
|
94
|
+
`sealed candidate profile materialization is unsupported for harness ${harness}`
|
|
95
|
+
);
|
|
71
96
|
}
|
|
72
|
-
return
|
|
97
|
+
return harness;
|
|
98
|
+
}
|
|
99
|
+
function createAgentCandidateProfileActivation(plan, profilePlan) {
|
|
100
|
+
const sourceByPath = new Map(plan.files.map((file) => [file.relPath, file]));
|
|
101
|
+
if (sourceByPath.size !== plan.files.length) {
|
|
102
|
+
throw new Error("candidate profile activation contains duplicate native file paths");
|
|
103
|
+
}
|
|
104
|
+
const files = profilePlan.material.files.map((expected) => {
|
|
105
|
+
const source = sourceByPath.get(expected.relPath);
|
|
106
|
+
if (!source) {
|
|
107
|
+
throw new Error(`candidate profile activation is missing ${expected.relPath}`);
|
|
108
|
+
}
|
|
109
|
+
const mode = source.mode ?? 420;
|
|
110
|
+
if (!Number.isSafeInteger(mode) || mode < 0 || mode > 511) {
|
|
111
|
+
throw new Error(`candidate profile activation has invalid mode for ${expected.relPath}`);
|
|
112
|
+
}
|
|
113
|
+
return { path: expected.relPath, mode, content: source.content };
|
|
114
|
+
});
|
|
115
|
+
if (files.length !== plan.files.length) {
|
|
116
|
+
throw new Error("candidate profile activation contains unplanned native files");
|
|
117
|
+
}
|
|
118
|
+
return parseAgentCandidateProfileActivation(
|
|
119
|
+
canonicalCandidateDocument({
|
|
120
|
+
kind: "agent-candidate-profile-activation",
|
|
121
|
+
profilePlan,
|
|
122
|
+
files
|
|
123
|
+
}).value,
|
|
124
|
+
profilePlan.digest
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
function parseAgentCandidateProfileActivation(input, expectedProfilePlanDigest) {
|
|
128
|
+
const activation = agentCandidateProfileActivationSchema.parse(input);
|
|
129
|
+
const planBytes = canonicalCandidateBytes(activation.profilePlan.material);
|
|
130
|
+
const profilePlanArtifact = activation.profilePlan.artifact;
|
|
131
|
+
if (sha256Bytes(planBytes) !== activation.profilePlan.digest || profilePlanArtifact.sha256 !== activation.profilePlan.digest || profilePlanArtifact.byteLength !== planBytes.byteLength || "content" in profilePlanArtifact && !Buffer.from(profilePlanArtifact.content, "base64").equals(Buffer.from(planBytes)) || expectedProfilePlanDigest !== void 0 && activation.profilePlan.digest !== expectedProfilePlanDigest) {
|
|
132
|
+
throw new Error("candidate profile activation has an invalid canonical profile plan");
|
|
133
|
+
}
|
|
134
|
+
if (canonicalCandidateDigest(omitTopLevelDigest(activation)) !== activation.digest) {
|
|
135
|
+
throw new Error("candidate profile activation digest does not match");
|
|
136
|
+
}
|
|
137
|
+
return immutableCandidateValue(activation);
|
|
73
138
|
}
|
|
74
|
-
|
|
75
|
-
// src/candidate-execution/profile.ts
|
|
76
|
-
import {
|
|
77
|
-
agentCandidateProfileSchema,
|
|
78
|
-
agentProfileDiffSchema,
|
|
79
|
-
agentProfileSchema,
|
|
80
|
-
applyAgentProfileDiff
|
|
81
|
-
} from "@tangle-network/agent-interface";
|
|
82
139
|
var CANDIDATE_PROFILE_DIRECT_FIELDS = [
|
|
83
140
|
"name",
|
|
84
141
|
"description",
|
|
@@ -137,18 +194,28 @@ function assertCandidateProfileBinding(measuredInput, bundled) {
|
|
|
137
194
|
if (measured.connections || measured.metadata || measured.extensions) {
|
|
138
195
|
throw new Error("proposal candidate profile contains fields unsupported by sealed candidates");
|
|
139
196
|
}
|
|
140
|
-
const normalized =
|
|
197
|
+
const normalized = agentCandidateProfileAsAgentProfile(bundled);
|
|
141
198
|
if (canonicalCandidateDigest(measured) !== canonicalCandidateDigest(normalized)) {
|
|
142
199
|
throw new Error("proposal candidateProfile does not match candidateBundle.profile");
|
|
143
200
|
}
|
|
144
201
|
}
|
|
145
202
|
function parseExactAgentProfile(input, label) {
|
|
146
|
-
|
|
203
|
+
let parsed;
|
|
204
|
+
try {
|
|
205
|
+
parsed = agentProfileSchema.parse(input);
|
|
206
|
+
} catch (cause) {
|
|
207
|
+
throw new Error(`${label} contains unsupported or non-canonical fields`, { cause });
|
|
208
|
+
}
|
|
147
209
|
assertCanonicalParse(input, parsed, label);
|
|
148
210
|
return parsed;
|
|
149
211
|
}
|
|
150
212
|
function parseExactAgentProfileDiff(input, label) {
|
|
151
|
-
|
|
213
|
+
let parsed;
|
|
214
|
+
try {
|
|
215
|
+
parsed = agentProfileDiffSchema.parse(input);
|
|
216
|
+
} catch (cause) {
|
|
217
|
+
throw new Error(`${label} contains unsupported or non-canonical fields`, { cause });
|
|
218
|
+
}
|
|
152
219
|
assertCanonicalParse(input, parsed, label);
|
|
153
220
|
return parsed;
|
|
154
221
|
}
|
|
@@ -172,7 +239,7 @@ function assertCandidateProfileExecutionSupport(profile) {
|
|
|
172
239
|
);
|
|
173
240
|
}
|
|
174
241
|
}
|
|
175
|
-
function
|
|
242
|
+
function agentCandidateProfileAsAgentProfile(candidate) {
|
|
176
243
|
const output = {};
|
|
177
244
|
copyDirectProfileFields(output, candidate);
|
|
178
245
|
if (candidate.model) output.model = { ...candidate.model };
|
|
@@ -375,13 +442,9 @@ import {
|
|
|
375
442
|
} from "@tangle-network/agent-interface";
|
|
376
443
|
|
|
377
444
|
// src/candidate-execution/claim-file-formats.ts
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
var PHASE_FORMAT_VERSION = 1;
|
|
382
|
-
|
|
383
|
-
// src/candidate-execution/claim-terminal.ts
|
|
384
|
-
import { agentCandidateArtifactRefSchema } from "@tangle-network/agent-interface";
|
|
445
|
+
import {
|
|
446
|
+
agentCandidateArtifactRefSchema
|
|
447
|
+
} from "@tangle-network/agent-interface";
|
|
385
448
|
|
|
386
449
|
// src/candidate-execution/exact-object.ts
|
|
387
450
|
function assertExactObjectKeys(value, required, label, optional = []) {
|
|
@@ -400,7 +463,31 @@ function assertExactObjectKeys(value, required, label, optional = []) {
|
|
|
400
463
|
}
|
|
401
464
|
}
|
|
402
465
|
|
|
466
|
+
// src/candidate-execution/claim-file-formats.ts
|
|
467
|
+
function sealCandidatePreparationEvidence(value, executionPlanDigest) {
|
|
468
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
469
|
+
throw new Error("candidate execution preparation evidence must be an object");
|
|
470
|
+
}
|
|
471
|
+
const record = value;
|
|
472
|
+
assertExactObjectKeys(
|
|
473
|
+
record,
|
|
474
|
+
["executionPlan", "materializationReceipt"],
|
|
475
|
+
"candidate execution preparation evidence"
|
|
476
|
+
);
|
|
477
|
+
const executionPlan = immutableCandidateValue(
|
|
478
|
+
agentCandidateArtifactRefSchema.parse(record.executionPlan)
|
|
479
|
+
);
|
|
480
|
+
const materializationReceipt = immutableCandidateValue(
|
|
481
|
+
agentCandidateArtifactRefSchema.parse(record.materializationReceipt)
|
|
482
|
+
);
|
|
483
|
+
if (executionPlan.sha256 !== executionPlanDigest) {
|
|
484
|
+
throw new Error("candidate execution plan artifact digest does not match its claim");
|
|
485
|
+
}
|
|
486
|
+
return Object.freeze({ executionPlan, materializationReceipt });
|
|
487
|
+
}
|
|
488
|
+
|
|
403
489
|
// src/candidate-execution/claim-terminal.ts
|
|
490
|
+
import { agentCandidateArtifactRefSchema as agentCandidateArtifactRefSchema2 } from "@tangle-network/agent-interface";
|
|
404
491
|
var SHA256_PATTERN = /^sha256:[a-f0-9]{64}$/;
|
|
405
492
|
function terminalRecord(claim, result) {
|
|
406
493
|
const terminal = sealTerminalResult(result);
|
|
@@ -409,6 +496,7 @@ function terminalRecord(claim, result) {
|
|
|
409
496
|
attempt: claim.attempt,
|
|
410
497
|
bundleDigest: claim.bundleDigest,
|
|
411
498
|
executionPlanDigest: claim.executionPlanDigest,
|
|
499
|
+
preparationEvidence: claim.preparationEvidence,
|
|
412
500
|
...terminal
|
|
413
501
|
};
|
|
414
502
|
return immutableCandidateValue({
|
|
@@ -419,7 +507,6 @@ function terminalRecord(claim, result) {
|
|
|
419
507
|
function recoveredTerminalRecord(claim, phase, evidence) {
|
|
420
508
|
const recovered = sealRecoveryEvidence(evidence, claim);
|
|
421
509
|
return terminalRecord(claim, {
|
|
422
|
-
schemaVersion: 1,
|
|
423
510
|
status: "failed",
|
|
424
511
|
failureClass: recovered.failureClass === "pre-model-infrastructure" && phase !== "claimed" ? "unknown" : recovered.failureClass,
|
|
425
512
|
usage: recovered.usage,
|
|
@@ -474,8 +561,8 @@ function sealTerminalRecordValue(value, label) {
|
|
|
474
561
|
"attempt",
|
|
475
562
|
"bundleDigest",
|
|
476
563
|
"executionPlanDigest",
|
|
564
|
+
"preparationEvidence",
|
|
477
565
|
"terminalDigest",
|
|
478
|
-
"schemaVersion",
|
|
479
566
|
"status",
|
|
480
567
|
"usage",
|
|
481
568
|
"modelSettlement",
|
|
@@ -487,8 +574,8 @@ function sealTerminalRecordValue(value, label) {
|
|
|
487
574
|
"attempt",
|
|
488
575
|
"bundleDigest",
|
|
489
576
|
"executionPlanDigest",
|
|
577
|
+
"preparationEvidence",
|
|
490
578
|
"terminalDigest",
|
|
491
|
-
"schemaVersion",
|
|
492
579
|
"status",
|
|
493
580
|
"failureClass",
|
|
494
581
|
"usage",
|
|
@@ -497,14 +584,19 @@ function sealTerminalRecordValue(value, label) {
|
|
|
497
584
|
],
|
|
498
585
|
label
|
|
499
586
|
);
|
|
587
|
+
const executionPlanDigest = requireString(
|
|
588
|
+
value.executionPlanDigest,
|
|
589
|
+
label,
|
|
590
|
+
"executionPlanDigest"
|
|
591
|
+
);
|
|
500
592
|
const identity = {
|
|
501
593
|
executionId: requireString(value.executionId, label, "executionId"),
|
|
502
594
|
attempt: requireNumber(value.attempt, label, "attempt"),
|
|
503
595
|
bundleDigest: requireString(value.bundleDigest, label, "bundleDigest"),
|
|
504
|
-
executionPlanDigest
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
596
|
+
executionPlanDigest,
|
|
597
|
+
preparationEvidence: sealCandidatePreparationEvidence(
|
|
598
|
+
value.preparationEvidence,
|
|
599
|
+
executionPlanDigest
|
|
508
600
|
)
|
|
509
601
|
};
|
|
510
602
|
assertExecutionId(identity.executionId);
|
|
@@ -513,28 +605,21 @@ function sealTerminalRecordValue(value, label) {
|
|
|
513
605
|
}
|
|
514
606
|
assertSha256Digest(identity.bundleDigest, "bundleDigest");
|
|
515
607
|
assertSha256Digest(identity.executionPlanDigest, "executionPlanDigest");
|
|
608
|
+
if (identity.preparationEvidence.executionPlan.sha256 !== identity.executionPlanDigest) {
|
|
609
|
+
throw new Error(`${label} execution plan artifact does not match executionPlanDigest`);
|
|
610
|
+
}
|
|
516
611
|
const result = sealTerminalResult(
|
|
517
612
|
status === "succeeded" ? {
|
|
518
|
-
schemaVersion: requireNumber(value.schemaVersion, label, "schemaVersion"),
|
|
519
613
|
status,
|
|
520
|
-
usage: requireObject(
|
|
521
|
-
value.usage,
|
|
522
|
-
label,
|
|
523
|
-
"usage"
|
|
524
|
-
),
|
|
614
|
+
usage: requireObject(value.usage, label, "usage"),
|
|
525
615
|
modelSettlement: requireArtifactRef(value.modelSettlement, label, "modelSettlement"),
|
|
526
616
|
taskOutcome: requireArtifactRef(value.taskOutcome, label, "taskOutcome"),
|
|
527
617
|
benchmarkResult: requireArtifactRef(value.benchmarkResult, label, "benchmarkResult"),
|
|
528
618
|
runReceipt: requireArtifactRef(value.runReceipt, label, "runReceipt")
|
|
529
619
|
} : {
|
|
530
|
-
schemaVersion: requireNumber(value.schemaVersion, label, "schemaVersion"),
|
|
531
620
|
status,
|
|
532
621
|
failureClass: requireFailureClass(value.failureClass, label),
|
|
533
|
-
usage: requireObject(
|
|
534
|
-
value.usage,
|
|
535
|
-
label,
|
|
536
|
-
"usage"
|
|
537
|
-
),
|
|
622
|
+
usage: requireObject(value.usage, label, "usage"),
|
|
538
623
|
modelSettlement: requireArtifactRef(value.modelSettlement, label, "modelSettlement"),
|
|
539
624
|
...value.failureEvidence ? {
|
|
540
625
|
failureEvidence: requireArtifactRef(
|
|
@@ -561,7 +646,7 @@ function sealTerminalRecordValue(value, label) {
|
|
|
561
646
|
});
|
|
562
647
|
}
|
|
563
648
|
function assertTerminalMatchesClaim(terminal, claim, path) {
|
|
564
|
-
if (terminal.executionId !== claim.executionId || terminal.attempt !== claim.attempt || terminal.bundleDigest !== claim.bundleDigest || terminal.executionPlanDigest !== claim.executionPlanDigest) {
|
|
649
|
+
if (terminal.executionId !== claim.executionId || terminal.attempt !== claim.attempt || terminal.bundleDigest !== claim.bundleDigest || terminal.executionPlanDigest !== claim.executionPlanDigest || canonicalCandidateDigest(terminal.preparationEvidence) !== canonicalCandidateDigest(claim.preparationEvidence)) {
|
|
565
650
|
throw new Error(`candidate execution terminal record at ${path} does not match its claim`);
|
|
566
651
|
}
|
|
567
652
|
}
|
|
@@ -640,16 +725,7 @@ function sealTerminalResult(result) {
|
|
|
640
725
|
}
|
|
641
726
|
assertExactObjectKeys(
|
|
642
727
|
result,
|
|
643
|
-
result.status === "succeeded" ? [
|
|
644
|
-
"schemaVersion",
|
|
645
|
-
"status",
|
|
646
|
-
"usage",
|
|
647
|
-
"modelSettlement",
|
|
648
|
-
"taskOutcome",
|
|
649
|
-
"benchmarkResult",
|
|
650
|
-
"runReceipt"
|
|
651
|
-
] : [
|
|
652
|
-
"schemaVersion",
|
|
728
|
+
result.status === "succeeded" ? ["status", "usage", "modelSettlement", "taskOutcome", "benchmarkResult", "runReceipt"] : [
|
|
653
729
|
"status",
|
|
654
730
|
"failureClass",
|
|
655
731
|
"usage",
|
|
@@ -658,14 +734,10 @@ function sealTerminalResult(result) {
|
|
|
658
734
|
],
|
|
659
735
|
"candidate execution terminal result"
|
|
660
736
|
);
|
|
661
|
-
if (result.schemaVersion !== 1) {
|
|
662
|
-
throw new Error("candidate execution terminal schemaVersion must be 1");
|
|
663
|
-
}
|
|
664
737
|
const usage = sealUsage(result.usage);
|
|
665
738
|
const modelSettlement = sealArtifactRef(result.modelSettlement, "modelSettlement");
|
|
666
739
|
if (result.status === "succeeded") {
|
|
667
740
|
return Object.freeze({
|
|
668
|
-
schemaVersion: 1,
|
|
669
741
|
status: "succeeded",
|
|
670
742
|
usage,
|
|
671
743
|
modelSettlement,
|
|
@@ -679,7 +751,6 @@ function sealTerminalResult(result) {
|
|
|
679
751
|
throw new Error("pre-model infrastructure failure cannot contain model calls");
|
|
680
752
|
}
|
|
681
753
|
return Object.freeze({
|
|
682
|
-
schemaVersion: 1,
|
|
683
754
|
status: "failed",
|
|
684
755
|
failureClass: result.failureClass,
|
|
685
756
|
usage,
|
|
@@ -713,7 +784,7 @@ function sealUsage(usage) {
|
|
|
713
784
|
});
|
|
714
785
|
}
|
|
715
786
|
function sealArtifactRef(ref, label) {
|
|
716
|
-
const parsed =
|
|
787
|
+
const parsed = agentCandidateArtifactRefSchema2.parse(ref);
|
|
717
788
|
if (!Number.isSafeInteger(parsed.byteLength)) {
|
|
718
789
|
throw new Error(`candidate execution terminal ${label} byteLength exceeds safe integer range`);
|
|
719
790
|
}
|
|
@@ -798,29 +869,15 @@ function candidateResultTimeout(timeoutMs, taskTimeoutMs) {
|
|
|
798
869
|
return effective;
|
|
799
870
|
}
|
|
800
871
|
async function withinCandidateCleanupDeadline(operation, deadlineAtMs, label) {
|
|
801
|
-
|
|
802
|
-
if (remainingMs <= 0) throw new CandidateCleanupTimeoutError(label);
|
|
803
|
-
const pending = Promise.resolve().then(operation);
|
|
804
|
-
void pending.catch(() => void 0);
|
|
805
|
-
let timer;
|
|
806
|
-
try {
|
|
807
|
-
const result = await Promise.race([
|
|
808
|
-
pending,
|
|
809
|
-
new Promise((_resolve, reject) => {
|
|
810
|
-
timer = setTimeout(() => reject(new CandidateCleanupTimeoutError(label)), remainingMs);
|
|
811
|
-
})
|
|
812
|
-
]);
|
|
813
|
-
if (Date.now() >= deadlineAtMs) throw new CandidateCleanupTimeoutError(label);
|
|
814
|
-
return result;
|
|
815
|
-
} finally {
|
|
816
|
-
if (timer) clearTimeout(timer);
|
|
817
|
-
}
|
|
872
|
+
return withinCandidateDeadline(operation, deadlineAtMs, new CandidateCleanupTimeoutError(label));
|
|
818
873
|
}
|
|
819
874
|
async function withinCandidateResultDeadline(operation, deadlineAtMs, label) {
|
|
875
|
+
return withinCandidateDeadline(operation, deadlineAtMs, new CandidateResultTimeoutError(label));
|
|
876
|
+
}
|
|
877
|
+
async function withinCandidateDeadline(operation, deadlineAtMs, timeoutError) {
|
|
820
878
|
const remainingMs = deadlineAtMs - Date.now();
|
|
821
|
-
if (remainingMs <= 0) throw
|
|
879
|
+
if (remainingMs <= 0) throw timeoutError;
|
|
822
880
|
const controller = new AbortController();
|
|
823
|
-
const timeoutError = new CandidateResultTimeoutError(label);
|
|
824
881
|
const pending = Promise.resolve().then(() => operation(controller.signal));
|
|
825
882
|
void pending.catch(() => void 0);
|
|
826
883
|
let timer;
|
|
@@ -949,8 +1006,8 @@ var InMemoryAgentCandidateExecutionClaimStore = class {
|
|
|
949
1006
|
}
|
|
950
1007
|
};
|
|
951
1008
|
var SHA256_PATTERN2 = /^sha256:[a-f0-9]{64}$/;
|
|
952
|
-
var LEASE_TOKEN_PATTERN = /^candidate-execution-lease
|
|
953
|
-
var PREPARATION_ID_PATTERN = /^candidate-preparation
|
|
1009
|
+
var LEASE_TOKEN_PATTERN = /^candidate-execution-lease\.[A-Za-z0-9_-]{43}$/;
|
|
1010
|
+
var PREPARATION_ID_PATTERN = /^candidate-preparation\.[A-Za-z0-9_-]{43}$/;
|
|
954
1011
|
function sealClaim(claim) {
|
|
955
1012
|
assertExactObjectKeys(
|
|
956
1013
|
claim,
|
|
@@ -961,6 +1018,7 @@ function sealClaim(claim) {
|
|
|
961
1018
|
"retryPolicy",
|
|
962
1019
|
"bundleDigest",
|
|
963
1020
|
"executionPlanDigest",
|
|
1021
|
+
"preparationEvidence",
|
|
964
1022
|
"retryLineageDigest",
|
|
965
1023
|
"leaseExpiresAtMs",
|
|
966
1024
|
"resultTimeoutMs",
|
|
@@ -986,6 +1044,10 @@ function sealClaim(claim) {
|
|
|
986
1044
|
}
|
|
987
1045
|
assertSha256Digest2(claim.bundleDigest, "bundleDigest");
|
|
988
1046
|
assertSha256Digest2(claim.executionPlanDigest, "executionPlanDigest");
|
|
1047
|
+
const preparationEvidence = sealCandidatePreparationEvidence(
|
|
1048
|
+
claim.preparationEvidence,
|
|
1049
|
+
claim.executionPlanDigest
|
|
1050
|
+
);
|
|
989
1051
|
assertSha256Digest2(claim.retryLineageDigest, "retryLineageDigest");
|
|
990
1052
|
assertPositiveTimestamp(claim.leaseExpiresAtMs, "leaseExpiresAtMs");
|
|
991
1053
|
candidateResultTimeout(claim.resultTimeoutMs, claim.resultTimeoutMs);
|
|
@@ -997,6 +1059,7 @@ function sealClaim(claim) {
|
|
|
997
1059
|
retryPolicy: claim.retryPolicy,
|
|
998
1060
|
bundleDigest: claim.bundleDigest,
|
|
999
1061
|
executionPlanDigest: claim.executionPlanDigest,
|
|
1062
|
+
preparationEvidence,
|
|
1000
1063
|
retryLineageDigest: claim.retryLineageDigest,
|
|
1001
1064
|
leaseExpiresAtMs: claim.leaseExpiresAtMs,
|
|
1002
1065
|
resultTimeoutMs: claim.resultTimeoutMs,
|
|
@@ -1080,7 +1143,7 @@ function newLease(claim) {
|
|
|
1080
1143
|
return Object.freeze({
|
|
1081
1144
|
executionId: claim.executionId,
|
|
1082
1145
|
attempt: claim.attempt,
|
|
1083
|
-
token: `candidate-execution-lease
|
|
1146
|
+
token: `candidate-execution-lease.${randomBytes(32).toString("base64url")}`,
|
|
1084
1147
|
expiresAtMs: claim.leaseExpiresAtMs
|
|
1085
1148
|
});
|
|
1086
1149
|
}
|
|
@@ -1131,19 +1194,16 @@ function rejectedRetry(claim, detail) {
|
|
|
1131
1194
|
async function readClaim(path) {
|
|
1132
1195
|
const parsed = await readJsonObject(path, "claim");
|
|
1133
1196
|
const record = parsed;
|
|
1134
|
-
if (record.version !== CLAIM_FORMAT_VERSION) {
|
|
1135
|
-
throw new Error(`candidate execution claim at ${path} has unsupported version`);
|
|
1136
|
-
}
|
|
1137
1197
|
assertExactObjectKeys(
|
|
1138
1198
|
parsed,
|
|
1139
1199
|
[
|
|
1140
|
-
"version",
|
|
1141
1200
|
"executionId",
|
|
1142
1201
|
"attempt",
|
|
1143
1202
|
"maxAttempts",
|
|
1144
1203
|
"retryPolicy",
|
|
1145
1204
|
"bundleDigest",
|
|
1146
1205
|
"executionPlanDigest",
|
|
1206
|
+
"preparationEvidence",
|
|
1147
1207
|
"retryLineageDigest",
|
|
1148
1208
|
"leaseExpiresAtMs",
|
|
1149
1209
|
"resultTimeoutMs",
|
|
@@ -1164,6 +1224,11 @@ async function readClaim(path) {
|
|
|
1164
1224
|
path,
|
|
1165
1225
|
"executionPlanDigest"
|
|
1166
1226
|
),
|
|
1227
|
+
preparationEvidence: requireObject2(
|
|
1228
|
+
record.preparationEvidence,
|
|
1229
|
+
path,
|
|
1230
|
+
"preparationEvidence"
|
|
1231
|
+
),
|
|
1167
1232
|
retryLineageDigest: requireString2(
|
|
1168
1233
|
record.retryLineageDigest,
|
|
1169
1234
|
path,
|
|
@@ -1199,10 +1264,7 @@ async function readClaimIfPresent(path) {
|
|
|
1199
1264
|
async function readTerminal(path) {
|
|
1200
1265
|
const parsed = await readJsonObject(path, "terminal record");
|
|
1201
1266
|
const record = parsed;
|
|
1202
|
-
|
|
1203
|
-
throw new Error(`candidate execution terminal record at ${path} has unsupported version`);
|
|
1204
|
-
}
|
|
1205
|
-
assertExactObjectKeys(parsed, ["version", "terminal"], `candidate execution terminal record at ${path}`);
|
|
1267
|
+
assertExactObjectKeys(parsed, ["terminal"], `candidate execution terminal record at ${path}`);
|
|
1206
1268
|
return sealTerminalRecordValue(
|
|
1207
1269
|
requireObject2(record.terminal, path, "terminal"),
|
|
1208
1270
|
`candidate execution terminal record at ${path}`
|
|
@@ -1226,12 +1288,9 @@ async function readTransitionIfPresent(path, claim) {
|
|
|
1226
1288
|
}
|
|
1227
1289
|
if (parsed.kind === "candidate-execution-phase") {
|
|
1228
1290
|
const record = parsed;
|
|
1229
|
-
if (record.version !== PHASE_FORMAT_VERSION) {
|
|
1230
|
-
throw new Error(`candidate execution phase record at ${path} has unsupported version`);
|
|
1231
|
-
}
|
|
1232
1291
|
assertExactObjectKeys(
|
|
1233
1292
|
parsed,
|
|
1234
|
-
["
|
|
1293
|
+
["kind", "executionId", "attempt", "executionPlanDigest", "phase"],
|
|
1235
1294
|
`candidate execution phase record at ${path}`
|
|
1236
1295
|
);
|
|
1237
1296
|
if (record.executionId !== claim.executionId || record.attempt !== claim.attempt || record.executionPlanDigest !== claim.executionPlanDigest || record.phase !== "candidate-may-run") {
|
|
@@ -1241,14 +1300,7 @@ async function readTransitionIfPresent(path, claim) {
|
|
|
1241
1300
|
}
|
|
1242
1301
|
if (parsed.kind === "candidate-execution-pending-terminal") {
|
|
1243
1302
|
const record = parsed;
|
|
1244
|
-
|
|
1245
|
-
throw new Error(`candidate execution pending record at ${path} has unsupported version`);
|
|
1246
|
-
}
|
|
1247
|
-
assertExactObjectKeys(
|
|
1248
|
-
parsed,
|
|
1249
|
-
["version", "kind", "terminal"],
|
|
1250
|
-
`candidate execution pending record at ${path}`
|
|
1251
|
-
);
|
|
1303
|
+
assertExactObjectKeys(parsed, ["kind", "terminal"], `candidate execution pending record at ${path}`);
|
|
1252
1304
|
const terminal = sealTerminalRecordValue(
|
|
1253
1305
|
requireObject2(record.terminal, path, "terminal"),
|
|
1254
1306
|
`candidate execution pending record at ${path}`
|
|
@@ -1398,6 +1450,8 @@ function candidateTerminalWindowMs(cleanupTimeoutMs) {
|
|
|
1398
1450
|
|
|
1399
1451
|
// src/candidate-execution/prepared-state.ts
|
|
1400
1452
|
import {
|
|
1453
|
+
agentCandidateBenchmarkSuiteSchema,
|
|
1454
|
+
agentCandidateBenchmarkTaskSchema,
|
|
1401
1455
|
agentCandidateExecutionPlanEvidenceSchema,
|
|
1402
1456
|
agentCandidateMaterializationReceiptSchema,
|
|
1403
1457
|
agentCandidateProfilePlanEvidenceSchema
|
|
@@ -1466,7 +1520,6 @@ async function readMaterializedWorkspaceFiles(root, expected, options = {}) {
|
|
|
1466
1520
|
}
|
|
1467
1521
|
function candidateWorkspaceManifest(files) {
|
|
1468
1522
|
return {
|
|
1469
|
-
schemaVersion: 2,
|
|
1470
1523
|
kind: "agent-candidate-workspace-manifest",
|
|
1471
1524
|
files: files.map((file) => ({
|
|
1472
1525
|
path: file.path,
|
|
@@ -1936,14 +1989,6 @@ function isNoEntry(error) {
|
|
|
1936
1989
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
1937
1990
|
}
|
|
1938
1991
|
|
|
1939
|
-
// src/candidate-execution/workspace-task.ts
|
|
1940
|
-
function workspaceTaskRepository(task) {
|
|
1941
|
-
if (task.outcome.kind !== "workspace" || !task.repository) {
|
|
1942
|
-
throw new Error("candidate runtime requires a workspace outcome with repository provenance");
|
|
1943
|
-
}
|
|
1944
|
-
return task.repository;
|
|
1945
|
-
}
|
|
1946
|
-
|
|
1947
1992
|
// src/candidate-execution/prepared-state.ts
|
|
1948
1993
|
var stateByExecution = /* @__PURE__ */ new WeakMap();
|
|
1949
1994
|
var lifecycleByExecution = /* @__PURE__ */ new WeakMap();
|
|
@@ -1952,9 +1997,11 @@ function createPreparedCandidateExecution(input) {
|
|
|
1952
1997
|
assertPrivateCandidateIntegrity(state);
|
|
1953
1998
|
const prepared = Object.freeze({
|
|
1954
1999
|
bundle: state.bundle,
|
|
2000
|
+
benchmark: Object.freeze({ suite: state.benchmarkSuite, task: state.benchmarkTask }),
|
|
1955
2001
|
executionId: state.executionId,
|
|
1956
2002
|
roots: state.roots,
|
|
1957
2003
|
profilePlan: evidenceView(state.profilePlan),
|
|
2004
|
+
profileActivation: state.profileActivation,
|
|
1958
2005
|
executionPlan: evidenceView(state.executionPlan),
|
|
1959
2006
|
materializationReceipt: state.materializationReceipt,
|
|
1960
2007
|
launch: state.launch,
|
|
@@ -2007,8 +2054,9 @@ function beginPreparedCandidateRun(prepared, modelAccess, memoryAccess) {
|
|
|
2007
2054
|
const material = state.executionPlan.value.material;
|
|
2008
2055
|
const request = Object.freeze({
|
|
2009
2056
|
executionId: state.executionId,
|
|
2057
|
+
benchmark: preparedBenchmark(state),
|
|
2010
2058
|
inputs: Object.freeze({
|
|
2011
|
-
task: workspaceInputView(
|
|
2059
|
+
task: workspaceInputView(state.benchmarkTask.workspace, state.executorInputs.taskFiles),
|
|
2012
2060
|
...material.candidateWorkspace && state.executorInputs.candidateFiles ? {
|
|
2013
2061
|
candidate: workspaceInputView(
|
|
2014
2062
|
material.candidateWorkspace,
|
|
@@ -2023,6 +2071,7 @@ function beginPreparedCandidateRun(prepared, modelAccess, memoryAccess) {
|
|
|
2023
2071
|
}),
|
|
2024
2072
|
roots: state.roots.execution,
|
|
2025
2073
|
profilePlan: evidenceView(state.profilePlan),
|
|
2074
|
+
profileActivation: state.profileActivation,
|
|
2026
2075
|
executionPlan: evidenceView(state.executionPlan),
|
|
2027
2076
|
materializationReceipt: state.materializationReceipt,
|
|
2028
2077
|
launch: immutableCandidateValue({ ...state.launch, env: completeEnvironment }),
|
|
@@ -2036,6 +2085,9 @@ function beginPreparedCandidateRun(prepared, modelAccess, memoryAccess) {
|
|
|
2036
2085
|
});
|
|
2037
2086
|
return { state, request };
|
|
2038
2087
|
}
|
|
2088
|
+
function preparedBenchmark(state) {
|
|
2089
|
+
return Object.freeze({ suite: state.benchmarkSuite, task: state.benchmarkTask });
|
|
2090
|
+
}
|
|
2039
2091
|
function consumePreparedCandidateExecution(prepared, outcome) {
|
|
2040
2092
|
transitionLifecycle(
|
|
2041
2093
|
prepared,
|
|
@@ -2048,10 +2100,16 @@ function beginPreparedCandidateSettlement(prepared) {
|
|
|
2048
2100
|
}
|
|
2049
2101
|
async function assertPreparedCandidateWorkspaces(state) {
|
|
2050
2102
|
const plan = state.executionPlan.value.material;
|
|
2051
|
-
await verifyMaterializedWorkspace(
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2103
|
+
await verifyMaterializedWorkspace(
|
|
2104
|
+
state.roots.staging.taskRoot,
|
|
2105
|
+
state.benchmarkTask.workspace.material,
|
|
2106
|
+
{
|
|
2107
|
+
ignoredProtectedRootEntries: [".git", ".sidecar"]
|
|
2108
|
+
}
|
|
2109
|
+
);
|
|
2110
|
+
if (state.benchmarkTask.repository) {
|
|
2111
|
+
await verifyTaskCheckout(state.roots.staging.taskRoot, state.benchmarkTask.repository);
|
|
2112
|
+
}
|
|
2055
2113
|
await verifyMaterializedProfileWorkspace(
|
|
2056
2114
|
state.roots.staging.profileRoot,
|
|
2057
2115
|
state.profilePlan.value.material
|
|
@@ -2065,9 +2123,19 @@ async function assertPreparedCandidateWorkspaces(state) {
|
|
|
2065
2123
|
}
|
|
2066
2124
|
}
|
|
2067
2125
|
function detachPreparedCandidateState(input) {
|
|
2126
|
+
const benchmarkSuite = immutableCandidateValue(
|
|
2127
|
+
agentCandidateBenchmarkSuiteSchema.parse(input.benchmarkSuite)
|
|
2128
|
+
);
|
|
2129
|
+
const benchmarkTask = immutableCandidateValue(
|
|
2130
|
+
agentCandidateBenchmarkTaskSchema.parse(input.benchmarkTask)
|
|
2131
|
+
);
|
|
2068
2132
|
const profilePlan = immutableCandidateValue(
|
|
2069
2133
|
agentCandidateProfilePlanEvidenceSchema.parse(input.profilePlan.value)
|
|
2070
2134
|
);
|
|
2135
|
+
const profileActivation = parseAgentCandidateProfileActivation(
|
|
2136
|
+
input.profileActivation,
|
|
2137
|
+
profilePlan.digest
|
|
2138
|
+
);
|
|
2071
2139
|
const executionPlan = immutableCandidateValue(
|
|
2072
2140
|
agentCandidateExecutionPlanEvidenceSchema.parse(input.executionPlan.value)
|
|
2073
2141
|
);
|
|
@@ -2083,6 +2151,8 @@ function detachPreparedCandidateState(input) {
|
|
|
2083
2151
|
return Object.freeze({
|
|
2084
2152
|
ports: input.ports,
|
|
2085
2153
|
bundle: input.bundle,
|
|
2154
|
+
benchmarkSuite,
|
|
2155
|
+
benchmarkTask,
|
|
2086
2156
|
executionId: input.executionId,
|
|
2087
2157
|
roots: immutableCandidateValue(input.roots),
|
|
2088
2158
|
profilePlan: Object.freeze({
|
|
@@ -2090,6 +2160,7 @@ function detachPreparedCandidateState(input) {
|
|
|
2090
2160
|
bytes: Uint8Array.from(input.profilePlan.bytes),
|
|
2091
2161
|
written: Object.freeze([...input.profilePlan.written])
|
|
2092
2162
|
}),
|
|
2163
|
+
profileActivation,
|
|
2093
2164
|
executionPlan: Object.freeze({
|
|
2094
2165
|
value: executionPlan,
|
|
2095
2166
|
bytes: Uint8Array.from(input.executionPlan.bytes)
|
|
@@ -2109,11 +2180,7 @@ function detachPreparedCandidateState(input) {
|
|
|
2109
2180
|
executorInputs: Object.freeze({
|
|
2110
2181
|
taskFiles: immutableExecutorFiles(input.executorInputs.taskFiles),
|
|
2111
2182
|
...input.executorInputs.candidateFiles ? { candidateFiles: immutableExecutorFiles(input.executorInputs.candidateFiles) } : {},
|
|
2112
|
-
profileFiles:
|
|
2113
|
-
input.executorInputs.profileFiles.map(
|
|
2114
|
-
(file) => Object.freeze({ ...file, bytes: Uint8Array.from(file.bytes) })
|
|
2115
|
-
)
|
|
2116
|
-
)
|
|
2183
|
+
profileFiles: immutableExecutorFiles(input.executorInputs.profileFiles)
|
|
2117
2184
|
}),
|
|
2118
2185
|
...input.memoryReservation ? { memoryReservation: immutableCandidateValue(input.memoryReservation) } : {},
|
|
2119
2186
|
...input.knowledge ? {
|
|
@@ -2134,6 +2201,7 @@ function assertPrivateCandidateIntegrity(state) {
|
|
|
2134
2201
|
throw new Error("prepared candidate bundle no longer matches its digest");
|
|
2135
2202
|
}
|
|
2136
2203
|
assertPlanEvidence(state.profilePlan.value, state.profilePlan.bytes, "profile plan");
|
|
2204
|
+
parseAgentCandidateProfileActivation(state.profileActivation, state.profilePlan.value.digest);
|
|
2137
2205
|
assertPlanEvidence(state.executionPlan.value, state.executionPlan.bytes, "execution plan");
|
|
2138
2206
|
agentCandidateExecutionPlanEvidenceSchema.parse(state.executionPlan.value);
|
|
2139
2207
|
const receipt = agentCandidateMaterializationReceiptSchema.parse(
|
|
@@ -2143,11 +2211,12 @@ function assertPrivateCandidateIntegrity(state) {
|
|
|
2143
2211
|
if (canonicalCandidateDigest(omitTopLevelDigest(receipt)) !== state.materializationReceipt.digest || !Buffer.from(receiptBytes).equals(Buffer.from(state.materializationReceipt.bytes))) {
|
|
2144
2212
|
throw new Error("prepared materialization receipt no longer matches its canonical bytes");
|
|
2145
2213
|
}
|
|
2146
|
-
|
|
2147
|
-
|
|
2214
|
+
assertSignedBenchmarkInput(state);
|
|
2215
|
+
const instruction = Buffer.from(state.benchmarkTask.instruction, "utf8");
|
|
2216
|
+
if (!Buffer.from(state.instruction.bytes).equals(instruction) || JSON.stringify(state.instruction.delivery) !== JSON.stringify(state.executionPlan.value.material.instructionDelivery)) {
|
|
2148
2217
|
throw new Error("prepared instruction no longer matches the signed execution plan");
|
|
2149
2218
|
}
|
|
2150
|
-
if (!/^candidate-preparation
|
|
2219
|
+
if (!/^candidate-preparation\.[A-Za-z0-9_-]{43}$/.test(state.preparationId) || !Number.isSafeInteger(state.reservationExpiresAtMs) || state.reservationExpiresAtMs <= 0 || !Number.isSafeInteger(state.cleanupTimeoutMs) || state.cleanupTimeoutMs <= 0 || !Number.isSafeInteger(state.resultTimeoutMs) || state.resultTimeoutMs <= 0 || JSON.stringify(state.resolvedModel) !== JSON.stringify(state.executionPlan.value.material.model.resolved) || state.modelReservation.digest !== state.executionPlan.value.material.model.access.grantDigest || state.modelReservation.preparationId !== state.preparationId || state.modelReservation.expiresAtMs !== state.reservationExpiresAtMs || canonicalCandidateDigest(state.modelReservation.network) !== canonicalCandidateDigest(state.executionPlan.value.material.model.access.network) || canonicalCandidateDigest(state.modelReservation.enforcedLimits) !== canonicalCandidateDigest(modelLimits(state.executionPlan.value.material.limits))) {
|
|
2151
2220
|
throw new Error("prepared model access no longer matches the signed execution plan");
|
|
2152
2221
|
}
|
|
2153
2222
|
assertExecutorInputs(state);
|
|
@@ -2175,7 +2244,7 @@ function assertPrivateCandidateIntegrity(state) {
|
|
|
2175
2244
|
[CANDIDATE_TRACE_ENV.traceRunId]: state.trace.runId
|
|
2176
2245
|
};
|
|
2177
2246
|
if (!state.trace.runId.startsWith(
|
|
2178
|
-
`${state.executionId}:attempt-${state.executionPlan.value.material.attempt
|
|
2247
|
+
`${state.executionId}:attempt-${state.executionPlan.value.material.runCell.attempt}:`
|
|
2179
2248
|
) || canonicalCandidateDigest(state.trace.tags) !== canonicalCandidateDigest(expectedTags) || canonicalCandidateDigest(state.trace.env) !== canonicalCandidateDigest(expectedTraceEnvironment)) {
|
|
2180
2249
|
throw new Error("prepared trace identity no longer matches the signed execution");
|
|
2181
2250
|
}
|
|
@@ -2220,7 +2289,7 @@ function knowledgeView(knowledge) {
|
|
|
2220
2289
|
function workspaceInputView(snapshot, sourceFiles) {
|
|
2221
2290
|
return Object.freeze({
|
|
2222
2291
|
snapshot,
|
|
2223
|
-
files: Object.freeze(sourceFiles.map((file) =>
|
|
2292
|
+
files: Object.freeze(sourceFiles.map((file) => executorFileView(file)))
|
|
2224
2293
|
});
|
|
2225
2294
|
}
|
|
2226
2295
|
function profileFileView(source) {
|
|
@@ -2233,9 +2302,22 @@ function profileFileView(source) {
|
|
|
2233
2302
|
}
|
|
2234
2303
|
});
|
|
2235
2304
|
}
|
|
2305
|
+
function executorFileView(source) {
|
|
2306
|
+
const bytes = Uint8Array.from(source.bytes);
|
|
2307
|
+
return Object.freeze({
|
|
2308
|
+
path: source.path,
|
|
2309
|
+
mode: source.mode,
|
|
2310
|
+
get bytes() {
|
|
2311
|
+
return Uint8Array.from(bytes);
|
|
2312
|
+
}
|
|
2313
|
+
});
|
|
2314
|
+
}
|
|
2236
2315
|
function assertExecutorInputs(state) {
|
|
2237
2316
|
const material = state.executionPlan.value.material;
|
|
2238
|
-
assertWorkspaceExecutorFiles(
|
|
2317
|
+
assertWorkspaceExecutorFiles(
|
|
2318
|
+
state.executorInputs.taskFiles,
|
|
2319
|
+
state.benchmarkTask.workspace.material
|
|
2320
|
+
);
|
|
2239
2321
|
if (material.candidateWorkspace) {
|
|
2240
2322
|
if (!state.executorInputs.candidateFiles) {
|
|
2241
2323
|
throw new Error("prepared candidate executor files are missing");
|
|
@@ -2293,6 +2375,22 @@ function assertWorkspaceExecutorFiles(actualFiles, expected) {
|
|
|
2293
2375
|
}
|
|
2294
2376
|
}
|
|
2295
2377
|
}
|
|
2378
|
+
function assertSignedBenchmarkInput(state) {
|
|
2379
|
+
const plan = state.executionPlan.value.material;
|
|
2380
|
+
const cell = plan.runCell;
|
|
2381
|
+
const suite = state.benchmarkSuite;
|
|
2382
|
+
const task = state.benchmarkTask;
|
|
2383
|
+
const receipt = state.materializationReceipt.value;
|
|
2384
|
+
const cellIndex = cell.taskIndex * suite.reps + cell.repetition;
|
|
2385
|
+
if (canonicalCandidateDigest(omitTopLevelDigest(suite)) !== suite.digest || canonicalCandidateDigest(omitTopLevelDigest(task)) !== task.digest || canonicalCandidateDigest(omitTopLevelDigest(cell)) !== cell.digest || cell.bundleDigest !== state.bundle.digest || cell.suiteDigest !== suite.digest || cell.taskDigest !== task.digest || suite.taskDigests[cell.taskIndex] !== task.digest || suite.seeds[cellIndex] !== cell.seed || cell.repetition >= suite.reps || cell.attempt < 1 || cell.attempt > task.attempt.maxAttempts) {
|
|
2386
|
+
throw new Error("prepared candidate no longer matches its signed experiment cell");
|
|
2387
|
+
}
|
|
2388
|
+
const suiteBytes = canonicalCandidateBytes(omitTopLevelDigest(suite));
|
|
2389
|
+
const taskBytes = canonicalCandidateBytes(omitTopLevelDigest(task));
|
|
2390
|
+
if (receipt.benchmark.suite.digest !== suite.digest || receipt.benchmark.suite.material.sha256 !== sha256Bytes(suiteBytes) || receipt.benchmark.suite.material.byteLength !== suiteBytes.byteLength || receipt.benchmark.task.digest !== task.digest || receipt.benchmark.task.material.sha256 !== sha256Bytes(taskBytes) || receipt.benchmark.task.material.byteLength !== taskBytes.byteLength) {
|
|
2391
|
+
throw new Error("materialization receipt no longer matches its signed benchmark input");
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2296
2394
|
function immutableExecutorFiles(files) {
|
|
2297
2395
|
return Object.freeze(
|
|
2298
2396
|
files.map((file) => Object.freeze({ ...file, bytes: Uint8Array.from(file.bytes) }))
|
|
@@ -2330,10 +2428,14 @@ function assertProtectedEnvironment(state, modelEnvironment, memoryEnvironment)
|
|
|
2330
2428
|
}
|
|
2331
2429
|
|
|
2332
2430
|
// src/candidate-execution/claim-plan.ts
|
|
2333
|
-
function candidateExecutionClaim(prepared) {
|
|
2431
|
+
function candidateExecutionClaim(prepared, preparationEvidence) {
|
|
2334
2432
|
const state = assertPreparedCandidateIntegrity(prepared);
|
|
2335
2433
|
const material = prepared.executionPlan.value.material;
|
|
2336
|
-
const attempt =
|
|
2434
|
+
const attempt = {
|
|
2435
|
+
number: material.runCell.attempt,
|
|
2436
|
+
maxAttempts: state.benchmarkTask.attempt.maxAttempts,
|
|
2437
|
+
retryPolicy: state.benchmarkTask.attempt.retryPolicy
|
|
2438
|
+
};
|
|
2337
2439
|
const nowMs = Date.now();
|
|
2338
2440
|
if (!Number.isSafeInteger(nowMs) || nowMs < 0) {
|
|
2339
2441
|
throw new Error("candidate execution claim-store clock returned an invalid timestamp");
|
|
@@ -2351,6 +2453,14 @@ function candidateExecutionClaim(prepared) {
|
|
|
2351
2453
|
"candidate preparation expires before its full execution and cleanup owner window"
|
|
2352
2454
|
);
|
|
2353
2455
|
}
|
|
2456
|
+
if (preparationEvidence.executionPlan.sha256 !== prepared.executionPlan.value.digest || preparationEvidence.executionPlan.byteLength !== state.executionPlan.bytes.byteLength) {
|
|
2457
|
+
throw new Error("persisted execution plan does not match its canonical preparation bytes");
|
|
2458
|
+
}
|
|
2459
|
+
if (preparationEvidence.materializationReceipt.sha256 !== state.materializationReceipt.digest || preparationEvidence.materializationReceipt.byteLength !== state.materializationReceipt.bytes.byteLength) {
|
|
2460
|
+
throw new Error(
|
|
2461
|
+
"persisted materialization receipt does not match its canonical preparation bytes"
|
|
2462
|
+
);
|
|
2463
|
+
}
|
|
2354
2464
|
return candidateClaimFileInternals.sealClaim({
|
|
2355
2465
|
executionId: prepared.executionId,
|
|
2356
2466
|
attempt: attempt.number,
|
|
@@ -2358,6 +2468,7 @@ function candidateExecutionClaim(prepared) {
|
|
|
2358
2468
|
retryPolicy: attempt.retryPolicy,
|
|
2359
2469
|
bundleDigest: prepared.bundle.digest,
|
|
2360
2470
|
executionPlanDigest: prepared.executionPlan.value.digest,
|
|
2471
|
+
preparationEvidence,
|
|
2361
2472
|
retryLineageDigest: retryLineageDigest(prepared, state.resultTimeoutMs),
|
|
2362
2473
|
leaseExpiresAtMs,
|
|
2363
2474
|
resultTimeoutMs: state.resultTimeoutMs,
|
|
@@ -2382,7 +2493,11 @@ function retryLineageDigest(prepared, resultTimeoutMs) {
|
|
|
2382
2493
|
resultTimeoutMs,
|
|
2383
2494
|
executionPlan: {
|
|
2384
2495
|
...material,
|
|
2385
|
-
|
|
2496
|
+
runCell: {
|
|
2497
|
+
...material.runCell,
|
|
2498
|
+
attempt: 0,
|
|
2499
|
+
digest: `sha256:${"0".repeat(64)}`
|
|
2500
|
+
},
|
|
2386
2501
|
model: {
|
|
2387
2502
|
...material.model,
|
|
2388
2503
|
access: {
|
|
@@ -2418,13 +2533,13 @@ function retryLineageDigest(prepared, resultTimeoutMs) {
|
|
|
2418
2533
|
|
|
2419
2534
|
// src/candidate-execution/output-artifacts.ts
|
|
2420
2535
|
import {
|
|
2421
|
-
agentCandidateArtifactRefSchema as
|
|
2536
|
+
agentCandidateArtifactRefSchema as agentCandidateArtifactRefSchema3
|
|
2422
2537
|
} from "@tangle-network/agent-interface";
|
|
2423
2538
|
async function persistCandidateOutputArtifact(port, input) {
|
|
2424
2539
|
input.signal?.throwIfAborted();
|
|
2425
2540
|
const bytes = Uint8Array.from(input.bytes);
|
|
2426
2541
|
const expectedDigest = sha256Bytes(bytes);
|
|
2427
|
-
const ref =
|
|
2542
|
+
const ref = agentCandidateArtifactRefSchema3.parse(
|
|
2428
2543
|
await port.put({
|
|
2429
2544
|
executionId: input.executionId,
|
|
2430
2545
|
purpose: input.purpose,
|
|
@@ -2447,6 +2562,7 @@ import {
|
|
|
2447
2562
|
agentCandidateTerminationSchema,
|
|
2448
2563
|
agentCandidateWorkspaceManifestMaterialSchema
|
|
2449
2564
|
} from "@tangle-network/agent-interface";
|
|
2565
|
+
var sealedFinalCaptureBrand = /* @__PURE__ */ Symbol("sealedAgentCandidateExecutorFinalCapture");
|
|
2450
2566
|
function sealAgentCandidateProtectedRunCapture(value) {
|
|
2451
2567
|
const capture = requireRecord(value, "candidate execution capture");
|
|
2452
2568
|
assertExactObjectKeys(capture, ["executionId", "termination"], "candidate execution capture");
|
|
@@ -2458,31 +2574,32 @@ function sealAgentCandidateProtectedRunCapture(value) {
|
|
|
2458
2574
|
termination: Object.freeze(agentCandidateTerminationSchema.parse(capture.termination))
|
|
2459
2575
|
});
|
|
2460
2576
|
}
|
|
2461
|
-
function sealAgentCandidateExecutorFinalCapture(value) {
|
|
2577
|
+
function sealAgentCandidateExecutorFinalCapture(value, expectedOutcome) {
|
|
2462
2578
|
const capture = requireRecord(value, "candidate final capture");
|
|
2463
|
-
assertExactObjectKeys(capture, [
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2579
|
+
assertExactObjectKeys(capture, [], "candidate final capture", [
|
|
2580
|
+
"taskOutcome",
|
|
2581
|
+
"memoryAfter",
|
|
2582
|
+
"evidence"
|
|
2583
|
+
]);
|
|
2584
|
+
const taskOutcome = capture.taskOutcome ? sealTaskOutcomeCapture(capture.taskOutcome, expectedOutcome) : void 0;
|
|
2468
2585
|
const memoryAfter = capture.memoryAfter ? sealMemoryCapture(capture.memoryAfter) : void 0;
|
|
2586
|
+
if (capture.evidence !== void 0 && !(capture.evidence instanceof Uint8Array)) {
|
|
2587
|
+
throw new Error("candidate executor evidence must be a byte array");
|
|
2588
|
+
}
|
|
2589
|
+
const evidence = capture.evidence ? Uint8Array.from(capture.evidence) : void 0;
|
|
2469
2590
|
return Object.freeze({
|
|
2470
|
-
stopped: true,
|
|
2471
2591
|
...taskOutcome ? { taskOutcome } : {},
|
|
2472
|
-
...memoryAfter ? { memoryAfter: Object.freeze(memoryAfter) } : {}
|
|
2592
|
+
...memoryAfter ? { memoryAfter: Object.freeze(memoryAfter) } : {},
|
|
2593
|
+
...evidence ? { evidence } : {},
|
|
2594
|
+
[sealedFinalCaptureBrand]: true
|
|
2473
2595
|
});
|
|
2474
2596
|
}
|
|
2475
|
-
function
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
termination: input.termination,
|
|
2482
|
-
stopped: true,
|
|
2483
|
-
taskOutcome: input.taskOutcome,
|
|
2484
|
-
...input.memoryAfter ? { memoryAfter: input.memoryAfter } : {}
|
|
2485
|
-
});
|
|
2597
|
+
function sealAgentCandidateExecutorStopAcknowledgement(value) {
|
|
2598
|
+
const capture = requireRecord(value, "candidate stop acknowledgement");
|
|
2599
|
+
assertExactObjectKeys(capture, ["stopped"], "candidate stop acknowledgement");
|
|
2600
|
+
if (capture.stopped !== true) {
|
|
2601
|
+
throw new Error("candidate stop acknowledgement does not prove process death");
|
|
2602
|
+
}
|
|
2486
2603
|
}
|
|
2487
2604
|
function sealMemoryCapture(value) {
|
|
2488
2605
|
const capture = requireRecord(value, "candidate memory capture");
|
|
@@ -2497,13 +2614,32 @@ function sealMemoryCapture(value) {
|
|
|
2497
2614
|
archive: Uint8Array.from(capture.archive)
|
|
2498
2615
|
});
|
|
2499
2616
|
}
|
|
2500
|
-
function sealTaskOutcomeCapture(value) {
|
|
2617
|
+
function sealTaskOutcomeCapture(value, expected) {
|
|
2501
2618
|
const capture = requireRecord(value, "candidate task capture");
|
|
2619
|
+
if (capture.kind === "output") {
|
|
2620
|
+
assertExactObjectKeys(capture, ["kind", "bytes"], "candidate task output capture");
|
|
2621
|
+
if (expected.kind !== "output") {
|
|
2622
|
+
throw new Error("candidate task output capture does not match the signed outcome kind");
|
|
2623
|
+
}
|
|
2624
|
+
if (!(capture.bytes instanceof Uint8Array)) {
|
|
2625
|
+
throw new Error("candidate task output capture must contain a byte array");
|
|
2626
|
+
}
|
|
2627
|
+
if (capture.bytes.byteLength > expected.maxBytes) {
|
|
2628
|
+
throw new Error(`candidate task output exceeds the frozen ${expected.maxBytes}-byte maximum`);
|
|
2629
|
+
}
|
|
2630
|
+
return Object.freeze({ kind: "output", bytes: Uint8Array.from(capture.bytes) });
|
|
2631
|
+
}
|
|
2502
2632
|
assertExactObjectKeys(
|
|
2503
2633
|
capture,
|
|
2504
|
-
["resultTree", "afterState", "archive", "gitDiff"],
|
|
2634
|
+
["kind", "resultTree", "afterState", "archive", "gitDiff"],
|
|
2505
2635
|
"candidate task capture"
|
|
2506
2636
|
);
|
|
2637
|
+
if (capture.kind !== "workspace") {
|
|
2638
|
+
throw new Error("candidate task capture has an invalid outcome kind");
|
|
2639
|
+
}
|
|
2640
|
+
if (expected.kind !== "workspace") {
|
|
2641
|
+
throw new Error("candidate workspace capture does not match the signed outcome kind");
|
|
2642
|
+
}
|
|
2507
2643
|
if (typeof capture.resultTree !== "string" || !/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(capture.resultTree)) {
|
|
2508
2644
|
throw new Error("candidate task capture resultTree is not a Git object id");
|
|
2509
2645
|
}
|
|
@@ -2512,6 +2648,7 @@ function sealTaskOutcomeCapture(value) {
|
|
|
2512
2648
|
}
|
|
2513
2649
|
const afterState = agentCandidateWorkspaceManifestMaterialSchema.parse(capture.afterState);
|
|
2514
2650
|
return Object.freeze({
|
|
2651
|
+
kind: "workspace",
|
|
2515
2652
|
resultTree: capture.resultTree,
|
|
2516
2653
|
afterState: Object.freeze(afterState),
|
|
2517
2654
|
archive: Uint8Array.from(capture.archive),
|
|
@@ -2526,11 +2663,11 @@ function requireRecord(value, label) {
|
|
|
2526
2663
|
}
|
|
2527
2664
|
|
|
2528
2665
|
// src/candidate-execution/finalize.ts
|
|
2529
|
-
import { mkdtemp as mkdtemp2, rm as rm2 } from "fs/promises";
|
|
2530
|
-
import { tmpdir as tmpdir2 } from "os";
|
|
2531
|
-
import { join as join2 } from "path";
|
|
2532
2666
|
import { isLlmSpan as isLlmSpan2, REDACTION_VERSION as REDACTION_VERSION2 } from "@tangle-network/agent-eval";
|
|
2533
|
-
import {
|
|
2667
|
+
import {
|
|
2668
|
+
agentCandidateRunReceiptSchema,
|
|
2669
|
+
agentCandidateWorkspaceSnapshotEvidenceSchema
|
|
2670
|
+
} from "@tangle-network/agent-interface";
|
|
2534
2671
|
|
|
2535
2672
|
// src/candidate-execution/model-settlement.ts
|
|
2536
2673
|
import { isLlmSpan } from "@tangle-network/agent-eval";
|
|
@@ -2557,7 +2694,6 @@ function sealAgentCandidateModelSettlement(settlement, expected) {
|
|
|
2557
2694
|
let outputTokens = 0;
|
|
2558
2695
|
let cachedInputTokens = 0;
|
|
2559
2696
|
let reasoningTokens = 0;
|
|
2560
|
-
let hasCachedInput = false;
|
|
2561
2697
|
let costUsdNanos = 0;
|
|
2562
2698
|
const calls = settlement.calls.map((source, index) => {
|
|
2563
2699
|
assertExactObjectKeys(
|
|
@@ -2610,7 +2746,6 @@ function sealAgentCandidateModelSettlement(settlement, expected) {
|
|
|
2610
2746
|
source.cachedInputTokens,
|
|
2611
2747
|
"cached input token total"
|
|
2612
2748
|
);
|
|
2613
|
-
hasCachedInput = true;
|
|
2614
2749
|
assertCount2(source.reasoningTokens, `model settlement call ${index} reasoningTokens`);
|
|
2615
2750
|
reasoningTokens = safeAdd(reasoningTokens, source.reasoningTokens, "reasoning token total");
|
|
2616
2751
|
assertCount2(source.costUsdNanos, `model settlement call ${index} costUsdNanos`);
|
|
@@ -2620,13 +2755,6 @@ function sealAgentCandidateModelSettlement(settlement, expected) {
|
|
|
2620
2755
|
return Object.freeze({ ...source });
|
|
2621
2756
|
});
|
|
2622
2757
|
const usage = Object.freeze({
|
|
2623
|
-
costUsd: costUsdNanos / USD_NANOS,
|
|
2624
|
-
inputTokens,
|
|
2625
|
-
outputTokens,
|
|
2626
|
-
...hasCachedInput ? { cachedInputTokens } : {},
|
|
2627
|
-
modelCalls: calls.length
|
|
2628
|
-
});
|
|
2629
|
-
const fixedUsage = Object.freeze({
|
|
2630
2758
|
costUsdNanos,
|
|
2631
2759
|
inputTokens,
|
|
2632
2760
|
outputTokens,
|
|
@@ -2641,9 +2769,7 @@ function sealAgentCandidateModelSettlement(settlement, expected) {
|
|
|
2641
2769
|
closed: true,
|
|
2642
2770
|
calls: Object.freeze(calls)
|
|
2643
2771
|
}),
|
|
2644
|
-
usage
|
|
2645
|
-
fixedUsage,
|
|
2646
|
-
costUsdNanos
|
|
2772
|
+
usage
|
|
2647
2773
|
});
|
|
2648
2774
|
}
|
|
2649
2775
|
async function appendAuthoritativeModelSettlementSpans(traceStore, runId, settlement) {
|
|
@@ -2904,66 +3030,15 @@ function escapeRegularExpression(value) {
|
|
|
2904
3030
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2905
3031
|
}
|
|
2906
3032
|
|
|
2907
|
-
// src/candidate-execution/workspace-snapshot.ts
|
|
2908
|
-
import {
|
|
2909
|
-
agentCandidateWorkspaceManifestMaterialSchema as agentCandidateWorkspaceManifestMaterialSchema2,
|
|
2910
|
-
agentCandidateWorkspaceSnapshotEvidenceSchema
|
|
2911
|
-
} from "@tangle-network/agent-interface";
|
|
2912
|
-
function provisionalCandidateWorkspaceSnapshot(materialInput, archive) {
|
|
2913
|
-
const material = immutableCandidateValue(
|
|
2914
|
-
agentCandidateWorkspaceManifestMaterialSchema2.parse(materialInput)
|
|
2915
|
-
);
|
|
2916
|
-
const manifestBytes = canonicalCandidateBytes(material);
|
|
2917
|
-
const snapshot = Object.freeze({
|
|
2918
|
-
schemaVersion: 2,
|
|
2919
|
-
kind: "agent-candidate-workspace-snapshot",
|
|
2920
|
-
digest: sha256Bytes(manifestBytes),
|
|
2921
|
-
material,
|
|
2922
|
-
manifest: Object.freeze(embeddedCandidateArtifact(manifestBytes)),
|
|
2923
|
-
archive: Object.freeze(embeddedCandidateArtifact(archive))
|
|
2924
|
-
});
|
|
2925
|
-
return Object.freeze({ material, manifestBytes, snapshot });
|
|
2926
|
-
}
|
|
2927
|
-
async function persistCandidateWorkspaceSnapshot(port, input) {
|
|
2928
|
-
input.signal?.throwIfAborted();
|
|
2929
|
-
const material = immutableCandidateValue(input.material);
|
|
2930
|
-
const manifestBytes = canonicalCandidateBytes(material);
|
|
2931
|
-
const [manifest, archive] = await Promise.all([
|
|
2932
|
-
persistCandidateOutputArtifact(port, {
|
|
2933
|
-
executionId: input.executionId,
|
|
2934
|
-
purpose: input.purpose === "task" ? "task-manifest" : "memory-after-manifest",
|
|
2935
|
-
bytes: manifestBytes,
|
|
2936
|
-
...input.signal ? { signal: input.signal } : {}
|
|
2937
|
-
}),
|
|
2938
|
-
persistCandidateOutputArtifact(port, {
|
|
2939
|
-
executionId: input.executionId,
|
|
2940
|
-
purpose: input.purpose === "task" ? "task-archive" : "memory-after-archive",
|
|
2941
|
-
bytes: input.archive,
|
|
2942
|
-
...input.signal ? { signal: input.signal } : {}
|
|
2943
|
-
})
|
|
2944
|
-
]);
|
|
2945
|
-
return immutableCandidateValue(
|
|
2946
|
-
agentCandidateWorkspaceSnapshotEvidenceSchema.parse({
|
|
2947
|
-
schemaVersion: 2,
|
|
2948
|
-
kind: "agent-candidate-workspace-snapshot",
|
|
2949
|
-
digest: sha256Bytes(manifestBytes),
|
|
2950
|
-
material,
|
|
2951
|
-
manifest,
|
|
2952
|
-
archive
|
|
2953
|
-
})
|
|
2954
|
-
);
|
|
2955
|
-
}
|
|
2956
|
-
|
|
2957
3033
|
// src/candidate-execution/finalize.ts
|
|
2958
3034
|
async function finalizeAgentCandidateRun(state, capture, traceStore, settlement, evidence, protectedValues, writeRedactionReport, signal) {
|
|
2959
3035
|
let termination;
|
|
2960
3036
|
try {
|
|
2961
3037
|
signal?.throwIfAborted();
|
|
2962
|
-
|
|
2963
|
-
if (protectedCapture.executionId !== state.executionId) {
|
|
3038
|
+
if (capture.executionId !== state.executionId) {
|
|
2964
3039
|
throw new Error("protected capture execution id does not match the prepared execution");
|
|
2965
3040
|
}
|
|
2966
|
-
termination =
|
|
3041
|
+
termination = capture.termination;
|
|
2967
3042
|
if (termination.kind === "timeout" && termination.timeoutMs !== state.executionPlan.value.material.limits.timeoutMs) {
|
|
2968
3043
|
throw new Error("timeout termination does not match the frozen execution limit");
|
|
2969
3044
|
}
|
|
@@ -2994,31 +3069,14 @@ async function finalizeAgentCandidateRun(state, capture, traceStore, settlement,
|
|
|
2994
3069
|
const modelSpans = orderedSpans.filter(isLlmSpan2);
|
|
2995
3070
|
assertTraceMatchesModelSettlement(modelSpans, settlement);
|
|
2996
3071
|
enforceLimits(state, run.startedAt, run.endedAt, orderedSpans, settlement);
|
|
2997
|
-
const finalCapture = sealAgentCandidateExecutorFinalCapture(evidence.finalCapture);
|
|
2998
3072
|
const memory = await memoryReceipt(
|
|
2999
3073
|
state,
|
|
3000
|
-
finalCapture,
|
|
3001
|
-
evidence.
|
|
3002
|
-
protectedValues,
|
|
3074
|
+
evidence.finalCapture,
|
|
3075
|
+
evidence.persistedCapture.memoryAfter,
|
|
3003
3076
|
signal
|
|
3004
3077
|
);
|
|
3005
|
-
const executorCaptureBytes = encodeAgentCandidateExecutorCapture({
|
|
3006
|
-
executionId: protectedCapture.executionId,
|
|
3007
|
-
executionPlanDigest: state.executionPlan.value.digest,
|
|
3008
|
-
termination: protectedCapture.termination,
|
|
3009
|
-
taskOutcome: evidence.taskOutcome.evidence,
|
|
3010
|
-
...memory.mode === "isolated" ? { memoryAfter: memory.afterState } : {}
|
|
3011
|
-
});
|
|
3012
|
-
assertNoProtectedBytes(executorCaptureBytes, protectedValues);
|
|
3013
|
-
const executorCapture = await persistCandidateOutputArtifact(evidence.outputArtifacts, {
|
|
3014
|
-
executionId: state.executionId,
|
|
3015
|
-
purpose: "executor-capture",
|
|
3016
|
-
bytes: executorCaptureBytes,
|
|
3017
|
-
signal
|
|
3018
|
-
});
|
|
3019
3078
|
const redacted = redactProtectedValue(
|
|
3020
3079
|
{
|
|
3021
|
-
schemaVersion: 1,
|
|
3022
3080
|
run: { ...run, redactionVersion: REDACTION_VERSION2 },
|
|
3023
3081
|
spans: orderedSpans,
|
|
3024
3082
|
events: orderedEvents,
|
|
@@ -3049,22 +3107,26 @@ async function finalizeAgentCandidateRun(state, capture, traceStore, settlement,
|
|
|
3049
3107
|
signal
|
|
3050
3108
|
});
|
|
3051
3109
|
const trace = {
|
|
3052
|
-
schemaVersion: 1,
|
|
3053
3110
|
artifact: traceArtifact,
|
|
3054
3111
|
eventCount: 1 + orderedSpans.length + orderedEvents.length + orderedBudget.length + orderedArtifacts.length,
|
|
3055
3112
|
modelCallCount: modelSpans.length
|
|
3056
3113
|
};
|
|
3057
3114
|
const document = canonicalCandidateDocument({
|
|
3058
|
-
schemaVersion: 3,
|
|
3059
3115
|
kind: "agent-candidate-run",
|
|
3060
3116
|
digestAlgorithm: "rfc8785-sha256",
|
|
3061
3117
|
bundleDigest: state.bundle.digest,
|
|
3118
|
+
runCellDigest: state.executionPlan.value.material.runCell.digest,
|
|
3062
3119
|
materializationReceiptDigest: state.materializationReceipt.digest,
|
|
3063
3120
|
executionPlanDigest: state.executionPlan.value.digest,
|
|
3121
|
+
timing: {
|
|
3122
|
+
startedAtMs: run.startedAt,
|
|
3123
|
+
endedAtMs: run.endedAt,
|
|
3124
|
+
durationMs: run.endedAt - run.startedAt
|
|
3125
|
+
},
|
|
3064
3126
|
memory,
|
|
3065
3127
|
trace,
|
|
3066
3128
|
termination,
|
|
3067
|
-
executorCapture,
|
|
3129
|
+
executorCapture: evidence.persistedCapture.evidence,
|
|
3068
3130
|
modelSettlement: evidence.modelSettlement,
|
|
3069
3131
|
taskOutcome: evidence.taskOutcome.evidence,
|
|
3070
3132
|
benchmarkResult: evidence.benchmarkResult
|
|
@@ -3080,8 +3142,8 @@ async function finalizeAgentCandidateRun(state, capture, traceStore, settlement,
|
|
|
3080
3142
|
succeeded: true,
|
|
3081
3143
|
receipt: document,
|
|
3082
3144
|
artifacts: {
|
|
3083
|
-
executorCapture,
|
|
3084
3145
|
modelSettlement: evidence.modelSettlement.artifact,
|
|
3146
|
+
executorCapture: evidence.persistedCapture.evidence,
|
|
3085
3147
|
taskOutcome: evidence.taskOutcome.evidence.artifact,
|
|
3086
3148
|
benchmarkResult: evidence.benchmarkResult.artifact,
|
|
3087
3149
|
runReceipt
|
|
@@ -3126,45 +3188,30 @@ function enforceLimits(state, startedAt, endedAt, spans, settlement) {
|
|
|
3126
3188
|
for (const [actual, limit, label] of checks) {
|
|
3127
3189
|
if (actual > limit) throw new Error(`protected ${label} ${actual} exceeds ${limit}`);
|
|
3128
3190
|
}
|
|
3129
|
-
if (
|
|
3130
|
-
throw new Error(
|
|
3191
|
+
if (usage.costUsdNanos > usdToNanos(limits.maxCostUsd, "frozen maxCostUsd")) {
|
|
3192
|
+
throw new Error(
|
|
3193
|
+
`protected cost USD ${usage.costUsdNanos / 1e9} exceeds ${limits.maxCostUsd}`
|
|
3194
|
+
);
|
|
3131
3195
|
}
|
|
3132
3196
|
}
|
|
3133
|
-
async function memoryReceipt(state, capture,
|
|
3197
|
+
async function memoryReceipt(state, capture, persisted, signal) {
|
|
3134
3198
|
signal?.throwIfAborted();
|
|
3135
3199
|
if (state.memory.mode === "disabled") {
|
|
3136
|
-
if (capture.memoryAfter !== void 0) {
|
|
3200
|
+
if (capture.memoryAfter !== void 0 || persisted !== void 0) {
|
|
3137
3201
|
throw new Error("disabled memory cannot return an after-state");
|
|
3138
3202
|
}
|
|
3139
3203
|
return { mode: "disabled" };
|
|
3140
3204
|
}
|
|
3141
3205
|
if (!capture.memoryAfter) throw new Error("isolated memory is missing its protected after-state");
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
const
|
|
3145
|
-
const
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
const root = await mkdtemp2(join2(tmpdir2(), "agent-candidate-memory-after-"));
|
|
3149
|
-
try {
|
|
3150
|
-
await state.ports.workspaces.materialize({
|
|
3151
|
-
role: "memory",
|
|
3152
|
-
snapshot: provisional.snapshot,
|
|
3153
|
-
archive: Uint8Array.from(archive),
|
|
3154
|
-
destination: root
|
|
3155
|
-
});
|
|
3156
|
-
const files = await readMaterializedWorkspaceFiles(root, afterState);
|
|
3157
|
-
for (const file of files) assertNoProtectedBytes(file.bytes, protectedValues);
|
|
3158
|
-
signal?.throwIfAborted();
|
|
3159
|
-
} finally {
|
|
3160
|
-
await rm2(root, { recursive: true, force: true });
|
|
3161
|
-
}
|
|
3162
|
-
const snapshot = await persistCandidateWorkspaceSnapshot(outputArtifacts, {
|
|
3163
|
-
executionId: state.executionId,
|
|
3206
|
+
if (!persisted) throw new Error("isolated memory is missing persisted capture evidence");
|
|
3207
|
+
const afterState = capture.memoryAfter.afterState;
|
|
3208
|
+
const manifestBytes = canonicalCandidateBytes(afterState);
|
|
3209
|
+
const snapshot = agentCandidateWorkspaceSnapshotEvidenceSchema.parse({
|
|
3210
|
+
kind: "agent-candidate-workspace-snapshot",
|
|
3211
|
+
digest: sha256Bytes(manifestBytes),
|
|
3164
3212
|
material: afterState,
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
signal
|
|
3213
|
+
manifest: persisted.manifest,
|
|
3214
|
+
archive: persisted.archive
|
|
3168
3215
|
});
|
|
3169
3216
|
return {
|
|
3170
3217
|
mode: "isolated",
|
|
@@ -3194,19 +3241,20 @@ function compareStrings(a, b) {
|
|
|
3194
3241
|
}
|
|
3195
3242
|
|
|
3196
3243
|
// src/candidate-execution/outcome-evidence.ts
|
|
3197
|
-
import { mkdtemp as
|
|
3198
|
-
import { tmpdir as
|
|
3199
|
-
import { join as
|
|
3244
|
+
import { mkdtemp as mkdtemp2, rm as rm2 } from "fs/promises";
|
|
3245
|
+
import { tmpdir as tmpdir2 } from "os";
|
|
3246
|
+
import { join as join2 } from "path";
|
|
3200
3247
|
import {
|
|
3201
3248
|
agentCandidateBenchmarkResultEvidenceSchema,
|
|
3202
3249
|
agentCandidateModelSettlementEvidenceSchema,
|
|
3203
|
-
agentCandidateTaskOutcomeEvidenceSchema
|
|
3250
|
+
agentCandidateTaskOutcomeEvidenceSchema,
|
|
3251
|
+
agentCandidateWorkspaceSnapshotEvidenceSchema as agentCandidateWorkspaceSnapshotEvidenceSchema2
|
|
3204
3252
|
} from "@tangle-network/agent-interface";
|
|
3205
3253
|
|
|
3206
3254
|
// src/candidate-execution/benchmark-grader.ts
|
|
3207
3255
|
async function runBoundCandidateBenchmarkGrader(input) {
|
|
3208
3256
|
input.signal?.throwIfAborted();
|
|
3209
|
-
const descriptor = snapshotGraderDescriptor(input.grader);
|
|
3257
|
+
const descriptor = snapshotGraderDescriptor(input.grader, input.expectedGrader);
|
|
3210
3258
|
const implementationBytes = await readVerifiedArtifact(descriptor.artifact, input.artifacts);
|
|
3211
3259
|
if (implementationBytes.byteLength === 0) {
|
|
3212
3260
|
throw new Error("candidate benchmark grader implementation cannot be empty");
|
|
@@ -3214,6 +3262,7 @@ async function runBoundCandidateBenchmarkGrader(input) {
|
|
|
3214
3262
|
const expectedImplementationDigest = sha256Bytes(implementationBytes);
|
|
3215
3263
|
const termination = immutableCandidateValue(input.termination);
|
|
3216
3264
|
const run = input.grader.run;
|
|
3265
|
+
const startedAtMs = Date.now();
|
|
3217
3266
|
const result = await run(
|
|
3218
3267
|
Object.freeze({
|
|
3219
3268
|
executionId: input.executionId,
|
|
@@ -3223,6 +3272,7 @@ async function runBoundCandidateBenchmarkGrader(input) {
|
|
|
3223
3272
|
signal: input.signal ?? new AbortController().signal
|
|
3224
3273
|
})
|
|
3225
3274
|
);
|
|
3275
|
+
const endedAtMs = Math.max(startedAtMs, Date.now());
|
|
3226
3276
|
input.signal?.throwIfAborted();
|
|
3227
3277
|
assertExactRunnerResult(result);
|
|
3228
3278
|
const evidence = Uint8Array.from(result.evidence);
|
|
@@ -3242,19 +3292,42 @@ async function runBoundCandidateBenchmarkGrader(input) {
|
|
|
3242
3292
|
}
|
|
3243
3293
|
return Object.freeze({
|
|
3244
3294
|
grader: descriptor,
|
|
3295
|
+
grading: immutableCandidateValue({
|
|
3296
|
+
usage: emptyFixedSpend(),
|
|
3297
|
+
timing: {
|
|
3298
|
+
startedAtMs,
|
|
3299
|
+
endedAtMs,
|
|
3300
|
+
durationMs: endedAtMs - startedAtMs
|
|
3301
|
+
}
|
|
3302
|
+
}),
|
|
3245
3303
|
evaluation: result.evaluation,
|
|
3246
3304
|
evidence
|
|
3247
3305
|
});
|
|
3248
3306
|
}
|
|
3249
|
-
function snapshotGraderDescriptor(grader) {
|
|
3307
|
+
function snapshotGraderDescriptor(grader, expected) {
|
|
3250
3308
|
if (!grader.name || !grader.version) {
|
|
3251
3309
|
throw new Error("candidate benchmark grader name and version must be non-empty");
|
|
3252
3310
|
}
|
|
3253
|
-
|
|
3311
|
+
const actual = {
|
|
3254
3312
|
name: grader.name,
|
|
3255
3313
|
version: grader.version,
|
|
3314
|
+
format: "tangle-grader",
|
|
3256
3315
|
artifact: grader.artifact
|
|
3257
|
-
}
|
|
3316
|
+
};
|
|
3317
|
+
if (canonicalCandidateDigest(actual) !== canonicalCandidateDigest(expected)) {
|
|
3318
|
+
throw new Error("candidate benchmark grader does not match the signed task grader");
|
|
3319
|
+
}
|
|
3320
|
+
return immutableCandidateValue(expected);
|
|
3321
|
+
}
|
|
3322
|
+
function emptyFixedSpend() {
|
|
3323
|
+
return {
|
|
3324
|
+
inputTokens: 0,
|
|
3325
|
+
outputTokens: 0,
|
|
3326
|
+
cachedInputTokens: 0,
|
|
3327
|
+
reasoningTokens: 0,
|
|
3328
|
+
modelCalls: 0,
|
|
3329
|
+
costUsdNanos: 0
|
|
3330
|
+
};
|
|
3258
3331
|
}
|
|
3259
3332
|
function detachedImplementation(bytes) {
|
|
3260
3333
|
const stored = Uint8Array.from(bytes);
|
|
@@ -3286,6 +3359,104 @@ function assertExactRunnerResult(value) {
|
|
|
3286
3359
|
}
|
|
3287
3360
|
}
|
|
3288
3361
|
|
|
3362
|
+
// src/candidate-execution/executor-capture-evidence.ts
|
|
3363
|
+
async function persistAgentCandidateExecutorCapture(identity, expected, capture, outputArtifacts, signal) {
|
|
3364
|
+
const executorEvidence = capture.evidence ? await persistCandidateOutputArtifact(outputArtifacts, {
|
|
3365
|
+
executionId: identity.executionId,
|
|
3366
|
+
purpose: "executor-native-evidence",
|
|
3367
|
+
bytes: capture.evidence,
|
|
3368
|
+
signal
|
|
3369
|
+
}) : void 0;
|
|
3370
|
+
const taskOutcome = capture.taskOutcome ? await persistTaskCapture(
|
|
3371
|
+
identity.executionId,
|
|
3372
|
+
expected,
|
|
3373
|
+
capture.taskOutcome,
|
|
3374
|
+
outputArtifacts,
|
|
3375
|
+
signal
|
|
3376
|
+
) : void 0;
|
|
3377
|
+
const memoryAfter = capture.memoryAfter ? await persistWorkspaceCapture(
|
|
3378
|
+
identity.executionId,
|
|
3379
|
+
"memory-after-manifest",
|
|
3380
|
+
"memory-after-archive",
|
|
3381
|
+
capture.memoryAfter.afterState,
|
|
3382
|
+
capture.memoryAfter.archive,
|
|
3383
|
+
outputArtifacts,
|
|
3384
|
+
signal
|
|
3385
|
+
) : void 0;
|
|
3386
|
+
const bytes = canonicalCandidateBytes({
|
|
3387
|
+
kind: "agent-candidate-executor-capture",
|
|
3388
|
+
executionPlanDigest: identity.executionPlanDigest,
|
|
3389
|
+
...executorEvidence ? { executorEvidence } : {},
|
|
3390
|
+
...taskOutcome ? { taskOutcome } : {},
|
|
3391
|
+
...memoryAfter ? { memoryAfter } : {}
|
|
3392
|
+
});
|
|
3393
|
+
const evidence = await persistCandidateOutputArtifact(outputArtifacts, {
|
|
3394
|
+
executionId: identity.executionId,
|
|
3395
|
+
purpose: "executor-capture",
|
|
3396
|
+
bytes,
|
|
3397
|
+
signal
|
|
3398
|
+
});
|
|
3399
|
+
return Object.freeze({
|
|
3400
|
+
evidence,
|
|
3401
|
+
...taskOutcome ? { taskOutcome: Object.freeze(taskOutcome) } : {},
|
|
3402
|
+
...memoryAfter ? { memoryAfter: Object.freeze(memoryAfter) } : {}
|
|
3403
|
+
});
|
|
3404
|
+
}
|
|
3405
|
+
async function persistTaskCapture(executionId, expected, capture, outputArtifacts, signal) {
|
|
3406
|
+
if (capture.kind === "output") {
|
|
3407
|
+
if (expected.kind !== "output")
|
|
3408
|
+
throw new Error("captured output does not match the signed task");
|
|
3409
|
+
const artifact = await persistCandidateOutputArtifact(outputArtifacts, {
|
|
3410
|
+
executionId,
|
|
3411
|
+
purpose: "task-output",
|
|
3412
|
+
bytes: capture.bytes,
|
|
3413
|
+
signal
|
|
3414
|
+
});
|
|
3415
|
+
return {
|
|
3416
|
+
kind: "output",
|
|
3417
|
+
spec: { mediaType: expected.mediaType, maxBytes: expected.maxBytes },
|
|
3418
|
+
artifact
|
|
3419
|
+
};
|
|
3420
|
+
}
|
|
3421
|
+
if (expected.kind !== "workspace") {
|
|
3422
|
+
throw new Error("captured workspace does not match the signed task");
|
|
3423
|
+
}
|
|
3424
|
+
const workspace = await persistWorkspaceCapture(
|
|
3425
|
+
executionId,
|
|
3426
|
+
"task-manifest",
|
|
3427
|
+
"task-archive",
|
|
3428
|
+
capture.afterState,
|
|
3429
|
+
capture.archive,
|
|
3430
|
+
outputArtifacts,
|
|
3431
|
+
signal
|
|
3432
|
+
);
|
|
3433
|
+
const gitDiff = await persistCandidateOutputArtifact(outputArtifacts, {
|
|
3434
|
+
executionId,
|
|
3435
|
+
purpose: "task-patch",
|
|
3436
|
+
bytes: capture.gitDiff,
|
|
3437
|
+
signal
|
|
3438
|
+
});
|
|
3439
|
+
return { kind: "workspace", resultTree: capture.resultTree, ...workspace, gitDiff };
|
|
3440
|
+
}
|
|
3441
|
+
async function persistWorkspaceCapture(executionId, manifestPurpose, archivePurpose, afterState, archiveBytes, outputArtifacts, signal) {
|
|
3442
|
+
const manifestBytes = canonicalCandidateBytes(afterState);
|
|
3443
|
+
const [manifest, archive] = await Promise.all([
|
|
3444
|
+
persistCandidateOutputArtifact(outputArtifacts, {
|
|
3445
|
+
executionId,
|
|
3446
|
+
purpose: manifestPurpose,
|
|
3447
|
+
bytes: manifestBytes,
|
|
3448
|
+
signal
|
|
3449
|
+
}),
|
|
3450
|
+
persistCandidateOutputArtifact(outputArtifacts, {
|
|
3451
|
+
executionId,
|
|
3452
|
+
purpose: archivePurpose,
|
|
3453
|
+
bytes: archiveBytes,
|
|
3454
|
+
signal
|
|
3455
|
+
})
|
|
3456
|
+
]);
|
|
3457
|
+
return { afterState, manifest, archive };
|
|
3458
|
+
}
|
|
3459
|
+
|
|
3289
3460
|
// src/candidate-execution/outcome-evidence.ts
|
|
3290
3461
|
async function persistCandidateModelSettlement(state, settlement, outputArtifacts) {
|
|
3291
3462
|
return await persistCandidateModelSettlementEvidence(
|
|
@@ -3300,7 +3471,6 @@ async function persistCandidateModelSettlement(state, settlement, outputArtifact
|
|
|
3300
3471
|
}
|
|
3301
3472
|
async function persistCandidateModelSettlementEvidence(identity, settlement, outputArtifacts) {
|
|
3302
3473
|
const material = {
|
|
3303
|
-
schemaVersion: 2,
|
|
3304
3474
|
kind: "agent-candidate-model-settlement-material",
|
|
3305
3475
|
executionPlanDigest: identity.executionPlanDigest,
|
|
3306
3476
|
preparationId: settlement.value.preparationId,
|
|
@@ -3321,7 +3491,7 @@ async function persistCandidateModelSettlementEvidence(identity, settlement, out
|
|
|
3321
3491
|
reasoningTokens: call.reasoningTokens ?? 0,
|
|
3322
3492
|
costUsdNanos: call.costUsdNanos
|
|
3323
3493
|
})),
|
|
3324
|
-
usage: settlement.
|
|
3494
|
+
usage: settlement.usage
|
|
3325
3495
|
};
|
|
3326
3496
|
const bytes = canonicalCandidateBytes(material);
|
|
3327
3497
|
const digest = sha256Bytes(bytes);
|
|
@@ -3332,7 +3502,6 @@ async function persistCandidateModelSettlementEvidence(identity, settlement, out
|
|
|
3332
3502
|
});
|
|
3333
3503
|
return immutableCandidateValue(
|
|
3334
3504
|
agentCandidateModelSettlementEvidenceSchema.parse({
|
|
3335
|
-
schemaVersion: 2,
|
|
3336
3505
|
kind: "agent-candidate-model-settlement",
|
|
3337
3506
|
digest,
|
|
3338
3507
|
material,
|
|
@@ -3340,16 +3509,53 @@ async function persistCandidateModelSettlementEvidence(identity, settlement, out
|
|
|
3340
3509
|
})
|
|
3341
3510
|
);
|
|
3342
3511
|
}
|
|
3343
|
-
async function
|
|
3512
|
+
async function persistVerifiedAgentCandidateExecutorCapture(state, capture, outputArtifacts, protectedValues, signal) {
|
|
3344
3513
|
signal?.throwIfAborted();
|
|
3514
|
+
const taskCapture = capture.taskOutcome;
|
|
3515
|
+
if (!taskCapture) throw new Error("candidate final capture is missing the task outcome");
|
|
3516
|
+
if (capture.evidence) assertNoProtectedBytes(capture.evidence, protectedValues);
|
|
3517
|
+
const expected = state.benchmarkTask.outcome;
|
|
3518
|
+
if (taskCapture.kind !== expected.kind) {
|
|
3519
|
+
throw new Error(
|
|
3520
|
+
`candidate captured ${taskCapture.kind} outcome does not match expected ${expected.kind} outcome`
|
|
3521
|
+
);
|
|
3522
|
+
}
|
|
3523
|
+
const verified = taskCapture.kind === "output" && expected.kind === "output" ? verifyOutputTaskCapture(taskCapture.bytes, expected, protectedValues) : taskCapture.kind === "workspace" && expected.kind === "workspace" ? await verifyWorkspaceTaskCapture(state, taskCapture, protectedValues, signal) : void 0;
|
|
3524
|
+
if (!verified) throw new Error("candidate task outcome kind could not be narrowed");
|
|
3525
|
+
await verifyMemoryCapture(state, capture, protectedValues, signal);
|
|
3526
|
+
const persistedCapture = await persistAgentCandidateExecutorCapture(
|
|
3527
|
+
{
|
|
3528
|
+
executionId: state.executionId,
|
|
3529
|
+
executionPlanDigest: state.executionPlan.value.digest
|
|
3530
|
+
},
|
|
3531
|
+
expected,
|
|
3532
|
+
capture,
|
|
3533
|
+
outputArtifacts,
|
|
3534
|
+
signal
|
|
3535
|
+
);
|
|
3536
|
+
const persisted = persistedCapture.taskOutcome;
|
|
3537
|
+
if (!persisted || persisted.kind !== verified.kind) {
|
|
3538
|
+
throw new Error("persisted task capture kind changed");
|
|
3539
|
+
}
|
|
3540
|
+
const taskOutcome = verified.kind === "output" && persisted.kind === "output" ? await persistVerifiedOutputTaskOutcome(state, verified, persisted, outputArtifacts, signal) : verified.kind === "workspace" && persisted.kind === "workspace" ? await persistVerifiedWorkspaceTaskOutcome(
|
|
3541
|
+
state,
|
|
3542
|
+
verified,
|
|
3543
|
+
persisted,
|
|
3544
|
+
outputArtifacts,
|
|
3545
|
+
signal
|
|
3546
|
+
) : void 0;
|
|
3547
|
+
if (!taskOutcome) throw new Error("persisted task outcome kind could not be narrowed");
|
|
3548
|
+
return Object.freeze({ persistedCapture, taskOutcome });
|
|
3549
|
+
}
|
|
3550
|
+
async function verifyWorkspaceTaskCapture(state, capture, protectedValues, signal) {
|
|
3551
|
+
const repository = state.benchmarkTask.repository;
|
|
3552
|
+
if (!repository) throw new Error("workspace task outcome is missing repository identity");
|
|
3345
3553
|
const patch = Uint8Array.from(capture.gitDiff);
|
|
3346
3554
|
const archive = Uint8Array.from(capture.archive);
|
|
3347
3555
|
if (archive.byteLength === 0) throw new Error("candidate task archive cannot be empty");
|
|
3348
3556
|
assertNoProtectedBytes(patch, protectedValues);
|
|
3349
3557
|
assertNoProtectedBytes(archive, protectedValues);
|
|
3350
|
-
const
|
|
3351
|
-
const afterState = provisional.material;
|
|
3352
|
-
const repository = workspaceTaskRepository(state.executionPlan.value.material.task);
|
|
3558
|
+
const afterState = immutableCandidateValue(capture.afterState);
|
|
3353
3559
|
const verified = await verifyTaskOutcomePatch({
|
|
3354
3560
|
repositoryRoot: state.roots.staging.taskRoot,
|
|
3355
3561
|
baseCommit: repository.baseCommit,
|
|
@@ -3359,24 +3565,38 @@ async function persistVerifiedCandidateTaskOutcome(state, capture, outputArtifac
|
|
|
3359
3565
|
afterState
|
|
3360
3566
|
});
|
|
3361
3567
|
signal?.throwIfAborted();
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3568
|
+
const manifestBytes = canonicalCandidateBytes(afterState);
|
|
3569
|
+
assertNoProtectedBytes(manifestBytes, protectedValues);
|
|
3570
|
+
const provisionalSnapshot = agentCandidateWorkspaceSnapshotEvidenceSchema2.parse({
|
|
3571
|
+
kind: "agent-candidate-workspace-snapshot",
|
|
3572
|
+
digest: sha256Bytes(manifestBytes),
|
|
3367
3573
|
material: afterState,
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
signal
|
|
3574
|
+
manifest: embeddedCandidateArtifact(manifestBytes),
|
|
3575
|
+
archive: embeddedCandidateArtifact(archive)
|
|
3371
3576
|
});
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3577
|
+
await verifyTaskOutcomeArchive(state, provisionalSnapshot, archive, protectedValues);
|
|
3578
|
+
signal?.throwIfAborted();
|
|
3579
|
+
return {
|
|
3580
|
+
kind: "workspace",
|
|
3581
|
+
patch,
|
|
3582
|
+
archive,
|
|
3583
|
+
afterState,
|
|
3584
|
+
manifestBytes,
|
|
3585
|
+
resultCommit: verified.resultCommit,
|
|
3586
|
+
resultTree: verified.resultTree,
|
|
3587
|
+
repository
|
|
3588
|
+
};
|
|
3589
|
+
}
|
|
3590
|
+
async function persistVerifiedWorkspaceTaskOutcome(state, verified, persisted, outputArtifacts, signal) {
|
|
3591
|
+
const { afterState, manifestBytes, patch, repository } = verified;
|
|
3592
|
+
const snapshot = agentCandidateWorkspaceSnapshotEvidenceSchema2.parse({
|
|
3593
|
+
kind: "agent-candidate-workspace-snapshot",
|
|
3594
|
+
digest: sha256Bytes(manifestBytes),
|
|
3595
|
+
material: afterState,
|
|
3596
|
+
manifest: persisted.manifest,
|
|
3597
|
+
archive: persisted.archive
|
|
3377
3598
|
});
|
|
3378
3599
|
const material = {
|
|
3379
|
-
schemaVersion: 2,
|
|
3380
3600
|
kind: "agent-candidate-task-outcome-material",
|
|
3381
3601
|
executionPlanDigest: state.executionPlan.value.digest,
|
|
3382
3602
|
outcome: {
|
|
@@ -3396,10 +3616,60 @@ async function persistVerifiedCandidateTaskOutcome(state, capture, outputArtifac
|
|
|
3396
3616
|
afterState: snapshot,
|
|
3397
3617
|
gitDiff: {
|
|
3398
3618
|
format: "git-diff-binary",
|
|
3399
|
-
artifact: gitDiff
|
|
3619
|
+
artifact: persisted.gitDiff
|
|
3400
3620
|
}
|
|
3401
3621
|
}
|
|
3402
3622
|
};
|
|
3623
|
+
const evidence = await persistTaskOutcomeEvidence(state, material, outputArtifacts, signal);
|
|
3624
|
+
const storedPatch = Uint8Array.from(patch);
|
|
3625
|
+
return Object.freeze({
|
|
3626
|
+
kind: "workspace",
|
|
3627
|
+
evidence,
|
|
3628
|
+
get patch() {
|
|
3629
|
+
return Uint8Array.from(storedPatch);
|
|
3630
|
+
},
|
|
3631
|
+
[verifiedTaskOutcomeBrand]: true
|
|
3632
|
+
});
|
|
3633
|
+
}
|
|
3634
|
+
function verifyOutputTaskCapture(capturedBytes, expected, protectedValues) {
|
|
3635
|
+
if (capturedBytes.byteLength === 0) throw new Error("candidate task output cannot be empty");
|
|
3636
|
+
if (capturedBytes.byteLength > expected.maxBytes) {
|
|
3637
|
+
throw new Error(`candidate task output exceeds the frozen ${expected.maxBytes}-byte maximum`);
|
|
3638
|
+
}
|
|
3639
|
+
const output = Uint8Array.from(capturedBytes);
|
|
3640
|
+
assertNoProtectedBytes(output, protectedValues);
|
|
3641
|
+
return {
|
|
3642
|
+
kind: "output",
|
|
3643
|
+
bytes: output,
|
|
3644
|
+
spec: { mediaType: expected.mediaType, maxBytes: expected.maxBytes }
|
|
3645
|
+
};
|
|
3646
|
+
}
|
|
3647
|
+
async function persistVerifiedOutputTaskOutcome(state, verified, persisted, outputArtifacts, signal) {
|
|
3648
|
+
if (persisted.spec.mediaType !== verified.spec.mediaType || persisted.spec.maxBytes !== verified.spec.maxBytes) {
|
|
3649
|
+
throw new Error("persisted task output changed the signed media constraints");
|
|
3650
|
+
}
|
|
3651
|
+
const material = {
|
|
3652
|
+
kind: "agent-candidate-task-outcome-material",
|
|
3653
|
+
executionPlanDigest: state.executionPlan.value.digest,
|
|
3654
|
+
outcome: {
|
|
3655
|
+
kind: "output",
|
|
3656
|
+
spec: verified.spec,
|
|
3657
|
+
artifact: persisted.artifact
|
|
3658
|
+
}
|
|
3659
|
+
};
|
|
3660
|
+
const evidence = await persistTaskOutcomeEvidence(state, material, outputArtifacts, signal);
|
|
3661
|
+
const storedOutput = Uint8Array.from(verified.bytes);
|
|
3662
|
+
return Object.freeze({
|
|
3663
|
+
kind: "output",
|
|
3664
|
+
evidence,
|
|
3665
|
+
spec: immutableCandidateValue(verified.spec),
|
|
3666
|
+
get bytes() {
|
|
3667
|
+
return Uint8Array.from(storedOutput);
|
|
3668
|
+
},
|
|
3669
|
+
[verifiedTaskOutcomeBrand]: true
|
|
3670
|
+
});
|
|
3671
|
+
}
|
|
3672
|
+
async function persistTaskOutcomeEvidence(state, material, outputArtifacts, signal) {
|
|
3403
3673
|
const bytes = canonicalCandidateBytes(material);
|
|
3404
3674
|
const digest = sha256Bytes(bytes);
|
|
3405
3675
|
const artifact = await persistCandidateOutputArtifact(outputArtifacts, {
|
|
@@ -3408,23 +3678,14 @@ async function persistVerifiedCandidateTaskOutcome(state, capture, outputArtifac
|
|
|
3408
3678
|
bytes,
|
|
3409
3679
|
signal
|
|
3410
3680
|
});
|
|
3411
|
-
|
|
3681
|
+
return immutableCandidateValue(
|
|
3412
3682
|
agentCandidateTaskOutcomeEvidenceSchema.parse({
|
|
3413
|
-
schemaVersion: 2,
|
|
3414
3683
|
kind: "agent-candidate-task-outcome",
|
|
3415
3684
|
digest,
|
|
3416
3685
|
material,
|
|
3417
3686
|
artifact
|
|
3418
3687
|
})
|
|
3419
3688
|
);
|
|
3420
|
-
const storedPatch = Uint8Array.from(patch);
|
|
3421
|
-
return Object.freeze({
|
|
3422
|
-
evidence,
|
|
3423
|
-
get patch() {
|
|
3424
|
-
return Uint8Array.from(storedPatch);
|
|
3425
|
-
},
|
|
3426
|
-
[verifiedTaskOutcomeBrand]: true
|
|
3427
|
-
});
|
|
3428
3689
|
}
|
|
3429
3690
|
async function persistCandidateBenchmarkResult(state, termination, outcome, grader, outputArtifacts, protectedValues, signal) {
|
|
3430
3691
|
signal?.throwIfAborted();
|
|
@@ -3433,6 +3694,7 @@ async function persistCandidateBenchmarkResult(state, termination, outcome, grad
|
|
|
3433
3694
|
executionId: state.executionId,
|
|
3434
3695
|
termination: frozenTermination,
|
|
3435
3696
|
outcome,
|
|
3697
|
+
expectedGrader: state.benchmarkTask.grader,
|
|
3436
3698
|
grader,
|
|
3437
3699
|
artifacts: outputArtifacts,
|
|
3438
3700
|
signal
|
|
@@ -3448,24 +3710,13 @@ async function persistCandidateBenchmarkResult(state, termination, outcome, grad
|
|
|
3448
3710
|
bytes: rawEvidence,
|
|
3449
3711
|
signal
|
|
3450
3712
|
});
|
|
3451
|
-
const task = state.executionPlan.value.material.task;
|
|
3452
3713
|
const material = {
|
|
3453
|
-
schemaVersion: 1,
|
|
3454
3714
|
kind: "agent-candidate-benchmark-result-material",
|
|
3455
3715
|
executionPlanDigest: state.executionPlan.value.digest,
|
|
3456
3716
|
taskOutcomeDigest: outcome.evidence.digest,
|
|
3457
|
-
|
|
3458
|
-
name: task.benchmark,
|
|
3459
|
-
version: task.benchmarkVersion,
|
|
3460
|
-
taskId: task.taskId,
|
|
3461
|
-
splitDigest: task.splitDigest
|
|
3462
|
-
},
|
|
3463
|
-
grader: {
|
|
3464
|
-
name: graded.grader.name,
|
|
3465
|
-
version: graded.grader.version,
|
|
3466
|
-
artifact: graded.grader.artifact
|
|
3467
|
-
},
|
|
3717
|
+
grader: graded.grader,
|
|
3468
3718
|
evidence: evidenceRef,
|
|
3719
|
+
grading: graded.grading,
|
|
3469
3720
|
score: evaluation.score,
|
|
3470
3721
|
passed: evaluation.passed,
|
|
3471
3722
|
dimensions: evaluation.dimensions
|
|
@@ -3480,7 +3731,6 @@ async function persistCandidateBenchmarkResult(state, termination, outcome, grad
|
|
|
3480
3731
|
});
|
|
3481
3732
|
return immutableCandidateValue(
|
|
3482
3733
|
agentCandidateBenchmarkResultEvidenceSchema.parse({
|
|
3483
|
-
schemaVersion: 1,
|
|
3484
3734
|
kind: "agent-candidate-benchmark-result",
|
|
3485
3735
|
digest,
|
|
3486
3736
|
material,
|
|
@@ -3489,7 +3739,7 @@ async function persistCandidateBenchmarkResult(state, termination, outcome, grad
|
|
|
3489
3739
|
);
|
|
3490
3740
|
}
|
|
3491
3741
|
async function verifyTaskOutcomeArchive(state, snapshot, archive, protectedValues) {
|
|
3492
|
-
const root = await
|
|
3742
|
+
const root = await mkdtemp2(join2(tmpdir2(), "agent-candidate-task-archive-"));
|
|
3493
3743
|
try {
|
|
3494
3744
|
await state.ports.workspaces.materialize({
|
|
3495
3745
|
role: "task",
|
|
@@ -3500,7 +3750,40 @@ async function verifyTaskOutcomeArchive(state, snapshot, archive, protectedValue
|
|
|
3500
3750
|
const files = await readMaterializedWorkspaceFiles(root, snapshot.material);
|
|
3501
3751
|
for (const file of files) assertNoProtectedBytes(file.bytes, protectedValues);
|
|
3502
3752
|
} finally {
|
|
3503
|
-
await
|
|
3753
|
+
await rm2(root, { recursive: true, force: true });
|
|
3754
|
+
}
|
|
3755
|
+
}
|
|
3756
|
+
async function verifyMemoryCapture(state, capture, protectedValues, signal) {
|
|
3757
|
+
if (state.memory.mode === "disabled") {
|
|
3758
|
+
if (capture.memoryAfter) throw new Error("disabled memory cannot return an after-state");
|
|
3759
|
+
return;
|
|
3760
|
+
}
|
|
3761
|
+
const memory = capture.memoryAfter;
|
|
3762
|
+
if (!memory) throw new Error("isolated memory is missing its protected after-state");
|
|
3763
|
+
if (memory.archive.byteLength === 0) throw new Error("isolated memory archive cannot be empty");
|
|
3764
|
+
const manifestBytes = canonicalCandidateBytes(memory.afterState);
|
|
3765
|
+
assertNoProtectedBytes(manifestBytes, protectedValues);
|
|
3766
|
+
assertNoProtectedBytes(memory.archive, protectedValues);
|
|
3767
|
+
const snapshot = agentCandidateWorkspaceSnapshotEvidenceSchema2.parse({
|
|
3768
|
+
kind: "agent-candidate-workspace-snapshot",
|
|
3769
|
+
digest: sha256Bytes(manifestBytes),
|
|
3770
|
+
material: memory.afterState,
|
|
3771
|
+
manifest: embeddedCandidateArtifact(manifestBytes),
|
|
3772
|
+
archive: embeddedCandidateArtifact(memory.archive)
|
|
3773
|
+
});
|
|
3774
|
+
const root = await mkdtemp2(join2(tmpdir2(), "agent-candidate-memory-after-"));
|
|
3775
|
+
try {
|
|
3776
|
+
await state.ports.workspaces.materialize({
|
|
3777
|
+
role: "memory",
|
|
3778
|
+
snapshot,
|
|
3779
|
+
archive: Uint8Array.from(memory.archive),
|
|
3780
|
+
destination: root
|
|
3781
|
+
});
|
|
3782
|
+
const files = await readMaterializedWorkspaceFiles(root, memory.afterState);
|
|
3783
|
+
for (const file of files) assertNoProtectedBytes(file.bytes, protectedValues);
|
|
3784
|
+
signal?.throwIfAborted();
|
|
3785
|
+
} finally {
|
|
3786
|
+
await rm2(root, { recursive: true, force: true });
|
|
3504
3787
|
}
|
|
3505
3788
|
}
|
|
3506
3789
|
function normalizeEvaluation(evaluation, termination) {
|
|
@@ -3683,9 +3966,29 @@ async function executePreparedAgentCandidate(prepared, options) {
|
|
|
3683
3966
|
} catch (error) {
|
|
3684
3967
|
return await failBeforeActivation(prepared, state, error, "failed", cleanupTimeoutMs);
|
|
3685
3968
|
}
|
|
3969
|
+
let preparationEvidence;
|
|
3970
|
+
try {
|
|
3971
|
+
const [executionPlan, materializationReceipt] = await Promise.all([
|
|
3972
|
+
persistCandidateOutputArtifact(options.outputArtifacts, {
|
|
3973
|
+
executionId: state.executionId,
|
|
3974
|
+
purpose: "execution-plan",
|
|
3975
|
+
bytes: state.executionPlan.bytes
|
|
3976
|
+
}),
|
|
3977
|
+
persistCandidateOutputArtifact(options.outputArtifacts, {
|
|
3978
|
+
executionId: state.executionId,
|
|
3979
|
+
purpose: "materialization-receipt",
|
|
3980
|
+
bytes: state.materializationReceipt.bytes
|
|
3981
|
+
})
|
|
3982
|
+
]);
|
|
3983
|
+
preparationEvidence = Object.freeze({ executionPlan, materializationReceipt });
|
|
3984
|
+
} catch (error) {
|
|
3985
|
+
return await failBeforeActivation(prepared, state, error, "failed", cleanupTimeoutMs);
|
|
3986
|
+
}
|
|
3686
3987
|
let acquired;
|
|
3687
3988
|
try {
|
|
3688
|
-
acquired = await options.claimStore.tryClaim(
|
|
3989
|
+
acquired = await options.claimStore.tryClaim(
|
|
3990
|
+
candidateExecutionClaim(prepared, preparationEvidence)
|
|
3991
|
+
);
|
|
3689
3992
|
} catch (error) {
|
|
3690
3993
|
return await failBeforeActivation(prepared, state, error, "failed", cleanupTimeoutMs);
|
|
3691
3994
|
}
|
|
@@ -3837,6 +4140,7 @@ async function executePreparedAgentCandidate(prepared, options) {
|
|
|
3837
4140
|
const execution = await runAndStopExecutor(
|
|
3838
4141
|
options.executor,
|
|
3839
4142
|
request,
|
|
4143
|
+
state.benchmarkTask.outcome,
|
|
3840
4144
|
protectedTraceStore,
|
|
3841
4145
|
deadlineAtMs,
|
|
3842
4146
|
cleanupTimeoutMs
|
|
@@ -3925,9 +4229,9 @@ async function executePreparedAgentCandidate(prepared, options) {
|
|
|
3925
4229
|
state.trace.runId,
|
|
3926
4230
|
settlementResult.settlement
|
|
3927
4231
|
);
|
|
3928
|
-
const taskOutcome = await
|
|
4232
|
+
const { persistedCapture, taskOutcome } = await persistVerifiedAgentCandidateExecutorCapture(
|
|
3929
4233
|
state,
|
|
3930
|
-
execution.finalCapture
|
|
4234
|
+
execution.finalCapture,
|
|
3931
4235
|
options.outputArtifacts,
|
|
3932
4236
|
protectedValues,
|
|
3933
4237
|
signal
|
|
@@ -3948,6 +4252,7 @@ async function executePreparedAgentCandidate(prepared, options) {
|
|
|
3948
4252
|
settlementResult.settlement,
|
|
3949
4253
|
{
|
|
3950
4254
|
finalCapture: execution.finalCapture,
|
|
4255
|
+
persistedCapture,
|
|
3951
4256
|
modelSettlement,
|
|
3952
4257
|
taskOutcome,
|
|
3953
4258
|
benchmarkResult,
|
|
@@ -3973,18 +4278,16 @@ async function executePreparedAgentCandidate(prepared, options) {
|
|
|
3973
4278
|
let terminal;
|
|
3974
4279
|
try {
|
|
3975
4280
|
terminal = result.succeeded ? {
|
|
3976
|
-
schemaVersion: 1,
|
|
3977
4281
|
status: "succeeded",
|
|
3978
|
-
usage: settlementResult.settlement.
|
|
4282
|
+
usage: settlementResult.settlement.usage,
|
|
3979
4283
|
modelSettlement: result.artifacts.modelSettlement,
|
|
3980
4284
|
taskOutcome: result.artifacts.taskOutcome,
|
|
3981
4285
|
benchmarkResult: result.artifacts.benchmarkResult,
|
|
3982
4286
|
runReceipt: result.artifacts.runReceipt
|
|
3983
4287
|
} : {
|
|
3984
|
-
schemaVersion: 1,
|
|
3985
4288
|
status: "failed",
|
|
3986
4289
|
failureClass,
|
|
3987
|
-
usage: settlementResult.settlement.
|
|
4290
|
+
usage: settlementResult.settlement.usage,
|
|
3988
4291
|
modelSettlement: modelSettlement.artifact,
|
|
3989
4292
|
failureEvidence: await withinCandidateCleanupDeadline(
|
|
3990
4293
|
() => persistFailureEvidence(
|
|
@@ -4031,7 +4334,7 @@ async function executePreparedAgentCandidate(prepared, options) {
|
|
|
4031
4334
|
settlementResult.settlement.usage
|
|
4032
4335
|
);
|
|
4033
4336
|
}
|
|
4034
|
-
async function runAndStopExecutor(executor, request, traceStore, deadlineAtMs, cleanupTimeoutMs) {
|
|
4337
|
+
async function runAndStopExecutor(executor, request, expectedOutcome, traceStore, deadlineAtMs, cleanupTimeoutMs) {
|
|
4035
4338
|
const timeoutMs = request.hardLimits.timeoutMs;
|
|
4036
4339
|
const timeoutError = new CandidateExecutionDeadlineError(timeoutMs);
|
|
4037
4340
|
if (Date.now() >= deadlineAtMs) {
|
|
@@ -4086,10 +4389,10 @@ async function runAndStopExecutor(executor, request, traceStore, deadlineAtMs, c
|
|
|
4086
4389
|
}
|
|
4087
4390
|
if (!capture || timedOut) controller.abort(executionError);
|
|
4088
4391
|
const stopReason = timedOut ? "timeout" : capture ? "completed" : "failed";
|
|
4089
|
-
|
|
4392
|
+
const cleanupDeadlineAtMs = Date.now() + cleanupTimeoutMs;
|
|
4090
4393
|
try {
|
|
4091
|
-
stopped = await withinCandidateCleanupDeadline(
|
|
4092
|
-
() => executor.
|
|
4394
|
+
const stopped = await withinCandidateCleanupDeadline(
|
|
4395
|
+
(cleanupSignal) => executor.stop(
|
|
4093
4396
|
{
|
|
4094
4397
|
executionId: request.executionId,
|
|
4095
4398
|
executionPlanDigest: request.executionPlan.value.digest
|
|
@@ -4097,35 +4400,65 @@ async function runAndStopExecutor(executor, request, traceStore, deadlineAtMs, c
|
|
|
4097
4400
|
{
|
|
4098
4401
|
traceStore,
|
|
4099
4402
|
reason: stopReason,
|
|
4100
|
-
signal:
|
|
4101
|
-
deadlineAtMs
|
|
4403
|
+
signal: cleanupSignal,
|
|
4404
|
+
deadlineAtMs: cleanupDeadlineAtMs
|
|
4102
4405
|
}
|
|
4103
4406
|
),
|
|
4104
|
-
|
|
4407
|
+
cleanupDeadlineAtMs,
|
|
4105
4408
|
"candidate process termination"
|
|
4106
4409
|
);
|
|
4107
|
-
|
|
4108
|
-
throw new Error("candidate executor did not acknowledge exact process termination");
|
|
4109
|
-
}
|
|
4410
|
+
sealAgentCandidateExecutorStopAcknowledgement(stopped);
|
|
4110
4411
|
} catch (stopError) {
|
|
4412
|
+
let disposalError2;
|
|
4413
|
+
try {
|
|
4414
|
+
await disposeExecutor(executor, request, cleanupDeadlineAtMs);
|
|
4415
|
+
} catch (error) {
|
|
4416
|
+
disposalError2 = error;
|
|
4417
|
+
}
|
|
4111
4418
|
if (timer) clearTimeout(timer);
|
|
4112
4419
|
controller.abort(stopError);
|
|
4113
4420
|
return {
|
|
4114
4421
|
kind: "error",
|
|
4115
|
-
error: new Error(joinErrors(executionError, stopError)),
|
|
4422
|
+
error: new Error(joinErrors(executionError, stopError, disposalError2)),
|
|
4116
4423
|
...timedOut ? { termination: { kind: "timeout", timeoutMs } } : {},
|
|
4117
4424
|
processStopped: false
|
|
4118
4425
|
};
|
|
4119
4426
|
}
|
|
4120
4427
|
let finalCapture;
|
|
4428
|
+
let finalCaptureError;
|
|
4121
4429
|
try {
|
|
4122
|
-
finalCapture = sealAgentCandidateExecutorFinalCapture(
|
|
4430
|
+
finalCapture = sealAgentCandidateExecutorFinalCapture(
|
|
4431
|
+
await withinCandidateCleanupDeadline(
|
|
4432
|
+
(cleanupSignal) => executor.capture(
|
|
4433
|
+
{
|
|
4434
|
+
executionId: request.executionId,
|
|
4435
|
+
executionPlanDigest: request.executionPlan.value.digest
|
|
4436
|
+
},
|
|
4437
|
+
{
|
|
4438
|
+
traceStore,
|
|
4439
|
+
signal: cleanupSignal
|
|
4440
|
+
}
|
|
4441
|
+
),
|
|
4442
|
+
cleanupDeadlineAtMs,
|
|
4443
|
+
"candidate final evidence capture"
|
|
4444
|
+
),
|
|
4445
|
+
expectedOutcome
|
|
4446
|
+
);
|
|
4123
4447
|
} catch (captureError) {
|
|
4448
|
+
finalCaptureError = captureError;
|
|
4449
|
+
}
|
|
4450
|
+
let disposalError;
|
|
4451
|
+
try {
|
|
4452
|
+
await disposeExecutor(executor, request, cleanupDeadlineAtMs);
|
|
4453
|
+
} catch (disposeError) {
|
|
4454
|
+
disposalError = disposeError;
|
|
4455
|
+
}
|
|
4456
|
+
if (finalCaptureError || disposalError || !finalCapture) {
|
|
4124
4457
|
if (timer) clearTimeout(timer);
|
|
4125
|
-
controller.abort(
|
|
4458
|
+
controller.abort(finalCaptureError ?? disposalError);
|
|
4126
4459
|
return {
|
|
4127
4460
|
kind: "error",
|
|
4128
|
-
error: new Error(joinErrors(executionError,
|
|
4461
|
+
error: new Error(joinErrors(executionError, finalCaptureError, disposalError)),
|
|
4129
4462
|
...timedOut ? { termination: { kind: "timeout", timeoutMs } } : {},
|
|
4130
4463
|
processStopped: true
|
|
4131
4464
|
};
|
|
@@ -4161,6 +4494,25 @@ async function runAndStopExecutor(executor, request, traceStore, deadlineAtMs, c
|
|
|
4161
4494
|
processStopped: true
|
|
4162
4495
|
};
|
|
4163
4496
|
}
|
|
4497
|
+
async function disposeExecutor(executor, request, cleanupDeadlineAtMs) {
|
|
4498
|
+
const dispose = executor.dispose;
|
|
4499
|
+
if (!dispose) return;
|
|
4500
|
+
const disposed = await withinCandidateCleanupDeadline(
|
|
4501
|
+
(cleanupSignal) => dispose.call(
|
|
4502
|
+
executor,
|
|
4503
|
+
{
|
|
4504
|
+
executionId: request.executionId,
|
|
4505
|
+
executionPlanDigest: request.executionPlan.value.digest
|
|
4506
|
+
},
|
|
4507
|
+
{ signal: cleanupSignal }
|
|
4508
|
+
),
|
|
4509
|
+
cleanupDeadlineAtMs,
|
|
4510
|
+
"candidate execution resource disposal"
|
|
4511
|
+
);
|
|
4512
|
+
if (!disposed || disposed.disposed !== true || Object.keys(disposed).some((key) => key !== "disposed")) {
|
|
4513
|
+
throw new Error("candidate executor did not acknowledge resource disposal");
|
|
4514
|
+
}
|
|
4515
|
+
}
|
|
4164
4516
|
async function failBeforeActivation(prepared, state, error, reason, cleanupTimeoutMs) {
|
|
4165
4517
|
beginPreparedCandidateSettlement(prepared);
|
|
4166
4518
|
const cleanupDeadlineAtMs = candidateCleanupDeadline(cleanupTimeoutMs);
|
|
@@ -4215,10 +4567,9 @@ async function failClaimedExecution(prepared, state, lease, claimStore, outputAr
|
|
|
4215
4567
|
claimStore,
|
|
4216
4568
|
lease,
|
|
4217
4569
|
{
|
|
4218
|
-
schemaVersion: 1,
|
|
4219
4570
|
status: "failed",
|
|
4220
4571
|
failureClass,
|
|
4221
|
-
usage: settled.settlement.
|
|
4572
|
+
usage: settled.settlement.usage,
|
|
4222
4573
|
modelSettlement: modelSettlement.artifact,
|
|
4223
4574
|
failureEvidence
|
|
4224
4575
|
},
|
|
@@ -4315,7 +4666,6 @@ async function finishClaim(store, lease, terminal, deadlineAtMs) {
|
|
|
4315
4666
|
}
|
|
4316
4667
|
async function persistFailureEvidence(state, reason, failureClass, termination, outputArtifacts) {
|
|
4317
4668
|
const bytes = canonicalCandidateBytes({
|
|
4318
|
-
schemaVersion: 1,
|
|
4319
4669
|
kind: "agent-candidate-execution-failure",
|
|
4320
4670
|
executionId: state.executionId,
|
|
4321
4671
|
bundleDigest: state.bundle.digest,
|
|
@@ -4347,10 +4697,24 @@ var CandidateExecutionDeadlineError = class extends Error {
|
|
|
4347
4697
|
};
|
|
4348
4698
|
|
|
4349
4699
|
// src/candidate-execution/verify.ts
|
|
4350
|
-
import { agentCandidateBundleSchema
|
|
4700
|
+
import { agentCandidateBundleSchema } from "@tangle-network/agent-interface";
|
|
4351
4701
|
var verifiedCandidateState = /* @__PURE__ */ new WeakMap();
|
|
4702
|
+
var AGENT_CANDIDATE_EXECUTION_SUPPORT = Object.freeze({
|
|
4703
|
+
outcomes: Object.freeze(["workspace", "output"]),
|
|
4704
|
+
code: Object.freeze(["disabled", "no-op", "git-patch"]),
|
|
4705
|
+
memory: Object.freeze(["disabled", "isolated"]),
|
|
4706
|
+
knowledge: true,
|
|
4707
|
+
profile: Object.freeze({
|
|
4708
|
+
mcpTransports: Object.freeze(["stdio"]),
|
|
4709
|
+
remoteMcp: false,
|
|
4710
|
+
tools: false,
|
|
4711
|
+
permissions: false,
|
|
4712
|
+
modes: false,
|
|
4713
|
+
confidential: false
|
|
4714
|
+
})
|
|
4715
|
+
});
|
|
4352
4716
|
async function verifyAgentCandidateBundle(input, ports) {
|
|
4353
|
-
const parsed =
|
|
4717
|
+
const parsed = agentCandidateBundleSchema.parse(input);
|
|
4354
4718
|
const withoutDigest = omitTopLevelDigest(parsed);
|
|
4355
4719
|
const actualDigest = canonicalCandidateDigest(withoutDigest);
|
|
4356
4720
|
if (actualDigest !== parsed.digest) {
|
|
@@ -4358,6 +4722,7 @@ async function verifyAgentCandidateBundle(input, ports) {
|
|
|
4358
4722
|
}
|
|
4359
4723
|
const canonicalBytes = canonicalCandidateBytes(withoutDigest);
|
|
4360
4724
|
verifyBytes(canonicalBytes, parsed.digest, canonicalBytes.byteLength, "candidate bundle");
|
|
4725
|
+
assertCandidateProfileExecutionSupport(parsed.profile);
|
|
4361
4726
|
const artifactBytes = /* @__PURE__ */ new Map();
|
|
4362
4727
|
const readArtifact = async (artifact) => {
|
|
4363
4728
|
const key = artifactCacheKey(artifact);
|
|
@@ -4454,35 +4819,28 @@ function resourceKey(resource) {
|
|
|
4454
4819
|
return canonicalCandidateDigest(resource);
|
|
4455
4820
|
}
|
|
4456
4821
|
|
|
4457
|
-
// src/candidate-execution/prepare.ts
|
|
4458
|
-
import { randomBytes as randomBytes2 } from "crypto";
|
|
4459
|
-
import { lstat as lstat2, readdir as readdir2 } from "fs/promises";
|
|
4460
|
-
import { isAbsolute, posix, relative as relative2, resolve as resolveHostPath } from "path";
|
|
4461
|
-
import {
|
|
4462
|
-
agentCandidateContainerSchema,
|
|
4463
|
-
agentCandidateExecutionLimitsSchema,
|
|
4464
|
-
agentCandidateExecutionPlanEvidenceSchema as agentCandidateExecutionPlanEvidenceSchema2,
|
|
4465
|
-
agentCandidateExecutionPlanMaterialSchema,
|
|
4466
|
-
agentCandidateMaterializationReceiptSchema as agentCandidateMaterializationReceiptSchema2,
|
|
4467
|
-
agentCandidateModelAccessNetworkSchema,
|
|
4468
|
-
agentCandidateWorkspaceSnapshotEvidenceSchema as agentCandidateWorkspaceSnapshotEvidenceSchema2,
|
|
4469
|
-
sha256DigestSchema
|
|
4470
|
-
} from "@tangle-network/agent-interface";
|
|
4471
|
-
import {
|
|
4472
|
-
applyAgentCandidateWorkspacePlan,
|
|
4473
|
-
materializeCandidateProfile
|
|
4474
|
-
} from "@tangle-network/agent-profile-materialize";
|
|
4475
|
-
|
|
4476
4822
|
// src/candidate-execution/knowledge.ts
|
|
4477
|
-
import { mkdtemp as
|
|
4478
|
-
import { tmpdir as
|
|
4479
|
-
import { join as
|
|
4823
|
+
import { mkdtemp as mkdtemp3, rm as rm3 } from "fs/promises";
|
|
4824
|
+
import { tmpdir as tmpdir3 } from "os";
|
|
4825
|
+
import { join as join3, posix } from "path";
|
|
4826
|
+
var CANDIDATE_KNOWLEDGE_ROOT_ENV = "TANGLE_CANDIDATE_KNOWLEDGE_ROOT";
|
|
4827
|
+
var CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG_ENV = "TANGLE_CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG";
|
|
4828
|
+
function candidateKnowledgeExecutionPaths(taskRoot, hasRetrievalConfig) {
|
|
4829
|
+
if (!posix.isAbsolute(taskRoot) || posix.normalize(taskRoot) !== taskRoot) {
|
|
4830
|
+
throw new Error("candidate knowledge requires a normalized absolute task root");
|
|
4831
|
+
}
|
|
4832
|
+
const parent = posix.join(taskRoot, ".tangle");
|
|
4833
|
+
return {
|
|
4834
|
+
root: posix.join(parent, "knowledge"),
|
|
4835
|
+
...hasRetrievalConfig ? { retrievalConfig: posix.join(parent, "knowledge-retrieval-config.json") } : {}
|
|
4836
|
+
};
|
|
4837
|
+
}
|
|
4480
4838
|
async function prepareAgentCandidateKnowledge(candidate, ports) {
|
|
4481
4839
|
const knowledge = candidate.bundle.knowledge;
|
|
4482
4840
|
if (!knowledge) return void 0;
|
|
4483
4841
|
const archive = await verifiedArtifactBytes(candidate, knowledge.snapshot.archive);
|
|
4484
4842
|
const retrievalConfig = knowledge.retrievalConfig ? await verifiedArtifactBytes(candidate, knowledge.retrievalConfig) : void 0;
|
|
4485
|
-
const root = await
|
|
4843
|
+
const root = await mkdtemp3(join3(tmpdir3(), "agent-candidate-knowledge-"));
|
|
4486
4844
|
try {
|
|
4487
4845
|
await ports.workspaces.materialize({
|
|
4488
4846
|
role: "knowledge",
|
|
@@ -4502,25 +4860,32 @@ async function prepareAgentCandidateKnowledge(candidate, ports) {
|
|
|
4502
4860
|
...retrievalConfig ? { retrievalConfig: Uint8Array.from(retrievalConfig) } : {}
|
|
4503
4861
|
});
|
|
4504
4862
|
} finally {
|
|
4505
|
-
await
|
|
4863
|
+
await rm3(root, { recursive: true, force: true });
|
|
4506
4864
|
}
|
|
4507
4865
|
}
|
|
4508
4866
|
|
|
4509
4867
|
// src/candidate-execution/prepare.ts
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4868
|
+
import { randomBytes as randomBytes2 } from "crypto";
|
|
4869
|
+
import { lstat as lstat2, readdir as readdir2 } from "fs/promises";
|
|
4870
|
+
import { isAbsolute, posix as posix2, relative as relative2, resolve as resolveHostPath } from "path";
|
|
4871
|
+
import {
|
|
4872
|
+
agentCandidateBenchmarkSuiteSchema as agentCandidateBenchmarkSuiteSchema2,
|
|
4873
|
+
agentCandidateBenchmarkTaskSchema as agentCandidateBenchmarkTaskSchema2,
|
|
4874
|
+
agentCandidateContainerSchema,
|
|
4875
|
+
agentCandidateExecutionLimitsSchema,
|
|
4876
|
+
agentCandidateExecutionPlanEvidenceSchema as agentCandidateExecutionPlanEvidenceSchema2,
|
|
4877
|
+
agentCandidateExecutionPlanMaterialSchema,
|
|
4878
|
+
agentCandidateMaterializationReceiptSchema as agentCandidateMaterializationReceiptSchema2,
|
|
4879
|
+
agentCandidateModelAccessNetworkSchema,
|
|
4880
|
+
agentCandidateRunCellSchema,
|
|
4881
|
+
agentCandidateTaskOutcomeSpecSchema,
|
|
4882
|
+
agentCandidateWorkspaceSnapshotEvidenceSchema as agentCandidateWorkspaceSnapshotEvidenceSchema3,
|
|
4883
|
+
sha256DigestSchema
|
|
4884
|
+
} from "@tangle-network/agent-interface";
|
|
4885
|
+
import {
|
|
4886
|
+
applyAgentCandidateWorkspacePlan,
|
|
4887
|
+
materializeCandidateProfile
|
|
4888
|
+
} from "@tangle-network/agent-profile-materialize";
|
|
4524
4889
|
var MIN_RESERVATION_TTL_MS = 15 * 6e4;
|
|
4525
4890
|
var PREPARED_HOLD_MARGIN_MS = 5 * 6e4;
|
|
4526
4891
|
async function prepareAgentCandidateExecution(candidate, task, ports, options = {}) {
|
|
@@ -4528,12 +4893,23 @@ async function prepareAgentCandidateExecution(candidate, task, ports, options =
|
|
|
4528
4893
|
const verifiedState = getVerifiedCandidateState(candidate);
|
|
4529
4894
|
assertSameVerificationPorts(verifiedState.ports, ports);
|
|
4530
4895
|
const bundle = candidate.bundle;
|
|
4531
|
-
|
|
4532
|
-
|
|
4896
|
+
if (task.runCell.bundleDigest !== bundle.digest) {
|
|
4897
|
+
throw new Error("candidate experiment cell does not bind the verified bundle");
|
|
4898
|
+
}
|
|
4899
|
+
const benchmarkTask = task.task;
|
|
4900
|
+
const attempt = {
|
|
4901
|
+
number: task.runCell.attempt,
|
|
4902
|
+
maxAttempts: benchmarkTask.attempt.maxAttempts,
|
|
4903
|
+
retryPolicy: benchmarkTask.attempt.retryPolicy
|
|
4904
|
+
};
|
|
4905
|
+
const harness = candidateMaterializerHarness(bundle.execution.harness);
|
|
4533
4906
|
assertTaskInput(task, bundle.execution.instructionDelivery);
|
|
4534
|
-
const resultTimeoutMs = candidateResultTimeout(
|
|
4907
|
+
const resultTimeoutMs = candidateResultTimeout(
|
|
4908
|
+
options.resultTimeoutMs,
|
|
4909
|
+
benchmarkTask.limits.timeoutMs
|
|
4910
|
+
);
|
|
4535
4911
|
const ownerWindowMs = candidateExecutionOwnerWindowMs(
|
|
4536
|
-
|
|
4912
|
+
benchmarkTask.limits.timeoutMs,
|
|
4537
4913
|
cleanupTimeoutMs,
|
|
4538
4914
|
resultTimeoutMs
|
|
4539
4915
|
);
|
|
@@ -4542,22 +4918,26 @@ async function prepareAgentCandidateExecution(candidate, task, ports, options =
|
|
|
4542
4918
|
throw new Error("candidate reservation window exceeds the supported timer range");
|
|
4543
4919
|
}
|
|
4544
4920
|
assertDisjointHostStagingRoots(task);
|
|
4545
|
-
const instructionBytes = Buffer.from(
|
|
4546
|
-
const
|
|
4547
|
-
|
|
4921
|
+
const instructionBytes = Buffer.from(benchmarkTask.instruction, "utf8");
|
|
4922
|
+
const taskArtifacts = await verifyWorkspaceSnapshotArtifacts(
|
|
4923
|
+
benchmarkTask.workspace,
|
|
4924
|
+
ports.artifacts
|
|
4925
|
+
);
|
|
4548
4926
|
await ports.workspaces.materialize({
|
|
4549
4927
|
role: "task",
|
|
4550
|
-
snapshot:
|
|
4928
|
+
snapshot: benchmarkTask.workspace,
|
|
4551
4929
|
archive: taskArtifacts.archive,
|
|
4552
4930
|
destination: task.stagingRoots.taskRoot
|
|
4553
4931
|
});
|
|
4554
|
-
await verifyMaterializedWorkspace(task.stagingRoots.taskRoot,
|
|
4932
|
+
await verifyMaterializedWorkspace(task.stagingRoots.taskRoot, benchmarkTask.workspace.material, {
|
|
4555
4933
|
ignoredProtectedRootEntries: [".git", ".sidecar"]
|
|
4556
4934
|
});
|
|
4557
|
-
|
|
4935
|
+
if (benchmarkTask.repository) {
|
|
4936
|
+
await verifyTaskCheckout(task.stagingRoots.taskRoot, benchmarkTask.repository);
|
|
4937
|
+
}
|
|
4558
4938
|
const taskExecutorFiles = await readMaterializedWorkspaceFiles(
|
|
4559
4939
|
task.stagingRoots.taskRoot,
|
|
4560
|
-
|
|
4940
|
+
benchmarkTask.workspace.material,
|
|
4561
4941
|
{ ignoredProtectedRootEntries: [".git", ".sidecar"] }
|
|
4562
4942
|
);
|
|
4563
4943
|
let candidateArchive;
|
|
@@ -4595,30 +4975,33 @@ async function prepareAgentCandidateExecution(candidate, task, ports, options =
|
|
|
4595
4975
|
);
|
|
4596
4976
|
await verifyMaterializedProfileWorkspace(
|
|
4597
4977
|
task.stagingRoots.profileRoot,
|
|
4598
|
-
profileApplication.profilePlan.material
|
|
4978
|
+
profileApplication.profileActivation.profilePlan.material
|
|
4599
4979
|
);
|
|
4600
4980
|
const profilePlanBytes = await readVerifiedArtifact(
|
|
4601
|
-
profileApplication.profilePlan.artifact,
|
|
4981
|
+
profileApplication.profileActivation.profilePlan.artifact,
|
|
4602
4982
|
ports.artifacts
|
|
4603
4983
|
);
|
|
4604
4984
|
if (!Buffer.from(profilePlanBytes).equals(
|
|
4605
|
-
Buffer.from(
|
|
4985
|
+
Buffer.from(
|
|
4986
|
+
canonicalCandidateBytes(profileApplication.profileActivation.profilePlan.material)
|
|
4987
|
+
)
|
|
4606
4988
|
)) {
|
|
4607
4989
|
throw new Error("profile materializer did not capture exact canonical plan bytes");
|
|
4608
4990
|
}
|
|
4991
|
+
const profileActivation = profileApplication.profileActivation;
|
|
4609
4992
|
const container = await resolveContainer(candidate, task, ports);
|
|
4610
4993
|
const resolvedModel = await resolveModel(candidate, task, ports);
|
|
4611
|
-
const preparationId = `candidate-preparation
|
|
4994
|
+
const preparationId = `candidate-preparation.${randomBytes2(32).toString("base64url")}`;
|
|
4612
4995
|
const reservationExpiresAtMs = Date.now() + Math.max(MIN_RESERVATION_TTL_MS, reservationWindowMs);
|
|
4613
4996
|
const modelReservation = await withinCandidateCleanupDeadline(
|
|
4614
4997
|
() => ports.models.reserveGrant({
|
|
4615
4998
|
executionId: task.executionId,
|
|
4616
4999
|
preparationId,
|
|
4617
5000
|
expiresAtMs: reservationExpiresAtMs,
|
|
4618
|
-
attempt
|
|
5001
|
+
attempt,
|
|
4619
5002
|
bundleDigest: bundle.digest,
|
|
4620
5003
|
resolved: resolvedModel,
|
|
4621
|
-
limits: modelLimits2(
|
|
5004
|
+
limits: modelLimits2(benchmarkTask.limits)
|
|
4622
5005
|
}),
|
|
4623
5006
|
candidateCleanupDeadline(cleanupTimeoutMs),
|
|
4624
5007
|
"protected model reservation"
|
|
@@ -4627,7 +5010,7 @@ async function prepareAgentCandidateExecution(candidate, task, ports, options =
|
|
|
4627
5010
|
try {
|
|
4628
5011
|
validateProtectedModelReservation(
|
|
4629
5012
|
modelReservation,
|
|
4630
|
-
|
|
5013
|
+
benchmarkTask.limits,
|
|
4631
5014
|
preparationId,
|
|
4632
5015
|
reservationExpiresAtMs
|
|
4633
5016
|
);
|
|
@@ -4641,6 +5024,10 @@ async function prepareAgentCandidateExecution(candidate, task, ports, options =
|
|
|
4641
5024
|
);
|
|
4642
5025
|
const memory = preparedMemory.value;
|
|
4643
5026
|
const knowledge = await prepareAgentCandidateKnowledge(candidate, ports);
|
|
5027
|
+
const knowledgePaths = knowledge ? candidateKnowledgeExecutionPaths(
|
|
5028
|
+
task.executionRoots.taskRoot,
|
|
5029
|
+
knowledge.retrievalConfig !== void 0
|
|
5030
|
+
) : void 0;
|
|
4644
5031
|
const baseLaunch = buildLaunch(candidate, task, profileApplication.flags);
|
|
4645
5032
|
const publicEnv = mergePublicEnvironment(
|
|
4646
5033
|
bundle.execution.env ?? {},
|
|
@@ -4650,30 +5037,25 @@ async function prepareAgentCandidateExecution(candidate, task, ports, options =
|
|
|
4650
5037
|
kind: "public",
|
|
4651
5038
|
value: bundle.execution.instructionDelivery.path
|
|
4652
5039
|
}
|
|
5040
|
+
} : {},
|
|
5041
|
+
knowledgePaths ? {
|
|
5042
|
+
[CANDIDATE_KNOWLEDGE_ROOT_ENV]: {
|
|
5043
|
+
kind: "public",
|
|
5044
|
+
value: knowledgePaths.root
|
|
5045
|
+
},
|
|
5046
|
+
...knowledgePaths.retrievalConfig ? {
|
|
5047
|
+
[CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG_ENV]: {
|
|
5048
|
+
kind: "public",
|
|
5049
|
+
value: knowledgePaths.retrievalConfig
|
|
5050
|
+
}
|
|
5051
|
+
} : {}
|
|
4653
5052
|
} : {}
|
|
4654
5053
|
);
|
|
4655
|
-
const routes = modelRoutes(bundle.profile,
|
|
5054
|
+
const routes = modelRoutes(bundle.profile, benchmarkTask.model.requested);
|
|
4656
5055
|
const executionMaterial = {
|
|
4657
|
-
schemaVersion: 2,
|
|
4658
5056
|
kind: "agent-candidate-execution-plan-material",
|
|
4659
|
-
|
|
5057
|
+
runCell: task.runCell,
|
|
4660
5058
|
executionId: task.executionId,
|
|
4661
|
-
attempt: task.attempt,
|
|
4662
|
-
task: {
|
|
4663
|
-
benchmark: task.benchmark,
|
|
4664
|
-
benchmarkVersion: task.benchmarkVersion,
|
|
4665
|
-
taskId: task.taskId,
|
|
4666
|
-
splitDigest: task.splitDigest,
|
|
4667
|
-
instruction: {
|
|
4668
|
-
encoding: "utf8",
|
|
4669
|
-
sha256: instructionDigest,
|
|
4670
|
-
byteLength: instructionBytes.byteLength,
|
|
4671
|
-
delivery: bundle.execution.instructionDelivery
|
|
4672
|
-
},
|
|
4673
|
-
repository: task.repository,
|
|
4674
|
-
outcome: { kind: "workspace" },
|
|
4675
|
-
workspace: task.workspace
|
|
4676
|
-
},
|
|
4677
5059
|
workspaces: {
|
|
4678
5060
|
taskRoot: task.executionRoots.taskRoot,
|
|
4679
5061
|
...task.executionRoots.candidateRoot ? { candidateRoot: task.executionRoots.candidateRoot } : {}
|
|
@@ -4683,6 +5065,8 @@ async function prepareAgentCandidateExecution(candidate, task, ports, options =
|
|
|
4683
5065
|
profile: profileApplication.application,
|
|
4684
5066
|
harness: bundle.execution.harness,
|
|
4685
5067
|
harnessVersion: bundle.execution.harnessVersion,
|
|
5068
|
+
instructionDelivery: bundle.execution.instructionDelivery,
|
|
5069
|
+
limits: benchmarkTask.limits,
|
|
4686
5070
|
container,
|
|
4687
5071
|
model: {
|
|
4688
5072
|
policy: "single",
|
|
@@ -4694,7 +5078,6 @@ async function prepareAgentCandidateExecution(candidate, task, ports, options =
|
|
|
4694
5078
|
},
|
|
4695
5079
|
routes
|
|
4696
5080
|
},
|
|
4697
|
-
grader: task.grader,
|
|
4698
5081
|
launch: {
|
|
4699
5082
|
executable: baseLaunch.executable,
|
|
4700
5083
|
args: baseLaunch.args,
|
|
@@ -4703,7 +5086,6 @@ async function prepareAgentCandidateExecution(candidate, task, ports, options =
|
|
|
4703
5086
|
},
|
|
4704
5087
|
...bundle.knowledge ? { knowledgeManifestDigest: bundle.knowledge.snapshot.digest } : {},
|
|
4705
5088
|
memory,
|
|
4706
|
-
limits: task.limits,
|
|
4707
5089
|
network: { mode: "disabled" }
|
|
4708
5090
|
};
|
|
4709
5091
|
agentCandidateExecutionPlanMaterialSchema.parse(executionMaterial);
|
|
@@ -4713,7 +5095,6 @@ async function prepareAgentCandidateExecution(candidate, task, ports, options =
|
|
|
4713
5095
|
throw new Error("execution plan canonical serializers disagree");
|
|
4714
5096
|
}
|
|
4715
5097
|
const executionPlan = agentCandidateExecutionPlanEvidenceSchema2.parse({
|
|
4716
|
-
schemaVersion: 2,
|
|
4717
5098
|
kind: "agent-candidate-execution-plan",
|
|
4718
5099
|
digest: executionDigest,
|
|
4719
5100
|
material: executionMaterial,
|
|
@@ -4722,11 +5103,24 @@ async function prepareAgentCandidateExecution(candidate, task, ports, options =
|
|
|
4722
5103
|
const entrypoint = candidateEntrypointReceipt(candidate);
|
|
4723
5104
|
const materializationReceipt = canonicalCandidateDocument(
|
|
4724
5105
|
{
|
|
4725
|
-
schemaVersion: 2,
|
|
4726
5106
|
kind: "agent-candidate-materialization",
|
|
4727
5107
|
digestAlgorithm: "rfc8785-sha256",
|
|
4728
5108
|
bundleDigest: bundle.digest,
|
|
4729
|
-
|
|
5109
|
+
benchmark: {
|
|
5110
|
+
suite: {
|
|
5111
|
+
digest: task.benchmarkSuite.digest,
|
|
5112
|
+
material: embeddedCandidateArtifact(
|
|
5113
|
+
canonicalCandidateBytes(omitTopLevelDigest(task.benchmarkSuite))
|
|
5114
|
+
)
|
|
5115
|
+
},
|
|
5116
|
+
task: {
|
|
5117
|
+
digest: benchmarkTask.digest,
|
|
5118
|
+
material: embeddedCandidateArtifact(
|
|
5119
|
+
canonicalCandidateBytes(omitTopLevelDigest(benchmarkTask))
|
|
5120
|
+
)
|
|
5121
|
+
}
|
|
5122
|
+
},
|
|
5123
|
+
profileActivation,
|
|
4730
5124
|
executionPlan,
|
|
4731
5125
|
...bundle.execution.workspace ? { candidateWorkspace: bundle.execution.workspace } : {},
|
|
4732
5126
|
codeKind: bundle.code.kind,
|
|
@@ -4740,7 +5134,7 @@ async function prepareAgentCandidateExecution(candidate, task, ports, options =
|
|
|
4740
5134
|
}
|
|
4741
5135
|
);
|
|
4742
5136
|
agentCandidateMaterializationReceiptSchema2.parse(materializationReceipt.value);
|
|
4743
|
-
const traceRunId = `${task.executionId}:attempt-${
|
|
5137
|
+
const traceRunId = `${task.executionId}:attempt-${attempt.number}:${canonicalCandidateDigest({ preparationId }).slice(7, 23)}`;
|
|
4744
5138
|
const traceTags = {
|
|
4745
5139
|
[CANDIDATE_TRACE_TAGS.executionId]: task.executionId,
|
|
4746
5140
|
[CANDIDATE_TRACE_TAGS.bundleDigest]: bundle.digest,
|
|
@@ -4758,16 +5152,19 @@ async function prepareAgentCandidateExecution(candidate, task, ports, options =
|
|
|
4758
5152
|
return createPreparedCandidateExecution({
|
|
4759
5153
|
ports,
|
|
4760
5154
|
bundle,
|
|
5155
|
+
benchmarkSuite: task.benchmarkSuite,
|
|
5156
|
+
benchmarkTask,
|
|
4761
5157
|
executionId: task.executionId,
|
|
4762
5158
|
roots: {
|
|
4763
5159
|
execution: { ...task.executionRoots },
|
|
4764
5160
|
staging: { ...task.stagingRoots }
|
|
4765
5161
|
},
|
|
4766
5162
|
profilePlan: {
|
|
4767
|
-
value: profileApplication.profilePlan,
|
|
5163
|
+
value: profileApplication.profileActivation.profilePlan,
|
|
4768
5164
|
bytes: profilePlanBytes,
|
|
4769
5165
|
written: [...profileApplication.application.mountPaths]
|
|
4770
5166
|
},
|
|
5167
|
+
profileActivation,
|
|
4771
5168
|
executionPlan: { value: executionPlan, bytes: executionBytes },
|
|
4772
5169
|
materializationReceipt,
|
|
4773
5170
|
launch: {
|
|
@@ -4798,7 +5195,7 @@ async function prepareAgentCandidateExecution(candidate, task, ports, options =
|
|
|
4798
5195
|
...candidateExecutorFiles ? { candidateFiles: candidateExecutorFiles } : {},
|
|
4799
5196
|
profileFiles: exactProfileExecutorFiles(
|
|
4800
5197
|
profileWorkspacePlan.files,
|
|
4801
|
-
profileApplication.profilePlan.material.files
|
|
5198
|
+
profileApplication.profileActivation.profilePlan.material.files
|
|
4802
5199
|
)
|
|
4803
5200
|
},
|
|
4804
5201
|
...preparedMemory.accessDigest && preparedMemory.value.mode === "isolated" ? {
|
|
@@ -4883,34 +5280,54 @@ function assertSameVerificationPorts(verified, execution) {
|
|
|
4883
5280
|
}
|
|
4884
5281
|
}
|
|
4885
5282
|
function assertTaskInput(task, delivery) {
|
|
5283
|
+
const benchmarkTask = agentCandidateBenchmarkTaskSchema2.parse(task.task);
|
|
5284
|
+
const benchmarkSuite = agentCandidateBenchmarkSuiteSchema2.parse(task.benchmarkSuite);
|
|
5285
|
+
const runCell = agentCandidateRunCellSchema.parse(task.runCell);
|
|
4886
5286
|
const requiredStrings = [
|
|
4887
5287
|
["executionId", task.executionId],
|
|
4888
|
-
["benchmark",
|
|
4889
|
-
["benchmarkVersion",
|
|
4890
|
-
["taskId",
|
|
4891
|
-
["repository identity", task.repository.identity],
|
|
4892
|
-
["repository root identity", task.repository.rootIdentity]
|
|
5288
|
+
["benchmark", benchmarkTask.benchmark.name],
|
|
5289
|
+
["benchmarkVersion", benchmarkTask.benchmark.version],
|
|
5290
|
+
["taskId", benchmarkTask.scenario.id]
|
|
4893
5291
|
];
|
|
5292
|
+
if (benchmarkTask.outcome.kind === "workspace" && !benchmarkTask.repository) {
|
|
5293
|
+
throw new Error("workspace task outcome requires repository identity");
|
|
5294
|
+
}
|
|
5295
|
+
if (benchmarkTask.repository) {
|
|
5296
|
+
requiredStrings.push(
|
|
5297
|
+
["repository identity", benchmarkTask.repository.identity],
|
|
5298
|
+
["repository root identity", benchmarkTask.repository.rootIdentity]
|
|
5299
|
+
);
|
|
5300
|
+
}
|
|
4894
5301
|
for (const [name, value] of requiredStrings) {
|
|
4895
5302
|
if (!value.trim()) throw new Error(`${name} must be non-empty`);
|
|
4896
5303
|
}
|
|
4897
5304
|
if (!/^[A-Za-z0-9._:-]{1,200}$/.test(task.executionId)) {
|
|
4898
5305
|
throw new Error("executionId must be a stable filesystem-neutral identifier");
|
|
4899
5306
|
}
|
|
4900
|
-
if (!
|
|
5307
|
+
if (!benchmarkTask.instruction || !isWellFormedUnicode(benchmarkTask.instruction)) {
|
|
4901
5308
|
throw new Error("task instruction must be non-empty well-formed Unicode");
|
|
4902
5309
|
}
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
agentCandidateExecutionLimitsSchema.parse(task.limits);
|
|
4906
|
-
if (!/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(task.repository.baseCommit)) {
|
|
4907
|
-
throw new Error("task repository base commit is not a full Git object id");
|
|
5310
|
+
if (canonicalCandidateDigest(omitTopLevelDigest(benchmarkTask)) !== benchmarkTask.digest || canonicalCandidateDigest(omitTopLevelDigest(benchmarkSuite)) !== benchmarkSuite.digest || canonicalCandidateDigest(omitTopLevelDigest(runCell)) !== runCell.digest) {
|
|
5311
|
+
throw new Error("candidate experiment cell contains an invalid content digest");
|
|
4908
5312
|
}
|
|
4909
|
-
|
|
4910
|
-
|
|
5313
|
+
const cellIndex = runCell.taskIndex * benchmarkSuite.reps + runCell.repetition;
|
|
5314
|
+
if (runCell.suiteDigest !== benchmarkSuite.digest || runCell.taskDigest !== benchmarkTask.digest || benchmarkSuite.taskDigests[runCell.taskIndex] !== benchmarkTask.digest || runCell.repetition >= benchmarkSuite.reps || benchmarkSuite.seeds[cellIndex] !== runCell.seed || runCell.attempt > benchmarkTask.attempt.maxAttempts) {
|
|
5315
|
+
throw new Error("candidate experiment cell does not match its signed suite and task");
|
|
4911
5316
|
}
|
|
4912
|
-
|
|
4913
|
-
|
|
5317
|
+
sha256DigestSchema.parse(benchmarkTask.benchmark.splitDigest);
|
|
5318
|
+
agentCandidateTaskOutcomeSpecSchema.parse(benchmarkTask.outcome);
|
|
5319
|
+
agentCandidateWorkspaceSnapshotEvidenceSchema3.parse(benchmarkTask.workspace);
|
|
5320
|
+
agentCandidateExecutionLimitsSchema.parse(benchmarkTask.limits);
|
|
5321
|
+
if (benchmarkTask.repository) {
|
|
5322
|
+
if (!/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(benchmarkTask.repository.baseCommit)) {
|
|
5323
|
+
throw new Error("task repository base commit is not a full Git object id");
|
|
5324
|
+
}
|
|
5325
|
+
if (!/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(benchmarkTask.repository.baseTree)) {
|
|
5326
|
+
throw new Error("task repository base tree is not a full Git object id");
|
|
5327
|
+
}
|
|
5328
|
+
if (benchmarkTask.repository.baseCommit.length !== benchmarkTask.repository.baseTree.length) {
|
|
5329
|
+
throw new Error("task repository Git object formats disagree");
|
|
5330
|
+
}
|
|
4914
5331
|
}
|
|
4915
5332
|
for (const [name, root] of [
|
|
4916
5333
|
["execution task root", task.executionRoots.taskRoot],
|
|
@@ -4920,34 +5337,36 @@ function assertTaskInput(task, delivery) {
|
|
|
4920
5337
|
["staging profile root", task.stagingRoots.profileRoot]
|
|
4921
5338
|
]) {
|
|
4922
5339
|
if (root === void 0) continue;
|
|
4923
|
-
const canonical = name.startsWith("execution") ?
|
|
5340
|
+
const canonical = name.startsWith("execution") ? posix2.isAbsolute(root) && posix2.normalize(root) === root : isAbsolute(root) && resolveHostPath(root) === root;
|
|
4924
5341
|
if (!canonical) throw new Error(`${name} must be a canonical absolute path`);
|
|
4925
5342
|
}
|
|
4926
|
-
if (!Number.isInteger(
|
|
5343
|
+
if (!Number.isInteger(runCell.attempt) || !Number.isInteger(benchmarkTask.attempt.maxAttempts) || runCell.attempt < 1 || runCell.attempt > benchmarkTask.attempt.maxAttempts || benchmarkTask.attempt.retryPolicy === "none" && benchmarkTask.attempt.maxAttempts !== 1) {
|
|
4927
5344
|
throw new Error("task attempt policy is invalid");
|
|
4928
5345
|
}
|
|
4929
|
-
const limits =
|
|
5346
|
+
const limits = benchmarkTask.limits;
|
|
4930
5347
|
if (!Number.isInteger(limits.timeoutMs) || limits.timeoutMs <= 0 || limits.timeoutMs > MAX_CANDIDATE_TIMER_INTERVAL_MS || !Number.isInteger(limits.maxSteps) || limits.maxSteps <= 0 || !Number.isInteger(limits.maxModelCalls) || limits.maxModelCalls < 0 || !Number.isInteger(limits.maxInputTokens) || limits.maxInputTokens < 0 || !Number.isInteger(limits.maxOutputTokens) || limits.maxOutputTokens < 0 || !Number.isFinite(limits.maxCostUsd) || limits.maxCostUsd < 0) {
|
|
4931
5348
|
throw new Error("task execution limits are invalid");
|
|
4932
5349
|
}
|
|
4933
5350
|
usdToNanos(limits.maxCostUsd, "task maxCostUsd");
|
|
4934
|
-
if (!
|
|
4935
|
-
|
|
5351
|
+
if (!benchmarkTask.model.requested.trim()) {
|
|
5352
|
+
throw new Error("evaluator model request must be non-empty");
|
|
5353
|
+
}
|
|
5354
|
+
if (!benchmarkTask.grader.name.trim() || !benchmarkTask.grader.version.trim()) {
|
|
4936
5355
|
throw new Error("evaluator benchmark grader identity must be non-empty");
|
|
4937
5356
|
}
|
|
4938
|
-
if (!Number.isInteger(
|
|
5357
|
+
if (!Number.isInteger(benchmarkTask.grader.artifact.byteLength) || benchmarkTask.grader.artifact.byteLength <= 0) {
|
|
4939
5358
|
throw new Error("evaluator benchmark grader artifact must be non-empty");
|
|
4940
5359
|
}
|
|
4941
|
-
sha256DigestSchema.parse(
|
|
4942
|
-
if (
|
|
4943
|
-
if (
|
|
5360
|
+
sha256DigestSchema.parse(benchmarkTask.grader.artifact.sha256);
|
|
5361
|
+
if (benchmarkTask.evaluatorTaskContainer) {
|
|
5362
|
+
if (benchmarkTask.evaluatorTaskContainer.source !== "evaluator-task-container" || !benchmarkTask.evaluatorTaskContainer.image.trim() || !benchmarkTask.evaluatorTaskContainer.platform.os.trim() || !benchmarkTask.evaluatorTaskContainer.platform.architecture.trim()) {
|
|
4944
5363
|
throw new Error("evaluator task container evidence is incomplete");
|
|
4945
5364
|
}
|
|
4946
|
-
sha256DigestSchema.parse(
|
|
4947
|
-
sha256DigestSchema.parse(
|
|
5365
|
+
sha256DigestSchema.parse(benchmarkTask.evaluatorTaskContainer.indexDigest);
|
|
5366
|
+
sha256DigestSchema.parse(benchmarkTask.evaluatorTaskContainer.manifestDigest);
|
|
4948
5367
|
agentCandidateContainerSchema.parse({
|
|
4949
|
-
image:
|
|
4950
|
-
indexDigest:
|
|
5368
|
+
image: benchmarkTask.evaluatorTaskContainer.image,
|
|
5369
|
+
indexDigest: benchmarkTask.evaluatorTaskContainer.indexDigest
|
|
4951
5370
|
});
|
|
4952
5371
|
}
|
|
4953
5372
|
if (delivery.kind === "utf8-file") {
|
|
@@ -4957,8 +5376,8 @@ function assertTaskInput(task, delivery) {
|
|
|
4957
5376
|
}
|
|
4958
5377
|
}
|
|
4959
5378
|
function executionPathsOverlap(left, right) {
|
|
4960
|
-
const a =
|
|
4961
|
-
const b =
|
|
5379
|
+
const a = posix2.normalize(left);
|
|
5380
|
+
const b = posix2.normalize(right);
|
|
4962
5381
|
return a === b || b.startsWith(a === "/" ? "/" : `${a}/`) || a.startsWith(b === "/" ? "/" : `${b}/`);
|
|
4963
5382
|
}
|
|
4964
5383
|
function assertDisjointHostStagingRoots(task) {
|
|
@@ -4990,51 +5409,45 @@ async function assertEmptyDirectory(path) {
|
|
|
4990
5409
|
throw new Error("profile staging root must be empty before materialization");
|
|
4991
5410
|
}
|
|
4992
5411
|
}
|
|
4993
|
-
function materializerHarness(harness) {
|
|
4994
|
-
if (!MATERIALIZER_HARNESSES.has(harness)) {
|
|
4995
|
-
throw new Error(
|
|
4996
|
-
`sealed candidate profile materialization is unsupported for harness ${harness}`
|
|
4997
|
-
);
|
|
4998
|
-
}
|
|
4999
|
-
return harness;
|
|
5000
|
-
}
|
|
5001
5412
|
async function resolveContainer(candidate, task, ports) {
|
|
5002
5413
|
const environment = candidate.bundle.execution.environment;
|
|
5414
|
+
const evaluatorTaskContainer = task.task.evaluatorTaskContainer;
|
|
5003
5415
|
const pinned = environment.kind === "pinned-container" ? environment.container : void 0;
|
|
5004
|
-
if (environment.kind === "evaluator-task-container" && !
|
|
5416
|
+
if (environment.kind === "evaluator-task-container" && !evaluatorTaskContainer) {
|
|
5005
5417
|
throw new Error("evaluator-task-container candidate requires an evaluator-owned task image");
|
|
5006
5418
|
}
|
|
5007
|
-
if (environment.kind === "pinned-container" &&
|
|
5419
|
+
if (environment.kind === "pinned-container" && evaluatorTaskContainer) {
|
|
5008
5420
|
throw new Error("pinned candidate containers cannot be replaced by a task image");
|
|
5009
5421
|
}
|
|
5010
5422
|
const resolved = await ports.containers.resolve({
|
|
5011
5423
|
candidate: pinned,
|
|
5012
|
-
evaluatorTaskContainer
|
|
5424
|
+
evaluatorTaskContainer
|
|
5013
5425
|
});
|
|
5014
5426
|
if (resolved.source !== environment.kind) throw new Error("resolved container source drifted");
|
|
5015
5427
|
if (pinned && (resolved.image !== pinned.image || resolved.indexDigest !== pinned.indexDigest)) {
|
|
5016
5428
|
throw new Error("resolved pinned container does not match the candidate image index");
|
|
5017
5429
|
}
|
|
5018
|
-
if (
|
|
5430
|
+
if (evaluatorTaskContainer && canonicalCandidateDigest(resolved) !== canonicalCandidateDigest(evaluatorTaskContainer)) {
|
|
5019
5431
|
throw new Error("resolved task container does not match evaluator-owned image evidence");
|
|
5020
5432
|
}
|
|
5021
5433
|
return resolved;
|
|
5022
5434
|
}
|
|
5023
5435
|
async function resolveModel(candidate, task, ports) {
|
|
5024
5436
|
const hints = candidate.bundle.profile.model;
|
|
5025
|
-
|
|
5437
|
+
const expected = task.task.model;
|
|
5438
|
+
if (hints?.default !== void 0 && hints.default !== expected.requested) {
|
|
5026
5439
|
throw new Error("candidate model preference conflicts with the evaluator-owned model");
|
|
5027
5440
|
}
|
|
5028
|
-
if (hints?.reasoningEffort !== void 0 && hints.reasoningEffort !==
|
|
5441
|
+
if (hints?.reasoningEffort !== void 0 && hints.reasoningEffort !== expected.reasoningEffort) {
|
|
5029
5442
|
throw new Error("candidate reasoning effort conflicts with the evaluator-owned effort");
|
|
5030
5443
|
}
|
|
5031
5444
|
const resolved = await ports.models.resolve({
|
|
5032
|
-
requested:
|
|
5445
|
+
requested: expected.requested,
|
|
5033
5446
|
harness: candidate.bundle.execution.harness,
|
|
5034
|
-
reasoningEffort:
|
|
5447
|
+
reasoningEffort: expected.reasoningEffort
|
|
5035
5448
|
});
|
|
5036
|
-
if (resolved
|
|
5037
|
-
throw new Error("model resolver drifted from the
|
|
5449
|
+
if (canonicalCandidateDigest(resolved) !== canonicalCandidateDigest(expected)) {
|
|
5450
|
+
throw new Error("model resolver drifted from the signed benchmark model");
|
|
5038
5451
|
}
|
|
5039
5452
|
return resolved;
|
|
5040
5453
|
}
|
|
@@ -5043,7 +5456,7 @@ async function prepareMemory(candidate, task, ports, preparationId, expiresAtMs,
|
|
|
5043
5456
|
if (policy.mode === "disabled") return { value: { mode: "disabled" } };
|
|
5044
5457
|
const seed = policy.seed ? await verifiedArtifactBytes(candidate, policy.seed) : void 0;
|
|
5045
5458
|
const executionSegment = canonicalCandidateDigest({ executionId: task.executionId }).slice(7);
|
|
5046
|
-
const taskSegment = canonicalCandidateDigest({
|
|
5459
|
+
const taskSegment = canonicalCandidateDigest({ taskDigest: task.task.digest }).slice(7);
|
|
5047
5460
|
const preparationSegment = canonicalCandidateDigest({ preparationId }).slice(7, 23);
|
|
5048
5461
|
const effectiveNamespace = `candidate/${candidate.bundle.digest.slice(7, 23)}/${executionSegment}/${taskSegment}/${preparationSegment}`;
|
|
5049
5462
|
const reset = await withinCandidateCleanupDeadline(
|
|
@@ -5110,7 +5523,7 @@ function buildLaunch(candidate, task, profileFlags) {
|
|
|
5110
5523
|
}
|
|
5111
5524
|
const candidateRoot = task.executionRoots.candidateRoot;
|
|
5112
5525
|
if (!candidateRoot) throw new Error("candidate entrypoint requires a container candidate root");
|
|
5113
|
-
const entrypoint =
|
|
5526
|
+
const entrypoint = posix2.join(candidateRoot, launch.entrypoint);
|
|
5114
5527
|
const candidateArgs = launch.args ?? [];
|
|
5115
5528
|
if (launch.interpreter) {
|
|
5116
5529
|
return {
|
|
@@ -5160,7 +5573,7 @@ function candidateEntrypointReceipt(candidate) {
|
|
|
5160
5573
|
function absoluteExecutionCwd(cwd, roots) {
|
|
5161
5574
|
const root = cwd.workspace === "task" ? roots.taskRoot : roots.candidateRoot;
|
|
5162
5575
|
if (!root) throw new Error("candidate cwd is missing its execution workspace root");
|
|
5163
|
-
const absolute = cwd.path === "." ? root :
|
|
5576
|
+
const absolute = cwd.path === "." ? root : posix2.join(root, cwd.path);
|
|
5164
5577
|
if (absolute !== root && !absolute.startsWith(`${root}/`)) {
|
|
5165
5578
|
throw new Error("candidate cwd escapes its execution workspace");
|
|
5166
5579
|
}
|
|
@@ -5236,20 +5649,19 @@ export {
|
|
|
5236
5649
|
canonicalCandidateDigest,
|
|
5237
5650
|
immutableCandidateValue,
|
|
5238
5651
|
canonicalCandidateDocument,
|
|
5652
|
+
verifyCanonicalCandidateDocument,
|
|
5239
5653
|
embeddedCandidateArtifact,
|
|
5240
5654
|
omitTopLevelDigest,
|
|
5241
5655
|
deepFreezeCandidate,
|
|
5242
|
-
|
|
5656
|
+
candidateMaterializerHarness,
|
|
5657
|
+
createAgentCandidateProfileActivation,
|
|
5658
|
+
parseAgentCandidateProfileActivation,
|
|
5243
5659
|
freezeGenericAgentCandidateProfile,
|
|
5244
|
-
assertCandidateProfileBinding,
|
|
5245
5660
|
parseExactAgentProfile,
|
|
5246
5661
|
parseExactAgentProfileDiff,
|
|
5247
5662
|
applyExactAgentProfileDiff,
|
|
5248
5663
|
parseExactCandidateProfile,
|
|
5249
|
-
|
|
5250
|
-
PENDING_FORMAT_VERSION,
|
|
5251
|
-
TERMINAL_FORMAT_VERSION,
|
|
5252
|
-
PHASE_FORMAT_VERSION,
|
|
5664
|
+
agentCandidateProfileAsAgentProfile,
|
|
5253
5665
|
assertExactObjectKeys,
|
|
5254
5666
|
terminalRecord,
|
|
5255
5667
|
recoveredTerminalRecord,
|
|
@@ -5264,6 +5676,7 @@ export {
|
|
|
5264
5676
|
candidateCleanupTimeout,
|
|
5265
5677
|
candidateCleanupDeadline,
|
|
5266
5678
|
withinCandidateCleanupDeadline,
|
|
5679
|
+
readVerifiedArtifact,
|
|
5267
5680
|
verifyBytes,
|
|
5268
5681
|
verifyMaterializedWorkspace,
|
|
5269
5682
|
captureMaterializedWorkspace,
|
|
@@ -5281,12 +5694,17 @@ export {
|
|
|
5281
5694
|
candidateClaimFileInternals,
|
|
5282
5695
|
sealAgentCandidateModelSettlement,
|
|
5283
5696
|
usdToNanos,
|
|
5284
|
-
|
|
5697
|
+
sealAgentCandidateExecutorStopAcknowledgement,
|
|
5285
5698
|
persistCandidateOutputArtifact,
|
|
5286
5699
|
persistCandidateModelSettlementEvidence,
|
|
5287
5700
|
RecoveryAgentCandidateTraceStore,
|
|
5288
5701
|
executePreparedAgentCandidate,
|
|
5702
|
+
AGENT_CANDIDATE_EXECUTION_SUPPORT,
|
|
5289
5703
|
verifyAgentCandidateBundle,
|
|
5704
|
+
verifiedResourceTextByDigest,
|
|
5705
|
+
CANDIDATE_KNOWLEDGE_ROOT_ENV,
|
|
5706
|
+
CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG_ENV,
|
|
5707
|
+
candidateKnowledgeExecutionPaths,
|
|
5290
5708
|
prepareAgentCandidateExecution
|
|
5291
5709
|
};
|
|
5292
|
-
//# sourceMappingURL=chunk-
|
|
5710
|
+
//# sourceMappingURL=chunk-WTZ37EQY.js.map
|