@tangle-network/agent-runtime 0.45.0 → 0.46.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/README.md +3 -3
- package/dist/agent.d.ts +5 -5
- package/dist/agent.js +2 -2
- package/dist/agent.js.map +1 -1
- package/dist/analyst-loop.d.ts +5 -40
- package/dist/analyst-loop.js +2 -4
- package/dist/{chunk-KEWO4KI6.js → chunk-65FQLI4V.js} +628 -138
- package/dist/chunk-65FQLI4V.js.map +1 -0
- package/dist/{chunk-NYN5RTLP.js → chunk-GN75RGM6.js} +7 -7
- package/dist/chunk-GN75RGM6.js.map +1 -0
- package/dist/{chunk-PRX45WE2.js → chunk-GSUO5QS6.js} +1 -119
- package/dist/chunk-GSUO5QS6.js.map +1 -0
- package/dist/{chunk-FK53TXOP.js → chunk-HNUXAZIJ.js} +4 -27
- package/dist/chunk-HNUXAZIJ.js.map +1 -0
- package/dist/{chunk-IJ6FGOPO.js → chunk-I42NHLKX.js} +3 -3
- package/dist/chunk-I42NHLKX.js.map +1 -0
- package/dist/{chunk-IJGS6J7X.js → chunk-JNPK46YH.js} +2 -2
- package/dist/{chunk-QR4UUC5P.js → chunk-KADIJAD4.js} +33 -19
- package/dist/chunk-KADIJAD4.js.map +1 -0
- package/dist/{chunk-Z2QXVBA6.js → chunk-KPN7OQ64.js} +4 -4
- package/dist/chunk-KPN7OQ64.js.map +1 -0
- package/dist/{chunk-KSMX62JF.js → chunk-VR4JIC5H.js} +2 -2
- package/dist/{coder-CczgMqFx.d.ts → coder-DCWFQpmJ.d.ts} +1 -1
- package/dist/{dynamic-BvllHV6M.d.ts → driver-C-mtBo7h.d.ts} +6 -6
- package/dist/{improvement-adapter-CWegd3vw.d.ts → improvement-adapter-BC4HhuAR.d.ts} +1 -1
- package/dist/improvement.d.ts +2 -2
- package/dist/index.d.ts +8 -8
- package/dist/index.js +8 -8
- package/dist/{kb-gate-D9GBocLN.d.ts → kb-gate-2Gwpz_27.d.ts} +7 -7
- package/dist/{loop-runner-bin-CPrCoKqC.d.ts → loop-runner-bin-D-K6bRp3.d.ts} +11 -11
- package/dist/loop-runner-bin.d.ts +6 -6
- package/dist/loop-runner-bin.js +6 -6
- package/dist/loops.d.ts +5 -5
- package/dist/loops.js +10 -10
- package/dist/mcp/bin.js +6 -6
- package/dist/mcp/bin.js.map +1 -1
- package/dist/mcp/index.d.ts +11 -11
- package/dist/mcp/index.js +7 -7
- package/dist/{otel-export-Dy2DyUCU.d.ts → otel-export-nurzFwuJ.d.ts} +1 -1
- package/dist/profiles.d.ts +8 -8
- package/dist/profiles.js +1 -1
- package/dist/profiles.js.map +1 -1
- package/dist/{run-loop--hSoIknW.d.ts → run-loop-CU2Y00Si.d.ts} +2 -2
- package/dist/runtime.d.ts +156 -52
- package/dist/runtime.js +10 -10
- package/dist/{types-1HbsFa7H.d.ts → types-BfoeiQRZ.d.ts} +20 -20
- package/dist/{types-DdzkffAm.d.ts → types-DnYoHvvZ.d.ts} +17 -5
- package/dist/{types-BtRLF2U3.d.ts → types-p8dWBIXL.d.ts} +1 -1
- package/dist/workflow.d.ts +3 -3
- package/dist/workflow.js +2 -2
- package/dist/workflow.js.map +1 -1
- package/package.json +13 -24
- package/skills/agent-runtime-adoption/SKILL.md +3 -3
- package/skills/generate-eval/SKILL.md +60 -0
- package/dist/chunk-FK53TXOP.js.map +0 -1
- package/dist/chunk-IJ6FGOPO.js.map +0 -1
- package/dist/chunk-KEWO4KI6.js.map +0 -1
- package/dist/chunk-NYN5RTLP.js.map +0 -1
- package/dist/chunk-PRX45WE2.js.map +0 -1
- package/dist/chunk-QR4UUC5P.js.map +0 -1
- package/dist/chunk-Z2QXVBA6.js.map +0 -1
- /package/dist/{chunk-IJGS6J7X.js.map → chunk-JNPK46YH.js.map} +0 -0
- /package/dist/{chunk-KSMX62JF.js.map → chunk-VR4JIC5H.js.map} +0 -0
|
@@ -3,22 +3,120 @@ import {
|
|
|
3
3
|
PlannerError,
|
|
4
4
|
RuntimeRunStateError,
|
|
5
5
|
ValidationError,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
extractLlmCallEvent,
|
|
9
|
-
mapWithConcurrency,
|
|
10
|
-
randomSuffix,
|
|
11
|
-
randomUuid,
|
|
12
|
-
sleep,
|
|
13
|
-
stringifySafe,
|
|
14
|
-
throwAbort,
|
|
15
|
-
throwIfAborted,
|
|
16
|
-
withTimeout,
|
|
17
|
-
zeroTokenUsage
|
|
18
|
-
} from "./chunk-PRX45WE2.js";
|
|
6
|
+
extractLlmCallEvent
|
|
7
|
+
} from "./chunk-GSUO5QS6.js";
|
|
19
8
|
|
|
20
9
|
// src/durable/spawn-journal.ts
|
|
21
10
|
import { createHash } from "crypto";
|
|
11
|
+
|
|
12
|
+
// src/runtime/util.ts
|
|
13
|
+
async function deleteBoxSafe(box) {
|
|
14
|
+
if (!box || typeof box.delete !== "function") return true;
|
|
15
|
+
try {
|
|
16
|
+
await box.delete();
|
|
17
|
+
return true;
|
|
18
|
+
} catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function randomSuffix(len = 8) {
|
|
23
|
+
return Math.random().toString(36).slice(2, 2 + len);
|
|
24
|
+
}
|
|
25
|
+
function randomUuid() {
|
|
26
|
+
return crypto.randomUUID();
|
|
27
|
+
}
|
|
28
|
+
function abortError() {
|
|
29
|
+
const err = new Error("aborted");
|
|
30
|
+
err.name = "AbortError";
|
|
31
|
+
return err;
|
|
32
|
+
}
|
|
33
|
+
function throwAbort() {
|
|
34
|
+
throw abortError();
|
|
35
|
+
}
|
|
36
|
+
function throwIfAborted(signal) {
|
|
37
|
+
if (signal?.aborted) throw abortError();
|
|
38
|
+
}
|
|
39
|
+
function sleep(ms, signal) {
|
|
40
|
+
return new Promise((resolve) => {
|
|
41
|
+
if (signal?.aborted) {
|
|
42
|
+
resolve();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
let onAbort;
|
|
46
|
+
const timer = setTimeout(() => {
|
|
47
|
+
if (onAbort && signal) signal.removeEventListener("abort", onAbort);
|
|
48
|
+
resolve();
|
|
49
|
+
}, ms);
|
|
50
|
+
if (signal) {
|
|
51
|
+
onAbort = () => {
|
|
52
|
+
clearTimeout(timer);
|
|
53
|
+
resolve();
|
|
54
|
+
};
|
|
55
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function withTimeout(promise, ms) {
|
|
60
|
+
return new Promise((resolve) => {
|
|
61
|
+
const timer = setTimeout(() => resolve(void 0), ms);
|
|
62
|
+
promise.then(
|
|
63
|
+
(value) => {
|
|
64
|
+
clearTimeout(timer);
|
|
65
|
+
resolve(value);
|
|
66
|
+
},
|
|
67
|
+
() => {
|
|
68
|
+
clearTimeout(timer);
|
|
69
|
+
resolve(void 0);
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function stringifySafe(value, opts = {}) {
|
|
75
|
+
let s;
|
|
76
|
+
try {
|
|
77
|
+
if (typeof value === "string") {
|
|
78
|
+
s = value;
|
|
79
|
+
} else {
|
|
80
|
+
const json = opts.pretty ? JSON.stringify(value, null, 2) : JSON.stringify(value);
|
|
81
|
+
s = json ?? String(value);
|
|
82
|
+
}
|
|
83
|
+
} catch {
|
|
84
|
+
s = String(value);
|
|
85
|
+
}
|
|
86
|
+
if (opts.max !== void 0 && s.length > opts.max) return `${s.slice(0, opts.max)}\u2026`;
|
|
87
|
+
return s;
|
|
88
|
+
}
|
|
89
|
+
function zeroTokenUsage() {
|
|
90
|
+
return { input: 0, output: 0 };
|
|
91
|
+
}
|
|
92
|
+
function addTokenUsage(acc, delta) {
|
|
93
|
+
acc.input += delta.input ?? 0;
|
|
94
|
+
acc.output += delta.output ?? 0;
|
|
95
|
+
}
|
|
96
|
+
async function mapWithConcurrency(items, limit, fn) {
|
|
97
|
+
const bound = Math.max(1, Math.floor(limit));
|
|
98
|
+
const results = new Array(items.length);
|
|
99
|
+
let next = 0;
|
|
100
|
+
let failed = false;
|
|
101
|
+
const worker = async () => {
|
|
102
|
+
while (!failed) {
|
|
103
|
+
const i = next;
|
|
104
|
+
next += 1;
|
|
105
|
+
if (i >= items.length) return;
|
|
106
|
+
try {
|
|
107
|
+
results[i] = await fn(items[i], i);
|
|
108
|
+
} catch (err) {
|
|
109
|
+
failed = true;
|
|
110
|
+
throw err;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
const workerCount = Math.min(bound, items.length);
|
|
115
|
+
await Promise.all(Array.from({ length: workerCount }, () => worker()));
|
|
116
|
+
return results;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// src/durable/spawn-journal.ts
|
|
22
120
|
function contentAddress(artifact) {
|
|
23
121
|
const hex = createHash("sha256").update(stableStringify(artifact), "utf-8").digest("hex");
|
|
24
122
|
return `sha256:${hex}`;
|
|
@@ -376,18 +474,100 @@ function deterministicCompletion(check) {
|
|
|
376
474
|
};
|
|
377
475
|
}
|
|
378
476
|
|
|
379
|
-
// src/runtime/
|
|
380
|
-
|
|
477
|
+
// src/runtime/personify/analyst.ts
|
|
478
|
+
var judgeEvidenceUri = /^(verdict|judge|score)\b/i;
|
|
479
|
+
var assertTraceDerivedFindings = (findings) => {
|
|
480
|
+
for (const f of findings) {
|
|
481
|
+
for (const ref of f.evidence_refs ?? []) {
|
|
482
|
+
if (ref.kind === "metric" && judgeEvidenceUri.test(ref.uri)) {
|
|
483
|
+
throw new PlannerError(
|
|
484
|
+
`steer-firewall: finding ${stringifySafe(f.finding_id)} cites judge-derived evidence (${stringifySafe(ref.uri)}); findings fed to a combinator's steer decision must be trace-derived, not judge-derived (selector \u2260 judge)`
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
function createScopeAnalyst(scope, options) {
|
|
491
|
+
if (!options.analyst || typeof options.analyst.act !== "function") {
|
|
492
|
+
throw new AnalystError("createScopeAnalyst: analyst must be an Agent with an act() method");
|
|
493
|
+
}
|
|
494
|
+
const label = options.label ?? "analyst";
|
|
495
|
+
return {
|
|
496
|
+
async analyze(input) {
|
|
497
|
+
const task = options.buildTask(input);
|
|
498
|
+
const spawned = scope.spawn(options.analyst, task, {
|
|
499
|
+
budget: options.budget,
|
|
500
|
+
label
|
|
501
|
+
});
|
|
502
|
+
if (!spawned.ok) {
|
|
503
|
+
throw new AnalystError(
|
|
504
|
+
`createScopeAnalyst: analyst spawn refused by the conserved pool (${spawned.reason}); cannot steer node ${stringifySafe(input.nodeId)} on an unrun analyst`
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
const settled = await drainAnalystSettlement(scope, spawned.handle.id);
|
|
508
|
+
const findings = readAnalystFindings(settled);
|
|
509
|
+
assertTraceDerivedFindings(findings);
|
|
510
|
+
return findings;
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
async function drainAnalystSettlement(scope, analystId) {
|
|
515
|
+
for (; ; ) {
|
|
516
|
+
const settled = await scope.next();
|
|
517
|
+
if (settled === null) {
|
|
518
|
+
throw new AnalystError(
|
|
519
|
+
`createScopeAnalyst: scope drained before analyst ${stringifySafe(analystId)} settled`
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
if (settled.handle.id === analystId) return settled;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
function readAnalystFindings(settled) {
|
|
526
|
+
if (settled.kind === "down") {
|
|
527
|
+
throw new AnalystError(
|
|
528
|
+
`createScopeAnalyst: analyst ${stringifySafe(settled.handle.id)} settled down (${settled.infra ? "infra" : "result"}): ${stringifySafe(settled.reason)}`
|
|
529
|
+
);
|
|
530
|
+
}
|
|
531
|
+
const out = settled.out;
|
|
532
|
+
if (!Array.isArray(out)) {
|
|
533
|
+
throw new PlannerError(
|
|
534
|
+
`createScopeAnalyst: analyst ${stringifySafe(settled.handle.id)} must return AnalystFinding[], got ${stringifySafe(out)}`
|
|
535
|
+
);
|
|
536
|
+
}
|
|
537
|
+
return out;
|
|
538
|
+
}
|
|
539
|
+
function buildSteerContext(findings, settledSoFar) {
|
|
540
|
+
assertTraceDerivedFindings(findings);
|
|
541
|
+
const lastValidScore = observedBestScore(settledSoFar);
|
|
542
|
+
return {
|
|
543
|
+
findings,
|
|
544
|
+
settledSoFar,
|
|
545
|
+
...lastValidScore !== void 0 ? { lastValidScore } : {}
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
function observedBestScore(settledSoFar) {
|
|
549
|
+
let best;
|
|
550
|
+
for (const s of settledSoFar) {
|
|
551
|
+
if (s.kind !== "done") continue;
|
|
552
|
+
const v = s.verdict;
|
|
553
|
+
if (!v || v.valid !== true || typeof v.score !== "number") continue;
|
|
554
|
+
if (best === void 0 || v.score > best) best = v.score;
|
|
555
|
+
}
|
|
556
|
+
return best;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// src/runtime/driver.ts
|
|
560
|
+
function createDriver(options) {
|
|
381
561
|
if (typeof options.planner !== "function") {
|
|
382
|
-
throw new ValidationError("
|
|
562
|
+
throw new ValidationError("createDriver: planner must be a function");
|
|
383
563
|
}
|
|
384
564
|
const maxIterations = options.maxIterations ?? 8;
|
|
385
565
|
if (!Number.isFinite(maxIterations) || maxIterations <= 0) {
|
|
386
|
-
throw new ValidationError("
|
|
566
|
+
throw new ValidationError("createDriver: maxIterations must be > 0");
|
|
387
567
|
}
|
|
388
568
|
const maxFanout = options.maxFanout ?? 4;
|
|
389
569
|
if (!Number.isFinite(maxFanout) || maxFanout < 1) {
|
|
390
|
-
throw new ValidationError("
|
|
570
|
+
throw new ValidationError("createDriver: maxFanout must be >= 1");
|
|
391
571
|
}
|
|
392
572
|
let pending;
|
|
393
573
|
return {
|
|
@@ -498,7 +678,7 @@ async function runAnalyze(analyze, task, history) {
|
|
|
498
678
|
const findings = await analyze({ task, history });
|
|
499
679
|
if (!Array.isArray(findings)) {
|
|
500
680
|
throw new PlannerError(
|
|
501
|
-
`
|
|
681
|
+
`createDriver: analyze hook must return AnalystFinding[], got ${stringifySafe(findings)}`
|
|
502
682
|
);
|
|
503
683
|
}
|
|
504
684
|
assertTraceDerivedFindings(findings);
|
|
@@ -508,23 +688,11 @@ async function runComplete(complete, task, history) {
|
|
|
508
688
|
const verdict = await complete.assess({ task, history });
|
|
509
689
|
if (!verdict || typeof verdict.done !== "boolean" || verdict.determinism !== "deterministic" && verdict.determinism !== "probabilistic") {
|
|
510
690
|
throw new PlannerError(
|
|
511
|
-
`
|
|
691
|
+
`createDriver: complete.assess must return a CompletionVerdict {done, determinism}, got ${stringifySafe(verdict)}`
|
|
512
692
|
);
|
|
513
693
|
}
|
|
514
694
|
return verdict;
|
|
515
695
|
}
|
|
516
|
-
var JUDGE_EVIDENCE_URI = /^(verdict|judge|score)\b/i;
|
|
517
|
-
function assertTraceDerivedFindings(findings) {
|
|
518
|
-
for (const f of findings) {
|
|
519
|
-
for (const ref of f.evidence_refs ?? []) {
|
|
520
|
-
if (ref.kind === "metric" && JUDGE_EVIDENCE_URI.test(ref.uri)) {
|
|
521
|
-
throw new PlannerError(
|
|
522
|
-
`steer-firewall: finding ${stringifySafe(f.finding_id)} cites judge-derived evidence (${stringifySafe(ref.uri)}); analyses fed to the driver must be trace-derived, not judge-derived (selector \u2260 judge)`
|
|
523
|
-
);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
696
|
function renderAnalyses(findings) {
|
|
529
697
|
if (findings.length === 0) return "";
|
|
530
698
|
const rows = findings.map((f) => {
|
|
@@ -535,6 +703,56 @@ function renderAnalyses(findings) {
|
|
|
535
703
|
${rows.join("\n")}`;
|
|
536
704
|
}
|
|
537
705
|
|
|
706
|
+
// src/runtime/inline-sandbox-client.ts
|
|
707
|
+
function isAsyncIterable(v) {
|
|
708
|
+
return typeof v === "object" && v !== null && Symbol.asyncIterator in v;
|
|
709
|
+
}
|
|
710
|
+
async function settle(exec, task, signal) {
|
|
711
|
+
const r = exec.execute(task, signal);
|
|
712
|
+
if (isAsyncIterable(r)) {
|
|
713
|
+
for await (const _ of r) {
|
|
714
|
+
}
|
|
715
|
+
return exec.resultArtifact();
|
|
716
|
+
}
|
|
717
|
+
return r;
|
|
718
|
+
}
|
|
719
|
+
function inlineSandboxClient(factory) {
|
|
720
|
+
let seq = 0;
|
|
721
|
+
return {
|
|
722
|
+
async create(_options) {
|
|
723
|
+
const id = `inline-${seq++}`;
|
|
724
|
+
return {
|
|
725
|
+
id,
|
|
726
|
+
async *streamPrompt(message) {
|
|
727
|
+
const controller = new AbortController();
|
|
728
|
+
const spec = { profile: { name: id }, harness: null };
|
|
729
|
+
const exec = factory(spec, { signal: controller.signal, seams: {} });
|
|
730
|
+
try {
|
|
731
|
+
const artifact = await settle(exec, message, controller.signal);
|
|
732
|
+
const out = artifact.out;
|
|
733
|
+
yield {
|
|
734
|
+
type: "result",
|
|
735
|
+
data: {
|
|
736
|
+
finalText: out?.content ?? "",
|
|
737
|
+
tokenUsage: {
|
|
738
|
+
inputTokens: artifact.spent.tokens.input,
|
|
739
|
+
outputTokens: artifact.spent.tokens.output
|
|
740
|
+
},
|
|
741
|
+
costUsd: artifact.spent.usd
|
|
742
|
+
}
|
|
743
|
+
};
|
|
744
|
+
} finally {
|
|
745
|
+
await exec.teardown("brutalKill").catch(() => {
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
},
|
|
749
|
+
async delete() {
|
|
750
|
+
}
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
|
|
538
756
|
// src/runtime/report-usage.ts
|
|
539
757
|
function reportLoopUsage(cost, result, source = "loop") {
|
|
540
758
|
cost.observe(result.costUsd, source);
|
|
@@ -648,6 +866,7 @@ async function acquireSandbox(client, options, acquire = {}) {
|
|
|
648
866
|
const sleep2 = acquire.sleep ?? ((ms) => sleep(ms, acquire.signal));
|
|
649
867
|
const pollMs = acquire.pollIntervalMs ?? 3e3;
|
|
650
868
|
const deadline = now() + (acquire.readyTimeoutMs ?? 6e5);
|
|
869
|
+
const appearScans = 5;
|
|
651
870
|
const name = options.name ?? acquire.name ?? `loop-sbx-${randomUuid()}`;
|
|
652
871
|
const createOpts = { ...options, name };
|
|
653
872
|
const c = client;
|
|
@@ -663,9 +882,12 @@ async function acquireSandbox(client, options, acquire = {}) {
|
|
|
663
882
|
if (!isRetryable(err)) throw err;
|
|
664
883
|
lastErr = err;
|
|
665
884
|
if (typeof c.list === "function") {
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
885
|
+
for (let scan = 0; scan < appearScans && now() < deadline; scan += 1) {
|
|
886
|
+
const found = (await c.list().catch(() => []))?.find((b) => b.name === name);
|
|
887
|
+
if (found)
|
|
888
|
+
return await waitReadyOrDestroy(found, deadline, pollMs, acquire.signal, now, sleep2);
|
|
889
|
+
if (scan < appearScans - 1) await sleep2(pollMs);
|
|
890
|
+
}
|
|
669
891
|
}
|
|
670
892
|
attempt += 1;
|
|
671
893
|
await sleep2(Math.min(pollMs * attempt, 15e3));
|
|
@@ -714,9 +936,13 @@ function isRetryable(err) {
|
|
|
714
936
|
if (typeof status === "number" && RETRYABLE_HTTP.has(status)) return true;
|
|
715
937
|
const name = e.name ?? "";
|
|
716
938
|
if (name === "TimeoutError" || name === "ServerError" || name === "NetworkError") return true;
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
939
|
+
const msg = e.message ?? "";
|
|
940
|
+
if (/\b(timed out|timeout|gateway|temporarily unavailable|too many requests|ECONNRESET|ETIMEDOUT|EAI_AGAIN)\b/i.test(
|
|
941
|
+
msg
|
|
942
|
+
)) {
|
|
943
|
+
return true;
|
|
944
|
+
}
|
|
945
|
+
return /provision failed|edge data plane|not reachable|failed to create sandbox/i.test(msg);
|
|
720
946
|
}
|
|
721
947
|
|
|
722
948
|
// src/runtime/sandbox-backend.ts
|
|
@@ -764,10 +990,31 @@ async function resolveCapabilities(client) {
|
|
|
764
990
|
// src/runtime/sandbox-lineage.ts
|
|
765
991
|
var TEARDOWN_TIMEOUT_MS = 15e3;
|
|
766
992
|
var DEFAULT_FORK_CONCURRENCY = 4;
|
|
993
|
+
async function* pollPromptEvents(box, prompt, sessionId, signal) {
|
|
994
|
+
if (signal.aborted) throwAbort();
|
|
995
|
+
const dispatched = await box.dispatchPrompt(prompt, { sessionId, signal });
|
|
996
|
+
const activeSessionId = dispatched.sessionId;
|
|
997
|
+
const result = await box.session(activeSessionId).result();
|
|
998
|
+
if (signal.aborted) throwAbort();
|
|
999
|
+
yield {
|
|
1000
|
+
type: "result",
|
|
1001
|
+
id: activeSessionId,
|
|
1002
|
+
data: {
|
|
1003
|
+
finalText: result.response ?? "",
|
|
1004
|
+
success: result.success,
|
|
1005
|
+
...result.error ? { error: result.error } : {},
|
|
1006
|
+
...result.usage ? { usage: result.usage } : {}
|
|
1007
|
+
}
|
|
1008
|
+
};
|
|
1009
|
+
}
|
|
1010
|
+
function promptEvents(streaming, box, prompt, sessionId, signal) {
|
|
1011
|
+
return streaming === "poll" ? pollPromptEvents(box, prompt, sessionId, signal) : box.streamPrompt(prompt, { sessionId, signal });
|
|
1012
|
+
}
|
|
767
1013
|
function createSandboxLineage(client, capabilities, options = {}) {
|
|
768
1014
|
if (!client || typeof client.create !== "function") {
|
|
769
1015
|
throw new ValidationError("createSandboxLineage: client.create is required");
|
|
770
1016
|
}
|
|
1017
|
+
const streaming = options.streaming ?? "sse";
|
|
771
1018
|
const forkConcurrency = Math.max(
|
|
772
1019
|
1,
|
|
773
1020
|
Math.floor(options.maxConcurrency ?? DEFAULT_FORK_CONCURRENCY)
|
|
@@ -784,13 +1031,13 @@ function createSandboxLineage(client, capabilities, options = {}) {
|
|
|
784
1031
|
async start(spec, prompt, signal) {
|
|
785
1032
|
const box = await acquireFresh(spec, signal);
|
|
786
1033
|
const sessionId = mintSessionId();
|
|
787
|
-
const events = box
|
|
1034
|
+
const events = promptEvents(streaming, box, prompt, sessionId, signal);
|
|
788
1035
|
return { handle: { box, sessionId }, events };
|
|
789
1036
|
},
|
|
790
1037
|
async continue(handle, prompt, signal) {
|
|
791
1038
|
if (signal.aborted) throwAbort();
|
|
792
1039
|
await assertSessionLive(handle.box, handle.sessionId);
|
|
793
|
-
return handle.box
|
|
1040
|
+
return promptEvents(streaming, handle.box, prompt, handle.sessionId, signal);
|
|
794
1041
|
},
|
|
795
1042
|
async fork(parent, prompts, specs, signal) {
|
|
796
1043
|
if (prompts.length === 0) {
|
|
@@ -808,14 +1055,14 @@ function createSandboxLineage(client, capabilities, options = {}) {
|
|
|
808
1055
|
const sessionId2 = mintSessionId();
|
|
809
1056
|
return {
|
|
810
1057
|
handle: { box: box2, sessionId: sessionId2 },
|
|
811
|
-
events:
|
|
1058
|
+
events: promptEvents(streaming, box2, prompt, sessionId2, signal)
|
|
812
1059
|
};
|
|
813
1060
|
}
|
|
814
1061
|
const box = await acquireFresh(spec, signal);
|
|
815
1062
|
const sessionId = mintSessionId();
|
|
816
1063
|
return {
|
|
817
1064
|
handle: { box, sessionId },
|
|
818
|
-
events: box
|
|
1065
|
+
events: promptEvents(streaming, box, prompt, sessionId, signal)
|
|
819
1066
|
};
|
|
820
1067
|
});
|
|
821
1068
|
},
|
|
@@ -884,6 +1131,7 @@ async function runLoop(options) {
|
|
|
884
1131
|
if (!Number.isFinite(maxConcurrency) || maxConcurrency <= 0) {
|
|
885
1132
|
throw new ValidationError("runLoop: maxConcurrency must be > 0");
|
|
886
1133
|
}
|
|
1134
|
+
const sandboxStreaming = options.lineage?.streaming ?? "sse";
|
|
887
1135
|
if (!options.ctx?.sandboxClient || typeof options.ctx.sandboxClient.create !== "function") {
|
|
888
1136
|
throw new ValidationError("runLoop: ctx.sandboxClient.create is required");
|
|
889
1137
|
}
|
|
@@ -1000,6 +1248,7 @@ async function runLoop(options) {
|
|
|
1000
1248
|
output: options.output,
|
|
1001
1249
|
validator: options.validator,
|
|
1002
1250
|
maxConcurrency,
|
|
1251
|
+
streaming: sandboxStreaming,
|
|
1003
1252
|
signal: controller.signal,
|
|
1004
1253
|
ctx: options.ctx,
|
|
1005
1254
|
runId,
|
|
@@ -1059,7 +1308,10 @@ async function setUpLineage(options, maxConcurrency) {
|
|
|
1059
1308
|
}
|
|
1060
1309
|
const capabilities = await probeSandboxCapabilities(options.ctx.sandboxClient);
|
|
1061
1310
|
return {
|
|
1062
|
-
lineage: createSandboxLineage(options.ctx.sandboxClient, capabilities, {
|
|
1311
|
+
lineage: createSandboxLineage(options.ctx.sandboxClient, capabilities, {
|
|
1312
|
+
maxConcurrency,
|
|
1313
|
+
streaming: lineageOpts.streaming
|
|
1314
|
+
}),
|
|
1063
1315
|
options: lineageOpts,
|
|
1064
1316
|
handles: /* @__PURE__ */ new Map(),
|
|
1065
1317
|
canPrune: typeof options.driver.describePlan !== "function"
|
|
@@ -1189,7 +1441,8 @@ async function executeIteration(args) {
|
|
|
1189
1441
|
stream = acquired.events;
|
|
1190
1442
|
} else {
|
|
1191
1443
|
box = await createSandboxForSpec(args.ctx.sandboxClient, spec, args.signal);
|
|
1192
|
-
|
|
1444
|
+
const prompt = spec.taskToPrompt(args.item.task);
|
|
1445
|
+
stream = args.streaming === "poll" ? promptEvents("poll", box, prompt, `${args.runId}-i${args.item.index}`, args.signal) : box.streamPrompt(prompt, { signal: args.signal });
|
|
1193
1446
|
}
|
|
1194
1447
|
const placement = describeSandboxPlacement(args.ctx.sandboxClient, box);
|
|
1195
1448
|
await emitTrace(args.ctx.traceEmitter, {
|
|
@@ -1479,88 +1732,6 @@ function loopDispatch(opts) {
|
|
|
1479
1732
|
return (profile, scenario, ctx) => runLoopForCell(opts, scenario, profile, ctx);
|
|
1480
1733
|
}
|
|
1481
1734
|
|
|
1482
|
-
// src/runtime/personify/analyst.ts
|
|
1483
|
-
var judgeEvidenceUri = /^(verdict|judge|score)\b/i;
|
|
1484
|
-
var assertTraceDerivedFindings2 = (findings) => {
|
|
1485
|
-
for (const f of findings) {
|
|
1486
|
-
for (const ref of f.evidence_refs ?? []) {
|
|
1487
|
-
if (ref.kind === "metric" && judgeEvidenceUri.test(ref.uri)) {
|
|
1488
|
-
throw new PlannerError(
|
|
1489
|
-
`steer-firewall: finding ${stringifySafe(f.finding_id)} cites judge-derived evidence (${stringifySafe(ref.uri)}); findings fed to a combinator's steer decision must be trace-derived, not judge-derived (selector \u2260 judge)`
|
|
1490
|
-
);
|
|
1491
|
-
}
|
|
1492
|
-
}
|
|
1493
|
-
}
|
|
1494
|
-
};
|
|
1495
|
-
function createScopeAnalyst(scope, options) {
|
|
1496
|
-
if (!options.analyst || typeof options.analyst.act !== "function") {
|
|
1497
|
-
throw new AnalystError("createScopeAnalyst: analyst must be an Agent with an act() method");
|
|
1498
|
-
}
|
|
1499
|
-
const label = options.label ?? "analyst";
|
|
1500
|
-
return {
|
|
1501
|
-
async analyze(input) {
|
|
1502
|
-
const task = options.buildTask(input);
|
|
1503
|
-
const spawned = scope.spawn(options.analyst, task, {
|
|
1504
|
-
budget: options.budget,
|
|
1505
|
-
label
|
|
1506
|
-
});
|
|
1507
|
-
if (!spawned.ok) {
|
|
1508
|
-
throw new AnalystError(
|
|
1509
|
-
`createScopeAnalyst: analyst spawn refused by the conserved pool (${spawned.reason}); cannot steer node ${stringifySafe(input.nodeId)} on an unrun analyst`
|
|
1510
|
-
);
|
|
1511
|
-
}
|
|
1512
|
-
const settled = await drainAnalystSettlement(scope, spawned.handle.id);
|
|
1513
|
-
const findings = readAnalystFindings(settled);
|
|
1514
|
-
assertTraceDerivedFindings2(findings);
|
|
1515
|
-
return findings;
|
|
1516
|
-
}
|
|
1517
|
-
};
|
|
1518
|
-
}
|
|
1519
|
-
async function drainAnalystSettlement(scope, analystId) {
|
|
1520
|
-
for (; ; ) {
|
|
1521
|
-
const settled = await scope.next();
|
|
1522
|
-
if (settled === null) {
|
|
1523
|
-
throw new AnalystError(
|
|
1524
|
-
`createScopeAnalyst: scope drained before analyst ${stringifySafe(analystId)} settled`
|
|
1525
|
-
);
|
|
1526
|
-
}
|
|
1527
|
-
if (settled.handle.id === analystId) return settled;
|
|
1528
|
-
}
|
|
1529
|
-
}
|
|
1530
|
-
function readAnalystFindings(settled) {
|
|
1531
|
-
if (settled.kind === "down") {
|
|
1532
|
-
throw new AnalystError(
|
|
1533
|
-
`createScopeAnalyst: analyst ${stringifySafe(settled.handle.id)} settled down (${settled.infra ? "infra" : "result"}): ${stringifySafe(settled.reason)}`
|
|
1534
|
-
);
|
|
1535
|
-
}
|
|
1536
|
-
const out = settled.out;
|
|
1537
|
-
if (!Array.isArray(out)) {
|
|
1538
|
-
throw new PlannerError(
|
|
1539
|
-
`createScopeAnalyst: analyst ${stringifySafe(settled.handle.id)} must return AnalystFinding[], got ${stringifySafe(out)}`
|
|
1540
|
-
);
|
|
1541
|
-
}
|
|
1542
|
-
return out;
|
|
1543
|
-
}
|
|
1544
|
-
function buildSteerContext(findings, settledSoFar) {
|
|
1545
|
-
assertTraceDerivedFindings2(findings);
|
|
1546
|
-
const lastValidScore = observedBestScore(settledSoFar);
|
|
1547
|
-
return {
|
|
1548
|
-
findings,
|
|
1549
|
-
settledSoFar,
|
|
1550
|
-
...lastValidScore !== void 0 ? { lastValidScore } : {}
|
|
1551
|
-
};
|
|
1552
|
-
}
|
|
1553
|
-
function observedBestScore(settledSoFar) {
|
|
1554
|
-
let best;
|
|
1555
|
-
for (const s of settledSoFar) {
|
|
1556
|
-
if (s.kind !== "done") continue;
|
|
1557
|
-
const v = s.verdict;
|
|
1558
|
-
if (!v || v.valid !== true || typeof v.score !== "number") continue;
|
|
1559
|
-
if (best === void 0 || v.score > best) best = v.score;
|
|
1560
|
-
}
|
|
1561
|
-
return best;
|
|
1562
|
-
}
|
|
1563
|
-
|
|
1564
1735
|
// src/runtime/supervise/scope.ts
|
|
1565
1736
|
function createScope(args) {
|
|
1566
1737
|
const children = /* @__PURE__ */ new Map();
|
|
@@ -1574,7 +1745,7 @@ function createScope(args) {
|
|
|
1574
1745
|
const spec = agent.executorSpec;
|
|
1575
1746
|
if (!isAgentSpec(spec)) {
|
|
1576
1747
|
throw new ValidationError(
|
|
1577
|
-
`scope.spawn: agent "${agent.name}" exposes no \`executorSpec\` (AgentSpec) to resolve a
|
|
1748
|
+
`scope.spawn: agent "${agent.name}" exposes no \`executorSpec\` (AgentSpec) to resolve a Executor`
|
|
1578
1749
|
);
|
|
1579
1750
|
}
|
|
1580
1751
|
const resolved = args.executors.resolve(spec);
|
|
@@ -1802,7 +1973,7 @@ async function runChild(live, executor, childAbort, task, opts, pool, ticket, bl
|
|
|
1802
1973
|
live.status = "running";
|
|
1803
1974
|
const ran = executor.execute(task, childAbort.signal);
|
|
1804
1975
|
let artifact;
|
|
1805
|
-
if (
|
|
1976
|
+
if (isAsyncIterable2(ran)) {
|
|
1806
1977
|
const spend = await foldStream(ran);
|
|
1807
1978
|
live.spent = spend;
|
|
1808
1979
|
artifact = executor.resultArtifact();
|
|
@@ -1924,7 +2095,7 @@ function downRecord(reason, infra) {
|
|
|
1924
2095
|
function zeroSpend2() {
|
|
1925
2096
|
return { iterations: 0, tokens: { input: 0, output: 0 }, usd: 0, ms: 0 };
|
|
1926
2097
|
}
|
|
1927
|
-
function
|
|
2098
|
+
function isAsyncIterable2(value) {
|
|
1928
2099
|
return typeof value === "object" && value !== null && typeof value[Symbol.asyncIterator] === "function";
|
|
1929
2100
|
}
|
|
1930
2101
|
function isAgentSpec(value) {
|
|
@@ -2463,6 +2634,7 @@ import { estimateCost, isModelPriced } from "@tangle-network/agent-eval";
|
|
|
2463
2634
|
var routerSeamKey = "router";
|
|
2464
2635
|
var sandboxSeamKey = "sandbox";
|
|
2465
2636
|
var cliSeamKey = "cli";
|
|
2637
|
+
var bridgeSeamKey = "bridge";
|
|
2466
2638
|
function contentRef(prefix, value) {
|
|
2467
2639
|
let str;
|
|
2468
2640
|
try {
|
|
@@ -2756,6 +2928,96 @@ function killWithGrace(proc, grace) {
|
|
|
2756
2928
|
}, grace);
|
|
2757
2929
|
});
|
|
2758
2930
|
}
|
|
2931
|
+
var bridgeExecutor = (spec, ctx) => {
|
|
2932
|
+
const seam = readSeam(ctx, bridgeSeamKey, "bridge");
|
|
2933
|
+
if (!seam.bridgeUrl || !seam.bridgeBearer || !seam.model) {
|
|
2934
|
+
throw new ValidationError(
|
|
2935
|
+
"bridgeExecutor: BridgeSeam.bridgeUrl + bridgeBearer + model required"
|
|
2936
|
+
);
|
|
2937
|
+
}
|
|
2938
|
+
const controller = new AbortController();
|
|
2939
|
+
const abortIfSignalled = () => {
|
|
2940
|
+
if (ctx.signal.aborted) controller.abort();
|
|
2941
|
+
};
|
|
2942
|
+
abortIfSignalled();
|
|
2943
|
+
if (!ctx.signal.aborted) ctx.signal.addEventListener("abort", abortIfSignalled, { once: true });
|
|
2944
|
+
let artifact;
|
|
2945
|
+
return {
|
|
2946
|
+
runtime: "cli",
|
|
2947
|
+
async execute(task, signal) {
|
|
2948
|
+
const messages = taskToMessages(task, spec);
|
|
2949
|
+
const started = Date.now();
|
|
2950
|
+
const linked = linkSignals(signal, controller.signal);
|
|
2951
|
+
const timer = seam.timeoutMs ? setTimeout(() => controller.abort(), seam.timeoutMs) : void 0;
|
|
2952
|
+
try {
|
|
2953
|
+
const res = await fetch(`${seam.bridgeUrl.replace(/\/$/, "")}/v1/chat/completions`, {
|
|
2954
|
+
method: "POST",
|
|
2955
|
+
headers: {
|
|
2956
|
+
"content-type": "application/json",
|
|
2957
|
+
authorization: `Bearer ${seam.bridgeBearer}`
|
|
2958
|
+
},
|
|
2959
|
+
body: JSON.stringify({
|
|
2960
|
+
model: seam.model,
|
|
2961
|
+
stream: false,
|
|
2962
|
+
...seam.agentProfile ? { agent_profile: seam.agentProfile } : {},
|
|
2963
|
+
messages
|
|
2964
|
+
}),
|
|
2965
|
+
...linked ? { signal: linked } : {}
|
|
2966
|
+
});
|
|
2967
|
+
if (!res.ok) {
|
|
2968
|
+
throw new ValidationError(
|
|
2969
|
+
`bridgeExecutor: bridge ${res.status}: ${(await res.text()).slice(0, 300)}`
|
|
2970
|
+
);
|
|
2971
|
+
}
|
|
2972
|
+
const data = await res.json();
|
|
2973
|
+
const u = data.usage;
|
|
2974
|
+
const usage = u && typeof u.prompt_tokens === "number" && typeof u.completion_tokens === "number" ? { input: u.prompt_tokens, output: u.completion_tokens } : void 0;
|
|
2975
|
+
const msg = data.choices?.[0]?.message;
|
|
2976
|
+
const content = msg?.content ?? "";
|
|
2977
|
+
const toolCalls = (msg?.tool_calls ?? []).map((t) => t.function?.name ?? "unknown");
|
|
2978
|
+
const spent = {
|
|
2979
|
+
iterations: 1,
|
|
2980
|
+
tokens: usage ? { input: usage.input, output: usage.output } : zeroTokenUsage(),
|
|
2981
|
+
usd: typeof u?.cost === "number" ? u.cost : 0,
|
|
2982
|
+
ms: Date.now() - started
|
|
2983
|
+
};
|
|
2984
|
+
const out = { content, toolCalls };
|
|
2985
|
+
artifact = { outRef: contentRef("bridge", { model: seam.model, content }), out, spent };
|
|
2986
|
+
return artifact;
|
|
2987
|
+
} finally {
|
|
2988
|
+
if (timer) clearTimeout(timer);
|
|
2989
|
+
}
|
|
2990
|
+
},
|
|
2991
|
+
teardown(_grace) {
|
|
2992
|
+
controller.abort();
|
|
2993
|
+
return Promise.resolve({ destroyed: true });
|
|
2994
|
+
},
|
|
2995
|
+
resultArtifact() {
|
|
2996
|
+
if (!artifact) {
|
|
2997
|
+
throw new ValidationError("bridgeExecutor: resultArtifact() read before execute()");
|
|
2998
|
+
}
|
|
2999
|
+
return { ...artifact, spent: artifact.spent };
|
|
3000
|
+
}
|
|
3001
|
+
};
|
|
3002
|
+
};
|
|
3003
|
+
function createExecutor(config) {
|
|
3004
|
+
return (spec, ctx) => {
|
|
3005
|
+
const { backend, ...seam } = config;
|
|
3006
|
+
const seamed = { ...ctx, seams: { ...ctx.seams, [backend]: seam } };
|
|
3007
|
+
switch (config.backend) {
|
|
3008
|
+
case "router":
|
|
3009
|
+
return routerInlineExecutor(spec, seamed);
|
|
3010
|
+
case "bridge":
|
|
3011
|
+
return bridgeExecutor(spec, seamed);
|
|
3012
|
+
case "cli":
|
|
3013
|
+
return cliExecutor(spec, seamed);
|
|
3014
|
+
case "sandbox": {
|
|
3015
|
+
const harness = spec.harness ?? config.harness ?? null;
|
|
3016
|
+
return sandboxExecutor({ ...spec, harness }, seamed);
|
|
3017
|
+
}
|
|
3018
|
+
}
|
|
3019
|
+
};
|
|
3020
|
+
}
|
|
2759
3021
|
function createExecutorRegistry() {
|
|
2760
3022
|
const factories = /* @__PURE__ */ new Map();
|
|
2761
3023
|
factories.set("router", routerInlineExecutor);
|
|
@@ -3538,6 +3800,234 @@ function requireSpend(rolled, id, root) {
|
|
|
3538
3800
|
return spend;
|
|
3539
3801
|
}
|
|
3540
3802
|
|
|
3803
|
+
// src/runtime/sandbox-run.ts
|
|
3804
|
+
async function openSandboxRun(client, options, deliverable) {
|
|
3805
|
+
const runId = options.runId ?? `sandbox-run-${randomSuffix()}`;
|
|
3806
|
+
const now = options.now ?? Date.now;
|
|
3807
|
+
const capabilities = await probeSandboxCapabilities(client);
|
|
3808
|
+
const lineage = createSandboxLineage(client, capabilities, {
|
|
3809
|
+
...options.maxConcurrency !== void 0 ? { maxConcurrency: options.maxConcurrency } : {}
|
|
3810
|
+
});
|
|
3811
|
+
let handle;
|
|
3812
|
+
let started = false;
|
|
3813
|
+
let runStartedAt;
|
|
3814
|
+
let failed = false;
|
|
3815
|
+
let turnCount = 0;
|
|
3816
|
+
function emit(event) {
|
|
3817
|
+
notifyRuntimeHookEvent(
|
|
3818
|
+
options.hooks,
|
|
3819
|
+
{
|
|
3820
|
+
id: `${runId}:${event.target}:${event.phase}${event.stepIndex === void 0 ? "" : `:${event.stepIndex}`}`,
|
|
3821
|
+
runId,
|
|
3822
|
+
scenarioId: options.scenarioId,
|
|
3823
|
+
target: event.target,
|
|
3824
|
+
phase: event.phase,
|
|
3825
|
+
timestamp: event.timestamp,
|
|
3826
|
+
stepIndex: event.stepIndex,
|
|
3827
|
+
payload: event.payload,
|
|
3828
|
+
metadata: { producer: "openSandboxRun" }
|
|
3829
|
+
},
|
|
3830
|
+
{ signal: options.signal }
|
|
3831
|
+
);
|
|
3832
|
+
}
|
|
3833
|
+
const runPayload = () => ({
|
|
3834
|
+
agentName: options.agentRun.name ?? options.agentRun.profile.name ?? "agent",
|
|
3835
|
+
profileName: options.agentRun.profile.name,
|
|
3836
|
+
backendType: backendType(options.agentRun),
|
|
3837
|
+
deliverableKind: deliverable.kind,
|
|
3838
|
+
...deliverable.kind === "artifact" ? { deliverablePath: deliverable.path } : {},
|
|
3839
|
+
...handle ? { sessionId: handle.sessionId, sandboxId: handle.box.id } : {}
|
|
3840
|
+
});
|
|
3841
|
+
const turnPayload = (prompt, turnKind, startedAt, result, error) => ({
|
|
3842
|
+
...runPayload(),
|
|
3843
|
+
turnKind,
|
|
3844
|
+
promptChars: prompt.length,
|
|
3845
|
+
promptHash: hashText(prompt),
|
|
3846
|
+
...result !== void 0 || error !== void 0 ? { durationMs: Math.max(0, now() - startedAt) } : {},
|
|
3847
|
+
...result ? {
|
|
3848
|
+
eventCount: result.events.length,
|
|
3849
|
+
eventTypes: eventTypeCounts(result.events),
|
|
3850
|
+
...result.readError !== void 0 ? { readError: result.readError } : {}
|
|
3851
|
+
} : {},
|
|
3852
|
+
...error !== void 0 ? { error: errorMessage(error) } : {}
|
|
3853
|
+
});
|
|
3854
|
+
async function settle2(box, events) {
|
|
3855
|
+
const collected = [];
|
|
3856
|
+
for await (const ev of events) collected.push(ev);
|
|
3857
|
+
if (deliverable.kind === "events") {
|
|
3858
|
+
return { out: deliverable.fromEvents(collected), events: collected };
|
|
3859
|
+
}
|
|
3860
|
+
throwIfAborted(options.signal);
|
|
3861
|
+
let raw = "";
|
|
3862
|
+
let readError;
|
|
3863
|
+
const readAttempts = 4;
|
|
3864
|
+
const readDelayMs = options.readRetryDelayMs ?? 1e3;
|
|
3865
|
+
for (let attempt = 0; attempt < readAttempts; attempt += 1) {
|
|
3866
|
+
throwIfAborted(options.signal);
|
|
3867
|
+
try {
|
|
3868
|
+
raw = await box.fs.read(deliverable.path);
|
|
3869
|
+
readError = void 0;
|
|
3870
|
+
break;
|
|
3871
|
+
} catch (err) {
|
|
3872
|
+
readError = err instanceof Error ? err.message : String(err);
|
|
3873
|
+
if (attempt < readAttempts - 1 && readDelayMs > 0)
|
|
3874
|
+
await sleep(readDelayMs * (attempt + 1), options.signal);
|
|
3875
|
+
}
|
|
3876
|
+
}
|
|
3877
|
+
return {
|
|
3878
|
+
out: deliverable.fromArtifact(raw, collected),
|
|
3879
|
+
events: collected,
|
|
3880
|
+
...readError !== void 0 ? { readError } : {}
|
|
3881
|
+
};
|
|
3882
|
+
}
|
|
3883
|
+
return {
|
|
3884
|
+
get box() {
|
|
3885
|
+
if (!handle) throw new Error("openSandboxRun: box unavailable before start()");
|
|
3886
|
+
return handle.box;
|
|
3887
|
+
},
|
|
3888
|
+
get sessionId() {
|
|
3889
|
+
if (!handle) throw new Error("openSandboxRun: sessionId unavailable before start()");
|
|
3890
|
+
return handle.sessionId;
|
|
3891
|
+
},
|
|
3892
|
+
async start(prompt) {
|
|
3893
|
+
if (started)
|
|
3894
|
+
throw new Error(
|
|
3895
|
+
"openSandboxRun: start() already called \u2014 use resume() to continue the session"
|
|
3896
|
+
);
|
|
3897
|
+
started = true;
|
|
3898
|
+
runStartedAt = now();
|
|
3899
|
+
emit({
|
|
3900
|
+
target: "agent.run",
|
|
3901
|
+
phase: "before",
|
|
3902
|
+
timestamp: runStartedAt,
|
|
3903
|
+
payload: { ...runPayload(), turnCount: 0 }
|
|
3904
|
+
});
|
|
3905
|
+
const stepIndex = turnCount;
|
|
3906
|
+
const turnStartedAt = now();
|
|
3907
|
+
emit({
|
|
3908
|
+
target: "agent.turn",
|
|
3909
|
+
phase: "before",
|
|
3910
|
+
timestamp: turnStartedAt,
|
|
3911
|
+
stepIndex,
|
|
3912
|
+
payload: turnPayload(prompt, "start", turnStartedAt)
|
|
3913
|
+
});
|
|
3914
|
+
try {
|
|
3915
|
+
const r = await lineage.start(
|
|
3916
|
+
options.agentRun,
|
|
3917
|
+
prompt,
|
|
3918
|
+
options.signal
|
|
3919
|
+
);
|
|
3920
|
+
handle = r.handle;
|
|
3921
|
+
const result = await settle2(handle.box, r.events);
|
|
3922
|
+
turnCount += 1;
|
|
3923
|
+
emit({
|
|
3924
|
+
target: "agent.turn",
|
|
3925
|
+
phase: "after",
|
|
3926
|
+
timestamp: now(),
|
|
3927
|
+
stepIndex,
|
|
3928
|
+
payload: turnPayload(prompt, "start", turnStartedAt, result)
|
|
3929
|
+
});
|
|
3930
|
+
return result;
|
|
3931
|
+
} catch (error) {
|
|
3932
|
+
failed = true;
|
|
3933
|
+
emit({
|
|
3934
|
+
target: "agent.turn",
|
|
3935
|
+
phase: "error",
|
|
3936
|
+
timestamp: now(),
|
|
3937
|
+
stepIndex,
|
|
3938
|
+
payload: turnPayload(prompt, "start", turnStartedAt, void 0, error)
|
|
3939
|
+
});
|
|
3940
|
+
emit({
|
|
3941
|
+
target: "agent.run",
|
|
3942
|
+
phase: "error",
|
|
3943
|
+
timestamp: now(),
|
|
3944
|
+
payload: { ...runPayload(), turnCount, error: errorMessage(error) }
|
|
3945
|
+
});
|
|
3946
|
+
throw error;
|
|
3947
|
+
}
|
|
3948
|
+
},
|
|
3949
|
+
async resume(prompt) {
|
|
3950
|
+
if (!handle) throw new Error("openSandboxRun: resume() called before start()");
|
|
3951
|
+
const stepIndex = turnCount;
|
|
3952
|
+
const turnStartedAt = now();
|
|
3953
|
+
emit({
|
|
3954
|
+
target: "agent.turn",
|
|
3955
|
+
phase: "before",
|
|
3956
|
+
timestamp: turnStartedAt,
|
|
3957
|
+
stepIndex,
|
|
3958
|
+
payload: turnPayload(prompt, "resume", turnStartedAt)
|
|
3959
|
+
});
|
|
3960
|
+
try {
|
|
3961
|
+
const result = await settle2(
|
|
3962
|
+
handle.box,
|
|
3963
|
+
await lineage.continue(handle, prompt, options.signal)
|
|
3964
|
+
);
|
|
3965
|
+
turnCount += 1;
|
|
3966
|
+
emit({
|
|
3967
|
+
target: "agent.turn",
|
|
3968
|
+
phase: "after",
|
|
3969
|
+
timestamp: now(),
|
|
3970
|
+
stepIndex,
|
|
3971
|
+
payload: turnPayload(prompt, "resume", turnStartedAt, result)
|
|
3972
|
+
});
|
|
3973
|
+
return result;
|
|
3974
|
+
} catch (error) {
|
|
3975
|
+
failed = true;
|
|
3976
|
+
emit({
|
|
3977
|
+
target: "agent.turn",
|
|
3978
|
+
phase: "error",
|
|
3979
|
+
timestamp: now(),
|
|
3980
|
+
stepIndex,
|
|
3981
|
+
payload: turnPayload(prompt, "resume", turnStartedAt, void 0, error)
|
|
3982
|
+
});
|
|
3983
|
+
emit({
|
|
3984
|
+
target: "agent.run",
|
|
3985
|
+
phase: "error",
|
|
3986
|
+
timestamp: now(),
|
|
3987
|
+
payload: { ...runPayload(), turnCount, error: errorMessage(error) }
|
|
3988
|
+
});
|
|
3989
|
+
throw error;
|
|
3990
|
+
}
|
|
3991
|
+
},
|
|
3992
|
+
async close() {
|
|
3993
|
+
await lineage.teardown();
|
|
3994
|
+
if (runStartedAt !== void 0) {
|
|
3995
|
+
emit({
|
|
3996
|
+
target: "agent.run",
|
|
3997
|
+
phase: "after",
|
|
3998
|
+
timestamp: now(),
|
|
3999
|
+
payload: {
|
|
4000
|
+
...runPayload(),
|
|
4001
|
+
turnCount,
|
|
4002
|
+
status: failed ? "error" : "completed",
|
|
4003
|
+
durationMs: Math.max(0, now() - runStartedAt)
|
|
4004
|
+
}
|
|
4005
|
+
});
|
|
4006
|
+
}
|
|
4007
|
+
}
|
|
4008
|
+
};
|
|
4009
|
+
}
|
|
4010
|
+
function backendType(spec) {
|
|
4011
|
+
const backend = spec.sandboxOverrides?.backend;
|
|
4012
|
+
return backend?.type;
|
|
4013
|
+
}
|
|
4014
|
+
function eventTypeCounts(events) {
|
|
4015
|
+
const counts = {};
|
|
4016
|
+
for (const event of events) counts[event.type] = (counts[event.type] ?? 0) + 1;
|
|
4017
|
+
return counts;
|
|
4018
|
+
}
|
|
4019
|
+
function hashText(value) {
|
|
4020
|
+
let hash = 2166136261;
|
|
4021
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
4022
|
+
hash ^= value.charCodeAt(i);
|
|
4023
|
+
hash = Math.imul(hash, 16777619);
|
|
4024
|
+
}
|
|
4025
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
4026
|
+
}
|
|
4027
|
+
function errorMessage(error) {
|
|
4028
|
+
return error instanceof Error ? error.message : String(error);
|
|
4029
|
+
}
|
|
4030
|
+
|
|
3541
4031
|
export {
|
|
3542
4032
|
contentAddress,
|
|
3543
4033
|
InMemoryResultBlobStore,
|
|
@@ -3550,8 +4040,12 @@ export {
|
|
|
3550
4040
|
stopSentinel,
|
|
3551
4041
|
sentinelCompletion,
|
|
3552
4042
|
deterministicCompletion,
|
|
3553
|
-
|
|
4043
|
+
assertTraceDerivedFindings,
|
|
4044
|
+
createScopeAnalyst,
|
|
4045
|
+
buildSteerContext,
|
|
4046
|
+
createDriver,
|
|
3554
4047
|
renderAnalyses,
|
|
4048
|
+
inlineSandboxClient,
|
|
3555
4049
|
reportLoopUsage,
|
|
3556
4050
|
defineRuntimeHooks,
|
|
3557
4051
|
composeRuntimeHooks,
|
|
@@ -3565,9 +4059,6 @@ export {
|
|
|
3565
4059
|
createSandboxForSpec,
|
|
3566
4060
|
defaultSelectWinner,
|
|
3567
4061
|
loopDispatch,
|
|
3568
|
-
assertTraceDerivedFindings2 as assertTraceDerivedFindings,
|
|
3569
|
-
createScopeAnalyst,
|
|
3570
|
-
buildSteerContext,
|
|
3571
4062
|
createScope,
|
|
3572
4063
|
settledToIteration,
|
|
3573
4064
|
pipeline,
|
|
@@ -3580,9 +4071,7 @@ export {
|
|
|
3580
4071
|
InMemoryCorpus,
|
|
3581
4072
|
FileCorpus,
|
|
3582
4073
|
renderCorpusToInstructions,
|
|
3583
|
-
|
|
3584
|
-
sandboxExecutor,
|
|
3585
|
-
cliExecutor,
|
|
4074
|
+
createExecutor,
|
|
3586
4075
|
createExecutorRegistry,
|
|
3587
4076
|
spendFromUsageEvents,
|
|
3588
4077
|
createBudgetPool,
|
|
@@ -3594,6 +4083,7 @@ export {
|
|
|
3594
4083
|
definePersona,
|
|
3595
4084
|
runPersonified,
|
|
3596
4085
|
trajectoryReport,
|
|
3597
|
-
equalKOnCost
|
|
4086
|
+
equalKOnCost,
|
|
4087
|
+
openSandboxRun
|
|
3598
4088
|
};
|
|
3599
|
-
//# sourceMappingURL=chunk-
|
|
4089
|
+
//# sourceMappingURL=chunk-65FQLI4V.js.map
|