@tangle-network/agent-runtime 0.101.1 → 0.102.1
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 +1 -1
- package/dist/agent.js +5 -3
- package/dist/agent.js.map +1 -1
- package/dist/analyst-loop.d.ts +1 -1
- package/dist/candidate-execution/index.d.ts +13 -2
- package/dist/candidate-execution/index.js +8 -3
- package/dist/chunk-377GOJHJ.js +578 -0
- package/dist/chunk-377GOJHJ.js.map +1 -0
- package/dist/{chunk-DI677IPX.js → chunk-3DW5DEKQ.js} +3 -3
- package/dist/{chunk-KVJQV342.js → chunk-6MR4IJRW.js} +25 -1777
- package/dist/chunk-6MR4IJRW.js.map +1 -0
- package/dist/{chunk-RJPQLUDA.js → chunk-7FJJUC73.js} +336 -43
- package/dist/chunk-7FJJUC73.js.map +1 -0
- package/dist/{chunk-TA4RBJLE.js → chunk-CI7WS6S2.js} +5 -5
- package/dist/{chunk-U4PRAATQ.js → chunk-CK76OZPM.js} +3 -3
- package/dist/{chunk-KSBUSEUA.js → chunk-KJ2Q4T7F.js} +2 -2
- package/dist/{chunk-MAONWP4R.js → chunk-KPHTCHQ4.js} +611 -1419
- package/dist/chunk-KPHTCHQ4.js.map +1 -0
- package/dist/{chunk-BXZ7GPL4.js → chunk-KSM6GFHP.js} +2 -2
- package/dist/chunk-L5DST3QC.js +351 -0
- package/dist/chunk-L5DST3QC.js.map +1 -0
- package/dist/{chunk-HGSHPVJ6.js → chunk-LJLG734E.js} +200 -441
- package/dist/chunk-LJLG734E.js.map +1 -0
- package/dist/chunk-ROILMKDL.js +1338 -0
- package/dist/chunk-ROILMKDL.js.map +1 -0
- package/dist/{chunk-N2CEE5Q3.js → chunk-RTB3TC73.js} +3 -3
- package/dist/chunk-SQ3ZJH3Y.js +3082 -0
- package/dist/chunk-SQ3ZJH3Y.js.map +1 -0
- package/dist/chunk-UPWGXKXB.js +254 -0
- package/dist/chunk-UPWGXKXB.js.map +1 -0
- package/dist/{completion-gate-C80jiRfN.d.ts → completion-gate-C6dhVN-N.d.ts} +2 -2
- package/dist/{coordination-BFE3Den7.d.ts → coordination-D9l_YmwW.d.ts} +6 -6
- package/dist/environment-provider.d.ts +2 -2
- package/dist/{improve-g75IE2Cx.d.ts → improve-B40dRu0X.d.ts} +47 -19
- package/dist/index.d.ts +331 -23
- package/dist/index.js +544 -136
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +63 -62
- package/dist/intelligence.js +62 -471
- package/dist/intelligence.js.map +1 -1
- package/dist/knowledge.d.ts +8 -8
- package/dist/knowledge.js +9 -7
- package/dist/{local-harness-ZqCx51u7.d.ts → local-harness-CtK9dSny.d.ts} +14 -2
- package/dist/{loop-runner-bin-Cn1N2rRo.d.ts → loop-runner-bin-PnWslIw4.d.ts} +2 -2
- package/dist/loop-runner-bin.d.ts +6 -6
- package/dist/loop-runner-bin.js +6 -4
- package/dist/loops.d.ts +231 -460
- package/dist/loops.js +58 -37
- package/dist/mcp/bin.js +2 -2
- package/dist/mcp/index.d.ts +184 -12
- package/dist/mcp/index.js +31 -9
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/memory-bin.d.ts +1 -0
- package/dist/mcp/memory-bin.js +22 -0
- package/dist/mcp/memory-bin.js.map +1 -0
- package/dist/profiles.d.ts +3 -3
- package/dist/structural-rollout-D7xik9XR.d.ts +446 -0
- package/dist/{substrate-DO2GHNg2.d.ts → substrate-Dyiqmd3o.d.ts} +1 -1
- package/dist/{supervise-BLPI50-w.d.ts → supervise-BQdNAXtK.d.ts} +4 -4
- package/dist/testing.js +255 -211
- package/dist/testing.js.map +1 -1
- package/dist/{types-B3vAW0Oq.d.ts → types-CLat4bT9.d.ts} +1 -1
- package/dist/{types-CmnA2iL3.d.ts → types-D870JlH0.d.ts} +2 -2
- package/dist/{worktree-fanout-DCA3G4bO.d.ts → worktree-fanout-DsIR4d6w.d.ts} +234 -234
- package/package.json +6 -5
- package/dist/chunk-HGSHPVJ6.js.map +0 -1
- package/dist/chunk-IKGCKPDX.js +0 -1115
- package/dist/chunk-IKGCKPDX.js.map +0 -1
- package/dist/chunk-KVJQV342.js.map +0 -1
- package/dist/chunk-MAONWP4R.js.map +0 -1
- package/dist/chunk-RJPQLUDA.js.map +0 -1
- package/dist/{chunk-DI677IPX.js.map → chunk-3DW5DEKQ.js.map} +0 -0
- package/dist/{chunk-TA4RBJLE.js.map → chunk-CI7WS6S2.js.map} +0 -0
- package/dist/{chunk-U4PRAATQ.js.map → chunk-CK76OZPM.js.map} +0 -0
- package/dist/{chunk-KSBUSEUA.js.map → chunk-KJ2Q4T7F.js.map} +0 -0
- package/dist/{chunk-BXZ7GPL4.js.map → chunk-KSM6GFHP.js.map} +0 -0
- package/dist/{chunk-N2CEE5Q3.js.map → chunk-RTB3TC73.js.map} +0 -0
- package/dist/{sanitize-BTSsdBXw.d.ts → sanitize-DEbPNtyI.d.ts} +58 -58
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
assertNoProtectedBytes,
|
|
3
|
+
createProtectedRecordRedactor,
|
|
4
|
+
redactProtectedReason,
|
|
5
|
+
redactProtectedValue
|
|
6
|
+
} from "./chunk-UPWGXKXB.js";
|
|
1
7
|
import {
|
|
2
8
|
contentAddress
|
|
3
9
|
} from "./chunk-IMSNJSXH.js";
|
|
@@ -2531,6 +2537,182 @@ function retryLineageDigest(prepared, resultTimeoutMs) {
|
|
|
2531
2537
|
});
|
|
2532
2538
|
}
|
|
2533
2539
|
|
|
2540
|
+
// src/candidate-execution/verify.ts
|
|
2541
|
+
import { agentCandidateBundleSchema } from "@tangle-network/agent-interface";
|
|
2542
|
+
var verifiedCandidateState = /* @__PURE__ */ new WeakMap();
|
|
2543
|
+
var AGENT_CANDIDATE_EXECUTION_SUPPORT = Object.freeze({
|
|
2544
|
+
outcomes: Object.freeze(["workspace", "output"]),
|
|
2545
|
+
code: Object.freeze(["disabled", "no-op", "git-patch"]),
|
|
2546
|
+
memory: Object.freeze(["disabled", "isolated"]),
|
|
2547
|
+
knowledge: true,
|
|
2548
|
+
profile: Object.freeze({
|
|
2549
|
+
mcpTransports: Object.freeze(["stdio"]),
|
|
2550
|
+
remoteMcp: false,
|
|
2551
|
+
tools: false,
|
|
2552
|
+
permissions: false,
|
|
2553
|
+
modes: false,
|
|
2554
|
+
confidential: false
|
|
2555
|
+
})
|
|
2556
|
+
});
|
|
2557
|
+
async function verifyAgentCandidateBundle(input, ports) {
|
|
2558
|
+
const parsed = agentCandidateBundleSchema.parse(input);
|
|
2559
|
+
const withoutDigest = omitTopLevelDigest(parsed);
|
|
2560
|
+
const actualDigest = canonicalCandidateDigest(withoutDigest);
|
|
2561
|
+
if (actualDigest !== parsed.digest) {
|
|
2562
|
+
throw new Error(`candidate bundle digest ${parsed.digest} does not match ${actualDigest}`);
|
|
2563
|
+
}
|
|
2564
|
+
const canonicalBytes = canonicalCandidateBytes(withoutDigest);
|
|
2565
|
+
verifyBytes(canonicalBytes, parsed.digest, canonicalBytes.byteLength, "candidate bundle");
|
|
2566
|
+
assertCandidateProfileExecutionSupport(parsed.profile);
|
|
2567
|
+
const artifactBytes = /* @__PURE__ */ new Map();
|
|
2568
|
+
const readArtifact = async (artifact) => {
|
|
2569
|
+
const key = artifactCacheKey(artifact);
|
|
2570
|
+
const existing = artifactBytes.get(key);
|
|
2571
|
+
if (existing) return Uint8Array.from(existing);
|
|
2572
|
+
const bytes = await readVerifiedArtifact(artifact, ports.artifacts);
|
|
2573
|
+
artifactBytes.set(key, Uint8Array.from(bytes));
|
|
2574
|
+
return bytes;
|
|
2575
|
+
};
|
|
2576
|
+
let patchBytes;
|
|
2577
|
+
if (parsed.code.kind === "git-patch") {
|
|
2578
|
+
patchBytes = await readArtifact(parsed.code.patch.artifact);
|
|
2579
|
+
}
|
|
2580
|
+
const materializedTree = await verifyCandidateCode(parsed.code, ports.repositories, patchBytes);
|
|
2581
|
+
const resourceBytes = /* @__PURE__ */ new Map();
|
|
2582
|
+
for (const resource of candidateResources(parsed)) {
|
|
2583
|
+
const bytes = resource.kind === "inline" ? Buffer.from(resource.content, "utf8") : await readCandidateGitHubResource(resource, ports.repositories);
|
|
2584
|
+
verifyBytes(
|
|
2585
|
+
bytes,
|
|
2586
|
+
resource.sha256,
|
|
2587
|
+
resource.byteLength,
|
|
2588
|
+
`candidate resource ${resource.name ?? (resource.kind === "github" ? resource.path : "<unnamed>")}`
|
|
2589
|
+
);
|
|
2590
|
+
resourceBytes.set(resourceKey(resource), Uint8Array.from(bytes));
|
|
2591
|
+
resourceBytes.set(resource.sha256, Uint8Array.from(bytes));
|
|
2592
|
+
}
|
|
2593
|
+
if (parsed.execution.workspace) {
|
|
2594
|
+
const workspace = await verifyWorkspaceSnapshotArtifacts(
|
|
2595
|
+
parsed.execution.workspace,
|
|
2596
|
+
ports.artifacts
|
|
2597
|
+
);
|
|
2598
|
+
artifactBytes.set(artifactCacheKey(parsed.execution.workspace.manifest), workspace.manifest);
|
|
2599
|
+
artifactBytes.set(artifactCacheKey(parsed.execution.workspace.archive), workspace.archive);
|
|
2600
|
+
}
|
|
2601
|
+
if (parsed.knowledge) {
|
|
2602
|
+
const knowledge = await verifyWorkspaceSnapshotArtifacts(
|
|
2603
|
+
parsed.knowledge.snapshot,
|
|
2604
|
+
ports.artifacts
|
|
2605
|
+
);
|
|
2606
|
+
artifactBytes.set(artifactCacheKey(parsed.knowledge.snapshot.manifest), knowledge.manifest);
|
|
2607
|
+
artifactBytes.set(artifactCacheKey(parsed.knowledge.snapshot.archive), knowledge.archive);
|
|
2608
|
+
if (parsed.knowledge.retrievalConfig) await readArtifact(parsed.knowledge.retrievalConfig);
|
|
2609
|
+
await readArtifact(parsed.knowledge.evaluation);
|
|
2610
|
+
}
|
|
2611
|
+
if (parsed.memory.mode === "isolated" && parsed.memory.seed)
|
|
2612
|
+
await readArtifact(parsed.memory.seed);
|
|
2613
|
+
deepFreezeCandidate(parsed);
|
|
2614
|
+
const verified = Object.freeze({
|
|
2615
|
+
bundle: parsed,
|
|
2616
|
+
...materializedTree === void 0 ? {} : { materializedTree },
|
|
2617
|
+
[verifiedCandidateBrand]: true
|
|
2618
|
+
});
|
|
2619
|
+
verifiedCandidateState.set(verified, { ports, artifactBytes, resourceBytes });
|
|
2620
|
+
return verified;
|
|
2621
|
+
}
|
|
2622
|
+
function getVerifiedCandidateState(candidate) {
|
|
2623
|
+
const state = verifiedCandidateState.get(candidate);
|
|
2624
|
+
if (!state || candidate[verifiedCandidateBrand] !== true) {
|
|
2625
|
+
throw new Error("candidate must come from verifyAgentCandidateBundle");
|
|
2626
|
+
}
|
|
2627
|
+
return state;
|
|
2628
|
+
}
|
|
2629
|
+
async function verifiedArtifactBytes(candidate, artifact) {
|
|
2630
|
+
const state = getVerifiedCandidateState(candidate);
|
|
2631
|
+
const key = artifactCacheKey(artifact);
|
|
2632
|
+
const existing = state.artifactBytes.get(key);
|
|
2633
|
+
if (existing) return Uint8Array.from(existing);
|
|
2634
|
+
const bytes = await readVerifiedArtifact(artifact, state.ports.artifacts);
|
|
2635
|
+
state.artifactBytes.set(key, Uint8Array.from(bytes));
|
|
2636
|
+
return bytes;
|
|
2637
|
+
}
|
|
2638
|
+
function verifiedResourceTextByDigest(candidate) {
|
|
2639
|
+
const output = /* @__PURE__ */ new Map();
|
|
2640
|
+
for (const resource of candidateResources(candidate.bundle)) {
|
|
2641
|
+
const bytes = getVerifiedCandidateState(candidate).resourceBytes.get(resource.sha256);
|
|
2642
|
+
if (!bytes) throw new Error(`candidate resource digest was not verified: ${resource.sha256}`);
|
|
2643
|
+
output.set(resource.sha256, new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
2644
|
+
}
|
|
2645
|
+
return output;
|
|
2646
|
+
}
|
|
2647
|
+
function candidateResources(bundle) {
|
|
2648
|
+
const resources = bundle.profile.resources;
|
|
2649
|
+
if (!resources) return [];
|
|
2650
|
+
const output = [];
|
|
2651
|
+
for (const mount of resources.files ?? []) output.push(mount.resource);
|
|
2652
|
+
output.push(...resources.tools ?? []);
|
|
2653
|
+
output.push(...resources.skills ?? []);
|
|
2654
|
+
output.push(...resources.agents ?? []);
|
|
2655
|
+
output.push(...resources.commands ?? []);
|
|
2656
|
+
if (typeof resources.instructions === "object") output.push(resources.instructions);
|
|
2657
|
+
return output;
|
|
2658
|
+
}
|
|
2659
|
+
function resourceKey(resource) {
|
|
2660
|
+
return canonicalCandidateDigest(resource);
|
|
2661
|
+
}
|
|
2662
|
+
|
|
2663
|
+
// src/candidate-execution/knowledge.ts
|
|
2664
|
+
import { mkdtemp as mkdtemp2, rm as rm2 } from "fs/promises";
|
|
2665
|
+
import { tmpdir as tmpdir2 } from "os";
|
|
2666
|
+
import { join as join2, posix } from "path";
|
|
2667
|
+
import { hashKnowledgeBase } from "@tangle-network/agent-knowledge";
|
|
2668
|
+
var CANDIDATE_KNOWLEDGE_ROOT_ENV = "TANGLE_CANDIDATE_KNOWLEDGE_ROOT";
|
|
2669
|
+
var CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG_ENV = "TANGLE_CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG";
|
|
2670
|
+
function candidateKnowledgeExecutionPaths(taskRoot, hasRetrievalConfig) {
|
|
2671
|
+
if (!posix.isAbsolute(taskRoot) || posix.normalize(taskRoot) !== taskRoot) {
|
|
2672
|
+
throw new Error("candidate knowledge requires a normalized absolute task root");
|
|
2673
|
+
}
|
|
2674
|
+
const parent = posix.join(taskRoot, ".tangle");
|
|
2675
|
+
return {
|
|
2676
|
+
root: posix.join(parent, "knowledge"),
|
|
2677
|
+
...hasRetrievalConfig ? { retrievalConfig: posix.join(parent, "knowledge-retrieval-config.json") } : {}
|
|
2678
|
+
};
|
|
2679
|
+
}
|
|
2680
|
+
async function prepareAgentCandidateKnowledge(candidate, ports, arm) {
|
|
2681
|
+
const knowledge = candidate.bundle.knowledge;
|
|
2682
|
+
if (!knowledge) return void 0;
|
|
2683
|
+
const archive = await verifiedArtifactBytes(candidate, knowledge.snapshot.archive);
|
|
2684
|
+
const retrievalConfig = knowledge.retrievalConfig ? await verifiedArtifactBytes(candidate, knowledge.retrievalConfig) : void 0;
|
|
2685
|
+
const root = await mkdtemp2(join2(tmpdir2(), "agent-candidate-knowledge-"));
|
|
2686
|
+
try {
|
|
2687
|
+
await ports.workspaces.materialize({
|
|
2688
|
+
role: "knowledge",
|
|
2689
|
+
snapshot: knowledge.snapshot,
|
|
2690
|
+
archive,
|
|
2691
|
+
destination: root
|
|
2692
|
+
});
|
|
2693
|
+
const expectedHash = arm === "baseline" ? knowledge.candidate.baseHash : knowledge.candidate.candidateHash;
|
|
2694
|
+
const actualHash = `sha256:${await hashKnowledgeBase(root)}`;
|
|
2695
|
+
if (actualHash !== expectedHash) {
|
|
2696
|
+
throw new Error(
|
|
2697
|
+
`materialized ${arm} knowledge does not match its measured content: expected ${expectedHash}, got ${actualHash}`
|
|
2698
|
+
);
|
|
2699
|
+
}
|
|
2700
|
+
const files = await readMaterializedWorkspaceFiles(root, knowledge.snapshot.material);
|
|
2701
|
+
return Object.freeze({
|
|
2702
|
+
candidate: knowledge.candidate,
|
|
2703
|
+
snapshot: knowledge.snapshot,
|
|
2704
|
+
files: Object.freeze(
|
|
2705
|
+
files.map(
|
|
2706
|
+
(file) => Object.freeze({ path: file.path, mode: file.mode, bytes: Uint8Array.from(file.bytes) })
|
|
2707
|
+
)
|
|
2708
|
+
),
|
|
2709
|
+
...retrievalConfig ? { retrievalConfig: Uint8Array.from(retrievalConfig) } : {}
|
|
2710
|
+
});
|
|
2711
|
+
} finally {
|
|
2712
|
+
await rm2(root, { recursive: true, force: true });
|
|
2713
|
+
}
|
|
2714
|
+
}
|
|
2715
|
+
|
|
2534
2716
|
// src/candidate-execution/output-artifacts.ts
|
|
2535
2717
|
import {
|
|
2536
2718
|
agentCandidateArtifactRefSchema as agentCandidateArtifactRefSchema3
|
|
@@ -2663,7 +2845,7 @@ function requireRecord(value, label) {
|
|
|
2663
2845
|
}
|
|
2664
2846
|
|
|
2665
2847
|
// src/candidate-execution/finalize.ts
|
|
2666
|
-
import { isLlmSpan as isLlmSpan2, REDACTION_VERSION
|
|
2848
|
+
import { isLlmSpan as isLlmSpan2, REDACTION_VERSION } from "@tangle-network/agent-eval";
|
|
2667
2849
|
import {
|
|
2668
2850
|
agentCandidateRunReceiptSchema,
|
|
2669
2851
|
agentCandidateWorkspaceSnapshotEvidenceSchema
|
|
@@ -2891,253 +3073,6 @@ function safeAdd(left, right, label) {
|
|
|
2891
3073
|
return total;
|
|
2892
3074
|
}
|
|
2893
3075
|
|
|
2894
|
-
// src/candidate-execution/protected-redaction.ts
|
|
2895
|
-
import { createHmac, randomBytes as randomBytes2 } from "crypto";
|
|
2896
|
-
import {
|
|
2897
|
-
DEFAULT_REDACTION_RULES,
|
|
2898
|
-
REDACTION_VERSION,
|
|
2899
|
-
redactString
|
|
2900
|
-
} from "@tangle-network/agent-eval";
|
|
2901
|
-
function createProtectedRecordRedactor(protectedValues) {
|
|
2902
|
-
const identityKey = randomBytes2(32);
|
|
2903
|
-
const aggregate = {
|
|
2904
|
-
version: REDACTION_VERSION,
|
|
2905
|
-
redactionCount: 0,
|
|
2906
|
-
byRule: {}
|
|
2907
|
-
};
|
|
2908
|
-
const mergeReport = (report) => {
|
|
2909
|
-
aggregate.version = report.version;
|
|
2910
|
-
aggregate.redactionCount += report.redactionCount;
|
|
2911
|
-
for (const [rule, count] of Object.entries(report.byRule)) {
|
|
2912
|
-
aggregate.byRule[rule] = (aggregate.byRule[rule] ?? 0) + count;
|
|
2913
|
-
}
|
|
2914
|
-
};
|
|
2915
|
-
const redactScalar = (value, record) => {
|
|
2916
|
-
const redacted = redactProtectedValue(value, protectedValues);
|
|
2917
|
-
if (record) mergeReport(redacted.report);
|
|
2918
|
-
return redacted.value;
|
|
2919
|
-
};
|
|
2920
|
-
const identifier = (value, record) => {
|
|
2921
|
-
const redacted = redactScalar(value, record);
|
|
2922
|
-
if (redacted === value) return value;
|
|
2923
|
-
const digest = createHmac("sha256", identityKey).update(value).digest("hex");
|
|
2924
|
-
return `${redacted}:hmac-sha256:${digest}`;
|
|
2925
|
-
};
|
|
2926
|
-
const transform = (value, record) => {
|
|
2927
|
-
const transformed = transformProtectedRecord(
|
|
2928
|
-
value,
|
|
2929
|
-
void 0,
|
|
2930
|
-
record,
|
|
2931
|
-
redactScalar,
|
|
2932
|
-
identifier
|
|
2933
|
-
);
|
|
2934
|
-
assertNoProtectedEvidence(transformed, protectedValues);
|
|
2935
|
-
return transformed;
|
|
2936
|
-
};
|
|
2937
|
-
return Object.freeze({
|
|
2938
|
-
record: (value) => transform(value, true),
|
|
2939
|
-
query: (value) => transform(value, false),
|
|
2940
|
-
identifier: (value) => identifier(value, false),
|
|
2941
|
-
traceIdentity: (trace) => transform(trace, false),
|
|
2942
|
-
report: () => ({
|
|
2943
|
-
version: aggregate.version,
|
|
2944
|
-
redactionCount: aggregate.redactionCount,
|
|
2945
|
-
byRule: { ...aggregate.byRule }
|
|
2946
|
-
})
|
|
2947
|
-
});
|
|
2948
|
-
}
|
|
2949
|
-
function redactProtectedValue(value, protectedValues) {
|
|
2950
|
-
const report = {
|
|
2951
|
-
version: REDACTION_VERSION,
|
|
2952
|
-
redactionCount: 0,
|
|
2953
|
-
byRule: {}
|
|
2954
|
-
};
|
|
2955
|
-
const rules = protectedRedactionRules(protectedValues);
|
|
2956
|
-
const redacted = redactNode(value, protectedValues, rules, report);
|
|
2957
|
-
assertNoProtectedEvidence(redacted, protectedValues);
|
|
2958
|
-
return { value: redacted, report };
|
|
2959
|
-
}
|
|
2960
|
-
function redactProtectedReason(reason, protectedValues) {
|
|
2961
|
-
try {
|
|
2962
|
-
return redactProtectedValue(reason, protectedValues).value;
|
|
2963
|
-
} catch {
|
|
2964
|
-
return "candidate execution failed with a protected error";
|
|
2965
|
-
}
|
|
2966
|
-
}
|
|
2967
|
-
function assertNoProtectedEvidence(value, protectedValues) {
|
|
2968
|
-
if (value instanceof Uint8Array) {
|
|
2969
|
-
assertNoProtectedBytes(value, protectedValues);
|
|
2970
|
-
return;
|
|
2971
|
-
}
|
|
2972
|
-
if (typeof value === "string") {
|
|
2973
|
-
for (const protectedValue of protectedValueVariants(protectedValues)) {
|
|
2974
|
-
if (value.includes(protectedValue)) {
|
|
2975
|
-
throw new Error("protected value survived candidate evidence redaction");
|
|
2976
|
-
}
|
|
2977
|
-
}
|
|
2978
|
-
if (decodedBase64ContainsProtectedValue(value, protectedValues)) {
|
|
2979
|
-
throw new Error("base64 protected value survived candidate evidence redaction");
|
|
2980
|
-
}
|
|
2981
|
-
return;
|
|
2982
|
-
}
|
|
2983
|
-
if (Array.isArray(value)) {
|
|
2984
|
-
for (const entry of value) assertNoProtectedEvidence(entry, protectedValues);
|
|
2985
|
-
return;
|
|
2986
|
-
}
|
|
2987
|
-
if (value && typeof value === "object") {
|
|
2988
|
-
for (const [key, entry] of Object.entries(value)) {
|
|
2989
|
-
assertNoProtectedEvidence(key, protectedValues);
|
|
2990
|
-
assertNoProtectedEvidence(entry, protectedValues);
|
|
2991
|
-
}
|
|
2992
|
-
}
|
|
2993
|
-
}
|
|
2994
|
-
function assertNoProtectedBytes(bytes, protectedValues) {
|
|
2995
|
-
if (containsProtectedBytes(bytes, protectedValues)) {
|
|
2996
|
-
throw new Error("protected value survived candidate evidence byte redaction");
|
|
2997
|
-
}
|
|
2998
|
-
}
|
|
2999
|
-
function redactNode(value, protectedValues, rules, report) {
|
|
3000
|
-
if (value instanceof Uint8Array) {
|
|
3001
|
-
if (containsProtectedBytes(value, protectedValues)) {
|
|
3002
|
-
recordRedaction(report, "candidate-access-binary", 1);
|
|
3003
|
-
return Uint8Array.from(Buffer.from("[redacted:candidate-access-binary]", "utf8"));
|
|
3004
|
-
}
|
|
3005
|
-
return Uint8Array.from(value);
|
|
3006
|
-
}
|
|
3007
|
-
if (typeof value === "string") {
|
|
3008
|
-
if (decodedBase64ContainsProtectedValue(value, protectedValues)) {
|
|
3009
|
-
recordRedaction(report, "candidate-access-binary", 1);
|
|
3010
|
-
return "[redacted:candidate-access-binary]";
|
|
3011
|
-
}
|
|
3012
|
-
const redacted = redactString(value, [...rules]);
|
|
3013
|
-
for (const [rule, count] of Object.entries(redacted.report.byRule)) {
|
|
3014
|
-
recordRedaction(report, rule, count);
|
|
3015
|
-
}
|
|
3016
|
-
return redacted.output;
|
|
3017
|
-
}
|
|
3018
|
-
if (Array.isArray(value)) {
|
|
3019
|
-
return value.map((entry) => redactNode(entry, protectedValues, rules, report));
|
|
3020
|
-
}
|
|
3021
|
-
if (value && typeof value === "object") {
|
|
3022
|
-
const entries = [];
|
|
3023
|
-
const seenKeys = /* @__PURE__ */ new Set();
|
|
3024
|
-
for (const [key, entry] of Object.entries(value)) {
|
|
3025
|
-
const redactedKey = redactNode(key, protectedValues, rules, report);
|
|
3026
|
-
if (typeof redactedKey !== "string" || seenKeys.has(redactedKey)) {
|
|
3027
|
-
throw new Error("protected evidence redaction produced an ambiguous object key");
|
|
3028
|
-
}
|
|
3029
|
-
seenKeys.add(redactedKey);
|
|
3030
|
-
entries.push([redactedKey, redactNode(entry, protectedValues, rules, report)]);
|
|
3031
|
-
}
|
|
3032
|
-
return Object.fromEntries(entries);
|
|
3033
|
-
}
|
|
3034
|
-
return value;
|
|
3035
|
-
}
|
|
3036
|
-
function transformProtectedRecord(value, fieldName, record, redactScalar, redactIdentifier) {
|
|
3037
|
-
if (value instanceof Uint8Array) return redactScalar(value, record);
|
|
3038
|
-
if (typeof value === "string") {
|
|
3039
|
-
return fieldName && isIdentifierFieldName(fieldName) ? redactIdentifier(value, record) : redactScalar(value, record);
|
|
3040
|
-
}
|
|
3041
|
-
if (Array.isArray(value)) {
|
|
3042
|
-
return value.map(
|
|
3043
|
-
(entry) => transformProtectedRecord(entry, fieldName, record, redactScalar, redactIdentifier)
|
|
3044
|
-
);
|
|
3045
|
-
}
|
|
3046
|
-
if (!value || typeof value !== "object") return value;
|
|
3047
|
-
if (fieldName === "tags") {
|
|
3048
|
-
return transformTagMap(value, record, redactScalar, redactIdentifier);
|
|
3049
|
-
}
|
|
3050
|
-
if (fieldName === "tag") {
|
|
3051
|
-
return transformTagFilter(value, record, redactScalar, redactIdentifier);
|
|
3052
|
-
}
|
|
3053
|
-
const entries = [];
|
|
3054
|
-
const seenKeys = /* @__PURE__ */ new Set();
|
|
3055
|
-
for (const [key, entry] of Object.entries(value)) {
|
|
3056
|
-
const redactedKey = redactScalar(key, record);
|
|
3057
|
-
if (seenKeys.has(redactedKey)) {
|
|
3058
|
-
throw new Error("protected evidence redaction produced an ambiguous object key");
|
|
3059
|
-
}
|
|
3060
|
-
seenKeys.add(redactedKey);
|
|
3061
|
-
entries.push([
|
|
3062
|
-
redactedKey,
|
|
3063
|
-
transformProtectedRecord(entry, key, record, redactScalar, redactIdentifier)
|
|
3064
|
-
]);
|
|
3065
|
-
}
|
|
3066
|
-
return Object.fromEntries(entries);
|
|
3067
|
-
}
|
|
3068
|
-
function transformTagMap(value, record, redactScalar, redactIdentifier) {
|
|
3069
|
-
const entries = [];
|
|
3070
|
-
const seenKeys = /* @__PURE__ */ new Set();
|
|
3071
|
-
for (const [key, entry] of Object.entries(value)) {
|
|
3072
|
-
const redactedKey = redactIdentifier(key, record);
|
|
3073
|
-
if (seenKeys.has(redactedKey)) {
|
|
3074
|
-
throw new Error("protected evidence redaction produced an ambiguous trace tag");
|
|
3075
|
-
}
|
|
3076
|
-
seenKeys.add(redactedKey);
|
|
3077
|
-
entries.push([
|
|
3078
|
-
redactedKey,
|
|
3079
|
-
typeof entry === "string" ? redactIdentifier(entry, record) : transformProtectedRecord(entry, key, record, redactScalar, redactIdentifier)
|
|
3080
|
-
]);
|
|
3081
|
-
}
|
|
3082
|
-
return Object.fromEntries(entries);
|
|
3083
|
-
}
|
|
3084
|
-
function transformTagFilter(value, record, redactScalar, redactIdentifier) {
|
|
3085
|
-
const output = {};
|
|
3086
|
-
for (const [key, entry] of Object.entries(value)) {
|
|
3087
|
-
const redactedKey = redactScalar(key, record);
|
|
3088
|
-
output[redactedKey] = (key === "key" || key === "value") && typeof entry === "string" ? redactIdentifier(entry, record) : transformProtectedRecord(entry, key, record, redactScalar, redactIdentifier);
|
|
3089
|
-
}
|
|
3090
|
-
return output;
|
|
3091
|
-
}
|
|
3092
|
-
function isIdentifierFieldName(name) {
|
|
3093
|
-
return /ids?$/i.test(name);
|
|
3094
|
-
}
|
|
3095
|
-
function protectedRedactionRules(protectedValues) {
|
|
3096
|
-
const exactRules = protectedValueVariants(protectedValues).sort((left, right) => right.length - left.length || left.localeCompare(right)).map((value, index) => ({
|
|
3097
|
-
id: `candidate-access-${index}`,
|
|
3098
|
-
pattern: new RegExp(escapeRegularExpression(value), "g"),
|
|
3099
|
-
replacement: "[redacted:candidate-access]"
|
|
3100
|
-
}));
|
|
3101
|
-
return [...exactRules, ...DEFAULT_REDACTION_RULES];
|
|
3102
|
-
}
|
|
3103
|
-
function recordRedaction(report, rule, count) {
|
|
3104
|
-
if (count <= 0) return;
|
|
3105
|
-
report.redactionCount += count;
|
|
3106
|
-
report.byRule[rule] = (report.byRule[rule] ?? 0) + count;
|
|
3107
|
-
}
|
|
3108
|
-
function containsProtectedBytes(bytes, protectedValues) {
|
|
3109
|
-
const source = Buffer.from(bytes);
|
|
3110
|
-
return protectedValueVariants(protectedValues).some(
|
|
3111
|
-
(value) => source.includes(Buffer.from(value, "utf8"))
|
|
3112
|
-
);
|
|
3113
|
-
}
|
|
3114
|
-
function decodedBase64ContainsProtectedValue(value, protectedValues) {
|
|
3115
|
-
if (value.length < 4 || value.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/.test(value)) {
|
|
3116
|
-
return false;
|
|
3117
|
-
}
|
|
3118
|
-
try {
|
|
3119
|
-
return containsProtectedBytes(Buffer.from(value, "base64"), protectedValues);
|
|
3120
|
-
} catch {
|
|
3121
|
-
return false;
|
|
3122
|
-
}
|
|
3123
|
-
}
|
|
3124
|
-
function protectedValueVariants(protectedValues) {
|
|
3125
|
-
const variants = /* @__PURE__ */ new Set();
|
|
3126
|
-
for (const value of normalizedProtectedValues(protectedValues)) {
|
|
3127
|
-
variants.add(value);
|
|
3128
|
-
variants.add(Buffer.from(value, "utf8").toString("base64"));
|
|
3129
|
-
variants.add(Buffer.from(value, "utf8").toString("base64url"));
|
|
3130
|
-
variants.add(encodeURIComponent(value));
|
|
3131
|
-
}
|
|
3132
|
-
return [...variants];
|
|
3133
|
-
}
|
|
3134
|
-
function normalizedProtectedValues(values) {
|
|
3135
|
-
return [...new Set(values.filter((value) => value.length > 0))];
|
|
3136
|
-
}
|
|
3137
|
-
function escapeRegularExpression(value) {
|
|
3138
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3139
|
-
}
|
|
3140
|
-
|
|
3141
3076
|
// src/candidate-execution/finalize.ts
|
|
3142
3077
|
async function finalizeAgentCandidateRun(state, capture, traceStore, traceIdentity, settlement, evidence, protectedValues, writeRedactionReport, signal) {
|
|
3143
3078
|
let termination;
|
|
@@ -3185,7 +3120,7 @@ async function finalizeAgentCandidateRun(state, capture, traceStore, traceIdenti
|
|
|
3185
3120
|
);
|
|
3186
3121
|
const redacted = redactProtectedValue(
|
|
3187
3122
|
{
|
|
3188
|
-
run: { ...run, redactionVersion:
|
|
3123
|
+
run: { ...run, redactionVersion: REDACTION_VERSION },
|
|
3189
3124
|
spans: orderedSpans,
|
|
3190
3125
|
events: orderedEvents,
|
|
3191
3126
|
budget: orderedBudget,
|
|
@@ -3201,7 +3136,7 @@ async function finalizeAgentCandidateRun(state, capture, traceStore, traceIdenti
|
|
|
3201
3136
|
...redacted.value,
|
|
3202
3137
|
evaluatorLimits: { resultTimeoutMs: state.resultTimeoutMs },
|
|
3203
3138
|
redaction: {
|
|
3204
|
-
version:
|
|
3139
|
+
version: REDACTION_VERSION,
|
|
3205
3140
|
redactionCount: (writeRedactionReport?.redactionCount ?? 0) + redacted.report.redactionCount,
|
|
3206
3141
|
byRule: combinedByRule
|
|
3207
3142
|
}
|
|
@@ -3348,9 +3283,9 @@ function compareStrings(a, b) {
|
|
|
3348
3283
|
}
|
|
3349
3284
|
|
|
3350
3285
|
// src/candidate-execution/outcome-evidence.ts
|
|
3351
|
-
import { mkdtemp as
|
|
3352
|
-
import { tmpdir as
|
|
3353
|
-
import { join as
|
|
3286
|
+
import { mkdtemp as mkdtemp3, rm as rm3 } from "fs/promises";
|
|
3287
|
+
import { tmpdir as tmpdir3 } from "os";
|
|
3288
|
+
import { join as join3 } from "path";
|
|
3354
3289
|
import {
|
|
3355
3290
|
agentCandidateBenchmarkResultEvidenceSchema,
|
|
3356
3291
|
agentCandidateModelSettlementEvidenceSchema,
|
|
@@ -3846,7 +3781,7 @@ async function persistCandidateBenchmarkResult(state, termination, outcome, grad
|
|
|
3846
3781
|
);
|
|
3847
3782
|
}
|
|
3848
3783
|
async function verifyTaskOutcomeArchive(state, snapshot, archive, protectedValues) {
|
|
3849
|
-
const root = await
|
|
3784
|
+
const root = await mkdtemp3(join3(tmpdir3(), "agent-candidate-task-archive-"));
|
|
3850
3785
|
try {
|
|
3851
3786
|
await state.ports.workspaces.materialize({
|
|
3852
3787
|
role: "task",
|
|
@@ -3857,7 +3792,7 @@ async function verifyTaskOutcomeArchive(state, snapshot, archive, protectedValue
|
|
|
3857
3792
|
const files = await readMaterializedWorkspaceFiles(root, snapshot.material);
|
|
3858
3793
|
for (const file of files) assertNoProtectedBytes(file.bytes, protectedValues);
|
|
3859
3794
|
} finally {
|
|
3860
|
-
await
|
|
3795
|
+
await rm3(root, { recursive: true, force: true });
|
|
3861
3796
|
}
|
|
3862
3797
|
}
|
|
3863
3798
|
async function verifyMemoryCapture(state, capture, protectedValues, signal) {
|
|
@@ -3878,7 +3813,7 @@ async function verifyMemoryCapture(state, capture, protectedValues, signal) {
|
|
|
3878
3813
|
manifest: embeddedCandidateArtifact(manifestBytes),
|
|
3879
3814
|
archive: embeddedCandidateArtifact(memory.archive)
|
|
3880
3815
|
});
|
|
3881
|
-
const root = await
|
|
3816
|
+
const root = await mkdtemp3(join3(tmpdir3(), "agent-candidate-memory-after-"));
|
|
3882
3817
|
try {
|
|
3883
3818
|
await state.ports.workspaces.materialize({
|
|
3884
3819
|
role: "memory",
|
|
@@ -3890,7 +3825,7 @@ async function verifyMemoryCapture(state, capture, protectedValues, signal) {
|
|
|
3890
3825
|
for (const file of files) assertNoProtectedBytes(file.bytes, protectedValues);
|
|
3891
3826
|
signal?.throwIfAborted();
|
|
3892
3827
|
} finally {
|
|
3893
|
-
await
|
|
3828
|
+
await rm3(root, { recursive: true, force: true });
|
|
3894
3829
|
}
|
|
3895
3830
|
}
|
|
3896
3831
|
function normalizeEvaluation(evaluation, termination) {
|
|
@@ -4794,184 +4729,8 @@ var CandidateExecutionDeadlineError = class extends Error {
|
|
|
4794
4729
|
}
|
|
4795
4730
|
};
|
|
4796
4731
|
|
|
4797
|
-
// src/candidate-execution/verify.ts
|
|
4798
|
-
import { agentCandidateBundleSchema } from "@tangle-network/agent-interface";
|
|
4799
|
-
var verifiedCandidateState = /* @__PURE__ */ new WeakMap();
|
|
4800
|
-
var AGENT_CANDIDATE_EXECUTION_SUPPORT = Object.freeze({
|
|
4801
|
-
outcomes: Object.freeze(["workspace", "output"]),
|
|
4802
|
-
code: Object.freeze(["disabled", "no-op", "git-patch"]),
|
|
4803
|
-
memory: Object.freeze(["disabled", "isolated"]),
|
|
4804
|
-
knowledge: true,
|
|
4805
|
-
profile: Object.freeze({
|
|
4806
|
-
mcpTransports: Object.freeze(["stdio"]),
|
|
4807
|
-
remoteMcp: false,
|
|
4808
|
-
tools: false,
|
|
4809
|
-
permissions: false,
|
|
4810
|
-
modes: false,
|
|
4811
|
-
confidential: false
|
|
4812
|
-
})
|
|
4813
|
-
});
|
|
4814
|
-
async function verifyAgentCandidateBundle(input, ports) {
|
|
4815
|
-
const parsed = agentCandidateBundleSchema.parse(input);
|
|
4816
|
-
const withoutDigest = omitTopLevelDigest(parsed);
|
|
4817
|
-
const actualDigest = canonicalCandidateDigest(withoutDigest);
|
|
4818
|
-
if (actualDigest !== parsed.digest) {
|
|
4819
|
-
throw new Error(`candidate bundle digest ${parsed.digest} does not match ${actualDigest}`);
|
|
4820
|
-
}
|
|
4821
|
-
const canonicalBytes = canonicalCandidateBytes(withoutDigest);
|
|
4822
|
-
verifyBytes(canonicalBytes, parsed.digest, canonicalBytes.byteLength, "candidate bundle");
|
|
4823
|
-
assertCandidateProfileExecutionSupport(parsed.profile);
|
|
4824
|
-
const artifactBytes = /* @__PURE__ */ new Map();
|
|
4825
|
-
const readArtifact = async (artifact) => {
|
|
4826
|
-
const key = artifactCacheKey(artifact);
|
|
4827
|
-
const existing = artifactBytes.get(key);
|
|
4828
|
-
if (existing) return Uint8Array.from(existing);
|
|
4829
|
-
const bytes = await readVerifiedArtifact(artifact, ports.artifacts);
|
|
4830
|
-
artifactBytes.set(key, Uint8Array.from(bytes));
|
|
4831
|
-
return bytes;
|
|
4832
|
-
};
|
|
4833
|
-
let patchBytes;
|
|
4834
|
-
if (parsed.code.kind === "git-patch") {
|
|
4835
|
-
patchBytes = await readArtifact(parsed.code.patch.artifact);
|
|
4836
|
-
}
|
|
4837
|
-
const materializedTree = await verifyCandidateCode(parsed.code, ports.repositories, patchBytes);
|
|
4838
|
-
const resourceBytes = /* @__PURE__ */ new Map();
|
|
4839
|
-
for (const resource of candidateResources(parsed)) {
|
|
4840
|
-
const bytes = resource.kind === "inline" ? Buffer.from(resource.content, "utf8") : await readCandidateGitHubResource(resource, ports.repositories);
|
|
4841
|
-
verifyBytes(
|
|
4842
|
-
bytes,
|
|
4843
|
-
resource.sha256,
|
|
4844
|
-
resource.byteLength,
|
|
4845
|
-
`candidate resource ${resource.name ?? (resource.kind === "github" ? resource.path : "<unnamed>")}`
|
|
4846
|
-
);
|
|
4847
|
-
resourceBytes.set(resourceKey(resource), Uint8Array.from(bytes));
|
|
4848
|
-
resourceBytes.set(resource.sha256, Uint8Array.from(bytes));
|
|
4849
|
-
}
|
|
4850
|
-
if (parsed.execution.workspace) {
|
|
4851
|
-
const workspace = await verifyWorkspaceSnapshotArtifacts(
|
|
4852
|
-
parsed.execution.workspace,
|
|
4853
|
-
ports.artifacts
|
|
4854
|
-
);
|
|
4855
|
-
artifactBytes.set(artifactCacheKey(parsed.execution.workspace.manifest), workspace.manifest);
|
|
4856
|
-
artifactBytes.set(artifactCacheKey(parsed.execution.workspace.archive), workspace.archive);
|
|
4857
|
-
}
|
|
4858
|
-
if (parsed.knowledge) {
|
|
4859
|
-
const knowledge = await verifyWorkspaceSnapshotArtifacts(
|
|
4860
|
-
parsed.knowledge.snapshot,
|
|
4861
|
-
ports.artifacts
|
|
4862
|
-
);
|
|
4863
|
-
artifactBytes.set(artifactCacheKey(parsed.knowledge.snapshot.manifest), knowledge.manifest);
|
|
4864
|
-
artifactBytes.set(artifactCacheKey(parsed.knowledge.snapshot.archive), knowledge.archive);
|
|
4865
|
-
if (parsed.knowledge.retrievalConfig) await readArtifact(parsed.knowledge.retrievalConfig);
|
|
4866
|
-
await readArtifact(parsed.knowledge.evaluation);
|
|
4867
|
-
}
|
|
4868
|
-
if (parsed.memory.mode === "isolated" && parsed.memory.seed)
|
|
4869
|
-
await readArtifact(parsed.memory.seed);
|
|
4870
|
-
deepFreezeCandidate(parsed);
|
|
4871
|
-
const verified = Object.freeze({
|
|
4872
|
-
bundle: parsed,
|
|
4873
|
-
...materializedTree === void 0 ? {} : { materializedTree },
|
|
4874
|
-
[verifiedCandidateBrand]: true
|
|
4875
|
-
});
|
|
4876
|
-
verifiedCandidateState.set(verified, { ports, artifactBytes, resourceBytes });
|
|
4877
|
-
return verified;
|
|
4878
|
-
}
|
|
4879
|
-
function getVerifiedCandidateState(candidate) {
|
|
4880
|
-
const state = verifiedCandidateState.get(candidate);
|
|
4881
|
-
if (!state || candidate[verifiedCandidateBrand] !== true) {
|
|
4882
|
-
throw new Error("candidate must come from verifyAgentCandidateBundle");
|
|
4883
|
-
}
|
|
4884
|
-
return state;
|
|
4885
|
-
}
|
|
4886
|
-
async function verifiedArtifactBytes(candidate, artifact) {
|
|
4887
|
-
const state = getVerifiedCandidateState(candidate);
|
|
4888
|
-
const key = artifactCacheKey(artifact);
|
|
4889
|
-
const existing = state.artifactBytes.get(key);
|
|
4890
|
-
if (existing) return Uint8Array.from(existing);
|
|
4891
|
-
const bytes = await readVerifiedArtifact(artifact, state.ports.artifacts);
|
|
4892
|
-
state.artifactBytes.set(key, Uint8Array.from(bytes));
|
|
4893
|
-
return bytes;
|
|
4894
|
-
}
|
|
4895
|
-
function verifiedResourceTextByDigest(candidate) {
|
|
4896
|
-
const output = /* @__PURE__ */ new Map();
|
|
4897
|
-
for (const resource of candidateResources(candidate.bundle)) {
|
|
4898
|
-
const bytes = getVerifiedCandidateState(candidate).resourceBytes.get(resource.sha256);
|
|
4899
|
-
if (!bytes) throw new Error(`candidate resource digest was not verified: ${resource.sha256}`);
|
|
4900
|
-
output.set(resource.sha256, new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
4901
|
-
}
|
|
4902
|
-
return output;
|
|
4903
|
-
}
|
|
4904
|
-
function candidateResources(bundle) {
|
|
4905
|
-
const resources = bundle.profile.resources;
|
|
4906
|
-
if (!resources) return [];
|
|
4907
|
-
const output = [];
|
|
4908
|
-
for (const mount of resources.files ?? []) output.push(mount.resource);
|
|
4909
|
-
output.push(...resources.tools ?? []);
|
|
4910
|
-
output.push(...resources.skills ?? []);
|
|
4911
|
-
output.push(...resources.agents ?? []);
|
|
4912
|
-
output.push(...resources.commands ?? []);
|
|
4913
|
-
if (typeof resources.instructions === "object") output.push(resources.instructions);
|
|
4914
|
-
return output;
|
|
4915
|
-
}
|
|
4916
|
-
function resourceKey(resource) {
|
|
4917
|
-
return canonicalCandidateDigest(resource);
|
|
4918
|
-
}
|
|
4919
|
-
|
|
4920
|
-
// src/candidate-execution/knowledge.ts
|
|
4921
|
-
import { mkdtemp as mkdtemp3, rm as rm3 } from "fs/promises";
|
|
4922
|
-
import { tmpdir as tmpdir3 } from "os";
|
|
4923
|
-
import { join as join3, posix } from "path";
|
|
4924
|
-
import { hashKnowledgeBase } from "@tangle-network/agent-knowledge";
|
|
4925
|
-
var CANDIDATE_KNOWLEDGE_ROOT_ENV = "TANGLE_CANDIDATE_KNOWLEDGE_ROOT";
|
|
4926
|
-
var CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG_ENV = "TANGLE_CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG";
|
|
4927
|
-
function candidateKnowledgeExecutionPaths(taskRoot, hasRetrievalConfig) {
|
|
4928
|
-
if (!posix.isAbsolute(taskRoot) || posix.normalize(taskRoot) !== taskRoot) {
|
|
4929
|
-
throw new Error("candidate knowledge requires a normalized absolute task root");
|
|
4930
|
-
}
|
|
4931
|
-
const parent = posix.join(taskRoot, ".tangle");
|
|
4932
|
-
return {
|
|
4933
|
-
root: posix.join(parent, "knowledge"),
|
|
4934
|
-
...hasRetrievalConfig ? { retrievalConfig: posix.join(parent, "knowledge-retrieval-config.json") } : {}
|
|
4935
|
-
};
|
|
4936
|
-
}
|
|
4937
|
-
async function prepareAgentCandidateKnowledge(candidate, ports, arm) {
|
|
4938
|
-
const knowledge = candidate.bundle.knowledge;
|
|
4939
|
-
if (!knowledge) return void 0;
|
|
4940
|
-
const archive = await verifiedArtifactBytes(candidate, knowledge.snapshot.archive);
|
|
4941
|
-
const retrievalConfig = knowledge.retrievalConfig ? await verifiedArtifactBytes(candidate, knowledge.retrievalConfig) : void 0;
|
|
4942
|
-
const root = await mkdtemp3(join3(tmpdir3(), "agent-candidate-knowledge-"));
|
|
4943
|
-
try {
|
|
4944
|
-
await ports.workspaces.materialize({
|
|
4945
|
-
role: "knowledge",
|
|
4946
|
-
snapshot: knowledge.snapshot,
|
|
4947
|
-
archive,
|
|
4948
|
-
destination: root
|
|
4949
|
-
});
|
|
4950
|
-
const expectedHash = arm === "baseline" ? knowledge.candidate.baseHash : knowledge.candidate.candidateHash;
|
|
4951
|
-
const actualHash = `sha256:${await hashKnowledgeBase(root)}`;
|
|
4952
|
-
if (actualHash !== expectedHash) {
|
|
4953
|
-
throw new Error(
|
|
4954
|
-
`materialized ${arm} knowledge does not match its measured content: expected ${expectedHash}, got ${actualHash}`
|
|
4955
|
-
);
|
|
4956
|
-
}
|
|
4957
|
-
const files = await readMaterializedWorkspaceFiles(root, knowledge.snapshot.material);
|
|
4958
|
-
return Object.freeze({
|
|
4959
|
-
candidate: knowledge.candidate,
|
|
4960
|
-
snapshot: knowledge.snapshot,
|
|
4961
|
-
files: Object.freeze(
|
|
4962
|
-
files.map(
|
|
4963
|
-
(file) => Object.freeze({ path: file.path, mode: file.mode, bytes: Uint8Array.from(file.bytes) })
|
|
4964
|
-
)
|
|
4965
|
-
),
|
|
4966
|
-
...retrievalConfig ? { retrievalConfig: Uint8Array.from(retrievalConfig) } : {}
|
|
4967
|
-
});
|
|
4968
|
-
} finally {
|
|
4969
|
-
await rm3(root, { recursive: true, force: true });
|
|
4970
|
-
}
|
|
4971
|
-
}
|
|
4972
|
-
|
|
4973
4732
|
// src/candidate-execution/prepare.ts
|
|
4974
|
-
import { randomBytes as
|
|
4733
|
+
import { randomBytes as randomBytes2 } from "crypto";
|
|
4975
4734
|
import { lstat as lstat2, readdir as readdir2 } from "fs/promises";
|
|
4976
4735
|
import { isAbsolute, posix as posix2, relative as relative2, resolve as resolveHostPath } from "path";
|
|
4977
4736
|
import {
|
|
@@ -5097,7 +4856,7 @@ async function prepareAgentCandidateExecution(candidate, task, ports, options =
|
|
|
5097
4856
|
const profileActivation = profileApplication.profileActivation;
|
|
5098
4857
|
const container = await resolveContainer(candidate, task, ports);
|
|
5099
4858
|
const resolvedModel = await resolveModel(candidate, task, ports);
|
|
5100
|
-
const preparationId = `candidate-preparation.${
|
|
4859
|
+
const preparationId = `candidate-preparation.${randomBytes2(32).toString("base64url")}`;
|
|
5101
4860
|
const reservationExpiresAtMs = Date.now() + Math.max(MIN_RESERVATION_TTL_MS, reservationWindowMs);
|
|
5102
4861
|
const modelReservation = await withinCandidateCleanupDeadline(
|
|
5103
4862
|
() => ports.models.reserveGrant({
|
|
@@ -5802,17 +5561,17 @@ export {
|
|
|
5802
5561
|
candidateClaimFileInternals,
|
|
5803
5562
|
sealAgentCandidateModelSettlement,
|
|
5804
5563
|
usdToNanos,
|
|
5805
|
-
sealAgentCandidateExecutorStopAcknowledgement,
|
|
5806
|
-
persistCandidateOutputArtifact,
|
|
5807
|
-
persistCandidateModelSettlementEvidence,
|
|
5808
|
-
RecoveryAgentCandidateTraceStore,
|
|
5809
|
-
executePreparedAgentCandidate,
|
|
5810
5564
|
AGENT_CANDIDATE_EXECUTION_SUPPORT,
|
|
5811
5565
|
verifyAgentCandidateBundle,
|
|
5812
5566
|
verifiedResourceTextByDigest,
|
|
5813
5567
|
CANDIDATE_KNOWLEDGE_ROOT_ENV,
|
|
5814
5568
|
CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG_ENV,
|
|
5815
5569
|
candidateKnowledgeExecutionPaths,
|
|
5570
|
+
sealAgentCandidateExecutorStopAcknowledgement,
|
|
5571
|
+
persistCandidateOutputArtifact,
|
|
5572
|
+
persistCandidateModelSettlementEvidence,
|
|
5573
|
+
RecoveryAgentCandidateTraceStore,
|
|
5574
|
+
executePreparedAgentCandidate,
|
|
5816
5575
|
prepareAgentCandidateExecution
|
|
5817
5576
|
};
|
|
5818
|
-
//# sourceMappingURL=chunk-
|
|
5577
|
+
//# sourceMappingURL=chunk-LJLG734E.js.map
|