@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
package/dist/intelligence.js
CHANGED
|
@@ -1,32 +1,36 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
AgentCandidateExperimentCellExecutionError,
|
|
3
|
+
createAgentImprovementActivation,
|
|
4
|
+
createAgentImprovementMeasuredComparison,
|
|
5
|
+
createAgentImprovementProposal,
|
|
6
|
+
executeAgentCandidateExperimentCell,
|
|
7
|
+
proposeAgentImprovement,
|
|
8
|
+
reviewAgentImprovementProposal,
|
|
9
|
+
runAgentCandidateExperiment,
|
|
10
|
+
verifyAgentImprovementActivation,
|
|
11
|
+
verifyAgentImprovementProposal,
|
|
12
|
+
verifyAgentImprovementReview,
|
|
13
|
+
verifyCandidateExecutionEvidence
|
|
14
|
+
} from "./chunk-G55QE4IQ.js";
|
|
5
15
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
prepareAgentCandidateExecution,
|
|
14
|
-
sealAgentCandidateBundle,
|
|
15
|
-
verifyAgentCandidateBundle
|
|
16
|
-
} from "./chunk-CNH7DF7Z.js";
|
|
16
|
+
AGENT_CANDIDATE_EXECUTION_SUPPORT,
|
|
17
|
+
CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG_ENV,
|
|
18
|
+
CANDIDATE_KNOWLEDGE_ROOT_ENV,
|
|
19
|
+
candidateKnowledgeExecutionPaths,
|
|
20
|
+
canonicalCandidateBytes,
|
|
21
|
+
parseAgentCandidateProfileActivation
|
|
22
|
+
} from "./chunk-WTZ37EQY.js";
|
|
17
23
|
import {
|
|
18
24
|
buildLoopOtelSpans,
|
|
19
25
|
buildRuntimeEventOtelSpans,
|
|
20
26
|
createOtelExporter,
|
|
21
27
|
flatOtelSpan
|
|
22
28
|
} from "./chunk-ISTDY47H.js";
|
|
23
|
-
import "./chunk-
|
|
29
|
+
import "./chunk-IMSNJSXH.js";
|
|
24
30
|
import "./chunk-3MDZX7YU.js";
|
|
25
|
-
import
|
|
26
|
-
runAnalystLoop
|
|
27
|
-
} from "./chunk-QDSOD7RC.js";
|
|
31
|
+
import "./chunk-QDSOD7RC.js";
|
|
28
32
|
import "./chunk-M22PL4GH.js";
|
|
29
|
-
import "./chunk-
|
|
33
|
+
import "./chunk-DHCHL6OG.js";
|
|
30
34
|
import "./chunk-EP6RVHMX.js";
|
|
31
35
|
import "./chunk-YEJR7IXO.js";
|
|
32
36
|
import "./chunk-DGUM43GV.js";
|
|
@@ -414,318 +418,6 @@ function isJsonSchema(v) {
|
|
|
414
418
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
415
419
|
}
|
|
416
420
|
|
|
417
|
-
// src/intelligence/improvement-cycle.ts
|
|
418
|
-
import { assertNoJudgeVerdict } from "@tangle-network/agent-eval/analyst";
|
|
419
|
-
import { agentCandidateBundleSchema } from "@tangle-network/agent-interface";
|
|
420
|
-
async function rethrowAfterImprovementDispose(cause, improvement) {
|
|
421
|
-
const disposeErrors = [];
|
|
422
|
-
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
423
|
-
try {
|
|
424
|
-
await improvement.dispose();
|
|
425
|
-
} catch (disposeCause) {
|
|
426
|
-
disposeErrors.push(disposeCause);
|
|
427
|
-
continue;
|
|
428
|
-
}
|
|
429
|
-
if (disposeErrors.length === 0) throw cause;
|
|
430
|
-
throw new AggregateError(
|
|
431
|
-
[cause, ...disposeErrors],
|
|
432
|
-
"proposeAgentImprovement failed; the improvement cleanup retry succeeded"
|
|
433
|
-
);
|
|
434
|
-
}
|
|
435
|
-
throw new AggregateError(
|
|
436
|
-
[cause, ...disposeErrors],
|
|
437
|
-
"proposeAgentImprovement failed and its improvement resources could not be cleaned"
|
|
438
|
-
);
|
|
439
|
-
}
|
|
440
|
-
async function proposeAgentImprovement(options) {
|
|
441
|
-
const writeBackSurface = options.improvement.skills?.writeBack ? "skill" : options.improvement.memory?.writeBack ? "memory" : null;
|
|
442
|
-
if (writeBackSurface) {
|
|
443
|
-
throw new Error(
|
|
444
|
-
`proposeAgentImprovement cannot write ${writeBackSurface} before human approval`
|
|
445
|
-
);
|
|
446
|
-
}
|
|
447
|
-
const analysis = await runAnalystLoop({
|
|
448
|
-
...options.analysis,
|
|
449
|
-
runId: options.runId
|
|
450
|
-
});
|
|
451
|
-
const findings = assertNoJudgeVerdict(
|
|
452
|
-
analysis.analystResult.findings,
|
|
453
|
-
"proposeAgentImprovement findings"
|
|
454
|
-
);
|
|
455
|
-
const improvement = await improve(options.profile, [...findings], options.improvement);
|
|
456
|
-
try {
|
|
457
|
-
const candidateBundle = improvement.shipped && options.buildCandidate ? await options.buildCandidate({ analysis, improvement }) : void 0;
|
|
458
|
-
const proposal = createAgentImprovementProposal({
|
|
459
|
-
runId: options.runId,
|
|
460
|
-
surface: options.improvement.surface ?? "prompt",
|
|
461
|
-
baselineProfile: options.profile,
|
|
462
|
-
candidateProfile: improvement.profile,
|
|
463
|
-
findings,
|
|
464
|
-
evaluation: improvement.raw,
|
|
465
|
-
...candidateBundle ? { candidateBundle } : {},
|
|
466
|
-
...options.now ? { now: options.now } : {}
|
|
467
|
-
});
|
|
468
|
-
return { analysis, improvement, proposal };
|
|
469
|
-
} catch (cause) {
|
|
470
|
-
return rethrowAfterImprovementDispose(cause, improvement);
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
function createAgentImprovementProposal(options) {
|
|
474
|
-
const findings = assertNoJudgeVerdict(
|
|
475
|
-
[...options.findings],
|
|
476
|
-
"createAgentImprovementProposal findings"
|
|
477
|
-
);
|
|
478
|
-
const candidateBundle = options.candidateBundle ? sealBuiltCandidate(options.candidateBundle) : void 0;
|
|
479
|
-
const baselineProfile = parseExactAgentProfile(
|
|
480
|
-
options.baselineProfile,
|
|
481
|
-
"proposal baseline profile"
|
|
482
|
-
);
|
|
483
|
-
const candidateProfile = parseExactAgentProfile(
|
|
484
|
-
options.candidateProfile,
|
|
485
|
-
"proposal candidate profile"
|
|
486
|
-
);
|
|
487
|
-
assertMeasuredProfileBinding({
|
|
488
|
-
surface: options.surface,
|
|
489
|
-
baselineProfile,
|
|
490
|
-
candidateProfile,
|
|
491
|
-
evaluation: options.evaluation,
|
|
492
|
-
hasExecutableBundle: candidateBundle !== void 0
|
|
493
|
-
});
|
|
494
|
-
if (candidateBundle) {
|
|
495
|
-
if (options.evaluation.gateDecision !== "ship") {
|
|
496
|
-
throw new Error("executable candidate bundle requires a passing measured comparison");
|
|
497
|
-
}
|
|
498
|
-
assertCandidateProfileBinding(candidateProfile, candidateBundle.profile);
|
|
499
|
-
}
|
|
500
|
-
const withoutDigest = {
|
|
501
|
-
schemaVersion: 1,
|
|
502
|
-
kind: "agent-improvement-proposal",
|
|
503
|
-
runId: options.runId,
|
|
504
|
-
surface: options.surface,
|
|
505
|
-
proposedAt: (options.now ?? (() => /* @__PURE__ */ new Date()))().toISOString(),
|
|
506
|
-
baselineProfile,
|
|
507
|
-
baselineProfileHash: canonicalCandidateDigest(baselineProfile),
|
|
508
|
-
candidateProfile,
|
|
509
|
-
candidateProfileHash: canonicalCandidateDigest(candidateProfile),
|
|
510
|
-
findings: canonicalJsonValue([...findings]),
|
|
511
|
-
evaluation: canonicalJsonValue(improvementEvaluation(options.evaluation)),
|
|
512
|
-
...candidateBundle ? { candidateBundle } : {}
|
|
513
|
-
};
|
|
514
|
-
return canonicalCandidateDocument(withoutDigest).value;
|
|
515
|
-
}
|
|
516
|
-
function reviewAgentImprovementProposal(inputProposal, input) {
|
|
517
|
-
const proposal = verifyAgentImprovementProposal(inputProposal);
|
|
518
|
-
if (!input.reviewedBy.trim()) throw new Error("candidate review requires reviewedBy");
|
|
519
|
-
if (!input.reason.trim()) throw new Error("candidate review requires a reason");
|
|
520
|
-
if (input.decision === "approve") {
|
|
521
|
-
if (proposal.evaluation.gateDecision !== "ship") {
|
|
522
|
-
throw new Error("candidate cannot be approved without a passing measured comparison");
|
|
523
|
-
}
|
|
524
|
-
if (!proposal.candidateBundle) {
|
|
525
|
-
throw new Error("candidate cannot be approved until an executable bundle is sealed");
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
const withoutDigest = {
|
|
529
|
-
schemaVersion: 1,
|
|
530
|
-
kind: "agent-improvement-review",
|
|
531
|
-
proposalDigest: proposal.digest,
|
|
532
|
-
...proposal.candidateBundle ? { candidateBundleDigest: proposal.candidateBundle.digest } : {},
|
|
533
|
-
decision: input.decision,
|
|
534
|
-
reviewedBy: input.reviewedBy,
|
|
535
|
-
reviewedAt: (input.now ?? (() => /* @__PURE__ */ new Date()))().toISOString(),
|
|
536
|
-
reason: input.reason,
|
|
537
|
-
...input.feedback === void 0 ? {} : { feedback: input.feedback }
|
|
538
|
-
};
|
|
539
|
-
return canonicalCandidateDocument(withoutDigest).value;
|
|
540
|
-
}
|
|
541
|
-
async function executeApprovedAgentCandidate(options) {
|
|
542
|
-
const proposal = verifyAgentImprovementProposal(options.proposal);
|
|
543
|
-
const review = verifyAgentImprovementReview(options.review);
|
|
544
|
-
if (review.decision !== "approve") throw new Error("candidate review is not an approval");
|
|
545
|
-
if (review.proposalDigest !== proposal.digest) {
|
|
546
|
-
throw new Error("candidate approval does not match the proposed improvement");
|
|
547
|
-
}
|
|
548
|
-
const bundle = proposal.candidateBundle;
|
|
549
|
-
if (!bundle) throw new Error("approved proposal does not contain an executable candidate bundle");
|
|
550
|
-
if (review.candidateBundleDigest !== bundle.digest) {
|
|
551
|
-
throw new Error("candidate approval does not match the executable bundle");
|
|
552
|
-
}
|
|
553
|
-
if (!await options.authorizeReview(review, proposal)) {
|
|
554
|
-
throw new Error("candidate approval was not authorized by the configured authority");
|
|
555
|
-
}
|
|
556
|
-
const verified = await verifyAgentCandidateBundle(bundle, options.ports);
|
|
557
|
-
const prepared = await prepareAgentCandidateExecution(
|
|
558
|
-
verified,
|
|
559
|
-
options.task,
|
|
560
|
-
options.ports,
|
|
561
|
-
options.preparation
|
|
562
|
-
);
|
|
563
|
-
const finalization = await executePreparedAgentCandidate(prepared, options.execution);
|
|
564
|
-
return {
|
|
565
|
-
finalization,
|
|
566
|
-
evidence: {
|
|
567
|
-
proposalDigest: proposal.digest,
|
|
568
|
-
reviewDigest: review.digest,
|
|
569
|
-
bundleDigest: bundle.digest,
|
|
570
|
-
executionId: prepared.executionId,
|
|
571
|
-
executionPlanDigest: prepared.executionPlan.value.digest,
|
|
572
|
-
materializationReceiptDigest: prepared.materializationReceipt.digest,
|
|
573
|
-
succeeded: finalization.succeeded,
|
|
574
|
-
...finalization.succeeded ? { runReceiptDigest: finalization.receipt.digest } : {}
|
|
575
|
-
}
|
|
576
|
-
};
|
|
577
|
-
}
|
|
578
|
-
function verifyAgentImprovementProposal(input) {
|
|
579
|
-
if (!isRecord(input) || input.kind !== "agent-improvement-proposal" || input.schemaVersion !== 1) {
|
|
580
|
-
throw new Error("invalid agent improvement proposal");
|
|
581
|
-
}
|
|
582
|
-
const proposal = input;
|
|
583
|
-
const parsedBaselineProfile = parseExactAgentProfile(
|
|
584
|
-
proposal.baselineProfile,
|
|
585
|
-
"proposal baseline profile"
|
|
586
|
-
);
|
|
587
|
-
if (proposal.baselineProfileHash !== canonicalCandidateDigest(parsedBaselineProfile)) {
|
|
588
|
-
throw new Error("proposal baselineProfileHash does not match baselineProfile");
|
|
589
|
-
}
|
|
590
|
-
const parsedProfile = parseExactAgentProfile(
|
|
591
|
-
proposal.candidateProfile,
|
|
592
|
-
"proposal candidate profile"
|
|
593
|
-
);
|
|
594
|
-
if (proposal.candidateProfileHash !== canonicalCandidateDigest(parsedProfile)) {
|
|
595
|
-
throw new Error("proposal candidateProfileHash does not match candidateProfile");
|
|
596
|
-
}
|
|
597
|
-
assertMeasuredProfileBinding({
|
|
598
|
-
surface: proposal.surface,
|
|
599
|
-
baselineProfile: parsedBaselineProfile,
|
|
600
|
-
candidateProfile: parsedProfile,
|
|
601
|
-
evaluation: proposal.evaluation,
|
|
602
|
-
hasExecutableBundle: proposal.candidateBundle !== void 0
|
|
603
|
-
});
|
|
604
|
-
if (!Array.isArray(proposal.findings)) throw new Error("proposal findings must be an array");
|
|
605
|
-
if (!isSha256Digest(proposal.digest)) throw new Error("proposal digest is invalid");
|
|
606
|
-
if (proposal.candidateBundle) {
|
|
607
|
-
const parsedBundle = agentCandidateBundleSchema.parse(proposal.candidateBundle);
|
|
608
|
-
const sealed = sealAgentCandidateBundle(omitTopLevelDigest(parsedBundle));
|
|
609
|
-
if (sealed.digest !== parsedBundle.digest)
|
|
610
|
-
throw new Error("proposal candidate bundle digest is invalid");
|
|
611
|
-
assertCandidateProfileBinding(parsedProfile, sealed.profile);
|
|
612
|
-
}
|
|
613
|
-
const actual = canonicalCandidateDigest(omitTopLevelDigest(proposal));
|
|
614
|
-
if (actual !== proposal.digest)
|
|
615
|
-
throw new Error("agent improvement proposal digest does not match");
|
|
616
|
-
return immutableCandidateValue(proposal);
|
|
617
|
-
}
|
|
618
|
-
function assertMeasuredProfileBinding(input) {
|
|
619
|
-
const baselineDigest = canonicalCandidateDigest(input.baselineProfile);
|
|
620
|
-
if (input.evaluation.gateDecision !== "ship") {
|
|
621
|
-
if (canonicalCandidateDigest(input.candidateProfile) !== baselineDigest) {
|
|
622
|
-
throw new Error("non-shipping evaluation must retain the baseline candidate profile");
|
|
623
|
-
}
|
|
624
|
-
return;
|
|
625
|
-
}
|
|
626
|
-
const measured = measuredWinnerProfile(
|
|
627
|
-
input.baselineProfile,
|
|
628
|
-
input.surface,
|
|
629
|
-
input.evaluation.winner.surface
|
|
630
|
-
);
|
|
631
|
-
if (!measured) {
|
|
632
|
-
if (input.hasExecutableBundle) {
|
|
633
|
-
throw new Error(
|
|
634
|
-
`executable '${input.surface}' candidate cannot be bound to its measured winner surface`
|
|
635
|
-
);
|
|
636
|
-
}
|
|
637
|
-
if (canonicalCandidateDigest(input.candidateProfile) !== baselineDigest) {
|
|
638
|
-
throw new Error(
|
|
639
|
-
`unbound '${input.surface}' improvement must retain the baseline candidate profile`
|
|
640
|
-
);
|
|
641
|
-
}
|
|
642
|
-
return;
|
|
643
|
-
}
|
|
644
|
-
if (canonicalCandidateDigest(input.candidateProfile) !== canonicalCandidateDigest(measured)) {
|
|
645
|
-
throw new Error("proposal candidate profile does not match the measured winner surface");
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
function measuredWinnerProfile(baselineProfile, surface, winner) {
|
|
649
|
-
if (surface === "code" || surface === "memory") return null;
|
|
650
|
-
if (typeof winner !== "string") {
|
|
651
|
-
throw new Error(`measured '${surface}' winner is not a serializable profile surface`);
|
|
652
|
-
}
|
|
653
|
-
if (surface !== "skills") {
|
|
654
|
-
return applyImprovementWinnerToProfile(baselineProfile, surface, winner);
|
|
655
|
-
}
|
|
656
|
-
try {
|
|
657
|
-
return applyImprovementWinnerToProfile(baselineProfile, surface, winner);
|
|
658
|
-
} catch {
|
|
659
|
-
return null;
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
function sealBuiltCandidate(input) {
|
|
663
|
-
if (!("digest" in input)) return sealAgentCandidateBundle(input);
|
|
664
|
-
const parsed = agentCandidateBundleSchema.parse(input);
|
|
665
|
-
const sealed = sealAgentCandidateBundle(omitTopLevelDigest(parsed));
|
|
666
|
-
if (sealed.digest !== parsed.digest) {
|
|
667
|
-
throw new Error("built candidate bundle digest is invalid");
|
|
668
|
-
}
|
|
669
|
-
return sealed;
|
|
670
|
-
}
|
|
671
|
-
function verifyAgentImprovementReview(input) {
|
|
672
|
-
if (!isRecord(input) || input.kind !== "agent-improvement-review" || input.schemaVersion !== 1) {
|
|
673
|
-
throw new Error("invalid agent improvement review");
|
|
674
|
-
}
|
|
675
|
-
const review = input;
|
|
676
|
-
if (!isSha256Digest(review.digest) || !isSha256Digest(review.proposalDigest)) {
|
|
677
|
-
throw new Error("candidate review digest is invalid");
|
|
678
|
-
}
|
|
679
|
-
if (review.candidateBundleDigest !== void 0 && !isSha256Digest(review.candidateBundleDigest)) {
|
|
680
|
-
throw new Error("candidate review bundle digest is invalid");
|
|
681
|
-
}
|
|
682
|
-
if (!["approve", "reject", "request-changes"].includes(review.decision)) {
|
|
683
|
-
throw new Error("candidate review decision is invalid");
|
|
684
|
-
}
|
|
685
|
-
const actual = canonicalCandidateDigest(omitTopLevelDigest(review));
|
|
686
|
-
if (actual !== review.digest) throw new Error("agent improvement review digest does not match");
|
|
687
|
-
return immutableCandidateValue(review);
|
|
688
|
-
}
|
|
689
|
-
function improvementEvaluation(result) {
|
|
690
|
-
return {
|
|
691
|
-
baseline: result.baseline,
|
|
692
|
-
winner: result.winner,
|
|
693
|
-
lift: result.lift,
|
|
694
|
-
diff: result.diff,
|
|
695
|
-
provenance: result.provenance,
|
|
696
|
-
gateDecision: result.gateDecision,
|
|
697
|
-
generationsExplored: result.generationsExplored,
|
|
698
|
-
durationMs: result.durationMs,
|
|
699
|
-
totalCostUsd: result.totalCostUsd,
|
|
700
|
-
insight: result.insight,
|
|
701
|
-
...result.power === void 0 ? {} : { power: result.power }
|
|
702
|
-
};
|
|
703
|
-
}
|
|
704
|
-
function isRecord(value) {
|
|
705
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
706
|
-
}
|
|
707
|
-
function isSha256Digest(value) {
|
|
708
|
-
return typeof value === "string" && /^sha256:[a-f0-9]{64}$/.test(value);
|
|
709
|
-
}
|
|
710
|
-
function canonicalJsonValue(value, path = "$") {
|
|
711
|
-
if (value === null || typeof value === "string" || typeof value === "boolean") return value;
|
|
712
|
-
if (typeof value === "number") {
|
|
713
|
-
if (!Number.isFinite(value)) throw new Error(`non-finite number at ${path}`);
|
|
714
|
-
return value;
|
|
715
|
-
}
|
|
716
|
-
if (Array.isArray(value)) {
|
|
717
|
-
return value.map((entry, index) => {
|
|
718
|
-
if (entry === void 0) throw new Error(`undefined array entry at ${path}[${index}]`);
|
|
719
|
-
return canonicalJsonValue(entry, `${path}[${index}]`);
|
|
720
|
-
});
|
|
721
|
-
}
|
|
722
|
-
if (typeof value === "object") {
|
|
723
|
-
const entries = Object.entries(value).filter(([, entry]) => entry !== void 0).map(([key, entry]) => [key, canonicalJsonValue(entry, `${path}.${key}`)]);
|
|
724
|
-
return Object.fromEntries(entries);
|
|
725
|
-
}
|
|
726
|
-
throw new Error(`unsupported proposal value at ${path}`);
|
|
727
|
-
}
|
|
728
|
-
|
|
729
421
|
// src/intelligence/resolver.ts
|
|
730
422
|
function emptyAccumulator() {
|
|
731
423
|
return {
|
|
@@ -1101,6 +793,467 @@ async function composeCertifiedProfileFromWire(base, profile, ctx = {}) {
|
|
|
1101
793
|
return composeCertifiedProfile(base, manifestFromProfile(profile), ctx);
|
|
1102
794
|
}
|
|
1103
795
|
|
|
796
|
+
// src/intelligence/sandbox-approved-candidate.ts
|
|
797
|
+
import { posix } from "path";
|
|
798
|
+
var sandboxCandidateExperimentExecutionSupport = Object.freeze({
|
|
799
|
+
outcomes: Object.freeze(["output"]),
|
|
800
|
+
outputMediaTypes: Object.freeze(["text/*", "application/json", "*+json"]),
|
|
801
|
+
code: Object.freeze(["disabled"]),
|
|
802
|
+
memory: Object.freeze(["disabled"]),
|
|
803
|
+
knowledge: true,
|
|
804
|
+
profile: AGENT_CANDIDATE_EXECUTION_SUPPORT.profile,
|
|
805
|
+
isolation: Object.freeze({
|
|
806
|
+
freshSandbox: true,
|
|
807
|
+
exactProcess: true,
|
|
808
|
+
egress: Object.freeze(["blocked", "strict"])
|
|
809
|
+
})
|
|
810
|
+
});
|
|
811
|
+
function createSandboxCandidateExperimentExecutor(options) {
|
|
812
|
+
const executor = new SandboxAgentCandidateExecutor(
|
|
813
|
+
options.client,
|
|
814
|
+
options.sandbox,
|
|
815
|
+
options.resultTimeoutMs
|
|
816
|
+
);
|
|
817
|
+
return Object.freeze({
|
|
818
|
+
executor,
|
|
819
|
+
async execute(input) {
|
|
820
|
+
return await executeAgentCandidateExperimentCell({
|
|
821
|
+
...input,
|
|
822
|
+
attempt: input.attempt ?? 1,
|
|
823
|
+
executionId: input.executionId,
|
|
824
|
+
executionRoots: input.executionRoots,
|
|
825
|
+
stagingRoots: input.stagingRoots,
|
|
826
|
+
ports: options.ports,
|
|
827
|
+
...input.preparation ? { preparation: input.preparation } : {},
|
|
828
|
+
execution: {
|
|
829
|
+
executor,
|
|
830
|
+
grader: options.grader,
|
|
831
|
+
outputArtifacts: options.outputArtifacts,
|
|
832
|
+
traceStore: options.traceStore,
|
|
833
|
+
claimStore: options.claimStore,
|
|
834
|
+
...options.cleanupTimeoutMs === void 0 ? {} : { cleanupTimeoutMs: options.cleanupTimeoutMs },
|
|
835
|
+
...options.resultTimeoutMs === void 0 ? {} : { resultTimeoutMs: options.resultTimeoutMs }
|
|
836
|
+
}
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
var SandboxAgentCandidateExecutor = class {
|
|
842
|
+
constructor(client, options = {}, captureTimeoutMs = 12e4) {
|
|
843
|
+
this.client = client;
|
|
844
|
+
this.options = options;
|
|
845
|
+
this.captureTimeoutMs = captureTimeoutMs;
|
|
846
|
+
}
|
|
847
|
+
client;
|
|
848
|
+
options;
|
|
849
|
+
captureTimeoutMs;
|
|
850
|
+
states = /* @__PURE__ */ new Map();
|
|
851
|
+
async execute(request, context) {
|
|
852
|
+
assertSupportedRequest(request);
|
|
853
|
+
const outcome = request.benchmark.task.outcome;
|
|
854
|
+
if (outcome.kind !== "output") throw new Error("sandbox executor requires an output task");
|
|
855
|
+
const key = executionKey(request.executionId, request.executionPlan.value.digest);
|
|
856
|
+
const sandbox = await this.client.create(sandboxCreateOptions(request, this.options), {
|
|
857
|
+
signal: context.signal,
|
|
858
|
+
timeoutMs: this.options.createTimeoutMs ?? 12e4
|
|
859
|
+
});
|
|
860
|
+
const state = { sandbox };
|
|
861
|
+
this.states.set(key, state);
|
|
862
|
+
if ((await sandbox.process.list()).length !== 0) {
|
|
863
|
+
throw new Error("fresh candidate sandbox already contains a process");
|
|
864
|
+
}
|
|
865
|
+
await materializeRequest(sandbox, request);
|
|
866
|
+
const launch = exactLaunch(request);
|
|
867
|
+
const startedAt = Date.now();
|
|
868
|
+
state.trace = {
|
|
869
|
+
runId: request.trace.runId,
|
|
870
|
+
scenarioId: request.benchmark.task.scenario.id,
|
|
871
|
+
startedAt,
|
|
872
|
+
deadlineAtMs: context.deadlineAtMs,
|
|
873
|
+
timeoutMs: request.hardLimits.timeoutMs,
|
|
874
|
+
tags: { ...request.trace.tags, sandboxId: sandbox.id },
|
|
875
|
+
written: false
|
|
876
|
+
};
|
|
877
|
+
const process2 = await sandbox.process.spawnExact(launch.executable, launch.args, {
|
|
878
|
+
cwd: request.launch.cwd,
|
|
879
|
+
env: { ...request.launch.env },
|
|
880
|
+
...launch.stdin === void 0 ? {} : { stdin: launch.stdin },
|
|
881
|
+
timeoutMs: request.hardLimits.timeoutMs
|
|
882
|
+
});
|
|
883
|
+
const outputPromise = collectOutput(process2, outcome.maxBytes);
|
|
884
|
+
let cancellation;
|
|
885
|
+
let cancellationTermination;
|
|
886
|
+
let processExited = false;
|
|
887
|
+
const cancel = () => {
|
|
888
|
+
if (processExited) return;
|
|
889
|
+
cancellationTermination = Date.now() >= context.deadlineAtMs ? { kind: "timeout", timeoutMs: request.hardLimits.timeoutMs } : { kind: "cancelled" };
|
|
890
|
+
cancellation ??= killProcess(process2);
|
|
891
|
+
};
|
|
892
|
+
context.signal.addEventListener("abort", cancel, { once: true });
|
|
893
|
+
if (context.signal.aborted) cancel();
|
|
894
|
+
try {
|
|
895
|
+
const waitedExitCode = await process2.wait();
|
|
896
|
+
processExited = true;
|
|
897
|
+
context.signal.removeEventListener("abort", cancel);
|
|
898
|
+
if (cancellation) await cancellation;
|
|
899
|
+
const status = await process2.status();
|
|
900
|
+
if (status.running || status.exitCode !== waitedExitCode) {
|
|
901
|
+
throw new Error("sandbox process returned an inconsistent terminal status");
|
|
902
|
+
}
|
|
903
|
+
state.output = await awaitOutput(outputPromise, context.signal, context.deadlineAtMs);
|
|
904
|
+
state.termination = cancellationTermination ?? processTermination(status);
|
|
905
|
+
await appendSandboxTrace(state, context.traceStore, status);
|
|
906
|
+
return { executionId: request.executionId, termination: state.termination };
|
|
907
|
+
} finally {
|
|
908
|
+
context.signal.removeEventListener("abort", cancel);
|
|
909
|
+
void outputPromise.catch(() => void 0);
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
async stop(request, context) {
|
|
913
|
+
context.signal.throwIfAborted();
|
|
914
|
+
const sandbox = await this.resolve(request, true);
|
|
915
|
+
if (!sandbox) return { stopped: true };
|
|
916
|
+
const statuses = await sandbox.process.list();
|
|
917
|
+
if (statuses.length > 1) throw new Error("candidate sandbox contains more than one process");
|
|
918
|
+
const status = statuses[0];
|
|
919
|
+
if (status?.running) {
|
|
920
|
+
const process2 = await sandbox.process.get(status.pid);
|
|
921
|
+
if (!process2) throw new Error("candidate sandbox lost its running process handle");
|
|
922
|
+
await killProcess(process2);
|
|
923
|
+
}
|
|
924
|
+
context.signal.throwIfAborted();
|
|
925
|
+
const remaining = await sandbox.process.list();
|
|
926
|
+
if (remaining.some((entry) => entry.running)) {
|
|
927
|
+
throw new Error("candidate sandbox process termination is not proven");
|
|
928
|
+
}
|
|
929
|
+
const state = this.states.get(executionKey(request.executionId, request.executionPlanDigest));
|
|
930
|
+
if (state) {
|
|
931
|
+
if (context.reason === "timeout") {
|
|
932
|
+
state.termination = { kind: "timeout", timeoutMs: state.trace?.timeoutMs ?? 0 };
|
|
933
|
+
}
|
|
934
|
+
await appendSandboxTrace(state, context.traceStore, remaining[0]);
|
|
935
|
+
}
|
|
936
|
+
return { stopped: true };
|
|
937
|
+
}
|
|
938
|
+
async capture(request, context) {
|
|
939
|
+
context.signal.throwIfAborted();
|
|
940
|
+
const sandbox = await this.resolve(request, false);
|
|
941
|
+
const statuses = await sandbox.process.list();
|
|
942
|
+
if (statuses.length > 1 || statuses.some((entry) => entry.running)) {
|
|
943
|
+
throw new Error("candidate sandbox must contain one stopped process before capture");
|
|
944
|
+
}
|
|
945
|
+
const state = this.states.get(executionKey(request.executionId, request.executionPlanDigest));
|
|
946
|
+
let output = state?.output;
|
|
947
|
+
let termination = state?.termination;
|
|
948
|
+
const status = statuses[0];
|
|
949
|
+
if (status && !output) {
|
|
950
|
+
const process2 = await sandbox.process.get(status.pid);
|
|
951
|
+
if (!process2) throw new Error("candidate sandbox lost its captured process handle");
|
|
952
|
+
const expected = sandboxOutputSpec(sandbox);
|
|
953
|
+
output = await awaitOutput(
|
|
954
|
+
collectOutput(process2, expected.maxBytes),
|
|
955
|
+
context.signal,
|
|
956
|
+
Date.now() + this.captureTimeoutMs
|
|
957
|
+
);
|
|
958
|
+
}
|
|
959
|
+
if (status && !termination) {
|
|
960
|
+
termination = processTermination(status);
|
|
961
|
+
}
|
|
962
|
+
context.signal.throwIfAborted();
|
|
963
|
+
const evidence = canonicalCandidateBytes({
|
|
964
|
+
kind: "sandbox-agent-candidate-capture",
|
|
965
|
+
sandboxId: sandbox.id,
|
|
966
|
+
executionId: request.executionId,
|
|
967
|
+
executionPlanDigest: request.executionPlanDigest,
|
|
968
|
+
...status ? {
|
|
969
|
+
process: {
|
|
970
|
+
pid: status.pid,
|
|
971
|
+
exitCode: status.exitCode,
|
|
972
|
+
...status.exitSignal ? { exitSignal: status.exitSignal } : {}
|
|
973
|
+
}
|
|
974
|
+
} : {},
|
|
975
|
+
...termination ? { termination } : {}
|
|
976
|
+
});
|
|
977
|
+
return {
|
|
978
|
+
...output ? { taskOutcome: { kind: "output", bytes: output } } : {},
|
|
979
|
+
evidence
|
|
980
|
+
};
|
|
981
|
+
}
|
|
982
|
+
async dispose(request, context) {
|
|
983
|
+
context.signal.throwIfAborted();
|
|
984
|
+
const sandbox = await this.resolve(request, true);
|
|
985
|
+
if (!sandbox) return { disposed: true };
|
|
986
|
+
try {
|
|
987
|
+
await sandbox.delete();
|
|
988
|
+
} catch (error) {
|
|
989
|
+
if (await this.client.get(sandbox.id)) throw error;
|
|
990
|
+
}
|
|
991
|
+
context.signal.throwIfAborted();
|
|
992
|
+
this.states.delete(executionKey(request.executionId, request.executionPlanDigest));
|
|
993
|
+
return { disposed: true };
|
|
994
|
+
}
|
|
995
|
+
async resolve(request, missingIsDeleted) {
|
|
996
|
+
const key = executionKey(request.executionId, request.executionPlanDigest);
|
|
997
|
+
const active = this.states.get(key)?.sandbox;
|
|
998
|
+
if (active) return active;
|
|
999
|
+
const matches = [];
|
|
1000
|
+
const scope = this.options.teamId ? `team:${this.options.teamId}` : "personal";
|
|
1001
|
+
for (let offset = 0; ; offset += 100) {
|
|
1002
|
+
const page = await this.client.list({ scope, limit: 100, offset });
|
|
1003
|
+
for (const candidate of page) {
|
|
1004
|
+
if (matchesExecution(candidate, request)) matches.push(candidate);
|
|
1005
|
+
}
|
|
1006
|
+
if (page.length < 100) break;
|
|
1007
|
+
}
|
|
1008
|
+
if (matches.length === 1) return matches[0];
|
|
1009
|
+
if (matches.length > 1) throw new Error("multiple sandboxes match one candidate execution");
|
|
1010
|
+
if (missingIsDeleted) return void 0;
|
|
1011
|
+
throw new Error("candidate sandbox evidence is unavailable");
|
|
1012
|
+
}
|
|
1013
|
+
};
|
|
1014
|
+
async function appendSandboxTrace(state, traceStore, status) {
|
|
1015
|
+
const trace = state.trace;
|
|
1016
|
+
if (!trace || trace.written) return;
|
|
1017
|
+
const endedAt = Math.max(trace.startedAt, Math.min(Date.now(), trace.deadlineAtMs));
|
|
1018
|
+
await traceStore.appendRun({
|
|
1019
|
+
runId: trace.runId,
|
|
1020
|
+
scenarioId: trace.scenarioId,
|
|
1021
|
+
startedAt: trace.startedAt,
|
|
1022
|
+
endedAt,
|
|
1023
|
+
status: state.termination?.kind !== "timeout" && status?.running === false && status.exitCode === 0 ? "completed" : "failed",
|
|
1024
|
+
tags: trace.tags
|
|
1025
|
+
});
|
|
1026
|
+
trace.written = true;
|
|
1027
|
+
}
|
|
1028
|
+
function assertSupportedRequest(request) {
|
|
1029
|
+
if (request.benchmark.task.outcome.kind !== "output") {
|
|
1030
|
+
throw new Error("sandbox candidate executor does not support workspace outcomes; use Pier");
|
|
1031
|
+
}
|
|
1032
|
+
if (request.executionPlan.value.material.codeKind !== "disabled" || request.inputs.candidate) {
|
|
1033
|
+
throw new Error("sandbox candidate executor does not support code workspaces; use Pier");
|
|
1034
|
+
}
|
|
1035
|
+
if (request.memory.mode !== "disabled") {
|
|
1036
|
+
throw new Error("sandbox candidate executor does not support isolated memory");
|
|
1037
|
+
}
|
|
1038
|
+
const mediaType = request.benchmark.task.outcome.mediaType.toLowerCase();
|
|
1039
|
+
if (!(mediaType.startsWith("text/") || mediaType === "application/json" || mediaType.endsWith("+json"))) {
|
|
1040
|
+
throw new Error("sandbox candidate executor supports only UTF-8 text and JSON outputs");
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
function sandboxCreateOptions(request, options = {}) {
|
|
1044
|
+
const material = request.executionPlan.value.material;
|
|
1045
|
+
const retentionSeconds = options.evidenceRetentionSeconds ?? 900;
|
|
1046
|
+
if (!Number.isSafeInteger(retentionSeconds) || retentionSeconds < 60) {
|
|
1047
|
+
throw new Error("sandbox evidence retention must be at least 60 seconds");
|
|
1048
|
+
}
|
|
1049
|
+
const maxLifetimeSeconds = Math.ceil(request.hardLimits.timeoutMs / 1e3) + retentionSeconds;
|
|
1050
|
+
const network = material.model.access.network;
|
|
1051
|
+
const egressPolicy = network.mode === "disabled" ? { mode: "blocked" } : {
|
|
1052
|
+
mode: "strict",
|
|
1053
|
+
allowDomains: [...network.domains],
|
|
1054
|
+
includeImplicitDomains: false
|
|
1055
|
+
};
|
|
1056
|
+
const value = {
|
|
1057
|
+
image: exactImage(material.container.image, material.container.manifestDigest),
|
|
1058
|
+
bare: true,
|
|
1059
|
+
publicEdge: false,
|
|
1060
|
+
ephemeral: true,
|
|
1061
|
+
sshEnabled: false,
|
|
1062
|
+
webTerminalEnabled: false,
|
|
1063
|
+
secrets: [],
|
|
1064
|
+
capabilities: [],
|
|
1065
|
+
egressPolicy,
|
|
1066
|
+
maxLifetimeSeconds,
|
|
1067
|
+
idempotencyKey: `candidate-${request.executionPlan.value.digest.slice("sha256:".length)}`,
|
|
1068
|
+
metadata: {
|
|
1069
|
+
kind: "agent-candidate-execution",
|
|
1070
|
+
executionId: request.executionId,
|
|
1071
|
+
executionPlanDigest: request.executionPlan.value.digest,
|
|
1072
|
+
outputMediaType: request.benchmark.task.outcome.kind === "output" ? request.benchmark.task.outcome.mediaType : "",
|
|
1073
|
+
outputMaxBytes: request.benchmark.task.outcome.kind === "output" ? request.benchmark.task.outcome.maxBytes : 0
|
|
1074
|
+
},
|
|
1075
|
+
...options.teamId ? { teamId: options.teamId } : {},
|
|
1076
|
+
...options.resources ? { resources: options.resources } : {}
|
|
1077
|
+
};
|
|
1078
|
+
return value;
|
|
1079
|
+
}
|
|
1080
|
+
async function materializeRequest(sandbox, request) {
|
|
1081
|
+
const knowledgePaths = assertKnowledgeExecutionBinding(request);
|
|
1082
|
+
for (const file of request.inputs.task.files) {
|
|
1083
|
+
await writeExactFile(sandbox, beneath(request.roots.taskRoot, file.path), file.bytes, file.mode);
|
|
1084
|
+
}
|
|
1085
|
+
const profileRoot = request.executionPlan.value.material.profile.targetWorkspace === "task" ? request.roots.taskRoot : request.roots.candidateRoot;
|
|
1086
|
+
if (!profileRoot) throw new Error("candidate profile targets a missing workspace");
|
|
1087
|
+
for (const file of request.profileActivation.files) {
|
|
1088
|
+
await writeExactFile(
|
|
1089
|
+
sandbox,
|
|
1090
|
+
beneath(profileRoot, file.path),
|
|
1091
|
+
Buffer.from(file.content, "utf8"),
|
|
1092
|
+
file.mode
|
|
1093
|
+
);
|
|
1094
|
+
}
|
|
1095
|
+
if (request.knowledge && knowledgePaths) {
|
|
1096
|
+
for (const file of request.knowledge.files) {
|
|
1097
|
+
await writeExactFile(sandbox, beneath(knowledgePaths.root, file.path), file.bytes, file.mode);
|
|
1098
|
+
}
|
|
1099
|
+
if (request.knowledge.retrievalConfig && knowledgePaths.retrievalConfig) {
|
|
1100
|
+
await writeExactFile(
|
|
1101
|
+
sandbox,
|
|
1102
|
+
knowledgePaths.retrievalConfig,
|
|
1103
|
+
request.knowledge.retrievalConfig,
|
|
1104
|
+
420
|
|
1105
|
+
);
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
if (request.instruction.delivery.kind === "utf8-file") {
|
|
1109
|
+
await writeExactFile(
|
|
1110
|
+
sandbox,
|
|
1111
|
+
request.instruction.delivery.path,
|
|
1112
|
+
request.instruction.bytes,
|
|
1113
|
+
420
|
|
1114
|
+
);
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
function assertKnowledgeExecutionBinding(request) {
|
|
1118
|
+
const knowledge = request.knowledge;
|
|
1119
|
+
if (!knowledge) {
|
|
1120
|
+
if (request.launch.env[CANDIDATE_KNOWLEDGE_ROOT_ENV] !== void 0 || request.launch.env[CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG_ENV] !== void 0) {
|
|
1121
|
+
throw new Error("candidate launch declares knowledge paths without verified knowledge");
|
|
1122
|
+
}
|
|
1123
|
+
return void 0;
|
|
1124
|
+
}
|
|
1125
|
+
const paths = candidateKnowledgeExecutionPaths(
|
|
1126
|
+
request.roots.taskRoot,
|
|
1127
|
+
knowledge.retrievalConfig !== void 0
|
|
1128
|
+
);
|
|
1129
|
+
if (request.launch.env[CANDIDATE_KNOWLEDGE_ROOT_ENV] !== paths.root || request.launch.env[CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG_ENV] !== paths.retrievalConfig) {
|
|
1130
|
+
throw new Error("candidate knowledge paths do not match the signed launch environment");
|
|
1131
|
+
}
|
|
1132
|
+
const reserved = [paths.root, paths.retrievalConfig].filter(
|
|
1133
|
+
(value) => value !== void 0
|
|
1134
|
+
);
|
|
1135
|
+
const profileRoot = request.executionPlan.value.material.profile.targetWorkspace === "task" ? request.roots.taskRoot : request.roots.candidateRoot;
|
|
1136
|
+
const otherFiles = [
|
|
1137
|
+
...request.inputs.task.files.map((file) => beneath(request.roots.taskRoot, file.path)),
|
|
1138
|
+
...profileRoot ? request.profileActivation.files.map((file) => beneath(profileRoot, file.path)) : [],
|
|
1139
|
+
...request.instruction.delivery.kind === "utf8-file" ? [request.instruction.delivery.path] : []
|
|
1140
|
+
];
|
|
1141
|
+
if (otherFiles.some(
|
|
1142
|
+
(path) => reserved.some(
|
|
1143
|
+
(reservedPath) => path === reservedPath || path.startsWith(`${reservedPath}/`) || reservedPath.startsWith(`${path}/`)
|
|
1144
|
+
)
|
|
1145
|
+
)) {
|
|
1146
|
+
throw new Error("candidate knowledge paths overlap other execution inputs");
|
|
1147
|
+
}
|
|
1148
|
+
return paths;
|
|
1149
|
+
}
|
|
1150
|
+
function exactLaunch(request) {
|
|
1151
|
+
const instruction = new TextDecoder("utf-8", { fatal: true }).decode(request.instruction.bytes);
|
|
1152
|
+
switch (request.instruction.delivery.kind) {
|
|
1153
|
+
case "argv-append":
|
|
1154
|
+
return { executable: request.launch.executable, args: [...request.launch.args, instruction] };
|
|
1155
|
+
case "stdin-utf8":
|
|
1156
|
+
return {
|
|
1157
|
+
executable: request.launch.executable,
|
|
1158
|
+
args: request.launch.args,
|
|
1159
|
+
stdin: instruction
|
|
1160
|
+
};
|
|
1161
|
+
case "utf8-file":
|
|
1162
|
+
return { executable: request.launch.executable, args: request.launch.args };
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
async function writeExactFile(sandbox, path, bytes, mode) {
|
|
1166
|
+
await sandbox.fs.write(path, Buffer.from(bytes).toString("base64"), {
|
|
1167
|
+
encoding: "base64",
|
|
1168
|
+
mode
|
|
1169
|
+
});
|
|
1170
|
+
}
|
|
1171
|
+
async function collectOutput(process2, maxBytes) {
|
|
1172
|
+
const chunks = [];
|
|
1173
|
+
let byteLength = 0;
|
|
1174
|
+
for await (const chunk of process2.stdout()) {
|
|
1175
|
+
const bytes = Buffer.from(chunk, "utf8");
|
|
1176
|
+
byteLength += bytes.byteLength;
|
|
1177
|
+
if (byteLength > maxBytes) {
|
|
1178
|
+
await killProcess(process2);
|
|
1179
|
+
throw new Error(`sandbox candidate output exceeds its ${maxBytes}-byte maximum`);
|
|
1180
|
+
}
|
|
1181
|
+
chunks.push(bytes);
|
|
1182
|
+
}
|
|
1183
|
+
return Uint8Array.from(Buffer.concat(chunks, byteLength));
|
|
1184
|
+
}
|
|
1185
|
+
async function awaitOutput(output, signal, deadlineAtMs) {
|
|
1186
|
+
signal.throwIfAborted();
|
|
1187
|
+
const remainingMs = deadlineAtMs - Date.now();
|
|
1188
|
+
if (remainingMs <= 0) throw new Error("sandbox candidate output deadline expired");
|
|
1189
|
+
let timer;
|
|
1190
|
+
let onAbort;
|
|
1191
|
+
try {
|
|
1192
|
+
return await Promise.race([
|
|
1193
|
+
output,
|
|
1194
|
+
new Promise((_resolve, reject) => {
|
|
1195
|
+
onAbort = () => reject(signal.reason ?? new Error("sandbox candidate output cancelled"));
|
|
1196
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
1197
|
+
timer = setTimeout(
|
|
1198
|
+
() => reject(new Error("sandbox candidate output deadline expired")),
|
|
1199
|
+
remainingMs
|
|
1200
|
+
);
|
|
1201
|
+
})
|
|
1202
|
+
]);
|
|
1203
|
+
} finally {
|
|
1204
|
+
if (onAbort) signal.removeEventListener("abort", onAbort);
|
|
1205
|
+
if (timer) clearTimeout(timer);
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
async function killProcess(process2) {
|
|
1209
|
+
const before = await process2.status();
|
|
1210
|
+
if (!before.running) return;
|
|
1211
|
+
try {
|
|
1212
|
+
await process2.kill("SIGKILL", { tree: true });
|
|
1213
|
+
} catch (error) {
|
|
1214
|
+
if ((await process2.status()).running) throw error;
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
function processTermination(status) {
|
|
1218
|
+
if (status.running) throw new Error("candidate process is still running");
|
|
1219
|
+
if (status.exitSignal) {
|
|
1220
|
+
if (!/^SIG[A-Z0-9]+$/.test(status.exitSignal)) {
|
|
1221
|
+
throw new Error("sandbox returned an invalid process signal");
|
|
1222
|
+
}
|
|
1223
|
+
return { kind: "signal", signal: status.exitSignal };
|
|
1224
|
+
}
|
|
1225
|
+
return { kind: "exit", exitCode: status.exitCode };
|
|
1226
|
+
}
|
|
1227
|
+
function matchesExecution(sandbox, request) {
|
|
1228
|
+
return sandbox.metadata?.kind === "agent-candidate-execution" && sandbox.metadata.executionId === request.executionId && sandbox.metadata.executionPlanDigest === request.executionPlanDigest;
|
|
1229
|
+
}
|
|
1230
|
+
function sandboxOutputSpec(sandbox) {
|
|
1231
|
+
const maxBytes = sandbox.metadata?.outputMaxBytes;
|
|
1232
|
+
if (!Number.isSafeInteger(maxBytes) || Number(maxBytes) < 1) {
|
|
1233
|
+
throw new Error("candidate sandbox output bound is unavailable");
|
|
1234
|
+
}
|
|
1235
|
+
return { maxBytes: Number(maxBytes) };
|
|
1236
|
+
}
|
|
1237
|
+
function executionKey(executionId, executionPlanDigest) {
|
|
1238
|
+
return `${executionId}\0${executionPlanDigest}`;
|
|
1239
|
+
}
|
|
1240
|
+
function exactImage(image, manifestDigest) {
|
|
1241
|
+
const marker = image.lastIndexOf("@");
|
|
1242
|
+
if (marker < 0) return `${image}@${manifestDigest}`;
|
|
1243
|
+
if (image.slice(marker + 1) !== manifestDigest) {
|
|
1244
|
+
throw new Error("candidate container image conflicts with its resolved manifest");
|
|
1245
|
+
}
|
|
1246
|
+
return image;
|
|
1247
|
+
}
|
|
1248
|
+
function beneath(root, relativePath) {
|
|
1249
|
+
if (posix.isAbsolute(relativePath)) throw new Error("candidate input path must be relative");
|
|
1250
|
+
const path = posix.normalize(relativePath);
|
|
1251
|
+
if (path === ".." || path.startsWith("../")) {
|
|
1252
|
+
throw new Error("candidate input path escapes its execution root");
|
|
1253
|
+
}
|
|
1254
|
+
return posix.join(root, path);
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1104
1257
|
// src/intelligence/with-intelligence.ts
|
|
1105
1258
|
import { applyAgentProfileDiff } from "@tangle-network/agent-interface";
|
|
1106
1259
|
function summarizeRuntimeEvents(events) {
|
|
@@ -1373,16 +1526,13 @@ function createIntelligenceClient(config) {
|
|
|
1373
1526
|
} : {},
|
|
1374
1527
|
...record.runtimeEvents ? { "tangle.runtime.event_count": record.runtimeEvents.length } : {},
|
|
1375
1528
|
...record.candidateExecution ? {
|
|
1376
|
-
"tangle.candidate.
|
|
1377
|
-
"tangle.candidate.
|
|
1378
|
-
"tangle.candidate.
|
|
1379
|
-
"tangle.candidate.
|
|
1380
|
-
"tangle.candidate.
|
|
1381
|
-
"tangle.candidate.
|
|
1382
|
-
"tangle.candidate.
|
|
1383
|
-
...record.candidateExecution.runReceiptDigest ? {
|
|
1384
|
-
"tangle.candidate.run_receipt_digest": record.candidateExecution.runReceiptDigest
|
|
1385
|
-
} : {}
|
|
1529
|
+
"tangle.candidate.bundle_digest": record.candidateExecution.receipt.bundleDigest,
|
|
1530
|
+
"tangle.candidate.experiment_digest": record.candidateExecution.materializationReceipt.executionPlan.material.runCell.experimentDigest,
|
|
1531
|
+
"tangle.candidate.execution_id": record.candidateExecution.materializationReceipt.executionPlan.material.executionId,
|
|
1532
|
+
"tangle.candidate.execution_plan_digest": record.candidateExecution.receipt.executionPlanDigest,
|
|
1533
|
+
"tangle.candidate.materialization_receipt_digest": record.candidateExecution.receipt.materializationReceiptDigest,
|
|
1534
|
+
"tangle.candidate.succeeded": record.candidateExecution.receipt.termination.kind === "exit" && record.candidateExecution.receipt.termination.exitCode === 0 && record.candidateExecution.receipt.benchmarkResult.material.passed,
|
|
1535
|
+
"tangle.candidate.run_receipt_digest": record.candidateExecution.receipt.digest
|
|
1386
1536
|
} : {}
|
|
1387
1537
|
};
|
|
1388
1538
|
if (record.profile) {
|
|
@@ -1532,28 +1682,37 @@ function createIntelligenceClient(config) {
|
|
|
1532
1682
|
};
|
|
1533
1683
|
}
|
|
1534
1684
|
export {
|
|
1685
|
+
AgentCandidateExperimentCellExecutionError,
|
|
1535
1686
|
CapabilityNotAdmittedError,
|
|
1536
1687
|
compileEffort,
|
|
1537
1688
|
composeCertifiedProfile,
|
|
1538
1689
|
composeCertifiedProfileFromWire,
|
|
1539
1690
|
composeCertifiedPrompt,
|
|
1691
|
+
createAgentImprovementActivation,
|
|
1692
|
+
createAgentImprovementMeasuredComparison,
|
|
1540
1693
|
createAgentImprovementProposal,
|
|
1541
1694
|
createCertifiedPromptSource,
|
|
1542
1695
|
createIntelligenceClient,
|
|
1696
|
+
createSandboxCandidateExperimentExecutor,
|
|
1543
1697
|
defaultEffortTier,
|
|
1544
1698
|
defaultRedactor,
|
|
1545
|
-
|
|
1699
|
+
executeAgentCandidateExperimentCell,
|
|
1546
1700
|
isIntelligenceOff,
|
|
1547
1701
|
manifestFromProfile,
|
|
1548
1702
|
normalizeCertifiedProfile,
|
|
1703
|
+
parseAgentCandidateProfileActivation,
|
|
1549
1704
|
proposeAgentImprovement,
|
|
1550
1705
|
pullCertified,
|
|
1551
1706
|
resolveEffort,
|
|
1552
1707
|
resolveIntelligenceBaseUrl,
|
|
1553
1708
|
resolveRedactor,
|
|
1554
1709
|
reviewAgentImprovementProposal,
|
|
1710
|
+
runAgentCandidateExperiment,
|
|
1711
|
+
sandboxCandidateExperimentExecutionSupport,
|
|
1712
|
+
verifyAgentImprovementActivation,
|
|
1555
1713
|
verifyAgentImprovementProposal,
|
|
1556
1714
|
verifyAgentImprovementReview,
|
|
1715
|
+
verifyCandidateExecutionEvidence,
|
|
1557
1716
|
withIntelligence
|
|
1558
1717
|
};
|
|
1559
1718
|
//# sourceMappingURL=intelligence.js.map
|