@tangle-network/agent-runtime 0.271.0 → 0.273.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{activation-DGbFPGR3.js → activation-Cx2dKA_l.js} +2 -2
- package/dist/{activation-DGbFPGR3.js.map → activation-Cx2dKA_l.js.map} +1 -1
- package/dist/{activation-BrJmwTLB.d.ts → activation-IfDlhR3J.d.ts} +2 -2
- package/dist/agent.d.ts +2 -2
- package/dist/agent.js +2 -2
- package/dist/candidate-execution/index.js +2 -2
- package/dist/{coordination-driver-iBGMKDvB.js → coordination-driver-CkcW4dxU.js} +155 -80
- package/dist/coordination-driver-CkcW4dxU.js.map +1 -0
- package/dist/{delegate-DOqUvaIz.js → delegate-Dvb1-mE-.js} +2 -2
- package/dist/{delegate-DOqUvaIz.js.map → delegate-Dvb1-mE-.js.map} +1 -1
- package/dist/durable.d.ts +3 -572
- package/dist/durable.js +92 -18
- package/dist/durable.js.map +1 -1
- package/dist/{graph-DnMcepkN.js → graph-C69Uxtzt.js} +14 -8
- package/dist/graph-C69Uxtzt.js.map +1 -0
- package/dist/{improvement-cycle-1IyRJo5h.js → improvement-cycle-CO2HRCQq.js} +4 -4
- package/dist/{improvement-cycle-1IyRJo5h.js.map → improvement-cycle-CO2HRCQq.js.map} +1 -1
- package/dist/{index-CL1dduJd.d.ts → index-D2ipSqkP.d.ts} +4318 -3102
- package/dist/index.d.ts +6 -450
- package/dist/index.js +14 -11
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +3 -3
- package/dist/intelligence.js +5 -5
- package/dist/kernel.d.ts +4 -4
- package/dist/kernel.js +9 -9
- package/dist/{loop-runner-bin-BPZ9tt1W.js → loop-runner-bin-B9MIq9O7.js} +3 -3
- package/dist/{loop-runner-bin-BPZ9tt1W.js.map → loop-runner-bin-B9MIq9O7.js.map} +1 -1
- package/dist/{loop-runner-bin-O_vM1w8Y.d.ts → loop-runner-bin-ThlwVkvo.d.ts} +3 -3
- package/dist/loop-runner-bin.d.ts +1 -1
- package/dist/loop-runner-bin.js +1 -1
- package/dist/mcp/bin.js +3 -3
- package/dist/mcp/index.d.ts +5 -5
- package/dist/mcp/index.js +4 -4
- package/dist/{openai-tools-DWHxpwx2.d.ts → openai-tools-Bb0mAr5z.d.ts} +2 -2
- package/dist/{prepare-oHUQdC5-.js → prepare-DVlvGP7V.js} +2 -2
- package/dist/{prepare-oHUQdC5-.js.map → prepare-DVlvGP7V.js.map} +1 -1
- package/dist/profiles.d.ts +2 -2
- package/dist/{protected-model-port-DqF0qDU6.js → protected-model-port-BrWgsCnl.js} +2 -2
- package/dist/{protected-model-port-DqF0qDU6.js.map → protected-model-port-BrWgsCnl.js.map} +1 -1
- package/dist/{protected-redaction--F3v1oo8.js → protected-redaction-DylCC_ot.js} +14 -20
- package/dist/protected-redaction-DylCC_ot.js.map +1 -0
- package/dist/{provision-supervisor-Cy8pqE95.js → provision-supervisor-BKAvsDtP.js} +3 -3
- package/dist/{provision-supervisor-Cy8pqE95.js.map → provision-supervisor-BKAvsDtP.js.map} +1 -1
- package/dist/{runtime-DVjIH1eo.js → runtime-CHxXrUeZ.js} +2079 -1441
- package/dist/runtime-CHxXrUeZ.js.map +1 -0
- package/dist/{server-CN9vzbSe.js → server-2OeFrEVG.js} +3 -3
- package/dist/{server-CN9vzbSe.js.map → server-2OeFrEVG.js.map} +1 -1
- package/dist/{stream-agent-turn-DbEsKgb_.d.ts → stream-agent-turn-ewm3BZAp.d.ts} +15 -16
- package/dist/{structural-rollout-I92sIfNl.js → structural-rollout-DCUprNpH.js} +2 -2
- package/dist/{structural-rollout-I92sIfNl.js.map → structural-rollout-DCUprNpH.js.map} +1 -1
- package/dist/{substrate-CbC03Vzo.d.ts → substrate-VKjmrksz.d.ts} +2 -2
- package/dist/{supervise-DJ_1i9vj.js → supervise-Dej5aSDa.js} +211 -48
- package/dist/supervise-Dej5aSDa.js.map +1 -0
- package/dist/{supervisor-Cvd5mf7x.js → supervisor-DdKPGluv.js} +952 -221
- package/dist/supervisor-DdKPGluv.js.map +1 -0
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +60 -60
- package/dist/tui/index.d.ts +1 -1
- package/dist/tui/index.js +1 -1
- package/dist/{types-Bo7z5aG5.d.ts → types-DMRc3jru.d.ts} +356 -64
- package/package.json +5 -5
- package/dist/coordination-driver-iBGMKDvB.js.map +0 -1
- package/dist/graph-DnMcepkN.js.map +0 -1
- package/dist/protected-redaction--F3v1oo8.js.map +0 -1
- package/dist/runtime-DVjIH1eo.js.map +0 -1
- package/dist/supervise-DJ_1i9vj.js.map +0 -1
- package/dist/supervisor-Cvd5mf7x.js.map +0 -1
|
@@ -15,6 +15,7 @@ import { applyWorkspacePlan, hashWorkspacePlan, materializeProfile, resolveAgent
|
|
|
15
15
|
import { homedir, hostname, tmpdir } from "node:os";
|
|
16
16
|
import { stripVTControlCharacters } from "node:util";
|
|
17
17
|
import { ATTR, deriveHexId, isW3CSpanId, isW3CTraceId } from "@tangle-network/agent-trace-contract";
|
|
18
|
+
import { REDACTION_VERSION as REDACTION_VERSION$1, redact } from "@tangle-network/agent-eval/traces";
|
|
18
19
|
import { SDKError, generateIdempotencyKey, withRetry } from "@tangle-network/agent-core";
|
|
19
20
|
import { collectAgentFinalMessageText, collectAgentResponseText } from "@tangle-network/sandbox";
|
|
20
21
|
import { request } from "node:http";
|
|
@@ -4797,7 +4798,7 @@ function sanitizeAgentRuntimeEvent(event, options = {}) {
|
|
|
4797
4798
|
if (event.type === "questions_end") return {
|
|
4798
4799
|
...base,
|
|
4799
4800
|
questions: event.questions.map((question) => sanitizeQuestion(question, options)),
|
|
4800
|
-
userAnswers: options.includeUserAnswers ? event.userAnswers : redactRecord(event.userAnswers)
|
|
4801
|
+
userAnswers: options.includeUserAnswers ? included(event.userAnswers) : redactRecord(event.userAnswers)
|
|
4801
4802
|
};
|
|
4802
4803
|
if (event.type === "acquisition_start") return {
|
|
4803
4804
|
...base,
|
|
@@ -4845,7 +4846,7 @@ function sanitizeRuntimeStreamEvent(event, options = {}) {
|
|
|
4845
4846
|
...withTask,
|
|
4846
4847
|
timestamp: event.timestamp,
|
|
4847
4848
|
questions: event.questions.map((question) => sanitizeQuestion(question, options)),
|
|
4848
|
-
userAnswers: options.includeUserAnswers ? event.userAnswers : redactRecord(event.userAnswers)
|
|
4849
|
+
userAnswers: options.includeUserAnswers ? included(event.userAnswers) : redactRecord(event.userAnswers)
|
|
4849
4850
|
};
|
|
4850
4851
|
if (event.type === "acquisition_start") return {
|
|
4851
4852
|
type: event.type,
|
|
@@ -4868,7 +4869,7 @@ function sanitizeRuntimeStreamEvent(event, options = {}) {
|
|
|
4868
4869
|
timestamp: event.timestamp,
|
|
4869
4870
|
toolName: event.toolName,
|
|
4870
4871
|
toolCallId: event.toolCallId,
|
|
4871
|
-
args: options.includeControlPayloads ? event.args : void 0
|
|
4872
|
+
args: options.includeControlPayloads ? included(event.args) : void 0
|
|
4872
4873
|
};
|
|
4873
4874
|
if (event.type === "tool_result") return {
|
|
4874
4875
|
type: event.type,
|
|
@@ -4877,7 +4878,7 @@ function sanitizeRuntimeStreamEvent(event, options = {}) {
|
|
|
4877
4878
|
timestamp: event.timestamp,
|
|
4878
4879
|
toolName: event.toolName,
|
|
4879
4880
|
toolCallId: event.toolCallId,
|
|
4880
|
-
result: options.includeControlPayloads ? event.result : void 0
|
|
4881
|
+
result: options.includeControlPayloads ? included(event.result) : void 0
|
|
4881
4882
|
};
|
|
4882
4883
|
if (event.type === "llm_call") return {
|
|
4883
4884
|
type: event.type,
|
|
@@ -4900,8 +4901,8 @@ function sanitizeRuntimeStreamEvent(event, options = {}) {
|
|
|
4900
4901
|
name: event.name,
|
|
4901
4902
|
mimeType: event.mimeType,
|
|
4902
4903
|
uri: options.includeEvidenceIds ? event.uri : void 0,
|
|
4903
|
-
content: options.includeControlPayloads ? event.content : void 0,
|
|
4904
|
-
metadata: options.includeMetadata ? event.metadata : void 0
|
|
4904
|
+
content: options.includeControlPayloads ? included(event.content) : void 0,
|
|
4905
|
+
metadata: options.includeMetadata ? included(event.metadata) : void 0
|
|
4905
4906
|
};
|
|
4906
4907
|
if (event.type === "proposal_created") return {
|
|
4907
4908
|
type: event.type,
|
|
@@ -4909,16 +4910,16 @@ function sanitizeRuntimeStreamEvent(event, options = {}) {
|
|
|
4909
4910
|
...withSession,
|
|
4910
4911
|
timestamp: event.timestamp,
|
|
4911
4912
|
proposalId: event.proposalId,
|
|
4912
|
-
title: options.includeControlPayloads ? event.title : void 0,
|
|
4913
|
-
content: options.includeControlPayloads ? event.content : void 0,
|
|
4913
|
+
title: options.includeControlPayloads ? included(event.title) : void 0,
|
|
4914
|
+
content: options.includeControlPayloads ? included(event.content) : void 0,
|
|
4914
4915
|
status: event.status
|
|
4915
4916
|
};
|
|
4916
4917
|
if (event.type === "final") {
|
|
4917
4918
|
const sanitizedError = event.error !== void 0 ? {
|
|
4918
4919
|
kind: event.error.kind,
|
|
4919
|
-
message: event.error.message,
|
|
4920
|
+
message: included(event.error.message),
|
|
4920
4921
|
status: event.error.status,
|
|
4921
|
-
body: options.includeControlPayloads ? event.error.body : void 0
|
|
4922
|
+
body: options.includeControlPayloads ? included(event.error.body) : void 0
|
|
4922
4923
|
} : void 0;
|
|
4923
4924
|
return {
|
|
4924
4925
|
type: event.type,
|
|
@@ -4927,8 +4928,8 @@ function sanitizeRuntimeStreamEvent(event, options = {}) {
|
|
|
4927
4928
|
timestamp: event.timestamp,
|
|
4928
4929
|
status: event.status,
|
|
4929
4930
|
reason: event.reason,
|
|
4930
|
-
text: options.includeControlPayloads ? event.text : void 0,
|
|
4931
|
-
metadata: options.includeMetadata ? event.metadata : void 0,
|
|
4931
|
+
text: options.includeControlPayloads ? included(event.text) : void 0,
|
|
4932
|
+
metadata: options.includeMetadata ? included(event.metadata) : void 0,
|
|
4932
4933
|
...sanitizedError !== void 0 ? { error: sanitizedError } : {}
|
|
4933
4934
|
};
|
|
4934
4935
|
}
|
|
@@ -4945,9 +4946,9 @@ function sanitizeTask(task, options) {
|
|
|
4945
4946
|
id: task.id,
|
|
4946
4947
|
intent: task.intent,
|
|
4947
4948
|
domain: task.domain,
|
|
4948
|
-
inputs: options.includeInputs ? task.inputs : task.inputs ? "[redacted]" : void 0,
|
|
4949
|
+
inputs: options.includeInputs ? included(task.inputs) : task.inputs ? "[redacted]" : void 0,
|
|
4949
4950
|
requiredKnowledge: task.requiredKnowledge?.map((requirement) => sanitizeKnowledgeRequirement(requirement, options)),
|
|
4950
|
-
metadata: options.includeMetadata ? task.metadata : task.metadata ? "[redacted]" : void 0
|
|
4951
|
+
metadata: options.includeMetadata ? included(task.metadata) : task.metadata ? "[redacted]" : void 0
|
|
4951
4952
|
};
|
|
4952
4953
|
}
|
|
4953
4954
|
function sanitizeRuntimeSession(session, options) {
|
|
@@ -4958,7 +4959,7 @@ function sanitizeRuntimeSession(session, options) {
|
|
|
4958
4959
|
hasResumeToken: Boolean(session.resumeToken),
|
|
4959
4960
|
createdAt: session.createdAt,
|
|
4960
4961
|
updatedAt: session.updatedAt,
|
|
4961
|
-
metadata: options.includeMetadata ? session.metadata : session.metadata ? "[redacted]" : void 0
|
|
4962
|
+
metadata: options.includeMetadata ? included(session.metadata) : session.metadata ? "[redacted]" : void 0
|
|
4962
4963
|
};
|
|
4963
4964
|
}
|
|
4964
4965
|
function sanitizeKnowledgeRequirement(requirement, options) {
|
|
@@ -5007,8 +5008,8 @@ function sanitizeControlStep(step, options) {
|
|
|
5007
5008
|
index: step.index,
|
|
5008
5009
|
decisionType: step.decision.type,
|
|
5009
5010
|
reason: step.decision.reason,
|
|
5010
|
-
action: options.includeControlPayloads && step.decision.type === "continue" ? step.decision.action : void 0,
|
|
5011
|
-
result: options.includeControlPayloads && actionOutcome?.ok ? actionOutcome.result : void 0,
|
|
5011
|
+
action: options.includeControlPayloads && step.decision.type === "continue" ? included(step.decision.action) : void 0,
|
|
5012
|
+
result: options.includeControlPayloads && actionOutcome?.ok ? included(actionOutcome.result) : void 0,
|
|
5012
5013
|
actionOk: actionOutcome?.ok,
|
|
5013
5014
|
actionError: actionOutcome?.ok === false ? actionOutcome.error : void 0,
|
|
5014
5015
|
durationMs: actionOutcome?.durationMs,
|
|
@@ -5041,10 +5042,17 @@ function summarizeEvals(evals, options) {
|
|
|
5041
5042
|
score: evalResult.score,
|
|
5042
5043
|
severity: evalResult.severity,
|
|
5043
5044
|
objective: evalResult.objective,
|
|
5044
|
-
detail: options.includeEvalDetails ? evalResult.detail : void 0,
|
|
5045
|
-
evidence: options.includeEvalDetails ? evalResult.evidence : void 0
|
|
5045
|
+
detail: options.includeEvalDetails ? included(evalResult.detail) : void 0,
|
|
5046
|
+
evidence: options.includeEvalDetails ? included(evalResult.evidence) : void 0
|
|
5046
5047
|
}));
|
|
5047
5048
|
}
|
|
5049
|
+
/**
|
|
5050
|
+
* An opted-in payload still goes through agent-eval's redaction core: the
|
|
5051
|
+
* flags decide whether content is shared, never whether credentials are.
|
|
5052
|
+
*/
|
|
5053
|
+
function included(value) {
|
|
5054
|
+
return value === void 0 ? value : redact(value).value;
|
|
5055
|
+
}
|
|
5048
5056
|
function redactRecord(record) {
|
|
5049
5057
|
return Object.fromEntries(Object.keys(record).map((key) => [key, "[redacted]"]));
|
|
5050
5058
|
}
|
|
@@ -5058,7 +5066,7 @@ function pickPublicStreamFields(event) {
|
|
|
5058
5066
|
} : void 0;
|
|
5059
5067
|
return {
|
|
5060
5068
|
backend: event.backend,
|
|
5061
|
-
message: event.message,
|
|
5069
|
+
message: included(event.message),
|
|
5062
5070
|
recoverable: event.recoverable,
|
|
5063
5071
|
...sanitizedError !== void 0 ? { error: sanitizedError } : {}
|
|
5064
5072
|
};
|
|
@@ -5491,9 +5499,10 @@ function buildRuntimeEventOtelSpans(events, traceId, parentSpanId, options = {})
|
|
|
5491
5499
|
"tangle.runtime.event": serialized(record)
|
|
5492
5500
|
};
|
|
5493
5501
|
let name = `tangle.runtime.${event.type}`;
|
|
5502
|
+
if (parentSpanId) attrs[ATTR.parentConfidence] = "explicit";
|
|
5494
5503
|
if (event.type === "tool_call" || event.type === "tool_result") {
|
|
5495
5504
|
name = `agent.${event.type}`;
|
|
5496
|
-
attrs[ATTR.spanKind] = "TOOL";
|
|
5505
|
+
if (event.type === "tool_call") attrs[ATTR.spanKind] = "TOOL";
|
|
5497
5506
|
attrs["tool.name"] = event.toolName;
|
|
5498
5507
|
if (event.toolCallId) attrs["tool.call_id"] = event.toolCallId;
|
|
5499
5508
|
const mcp = mcpIdentity(event.toolName);
|
|
@@ -5559,7 +5568,8 @@ function buildLoopOtelSpans(events, traceId, rootParentSpanId) {
|
|
|
5559
5568
|
endTimeUnixNano: msToNs(node.endMs),
|
|
5560
5569
|
attributes: toOtelAttributes({
|
|
5561
5570
|
...node.attrs,
|
|
5562
|
-
[ATTR.spanKind]: LOOP_SPAN_KIND[node.kind]
|
|
5571
|
+
[ATTR.spanKind]: LOOP_SPAN_KIND[node.kind],
|
|
5572
|
+
...node.parentSpanId === void 0 && rootParentSpanId ? { [ATTR.parentConfidence]: "explicit" } : {}
|
|
5563
5573
|
}),
|
|
5564
5574
|
status: { code: node.error ? 2 : 1 }
|
|
5565
5575
|
}));
|
|
@@ -5630,10 +5640,15 @@ function buildLoopSpanNodes(events) {
|
|
|
5630
5640
|
const iterStartTs = /* @__PURE__ */ new Map();
|
|
5631
5641
|
const placementByIdx = /* @__PURE__ */ new Map();
|
|
5632
5642
|
let currentRoundId;
|
|
5643
|
+
/** Plan round index → its span id, so an iteration joins the round it records (`groupId`). */
|
|
5644
|
+
const roundIdByIndex = /* @__PURE__ */ new Map();
|
|
5633
5645
|
let pendingRound;
|
|
5634
5646
|
const flushRound = (endMs) => {
|
|
5635
5647
|
if (!pendingRound) return;
|
|
5636
|
-
out.push(make(pendingRound.id, rootId, "loop.round", "round", pendingRound.start, endMs,
|
|
5648
|
+
out.push(make(pendingRound.id, rootId, "loop.round", "round", pendingRound.start, endMs, {
|
|
5649
|
+
...pendingRound.attrs,
|
|
5650
|
+
[ATTR.parentConfidence]: "explicit"
|
|
5651
|
+
}));
|
|
5637
5652
|
pendingRound = void 0;
|
|
5638
5653
|
};
|
|
5639
5654
|
for (const e of events) {
|
|
@@ -5661,6 +5676,7 @@ function buildLoopSpanNodes(events) {
|
|
|
5661
5676
|
attrs
|
|
5662
5677
|
};
|
|
5663
5678
|
currentRoundId = id;
|
|
5679
|
+
roundIdByIndex.set(roundIdx, id);
|
|
5664
5680
|
break;
|
|
5665
5681
|
}
|
|
5666
5682
|
case "loop.iteration.started": {
|
|
@@ -5707,6 +5723,8 @@ function buildLoopSpanNodes(events) {
|
|
|
5707
5723
|
if (err) attrs["tangle.loop.error"] = err;
|
|
5708
5724
|
const gid = num(p.groupId);
|
|
5709
5725
|
if (gid !== void 0) attrs["tangle.loop.iteration.group_id"] = gid;
|
|
5726
|
+
const recordedRoundId = gid === void 0 ? void 0 : roundIdByIndex.get(gid);
|
|
5727
|
+
attrs[ATTR.parentConfidence] = recordedRoundId ? "explicit" : "heuristic";
|
|
5710
5728
|
const par = num(p.parentIndex);
|
|
5711
5729
|
if (par !== void 0) attrs["tangle.loop.iteration.parent_index"] = par;
|
|
5712
5730
|
const dur = num(p.durationMs);
|
|
@@ -5714,7 +5732,7 @@ function buildLoopSpanNodes(events) {
|
|
|
5714
5732
|
const preview = str(p.outputPreview);
|
|
5715
5733
|
if (preview) attrs["tangle.loop.iteration.output_preview"] = preview;
|
|
5716
5734
|
Object.assign(attrs, placementByIdx.get(idx) ?? {});
|
|
5717
|
-
out.push(make(generateSpanId(), currentRoundId ?? rootId, "loop.iteration", "branch", start, e.timestamp, attrs, err !== void 0));
|
|
5735
|
+
out.push(make(generateSpanId(), recordedRoundId ?? currentRoundId ?? rootId, "loop.iteration", "branch", start, e.timestamp, attrs, err !== void 0));
|
|
5718
5736
|
break;
|
|
5719
5737
|
}
|
|
5720
5738
|
case "loop.decision":
|
|
@@ -6055,11 +6073,11 @@ const HARNESS_ROOTS = Object.freeze({
|
|
|
6055
6073
|
]),
|
|
6056
6074
|
codex: Object.freeze([".codex/sessions", ".codex/history.jsonl"]),
|
|
6057
6075
|
opencode: Object.freeze([
|
|
6058
|
-
".local/share/opencode/storage",
|
|
6059
|
-
".local/share/opencode/export",
|
|
6060
|
-
".local/share/opencode/log",
|
|
6061
6076
|
".opencode/sessions",
|
|
6062
|
-
".opencode/messages"
|
|
6077
|
+
".opencode/messages",
|
|
6078
|
+
".local/share/opencode/export",
|
|
6079
|
+
".local/share/opencode/storage",
|
|
6080
|
+
".local/share/opencode/log"
|
|
6063
6081
|
]),
|
|
6064
6082
|
pi: Object.freeze([".pi/agent/sessions"])
|
|
6065
6083
|
});
|
|
@@ -6097,6 +6115,126 @@ function harnessTranscriptUnavailable(reason) {
|
|
|
6097
6115
|
return unavailable$2(reason);
|
|
6098
6116
|
}
|
|
6099
6117
|
/**
|
|
6118
|
+
* Read one executor's harness-transcript receipt without letting a broken port escape.
|
|
6119
|
+
*
|
|
6120
|
+
* The three answers this has to keep apart, because #1214 and #1244 are both about an artifact
|
|
6121
|
+
* that reads as coverage without being coverage:
|
|
6122
|
+
* - `available` the transcript survived;
|
|
6123
|
+
* - a reason the CAPTURE produced a box existed and could not be read;
|
|
6124
|
+
* - `executor-exposes-no-transcript` this runtime has no transcript to offer at all;
|
|
6125
|
+
* - `execution-never-started` no environment was ever created (the executor's
|
|
6126
|
+
* own seed, set before `create`);
|
|
6127
|
+
* - `capture-did-not-run` the port answered nothing, so the capture was
|
|
6128
|
+
* skipped rather than attempted and failed.
|
|
6129
|
+
*
|
|
6130
|
+
* Mirrors the supervise scope's `readInteractiveSession`: an absence is always a named reason,
|
|
6131
|
+
* never `undefined`. The scope reads each child with it, and `supervise` reads the root with it.
|
|
6132
|
+
*/
|
|
6133
|
+
function readHarnessTranscript(executor) {
|
|
6134
|
+
if (!executor.harnessTranscript) return harnessTranscriptUnavailable("executor-exposes-no-transcript");
|
|
6135
|
+
let reported;
|
|
6136
|
+
try {
|
|
6137
|
+
reported = executor.harnessTranscript();
|
|
6138
|
+
} catch {
|
|
6139
|
+
return harnessTranscriptUnavailable("executor-exposes-no-transcript");
|
|
6140
|
+
}
|
|
6141
|
+
if (reported === void 0) return harnessTranscriptUnavailable("capture-did-not-run");
|
|
6142
|
+
const capture = reported;
|
|
6143
|
+
if (capture.status === "captured" && capture.artifact) return capture;
|
|
6144
|
+
if (capture.status === "unavailable" && capture.reason) return capture;
|
|
6145
|
+
return harnessTranscriptUnavailable("executor-exposes-no-transcript");
|
|
6146
|
+
}
|
|
6147
|
+
/**
|
|
6148
|
+
* Bounds on the subagent export, per capture. The capture runs after every turn and again at
|
|
6149
|
+
* release, so they bound how long a turn's end or a teardown can wait on it; each session they
|
|
6150
|
+
* leave out is named in `skipped`.
|
|
6151
|
+
*/
|
|
6152
|
+
const MAX_SUBAGENT_EXPORTS = 32;
|
|
6153
|
+
const SUBAGENT_EXPORT_SECONDS = 120;
|
|
6154
|
+
/** The script starts no export after SUBAGENT_EXPORT_SECONDS and bounds each one at 30 s, so it
|
|
6155
|
+
* ends inside this. It is passed to `exec`, because the Sandbox SDK's default is 30 s. */
|
|
6156
|
+
const SUBAGENT_EXPORT_EXEC_MS = 180 * 1e3;
|
|
6157
|
+
const SUBAGENT_EXPORT_DIR = "~/.local/share/opencode/export";
|
|
6158
|
+
/**
|
|
6159
|
+
* The export, run in the box. For each sidecar record it reads the runtime home and the parent
|
|
6160
|
+
* session, collects the subagent sessions its messages name, and writes `opencode export` of each
|
|
6161
|
+
* one under `export`, where the capture reads it. It prints one `<state> <sessionId>` line per
|
|
6162
|
+
* subagent: `exported`, `failed`, or `unexported` (over a bound), then `done`. Every capture exports again,
|
|
6163
|
+
* because a later turn can continue a subagent and the store changes with every turn; an export
|
|
6164
|
+
* takes about 2 s in a Tangle box. Each export goes to a temporary file first, so a failed or
|
|
6165
|
+
* interrupted export never leaves a partial file for the capture to read.
|
|
6166
|
+
*/
|
|
6167
|
+
const SUBAGENT_EXPORT_SCRIPT = String.raw`cd "$HOME" 2>/dev/null || exit 0
|
|
6168
|
+
out="$HOME/.local/share/opencode/export"
|
|
6169
|
+
t=""; command -v timeout >/dev/null 2>&1 && t="timeout 30"
|
|
6170
|
+
start=$(date +%s); n=0
|
|
6171
|
+
for rec in .opencode/sessions/*.json; do
|
|
6172
|
+
[ -f "$rec" ] || continue
|
|
6173
|
+
h=$(sed -n 's/.*"providerSessionHome"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$rec" | head -n 1)
|
|
6174
|
+
p=$(sed -n 's/.*"providerSessionId"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$rec" | head -n 1)
|
|
6175
|
+
db="$h/.local/share/opencode/opencode.db"
|
|
6176
|
+
case "$h" in /*) [ -f "$db" ] || continue ;; *) continue ;; esac
|
|
6177
|
+
ids=$(grep -rhoE '<task id=\\?"ses_[A-Za-z0-9]+|task_id: ses_[A-Za-z0-9]+|"sessionId"[[:space:]]*:[[:space:]]*"ses_[A-Za-z0-9]+' ".opencode/messages/$(basename "$rec" .json)" 2>/dev/null | grep -oE 'ses_[A-Za-z0-9]+' | sort -u)
|
|
6178
|
+
for id in $ids; do
|
|
6179
|
+
[ "$id" = "$p" ] && continue
|
|
6180
|
+
n=$((n + 1))
|
|
6181
|
+
if [ "$n" -gt ${MAX_SUBAGENT_EXPORTS} ] || [ $(($(date +%s) - start)) -ge ${SUBAGENT_EXPORT_SECONDS} ]; then echo "unexported $id"; continue; fi
|
|
6182
|
+
mkdir -p "$out" && tmp=$(mktemp) || { echo "failed $id"; continue; }
|
|
6183
|
+
if HOME="$h" XDG_DATA_HOME="$h/.local/share" XDG_CONFIG_HOME="$h/.config" XDG_STATE_HOME="$h/.local/state" XDG_CACHE_HOME="$h/.cache" OPENCODE_DISABLE_AUTOUPDATE=1 OPENCODE_DISABLE_MODELS_FETCH=1 $t opencode export "$id" > "$tmp" 2>/dev/null && [ -s "$tmp" ]; then
|
|
6184
|
+
mv "$tmp" "$out/$id.json" && echo "exported $id"
|
|
6185
|
+
else
|
|
6186
|
+
rm -f "$tmp"; echo "failed $id"
|
|
6187
|
+
fi
|
|
6188
|
+
done
|
|
6189
|
+
done
|
|
6190
|
+
echo done`;
|
|
6191
|
+
/**
|
|
6192
|
+
* Export each opencode subagent session a Tangle box's sidecar names, so the capture carries the
|
|
6193
|
+
* subagent's own steps (#1264).
|
|
6194
|
+
*
|
|
6195
|
+
* The sidecar runs opencode under a private runtime home and records the parent session under
|
|
6196
|
+
* `.opencode/sessions` and `.opencode/messages`. A `task` subagent runs in a child session, and
|
|
6197
|
+
* those records name it only in the tool's result (`<task id="ses_…">`, or `task_id: ses_…` on a
|
|
6198
|
+
* failure). Its steps are only in the runtime home's `opencode.db`, which a text capture cannot
|
|
6199
|
+
* carry. Each sidecar record names that home as `providerSessionHome`, so `opencode export` reads
|
|
6200
|
+
* the child from there. A shared-box worker exports its own subagents after each turn (#1371) and
|
|
6201
|
+
* keeps no sidecar record, so the export finds nothing to do for it.
|
|
6202
|
+
*
|
|
6203
|
+
* Returns the sessions it could not export, as `skipped` entries. An export that did not run, or
|
|
6204
|
+
* stopped before its `done` line, is named once, because the subagents it did not reach are
|
|
6205
|
+
* unknown.
|
|
6206
|
+
*/
|
|
6207
|
+
async function exportSubagentSessions(environment, signal) {
|
|
6208
|
+
if (!environment.exec || signal?.aborted) return [];
|
|
6209
|
+
let stdout;
|
|
6210
|
+
try {
|
|
6211
|
+
stdout = (await environment.exec(SUBAGENT_EXPORT_SCRIPT, {
|
|
6212
|
+
timeoutMs: SUBAGENT_EXPORT_EXEC_MS,
|
|
6213
|
+
...signal ? { signal } : {}
|
|
6214
|
+
})).stdout ?? "";
|
|
6215
|
+
} catch {
|
|
6216
|
+
return [{
|
|
6217
|
+
path: SUBAGENT_EXPORT_DIR,
|
|
6218
|
+
reason: "subagent-export-did-not-run"
|
|
6219
|
+
}];
|
|
6220
|
+
}
|
|
6221
|
+
const lines = stdout.split("\n").map((line) => line.trim());
|
|
6222
|
+
const gaps = [];
|
|
6223
|
+
for (const line of lines) {
|
|
6224
|
+
const match = /^(failed|unexported) (ses_[A-Za-z0-9]+)$/u.exec(line);
|
|
6225
|
+
if (match === null) continue;
|
|
6226
|
+
gaps.push({
|
|
6227
|
+
path: `${SUBAGENT_EXPORT_DIR}/${match[2]}.json`,
|
|
6228
|
+
reason: match[1] === "failed" ? "subagent-export-failed" : "subagent-export-over-bound"
|
|
6229
|
+
});
|
|
6230
|
+
}
|
|
6231
|
+
if (!lines.includes("done")) gaps.push({
|
|
6232
|
+
path: SUBAGENT_EXPORT_DIR,
|
|
6233
|
+
reason: "subagent-export-incomplete"
|
|
6234
|
+
});
|
|
6235
|
+
return gaps;
|
|
6236
|
+
}
|
|
6237
|
+
/**
|
|
6100
6238
|
* Enumerate candidate transcript paths inside the environment.
|
|
6101
6239
|
*
|
|
6102
6240
|
* `find -printf` is given the roots and prints one `size<TAB>path` line per file. A missing root
|
|
@@ -6157,12 +6295,13 @@ async function captureHarnessTranscript(environment, harness, signal) {
|
|
|
6157
6295
|
if (harness === void 0) return unavailable$2("unknown-harness");
|
|
6158
6296
|
const roots = HARNESS_ROOTS[harness];
|
|
6159
6297
|
if (!roots) return unavailable$2("unknown-harness");
|
|
6298
|
+
const unexported = harness === "opencode" ? await exportSubagentSessions(environment, signal) : [];
|
|
6160
6299
|
const enumerated = await enumerate(environment, roots, signal);
|
|
6161
6300
|
if (enumerated === void 0) return unavailable$2("enumeration-failed");
|
|
6162
6301
|
const { paths } = enumerated;
|
|
6163
|
-
if (paths.length === 0 && enumerated.omitted.length === 0) return unavailable$2("no-transcript");
|
|
6302
|
+
if (paths.length === 0 && enumerated.omitted.length === 0 && unexported.length === 0) return unavailable$2("no-transcript");
|
|
6164
6303
|
const files = [];
|
|
6165
|
-
const skipped = [...enumerated.omitted];
|
|
6304
|
+
const skipped = [...unexported, ...enumerated.omitted];
|
|
6166
6305
|
let total = 0;
|
|
6167
6306
|
for (const path of paths) {
|
|
6168
6307
|
if (signal?.aborted) {
|
|
@@ -6236,6 +6375,73 @@ async function captureHarnessTranscript(environment, harness, signal) {
|
|
|
6236
6375
|
});
|
|
6237
6376
|
}
|
|
6238
6377
|
/**
|
|
6378
|
+
* A transcript this process holds in memory, one JSON line per record, as a capture under the same
|
|
6379
|
+
* bounds a box's session files get: each file at most MAX_FILE_BYTES, all files together at most
|
|
6380
|
+
* MAX_TOTAL_BYTES. Lines fill `<name>-000.jsonl`, `<name>-001.jsonl`, ... in order, and a line is
|
|
6381
|
+
* never split. A line longer than one file, and every line past the total, is named in `skipped`
|
|
6382
|
+
* with its line number, so a cut transcript never reads as the whole one.
|
|
6383
|
+
*/
|
|
6384
|
+
function harnessTranscriptFromLines(harness, name, lines) {
|
|
6385
|
+
if (lines.length === 0) return unavailable$2("no-transcript");
|
|
6386
|
+
const files = [];
|
|
6387
|
+
const skipped = [];
|
|
6388
|
+
let total = 0;
|
|
6389
|
+
let chunk = [];
|
|
6390
|
+
let chunkBytes = 0;
|
|
6391
|
+
const flush = () => {
|
|
6392
|
+
if (chunk.length === 0) return;
|
|
6393
|
+
const content = `${chunk.join("\n")}\n`;
|
|
6394
|
+
files.push(Object.freeze({
|
|
6395
|
+
path: `${name}-${String(files.length).padStart(3, "0")}.jsonl`,
|
|
6396
|
+
bytes: Buffer.byteLength(content, "utf8"),
|
|
6397
|
+
content
|
|
6398
|
+
}));
|
|
6399
|
+
chunk = [];
|
|
6400
|
+
chunkBytes = 0;
|
|
6401
|
+
};
|
|
6402
|
+
lines.forEach((line, index) => {
|
|
6403
|
+
const bytes = Buffer.byteLength(line, "utf8") + 1;
|
|
6404
|
+
const where = `${name} line ${index + 1}`;
|
|
6405
|
+
if (bytes > MAX_FILE_BYTES) {
|
|
6406
|
+
skipped.push({
|
|
6407
|
+
path: where,
|
|
6408
|
+
reason: "file-exceeds-byte-bound"
|
|
6409
|
+
});
|
|
6410
|
+
return;
|
|
6411
|
+
}
|
|
6412
|
+
if (total + bytes > MAX_TOTAL_BYTES) {
|
|
6413
|
+
skipped.push({
|
|
6414
|
+
path: where,
|
|
6415
|
+
reason: "total-byte-budget-exhausted"
|
|
6416
|
+
});
|
|
6417
|
+
return;
|
|
6418
|
+
}
|
|
6419
|
+
if (chunkBytes + bytes > MAX_FILE_BYTES) flush();
|
|
6420
|
+
chunk.push(line);
|
|
6421
|
+
chunkBytes += bytes;
|
|
6422
|
+
total += bytes;
|
|
6423
|
+
});
|
|
6424
|
+
flush();
|
|
6425
|
+
if (files.length === 0) return Object.freeze({
|
|
6426
|
+
status: "unavailable",
|
|
6427
|
+
reason: "nothing-carried",
|
|
6428
|
+
skipped: Object.freeze(skipped)
|
|
6429
|
+
});
|
|
6430
|
+
const artifact = Object.freeze({
|
|
6431
|
+
schemaVersion: 1,
|
|
6432
|
+
harness,
|
|
6433
|
+
files: Object.freeze(files),
|
|
6434
|
+
skipped: Object.freeze(skipped)
|
|
6435
|
+
});
|
|
6436
|
+
return Object.freeze({
|
|
6437
|
+
status: "captured",
|
|
6438
|
+
artifact,
|
|
6439
|
+
fileCount: files.length,
|
|
6440
|
+
totalBytes: total,
|
|
6441
|
+
skippedCount: skipped.length
|
|
6442
|
+
});
|
|
6443
|
+
}
|
|
6444
|
+
/**
|
|
6239
6445
|
* Persist a capture under its own content ref and return the receipt a settlement carries.
|
|
6240
6446
|
*
|
|
6241
6447
|
* The scope calls this, not the executor: storage stays out of every provider and destroy site,
|
|
@@ -6391,81 +6597,40 @@ function publicCreateOptions(create) {
|
|
|
6391
6597
|
}
|
|
6392
6598
|
//#endregion
|
|
6393
6599
|
//#region src/redact.ts
|
|
6394
|
-
const redactedMarker = "[redacted]";
|
|
6395
|
-
/** Secret-bearing key names: when an object key matches, its value is fully
|
|
6396
|
-
* replaced regardless of the value's own content. Lowercased compare. */
|
|
6397
|
-
const secretKeyPattern = /(api[-_]?key|secret|token|password|passwd|authorization|auth|private[-_]?key|credential|access[-_]?key|client[-_]?secret|session[-_]?(id|token)|cookie|bearer)/i;
|
|
6398
|
-
/** AgentProfile's numeric model limits describe compute, not credentials. */
|
|
6399
|
-
const tokenLimitKeyPattern = /^max(?:VisibleOutput|Reasoning|TotalOutput)Tokens$/;
|
|
6400
|
-
/** In-value secret/PII patterns scrubbed from any string, regardless of key. */
|
|
6401
|
-
const valuePatterns = [
|
|
6402
|
-
/\bBearer\s+[A-Za-z0-9._\-+/=]{8,}/gi,
|
|
6403
|
-
/\b(?:sk|pk|rk|ak)[-_][A-Za-z0-9_-]{12,}/g,
|
|
6404
|
-
/\bgh[pousr]_[A-Za-z0-9]{20,}/g,
|
|
6405
|
-
/\bAKIA[0-9A-Z]{16}\b/g,
|
|
6406
|
-
/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,
|
|
6407
|
-
/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g
|
|
6408
|
-
];
|
|
6409
|
-
/** Secret assignments embedded inside an otherwise opaque string, including
|
|
6410
|
-
* serialized JSON and log-style `key=value` text. */
|
|
6411
|
-
const secretAssignmentPattern = /((?:"|')?(?:api[-_]?key|secret|token|password|passwd|authorization|auth|private[-_]?key|credential|access[-_]?key|client[-_]?secret|session[-_]?(?:id|token)|cookie|bearer)(?:"|')?\s*[:=]\s*)(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|[^\s,;}]+)/gi;
|
|
6412
|
-
/** Scrub a single string of in-value secret/PII patterns. */
|
|
6413
|
-
function scrubString(input) {
|
|
6414
|
-
let out = input;
|
|
6415
|
-
for (const pattern of valuePatterns) out = out.replace(pattern, redactedMarker);
|
|
6416
|
-
return out.replace(secretAssignmentPattern, `$1${redactedMarker}`);
|
|
6417
|
-
}
|
|
6418
6600
|
/**
|
|
6419
|
-
*
|
|
6420
|
-
*
|
|
6421
|
-
*
|
|
6422
|
-
*
|
|
6601
|
+
* Redaction for values that may leave the Runtime process. The built-in
|
|
6602
|
+
* redactor is agent-eval's redaction core (`@tangle-network/agent-eval/traces`,
|
|
6603
|
+
* default profile): credentials found by field name or value shape are
|
|
6604
|
+
* replaced whole, email, card, SSN and phone values in place, and token counts
|
|
6605
|
+
* such as `inputTokens` or `max_tokens` are kept. A customer with
|
|
6606
|
+
* domain-specific PII supplies their own `redact` hook.
|
|
6607
|
+
*
|
|
6608
|
+
* This is narrower than `src/sanitize.ts`, which drops fields of the runtime's
|
|
6609
|
+
* *event envelope* unless the caller opts in: here the value is opaque customer
|
|
6610
|
+
* payload, so the scrub is value-shaped, not schema-shaped.
|
|
6611
|
+
*
|
|
6612
|
+
* @experimental
|
|
6613
|
+
*/
|
|
6614
|
+
/**
|
|
6615
|
+
* The built-in redactor. Cycle-safe, depth-bounded and total: it never throws
|
|
6616
|
+
* on customer input and never mutates it.
|
|
6423
6617
|
*/
|
|
6424
6618
|
function defaultRedactor(value) {
|
|
6425
|
-
return
|
|
6426
|
-
}
|
|
6427
|
-
const maxDepth = 32;
|
|
6428
|
-
function walk(value, seen, depth) {
|
|
6429
|
-
if (depth > maxDepth) return "[truncated]";
|
|
6430
|
-
if (typeof value === "string") return scrubString(value);
|
|
6431
|
-
if (value === null || typeof value !== "object") return value;
|
|
6432
|
-
if (seen.has(value)) return "[circular]";
|
|
6433
|
-
seen.add(value);
|
|
6434
|
-
if (Array.isArray(value)) return value.map((item) => walk(item, seen, depth + 1));
|
|
6435
|
-
const out = {};
|
|
6436
|
-
for (const [key, v] of Object.entries(value)) {
|
|
6437
|
-
const tokenLimit = tokenLimitKeyPattern.test(key) && typeof v === "number" && Number.isSafeInteger(v) && v >= 0;
|
|
6438
|
-
if (secretKeyPattern.test(key) && !tokenLimit) {
|
|
6439
|
-
out[key] = redactedMarker;
|
|
6440
|
-
continue;
|
|
6441
|
-
}
|
|
6442
|
-
out[key] = walk(v, seen, depth + 1);
|
|
6443
|
-
}
|
|
6444
|
-
return out;
|
|
6619
|
+
return redact(value).value;
|
|
6445
6620
|
}
|
|
6446
6621
|
/** Stable identity input for saved work that depends on built-in redaction behavior. */
|
|
6447
6622
|
function defaultRedactorIdentityMaterial() {
|
|
6448
|
-
const patternIdentity = (pattern) => ({
|
|
6449
|
-
source: pattern.source,
|
|
6450
|
-
flags: pattern.flags
|
|
6451
|
-
});
|
|
6452
6623
|
return {
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
valuePatterns: valuePatterns.map(patternIdentity),
|
|
6457
|
-
secretAssignmentPattern: patternIdentity(secretAssignmentPattern),
|
|
6458
|
-
maxDepth,
|
|
6459
|
-
scrubString: Function.prototype.toString.call(scrubString),
|
|
6460
|
-
walk: Function.prototype.toString.call(walk),
|
|
6461
|
-
defaultRedactor: Function.prototype.toString.call(defaultRedactor)
|
|
6624
|
+
core: "@tangle-network/agent-eval/traces redact",
|
|
6625
|
+
profile: "default",
|
|
6626
|
+
version: REDACTION_VERSION$1
|
|
6462
6627
|
};
|
|
6463
6628
|
}
|
|
6464
6629
|
/**
|
|
6465
6630
|
* Resolve the redactor a client uses. A caller-supplied hook handles
|
|
6466
6631
|
* domain-specific values first, then the built-in scrubber still removes
|
|
6467
|
-
*
|
|
6468
|
-
*
|
|
6632
|
+
* credentials and personal data. Returning `false` is the explicit opt-out for
|
|
6633
|
+
* already-reviewed public values.
|
|
6469
6634
|
*/
|
|
6470
6635
|
function resolveRedactor(redact) {
|
|
6471
6636
|
if (redact === false) return (value) => value;
|
|
@@ -9097,7 +9262,7 @@ async function providerExecutionSource(args, turn, signal) {
|
|
|
9097
9262
|
const dispatched = [...admissions].reverse().find((admission) => admission.phase === "dispatched");
|
|
9098
9263
|
const intent = admissions.find((admission) => admission.phase === "intent");
|
|
9099
9264
|
const environmentAdmission = admissions.find((admission) => admission.phase === "environment");
|
|
9100
|
-
if (args.recovering) {
|
|
9265
|
+
if (args.recovering && admissions.length > 0) {
|
|
9101
9266
|
if (!intent) throw new Error("retained provider execution has no original intent");
|
|
9102
9267
|
assertRetainedRunReplayMaterial(args.provider, material, intent);
|
|
9103
9268
|
}
|
|
@@ -9145,7 +9310,7 @@ async function providerExecutionSource(args, turn, signal) {
|
|
|
9145
9310
|
if (recovered.outcome !== "recovered") throw new Error(`retained provider execution is ${recovered.outcome}`);
|
|
9146
9311
|
handle = recovered.handle;
|
|
9147
9312
|
} else {
|
|
9148
|
-
if (args.recovering) throw new Error("retained provider execution has no durable admission");
|
|
9313
|
+
if (args.recovering && admissions.length > 0) throw new Error("retained provider execution has no durable admission");
|
|
9149
9314
|
handle = await startRetainedRun({
|
|
9150
9315
|
provider: args.provider,
|
|
9151
9316
|
...material,
|
|
@@ -16786,6 +16951,15 @@ function assertContentAddress(outRef, artifact) {
|
|
|
16786
16951
|
if (outRef !== expected) throw new Error(`blob outRef '${outRef}' does not match the artifact content hash '${expected}'; a content-addressed store refuses a mismatched ref (breaks the replay invariant)`);
|
|
16787
16952
|
}
|
|
16788
16953
|
/**
|
|
16954
|
+
* Append every event as one grouped publication where the journal supports it (`appendEvents`),
|
|
16955
|
+
* preserving legacy per-event appends otherwise — the SQL contexts' fenced head advances once.
|
|
16956
|
+
* @internal
|
|
16957
|
+
*/
|
|
16958
|
+
async function appendSpawnEvents(journal, root, events) {
|
|
16959
|
+
if (journal.appendEvents !== void 0) return journal.appendEvents(root, events);
|
|
16960
|
+
for (const event of events) await journal.appendEvent(root, event);
|
|
16961
|
+
}
|
|
16962
|
+
/**
|
|
16789
16963
|
* In-memory `SpawnJournal`. Appends are observed-committed only; the impl enforces
|
|
16790
16964
|
* the corruption guards a durable replay rests on:
|
|
16791
16965
|
* - an event before `beginTree` is a corrupted tree (fail loud),
|
|
@@ -17886,6 +18060,96 @@ function executionTaskPrompt$1(task, configuredPrompt) {
|
|
|
17886
18060
|
return prompt;
|
|
17887
18061
|
}
|
|
17888
18062
|
//#endregion
|
|
18063
|
+
//#region src/runtime/supervise/router-transcript.ts
|
|
18064
|
+
/**
|
|
18065
|
+
* The conversation of a router-brained agent, kept as it happens.
|
|
18066
|
+
*
|
|
18067
|
+
* A router-brained agent (`harness` omitted or `cli-base`) runs its tool loop in this process, so
|
|
18068
|
+
* its whole conversation is in the loop's `messages` and nowhere else. Before this, Runtime
|
|
18069
|
+
* metered each turn's usage and tool-call names and kept nothing the agent said, saw, or asked a
|
|
18070
|
+
* tool to do: a 316-agent tree on 2026-09-24 settled with 0 of 316 transcripts, and the 37 agents
|
|
18071
|
+
* still running when its driver process stopped left no record at all (agent-runtime#1377).
|
|
18072
|
+
*
|
|
18073
|
+
* The recorder keeps each message once, in the order the model saw it, and serves two readers:
|
|
18074
|
+
* - each turn's `agent.turn` event carries the messages that turn added (the loop's inputs since
|
|
18075
|
+
* the previous turn, then the reply), so an observer journal holds every agent's conversation
|
|
18076
|
+
* while the run is live;
|
|
18077
|
+
* - `capture()` returns the whole conversation as a harness transcript, so the agent settles
|
|
18078
|
+
* with an `available` receipt instead of `executor-exposes-no-transcript`.
|
|
18079
|
+
*
|
|
18080
|
+
* The loop mutates `messages` in place: it appends the reply it was given, each tool result, and
|
|
18081
|
+
* any inbox message, and a compaction replaces the middle with a distilled note. The recorder
|
|
18082
|
+
* therefore reads new messages twice per turn, before compaction can remove them and again when
|
|
18083
|
+
* the model is called, and it identifies a message by object identity. The loop's own copy of a
|
|
18084
|
+
* reply is skipped, because the recorder already kept the reply when the model returned it.
|
|
18085
|
+
*/
|
|
18086
|
+
/** The harness name a router-brained agent's transcript carries. */
|
|
18087
|
+
const ROUTER_TRANSCRIPT_HARNESS = "router";
|
|
18088
|
+
/**
|
|
18089
|
+
* The most bytes of one message's `content` a turn event carries. A longer content is cut, and
|
|
18090
|
+
* the message says so with its full length, so a reader never takes a cut message for the whole.
|
|
18091
|
+
* The settled transcript keeps the full content, within the bounds of `harnessTranscriptFromLines`.
|
|
18092
|
+
*/
|
|
18093
|
+
const TURN_CONTENT_BYTES = 256 * 1024;
|
|
18094
|
+
function createRouterTranscript() {
|
|
18095
|
+
const kept = [];
|
|
18096
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
18097
|
+
let turnStart = 0;
|
|
18098
|
+
let replyEchoPending = false;
|
|
18099
|
+
let live;
|
|
18100
|
+
const observe = (messages) => {
|
|
18101
|
+
live = messages;
|
|
18102
|
+
for (const message of messages) {
|
|
18103
|
+
if (message === null || typeof message !== "object" || seen.has(message)) continue;
|
|
18104
|
+
seen.add(message);
|
|
18105
|
+
if (replyEchoPending) {
|
|
18106
|
+
replyEchoPending = false;
|
|
18107
|
+
if (message.role === "assistant") continue;
|
|
18108
|
+
}
|
|
18109
|
+
kept.push(message);
|
|
18110
|
+
}
|
|
18111
|
+
};
|
|
18112
|
+
return {
|
|
18113
|
+
observe,
|
|
18114
|
+
reply(reply) {
|
|
18115
|
+
const message = {
|
|
18116
|
+
role: "assistant",
|
|
18117
|
+
content: reply.content ?? "",
|
|
18118
|
+
...reply.toolCalls && reply.toolCalls.length > 0 ? { tool_calls: reply.toolCalls.map((call) => ({
|
|
18119
|
+
id: call.id,
|
|
18120
|
+
type: "function",
|
|
18121
|
+
function: {
|
|
18122
|
+
name: call.name,
|
|
18123
|
+
arguments: call.arguments
|
|
18124
|
+
}
|
|
18125
|
+
})) } : {}
|
|
18126
|
+
};
|
|
18127
|
+
kept.push(message);
|
|
18128
|
+
replyEchoPending = true;
|
|
18129
|
+
const added = kept.slice(turnStart).map(forTurnEvent);
|
|
18130
|
+
turnStart = kept.length;
|
|
18131
|
+
return added;
|
|
18132
|
+
},
|
|
18133
|
+
capture() {
|
|
18134
|
+
if (live !== void 0) observe(live);
|
|
18135
|
+
if (kept.length === 0) return harnessTranscriptUnavailable("execution-never-started");
|
|
18136
|
+
return harnessTranscriptFromLines(ROUTER_TRANSCRIPT_HARNESS, "conversation", kept.map((message) => JSON.stringify(message)));
|
|
18137
|
+
}
|
|
18138
|
+
};
|
|
18139
|
+
}
|
|
18140
|
+
function forTurnEvent(message) {
|
|
18141
|
+
const content = message.content;
|
|
18142
|
+
if (typeof content !== "string") return message;
|
|
18143
|
+
const bytes = Buffer.byteLength(content);
|
|
18144
|
+
if (bytes <= 262144) return message;
|
|
18145
|
+
return {
|
|
18146
|
+
...message,
|
|
18147
|
+
content: Buffer.from(content).subarray(0, TURN_CONTENT_BYTES).toString("utf8"),
|
|
18148
|
+
contentBytes: bytes,
|
|
18149
|
+
contentCut: true
|
|
18150
|
+
};
|
|
18151
|
+
}
|
|
18152
|
+
//#endregion
|
|
17889
18153
|
//#region src/runtime/supervise/sandbox-session.ts
|
|
17890
18154
|
/** Ceiling on continuation turns. Turn 0 is the task; every later turn is a folded steer, so
|
|
17891
18155
|
* this bounds how many times a supervisor may redirect ONE worker before it must respawn. */
|
|
@@ -18497,6 +18761,7 @@ const routerInlineExecutor = (spec, ctx) => {
|
|
|
18497
18761
|
const requestIdentity = routerRequestIdentity(ctx);
|
|
18498
18762
|
const controller = linkAbort(ctx.signal);
|
|
18499
18763
|
let artifact;
|
|
18764
|
+
const transcript = createRouterTranscript();
|
|
18500
18765
|
const executionId = ctx.node?.nodeId ?? `router-request-${randomUUID()}`;
|
|
18501
18766
|
const attemptId = ctx.node?.attemptId ?? newExecutionAttemptId(executionId);
|
|
18502
18767
|
let executor;
|
|
@@ -18504,6 +18769,7 @@ const routerInlineExecutor = (spec, ctx) => {
|
|
|
18504
18769
|
runtime: "router",
|
|
18505
18770
|
async execute(task, signal) {
|
|
18506
18771
|
const messages = taskToMessages(task, spec, profileExecution.systemPrompt);
|
|
18772
|
+
transcript.observe(messages);
|
|
18507
18773
|
const started = Date.now();
|
|
18508
18774
|
const linked = linkAbort(signal, controller.signal).signal;
|
|
18509
18775
|
const extraBody = {
|
|
@@ -18541,6 +18807,10 @@ const routerInlineExecutor = (spec, ctx) => {
|
|
|
18541
18807
|
...requestIdentity
|
|
18542
18808
|
}));
|
|
18543
18809
|
if (r.model !== void 0) recordRuntimeOwnedProviderModel(executor, r.model);
|
|
18810
|
+
transcript.reply({
|
|
18811
|
+
content: r.content,
|
|
18812
|
+
toolCalls: "toolCalls" in r ? r.toolCalls : []
|
|
18813
|
+
});
|
|
18544
18814
|
const spent = {
|
|
18545
18815
|
...addResourceSpend(r.resources),
|
|
18546
18816
|
iterations: 1,
|
|
@@ -18576,6 +18846,7 @@ const routerInlineExecutor = (spec, ctx) => {
|
|
|
18576
18846
|
};
|
|
18577
18847
|
return artifact;
|
|
18578
18848
|
},
|
|
18849
|
+
harnessTranscript: () => transcript.capture(),
|
|
18579
18850
|
cancel(_request) {
|
|
18580
18851
|
controller.abort("executor cancelled");
|
|
18581
18852
|
return Promise.resolve(localAbortCancellation("the Router chat-completions API exposes no cancel operation; the local request was aborted and the provider may still bill the completion"));
|
|
@@ -18676,12 +18947,14 @@ const routerToolsInlineExecutor = (spec, ctx) => {
|
|
|
18676
18947
|
const controller = linkAbort(ctx.signal);
|
|
18677
18948
|
const inbox = createInbox();
|
|
18678
18949
|
let artifact;
|
|
18950
|
+
const transcript = createRouterTranscript();
|
|
18679
18951
|
const executionId = ctx.node?.nodeId ?? `router-tools-run-${randomUUID()}`;
|
|
18680
18952
|
const attemptId = ctx.node?.attemptId ?? newExecutionAttemptId(executionId);
|
|
18681
18953
|
let executor;
|
|
18682
18954
|
executor = attestRuntimeOwnedExecutor({
|
|
18683
18955
|
runtime: "router",
|
|
18684
18956
|
deliver: (m) => inbox.deliver(m),
|
|
18957
|
+
harnessTranscript: () => transcript.capture(),
|
|
18685
18958
|
async execute(task, signal) {
|
|
18686
18959
|
const started = Date.now();
|
|
18687
18960
|
const messages = seam.initialMessages ? taskToMessages({ messages: [...seam.initialMessages, {
|
|
@@ -18720,6 +18993,7 @@ const routerToolsInlineExecutor = (spec, ctx) => {
|
|
|
18720
18993
|
interruptSig.addEventListener("abort", abortTurn, { once: true });
|
|
18721
18994
|
const cleanup = () => external.removeEventListener("abort", abortTurn);
|
|
18722
18995
|
let res;
|
|
18996
|
+
transcript.observe(messages);
|
|
18723
18997
|
try {
|
|
18724
18998
|
recordRuntimeOwnedProviderAttemptStart(executor);
|
|
18725
18999
|
res = await (profileExecution.stream === true ? streamRouterChatWithTools : routerChatWithTools)({
|
|
@@ -18756,6 +19030,10 @@ const routerToolsInlineExecutor = (spec, ctx) => {
|
|
|
18756
19030
|
}
|
|
18757
19031
|
cleanup();
|
|
18758
19032
|
turns += 1;
|
|
19033
|
+
transcript.reply({
|
|
19034
|
+
content: res.content,
|
|
19035
|
+
toolCalls: res.toolCalls
|
|
19036
|
+
});
|
|
18759
19037
|
const priorResources = resources;
|
|
18760
19038
|
resources = addResourceSpend(resources, res.resources).resources;
|
|
18761
19039
|
resources = addResourceSpend(Object.fromEntries(Object.entries(resources ?? {}).map(([name, value]) => [name, {
|
|
@@ -21315,7 +21593,7 @@ async function prepareInterruptedExecutors(opts, events, signal, now, parentId =
|
|
|
21315
21593
|
continue;
|
|
21316
21594
|
}
|
|
21317
21595
|
const admissions = current.flatMap((event) => event.kind === "execution-admitted" ? [event.admission] : []);
|
|
21318
|
-
if (!opts.recoverExecutor || admissions.length === 0 && !node.ownedTreeRoot) continue;
|
|
21596
|
+
if (!opts.recoverExecutor || admissions.length === 0 && !node.ownedTreeRoot && (opts.journal.appendEvents === void 0 || latestInput === void 0)) continue;
|
|
21319
21597
|
const taskRef = inputs[0]?.taskRef;
|
|
21320
21598
|
if (!node.profileRef || !taskRef || !node.identity?.profileDigest || !node.identity.taskDigest) throw new RuntimeRunStateError(`cannot recover '${node.id}' without exact profile and task bytes`);
|
|
21321
21599
|
const profile = agentProfileSchema.parse(await opts.blobs.get(node.profileRef));
|
|
@@ -23415,29 +23693,31 @@ function createScope(args) {
|
|
|
23415
23693
|
});
|
|
23416
23694
|
const profileRef = contentAddress(spec.profile);
|
|
23417
23695
|
const taskRef = identity?.taskDigest === void 0 ? void 0 : contentAddress(task);
|
|
23418
|
-
const spawnCommitted = recovery ? Promise.resolve() : args.blobs.put(profileRef, spec.profile).then(() => taskRef === void 0 ? void 0 : args.blobs.put(taskRef, task)).then(() =>
|
|
23419
|
-
|
|
23420
|
-
|
|
23421
|
-
|
|
23422
|
-
|
|
23423
|
-
|
|
23424
|
-
|
|
23425
|
-
|
|
23426
|
-
|
|
23427
|
-
|
|
23428
|
-
|
|
23429
|
-
|
|
23430
|
-
|
|
23431
|
-
|
|
23432
|
-
|
|
23433
|
-
|
|
23434
|
-
|
|
23696
|
+
const spawnCommitted = recovery ? Promise.resolve() : args.blobs.put(profileRef, spec.profile).then(() => taskRef === void 0 ? void 0 : args.blobs.put(taskRef, task)).then(async () => {
|
|
23697
|
+
const events = [{
|
|
23698
|
+
kind: "spawned",
|
|
23699
|
+
id,
|
|
23700
|
+
parent: args.parentId,
|
|
23701
|
+
label: opts.label,
|
|
23702
|
+
...opts.key !== void 0 ? { key: opts.key } : {},
|
|
23703
|
+
...opts.assignmentId === void 0 ? {} : { assignmentId: opts.assignmentId },
|
|
23704
|
+
...opts.successorOf === void 0 ? {} : { successorOf: opts.successorOf },
|
|
23705
|
+
budget: opts.budget,
|
|
23706
|
+
runtime: executor.runtime,
|
|
23707
|
+
...ownedTreeRoot === void 0 ? {} : { ownedTreeRoot },
|
|
23708
|
+
...identity ? { identity } : {},
|
|
23709
|
+
profileRef,
|
|
23710
|
+
seq: ordinal,
|
|
23711
|
+
at: new Date(now()).toISOString()
|
|
23712
|
+
}];
|
|
23713
|
+
if (taskRef !== void 0) events.push({
|
|
23435
23714
|
kind: "execution-input",
|
|
23436
23715
|
id,
|
|
23437
23716
|
taskRef,
|
|
23438
23717
|
seq: ordinal,
|
|
23439
23718
|
at: new Date(now()).toISOString()
|
|
23440
23719
|
});
|
|
23720
|
+
await appendSpawnEvents(args.journal, args.root, events);
|
|
23441
23721
|
}).then(async () => {
|
|
23442
23722
|
if (args.workerTraceUnpropagated === void 0 || workerTrace === void 0) return;
|
|
23443
23723
|
await args.journal.appendEvent(args.root, {
|
|
@@ -23567,6 +23847,7 @@ function createScope(args) {
|
|
|
23567
23847
|
childId: id,
|
|
23568
23848
|
label: opts.label,
|
|
23569
23849
|
...opts.assignmentId === void 0 ? {} : { assignmentId: opts.assignmentId },
|
|
23850
|
+
...opts.key === void 0 ? {} : { key: opts.key },
|
|
23570
23851
|
...opts.successorOf === void 0 ? {} : { successorOf: opts.successorOf },
|
|
23571
23852
|
runtime: executor.runtime,
|
|
23572
23853
|
...identity ? { identity } : {},
|
|
@@ -24227,7 +24508,7 @@ async function recordScopeOwnerMaterialization(scope, runtime, declaration, bind
|
|
|
24227
24508
|
/** @internal Kernel identity for constructing the exact deferred owner executor. */
|
|
24228
24509
|
/**
|
|
24229
24510
|
* @internal Each driver attempt of the scope owner is its own execution attempt. A driver retry
|
|
24230
|
-
* after a failed drive, and the
|
|
24511
|
+
* after a failed drive, and the continuation re-entry after an unmet completion check, both
|
|
24231
24512
|
* run the harness again and report a new execution binding; the journal keys owner bindings by
|
|
24232
24513
|
* attempt id, so every attempt after the first is given a fresh kernel-minted id and its
|
|
24233
24514
|
* published flags are cleared, and the new binding lands beside the earlier ones. The first
|
|
@@ -25233,35 +25514,6 @@ function downRecord(reason, infra, trace, metered, providerModel, outRef, harnes
|
|
|
25233
25514
|
...outRef === void 0 ? {} : { outRef }
|
|
25234
25515
|
};
|
|
25235
25516
|
}
|
|
25236
|
-
/**
|
|
25237
|
-
* Read one executor's harness-transcript receipt without letting a broken port escape.
|
|
25238
|
-
*
|
|
25239
|
-
* The three answers this has to keep apart, because #1214 and #1244 are both about an artifact
|
|
25240
|
-
* that reads as coverage without being coverage:
|
|
25241
|
-
* - `available` the transcript survived;
|
|
25242
|
-
* - a reason the CAPTURE produced a box existed and could not be read;
|
|
25243
|
-
* - `executor-exposes-no-transcript` this runtime has no transcript to offer at all;
|
|
25244
|
-
* - `execution-never-started` no environment was ever created (the executor's
|
|
25245
|
-
* own seed, set before `create`);
|
|
25246
|
-
* - `capture-did-not-run` the port answered nothing, so the capture was
|
|
25247
|
-
* skipped rather than attempted and failed.
|
|
25248
|
-
*
|
|
25249
|
-
* Mirrors `readInteractiveSession` above: an absence is always a named reason, never `undefined`.
|
|
25250
|
-
*/
|
|
25251
|
-
function readHarnessTranscript(executor) {
|
|
25252
|
-
if (!executor.harnessTranscript) return harnessTranscriptUnavailable("executor-exposes-no-transcript");
|
|
25253
|
-
let reported;
|
|
25254
|
-
try {
|
|
25255
|
-
reported = executor.harnessTranscript();
|
|
25256
|
-
} catch {
|
|
25257
|
-
return harnessTranscriptUnavailable("executor-exposes-no-transcript");
|
|
25258
|
-
}
|
|
25259
|
-
if (reported === void 0) return harnessTranscriptUnavailable("capture-did-not-run");
|
|
25260
|
-
const capture = reported;
|
|
25261
|
-
if (capture.status === "captured" && capture.artifact) return capture;
|
|
25262
|
-
if (capture.status === "unavailable" && capture.reason) return capture;
|
|
25263
|
-
return harnessTranscriptUnavailable("executor-exposes-no-transcript");
|
|
25264
|
-
}
|
|
25265
25517
|
/** The one place an absent interactive process is spelled, so every refusal reads the same. */
|
|
25266
25518
|
function noInteractiveSession(reason) {
|
|
25267
25519
|
return Object.freeze({
|
|
@@ -25681,6 +25933,493 @@ function unreportedSpend(total, prior) {
|
|
|
25681
25933
|
};
|
|
25682
25934
|
}
|
|
25683
25935
|
//#endregion
|
|
25936
|
+
//#region src/runtime/supervise/continuation.ts
|
|
25937
|
+
/**
|
|
25938
|
+
* The continuation: what a manager with a completion check is told when its turn ends and the
|
|
25939
|
+
* check is unmet, and the one rule that decides whether it is sent back.
|
|
25940
|
+
*
|
|
25941
|
+
* Measured on discovery-lab before this module (2026-09-24, 670 settled runs, 1,596 re-entries):
|
|
25942
|
+
* 1,565 re-entries followed a failed turn and resent the original task, and 31 carried note text.
|
|
25943
|
+
* The note Runtime wrote itself held seven fixed lines and no field for the check's verdict. Of 40
|
|
25944
|
+
* episodes where the director ended on its own and the outside check disagreed, 33 were told
|
|
25945
|
+
* nothing before they ended. 100 of 236 resubmits sent the identical packet. So the director
|
|
25946
|
+
* mostly graded itself, and when it was wrong it heard nothing it could use.
|
|
25947
|
+
*
|
|
25948
|
+
* The design (discovery `docs/38-one-loop-and-continuation.md`) makes three things single, and
|
|
25949
|
+
* this module holds the part Runtime owns:
|
|
25950
|
+
*
|
|
25951
|
+
* - ONE CHECK. A check reading is a {@link CheckVerdict}: pass, the items it read, the composite,
|
|
25952
|
+
* and one `FAIL <item> <where>: <reason>` line per failed item. The same check decides
|
|
25953
|
+
* `submit_result`, runs when a turn ends without an accepted result, scores the finished run,
|
|
25954
|
+
* and ranks versions. A check that could not run gives no verdict ({@link CheckUnavailableError}),
|
|
25955
|
+
* and the loop pauses instead of blaming the director.
|
|
25956
|
+
* - ONE RESEND RULE. {@link ContinuationPolicy} is required for a manager with a check. It holds a
|
|
25957
|
+
* deadline and `maxBarren`, the re-entered turns in a row that may end without progress. There
|
|
25958
|
+
* is no re-prompt count and no default: a retry default in source is a research decision.
|
|
25959
|
+
* - ONE NOTE. {@link composeContinuationNote} writes it. Runtime owns the facts and their order;
|
|
25960
|
+
* the {@link ContinuationProfile} owns every instruction word, so an optimizer can change the
|
|
25961
|
+
* words without touching code. A play may append a section, never remove or rewrite one.
|
|
25962
|
+
*
|
|
25963
|
+
* Evidence behind the note's shape: located errors help (given the first mistake's true location,
|
|
25964
|
+
* fix rates rose 23.5 to 43.9 points, Tyen 2023); unsupported pressure does not (threats and tips
|
|
25965
|
+
* had no significant effect, Wharton 2025; challenges without evidence flipped correct answers,
|
|
25966
|
+
* FlipFlop); repeated summaries drop detail while itemized additions do not (ACE). So the note is
|
|
25967
|
+
* a list of located facts, findings are added and marked resolved rather than rewritten, and the
|
|
25968
|
+
* profile, not this file, decides how blunt the words are.
|
|
25969
|
+
*/
|
|
25970
|
+
/**
|
|
25971
|
+
* The check could not run: its box did not start, its judge's provider refused, its program
|
|
25972
|
+
* crashed. It is not a verdict on the result. Inside a run the loop pauses, as it does for an
|
|
25973
|
+
* unavailable upstream, and the refusal tells the director its result was not judged.
|
|
25974
|
+
*/
|
|
25975
|
+
var CheckUnavailableError = class extends Error {
|
|
25976
|
+
constructor(message, options) {
|
|
25977
|
+
super(message, options);
|
|
25978
|
+
this.name = "CheckUnavailableError";
|
|
25979
|
+
}
|
|
25980
|
+
};
|
|
25981
|
+
/** Read a check function's return value into a verdict. Anything but `true` or a passing verdict
|
|
25982
|
+
* is a failure: a check fails closed. */
|
|
25983
|
+
function checkVerdictOf(outcome) {
|
|
25984
|
+
if (outcome === true) return { pass: true };
|
|
25985
|
+
if (typeof outcome !== "object" || outcome === null || Array.isArray(outcome)) return { pass: false };
|
|
25986
|
+
const raw = outcome;
|
|
25987
|
+
const items = typeof raw.items === "object" && raw.items !== null && !Array.isArray(raw.items) ? Object.fromEntries(Object.entries(raw.items).filter((entry) => typeof entry[1] === "number" && Number.isFinite(entry[1]))) : void 0;
|
|
25988
|
+
const failures = Array.isArray(raw.failures) ? raw.failures.filter((line) => typeof line === "string" && line.trim() !== "") : void 0;
|
|
25989
|
+
return Object.freeze({
|
|
25990
|
+
pass: raw.pass === true,
|
|
25991
|
+
...items === void 0 ? {} : { items: Object.freeze(items) },
|
|
25992
|
+
...finite(raw.composite) ? { composite: raw.composite } : {},
|
|
25993
|
+
...finite(raw.threshold) ? { threshold: raw.threshold } : {},
|
|
25994
|
+
...failures === void 0 ? {} : { failures: Object.freeze(failures) },
|
|
25995
|
+
...typeof raw.review === "string" && raw.review.trim() !== "" ? { review: raw.review.trim() } : {}
|
|
25996
|
+
});
|
|
25997
|
+
}
|
|
25998
|
+
/**
|
|
25999
|
+
* Read an agent-eval `JudgeScore` from a check program into a verdict.
|
|
26000
|
+
*
|
|
26001
|
+
* Each dimension is a checked item. `notes` lines that start with `FAIL ` are the failures; the
|
|
26002
|
+
* remaining lines are the check's review. The verdict passes when `composite >= threshold` and the
|
|
26003
|
+
* score is not marked `failed`; a `failed` score means the judge itself did not run, which is
|
|
26004
|
+
* {@link CheckUnavailableError}, not a verdict.
|
|
26005
|
+
*/
|
|
26006
|
+
function verdictFromJudgeScore(score, threshold) {
|
|
26007
|
+
if (score.failed === true) throw new CheckUnavailableError(`the check's judge did not run: ${score.notes}`);
|
|
26008
|
+
const lines = score.notes.split("\n").map((line) => line.trimEnd());
|
|
26009
|
+
const failures = lines.filter((line) => line.startsWith("FAIL "));
|
|
26010
|
+
const review = lines.filter((line) => !line.startsWith("FAIL ") && line.trim() !== "").join("\n");
|
|
26011
|
+
return checkVerdictOf({
|
|
26012
|
+
pass: score.composite >= threshold,
|
|
26013
|
+
items: score.dimensions,
|
|
26014
|
+
composite: score.composite,
|
|
26015
|
+
threshold,
|
|
26016
|
+
failures,
|
|
26017
|
+
...review === "" ? {} : { review }
|
|
26018
|
+
});
|
|
26019
|
+
}
|
|
26020
|
+
/** Items that fail in `verdict`: every item below 1, or the named items of its FAIL lines. */
|
|
26021
|
+
function failedItems(verdict) {
|
|
26022
|
+
if (verdict.items !== void 0) return Object.entries(verdict.items).filter(([, value]) => value < 1).map(([name]) => name);
|
|
26023
|
+
return (verdict.failures ?? []).map((line) => line.slice(5).split(/[\s:]/u)[0] ?? "");
|
|
26024
|
+
}
|
|
26025
|
+
/** Items that pass in `verdict`. */
|
|
26026
|
+
function passedItems(verdict) {
|
|
26027
|
+
return Object.entries(verdict.items ?? {}).filter(([, value]) => value >= 1).map(([name]) => name);
|
|
26028
|
+
}
|
|
26029
|
+
/** Resolve and check a policy before any compute. Returns the deadline in epoch ms. */
|
|
26030
|
+
function admitContinuationPolicy(policy, context) {
|
|
26031
|
+
if (typeof policy !== "object" || policy === null) throw new ValidationError$1(`${context}: continuation must be an object`);
|
|
26032
|
+
const deadlineMs = typeof policy.deadline === "string" ? Date.parse(policy.deadline) : policy.deadline;
|
|
26033
|
+
if (typeof deadlineMs !== "number" || !Number.isFinite(deadlineMs) || deadlineMs <= 0) throw new ValidationError$1(`${context}: continuation.deadline must be a finite time (epoch ms or ISO 8601)`);
|
|
26034
|
+
if (!Number.isInteger(policy.maxBarren) || policy.maxBarren < 1) throw new ValidationError$1(`${context}: continuation.maxBarren must be an integer >= 1`);
|
|
26035
|
+
if (policy.failures !== "verbatim" && policy.failures !== "off") throw new ValidationError$1(`${context}: continuation.failures must be 'verbatim' or 'off'`);
|
|
26036
|
+
if (policy.panel !== "on" && policy.panel !== "off") throw new ValidationError$1(`${context}: continuation.panel must be 'on' or 'off'`);
|
|
26037
|
+
if (policy.bar !== "on" && policy.bar !== "off") throw new ValidationError$1(`${context}: continuation.bar must be 'on' or 'off'`);
|
|
26038
|
+
if (policy.panel === "on") {
|
|
26039
|
+
if (typeof policy.runPanel !== "function") throw new ValidationError$1(`${context}: continuation.panel 'on' needs runPanel`);
|
|
26040
|
+
const usd = policy.panelUsd;
|
|
26041
|
+
if (usd === void 0 || !finite(usd.perContinuation) || !finite(usd.perRun) || usd.perContinuation <= 0 || usd.perRun < usd.perContinuation) throw new ValidationError$1(`${context}: continuation.panel 'on' needs panelUsd with 0 < perContinuation <= perRun`);
|
|
26042
|
+
}
|
|
26043
|
+
if (policy.append !== void 0 && typeof policy.append !== "function") throw new ValidationError$1(`${context}: continuation.append must be a function`);
|
|
26044
|
+
admitContinuationProfile(policy.profile, context);
|
|
26045
|
+
return deadlineMs;
|
|
26046
|
+
}
|
|
26047
|
+
/** The facts a profile template may name. */
|
|
26048
|
+
const CONTINUATION_FACTS = [
|
|
26049
|
+
"composite",
|
|
26050
|
+
"threshold",
|
|
26051
|
+
"failed",
|
|
26052
|
+
"total",
|
|
26053
|
+
"reads",
|
|
26054
|
+
"owed",
|
|
26055
|
+
"settled",
|
|
26056
|
+
"delivered",
|
|
26057
|
+
"continuation"
|
|
26058
|
+
];
|
|
26059
|
+
const factNames = new Set(CONTINUATION_FACTS);
|
|
26060
|
+
const placeholder = /\{([a-zA-Z]+)\}/gu;
|
|
26061
|
+
function admitContinuationProfile(profile, context) {
|
|
26062
|
+
if (typeof profile !== "object" || profile === null) throw new ValidationError$1(`${context}: continuation.profile must be an object`);
|
|
26063
|
+
if (typeof profile.id !== "string" || profile.id.trim() === "") throw new ValidationError$1(`${context}: continuation.profile.id must be non-empty`);
|
|
26064
|
+
const texts = [
|
|
26065
|
+
["opening", profile.opening],
|
|
26066
|
+
["plan", profile.plan],
|
|
26067
|
+
["rules", profile.rules],
|
|
26068
|
+
...Object.entries(profile.headings ?? {}).map(([key, value]) => [`headings.${key}`, value]),
|
|
26069
|
+
...profile.barRule === void 0 ? [] : [["barRule", profile.barRule]]
|
|
26070
|
+
];
|
|
26071
|
+
for (const key of [
|
|
26072
|
+
"failures",
|
|
26073
|
+
"protected",
|
|
26074
|
+
"changed",
|
|
26075
|
+
"findings",
|
|
26076
|
+
"bar",
|
|
26077
|
+
"plan",
|
|
26078
|
+
"rules"
|
|
26079
|
+
]) if (typeof profile.headings?.[key] !== "string") throw new ValidationError$1(`${context}: continuation.profile.headings.${key} must be a string`);
|
|
26080
|
+
for (const [key, text] of texts) {
|
|
26081
|
+
if (typeof text !== "string") throw new ValidationError$1(`${context}: continuation.profile.${key} must be a string`);
|
|
26082
|
+
for (const match of text.matchAll(placeholder)) if (!factNames.has(match[1] ?? "")) throw new ValidationError$1(`${context}: continuation.profile.${key} names {${match[1]}}, which is not a fact Runtime supplies (${CONTINUATION_FACTS.join(", ")})`);
|
|
26083
|
+
}
|
|
26084
|
+
if (profile.review !== void 0) {
|
|
26085
|
+
if (typeof profile.review !== "string" || profile.review.trim() === "") throw new ValidationError$1(`${context}: continuation.profile.review must be non-empty`);
|
|
26086
|
+
for (const match of profile.review.matchAll(placeholder)) if (![
|
|
26087
|
+
"version",
|
|
26088
|
+
"path",
|
|
26089
|
+
"score"
|
|
26090
|
+
].includes(match[1] ?? "")) throw new ValidationError$1(`${context}: continuation.profile.review names {${match[1]}}; it may name {version}, {path} and {score}`);
|
|
26091
|
+
}
|
|
26092
|
+
if (profile.opening.trim() === "") throw new ValidationError$1(`${context}: continuation.profile.opening must be non-empty`);
|
|
26093
|
+
for (const [index, question] of (profile.questions ?? []).entries()) if (typeof question !== "string" || question.trim() === "") throw new ValidationError$1(`${context}: continuation.profile.questions[${index}] must be a non-empty string`);
|
|
26094
|
+
}
|
|
26095
|
+
/** Findings reach the note only when every citation resolves, at least two distinct spans are
|
|
26096
|
+
* cited, and the independent verifier agreed. The best method in Who&When found the failing step
|
|
26097
|
+
* 14.2% of the time, so an unverified finding is noise with a citation. */
|
|
26098
|
+
function admitFinding(finding) {
|
|
26099
|
+
if (!finding.verified) return false;
|
|
26100
|
+
if (finding.citations.length === 0) return false;
|
|
26101
|
+
if (!finding.citations.every((citation) => citation.resolved)) return false;
|
|
26102
|
+
return new Set(finding.citations.map((citation) => citation.uri)).size >= 2;
|
|
26103
|
+
}
|
|
26104
|
+
/** About 1,500 tokens of findings. */
|
|
26105
|
+
const FINDINGS_CHAR_CAP = 6e3;
|
|
26106
|
+
/**
|
|
26107
|
+
* Rank the admitted findings by how many failed items they explain, drop repeats, and keep them
|
|
26108
|
+
* within the note's cap. Earlier findings stay as they were written (ACE: itemized additions keep
|
|
26109
|
+
* detail that repeated rewrites lose); a finding whose items all pass now is marked resolved.
|
|
26110
|
+
*/
|
|
26111
|
+
function distillFindings(prior, proposed, failing, continuation) {
|
|
26112
|
+
const key = (claim) => claim.toLowerCase().replace(/\s+/gu, " ").trim();
|
|
26113
|
+
const known = new Set(prior.map((finding) => key(finding.claim)));
|
|
26114
|
+
const carried = prior.map((finding) => finding.resolvedAt === void 0 && (finding.items?.length ?? 0) > 0 && (finding.items ?? []).every((item) => !failing.has(item)) ? {
|
|
26115
|
+
...finding,
|
|
26116
|
+
resolvedAt: continuation
|
|
26117
|
+
} : finding);
|
|
26118
|
+
const fresh = proposed.filter(admitFinding).filter((finding) => {
|
|
26119
|
+
const k = key(finding.claim);
|
|
26120
|
+
if (known.has(k)) return false;
|
|
26121
|
+
known.add(k);
|
|
26122
|
+
return true;
|
|
26123
|
+
}).map((finding) => ({
|
|
26124
|
+
finding,
|
|
26125
|
+
links: (finding.items ?? []).filter((item) => failing.has(item)).length
|
|
26126
|
+
})).sort((a, b) => b.links - a.links);
|
|
26127
|
+
const out = [...carried];
|
|
26128
|
+
let used = carried.filter((finding) => finding.resolvedAt === void 0).reduce((sum, finding) => sum + finding.claim.length, 0);
|
|
26129
|
+
for (const { finding } of fresh) {
|
|
26130
|
+
if (used + finding.claim.length > FINDINGS_CHAR_CAP) break;
|
|
26131
|
+
used += finding.claim.length;
|
|
26132
|
+
out.push({
|
|
26133
|
+
...finding,
|
|
26134
|
+
admittedAt: continuation
|
|
26135
|
+
});
|
|
26136
|
+
}
|
|
26137
|
+
return out;
|
|
26138
|
+
}
|
|
26139
|
+
/** Expand the profile's question templates over the failed items and the settled workers. */
|
|
26140
|
+
function expandQuestions(templates, failing, workers) {
|
|
26141
|
+
const out = [];
|
|
26142
|
+
for (const template of templates) {
|
|
26143
|
+
const hasItem = template.includes("{item}");
|
|
26144
|
+
const hasWorker = template.includes("{worker}");
|
|
26145
|
+
if (!hasItem && !hasWorker) {
|
|
26146
|
+
out.push(template);
|
|
26147
|
+
continue;
|
|
26148
|
+
}
|
|
26149
|
+
const items = hasItem ? failing : [""];
|
|
26150
|
+
const each = hasWorker ? workers.map((worker) => `${worker.id} (${worker.label})`) : [""];
|
|
26151
|
+
for (const item of items) for (const worker of each) out.push(template.replaceAll("{item}", item).replaceAll("{worker}", worker));
|
|
26152
|
+
}
|
|
26153
|
+
return out;
|
|
26154
|
+
}
|
|
26155
|
+
/**
|
|
26156
|
+
* Write one continuation note, sections 1 to 8 of docs/38. Section 9, the run's state, is
|
|
26157
|
+
* `composeReentryTask`, which wraps this text. Pure: the same input writes the same note.
|
|
26158
|
+
*/
|
|
26159
|
+
function composeContinuationNote(input) {
|
|
26160
|
+
const { profile, verdict } = input;
|
|
26161
|
+
const items = verdict?.items ?? {};
|
|
26162
|
+
const total = Object.keys(items).length;
|
|
26163
|
+
const failing = verdict === void 0 ? [] : failedItems(verdict);
|
|
26164
|
+
const facts = {
|
|
26165
|
+
composite: verdict?.composite === void 0 ? "unknown" : format(verdict.composite),
|
|
26166
|
+
threshold: verdict?.threshold === void 0 ? "unknown" : format(verdict.threshold),
|
|
26167
|
+
failed: verdict === void 0 || total === 0 && (verdict.failures?.length ?? 0) === 0 ? "unknown" : String(failing.length),
|
|
26168
|
+
total: total === 0 ? "unknown" : String(total),
|
|
26169
|
+
reads: String(input.reads),
|
|
26170
|
+
owed: input.owed?.trim() || "not described",
|
|
26171
|
+
settled: String(input.progress.settledCount),
|
|
26172
|
+
delivered: String(input.progress.deliveredCount ?? 0),
|
|
26173
|
+
continuation: String(input.continuation)
|
|
26174
|
+
};
|
|
26175
|
+
const fill = (text) => text.replace(placeholder, (_, name) => facts[name] ?? `{${name}}`);
|
|
26176
|
+
const sections = [verdict === void 0 ? "No result has reached the check yet. The run ends only when a result passes it through submit_result." : verdict.pass ? "The check passes on the current state, but no result was submitted. Call submit_result to end the run." : fill(profile.opening).trim()];
|
|
26177
|
+
const section = (heading, body) => {
|
|
26178
|
+
if (body.length === 0) return;
|
|
26179
|
+
sections.push([...heading.trim() === "" ? [] : [`## ${fill(heading)}`], ...body].join("\n"));
|
|
26180
|
+
};
|
|
26181
|
+
if (input.failures === "verbatim" && verdict !== void 0) {
|
|
26182
|
+
const lines = verdict.failures ?? [];
|
|
26183
|
+
const shown = lines.slice(0, 40);
|
|
26184
|
+
const more = lines.length - shown.length;
|
|
26185
|
+
section(profile.headings.failures, [...shown, ...more > 0 ? [input.canReadMore ? `${more} more failure lines: call read_continuation with continuation ${input.continuation}.` : `${more} more failure lines are not shown.`] : []]);
|
|
26186
|
+
const passing = passedItems(verdict);
|
|
26187
|
+
section(profile.headings.protected, passing.length === 0 ? [] : [passing.join(", ")]);
|
|
26188
|
+
if (input.previous !== void 0) {
|
|
26189
|
+
const before = new Set(failedItems(input.previous));
|
|
26190
|
+
const now = new Set(failing);
|
|
26191
|
+
const fixed = [...before].filter((item) => !now.has(item));
|
|
26192
|
+
const broke = [...now].filter((item) => !before.has(item));
|
|
26193
|
+
section(profile.headings.changed, [
|
|
26194
|
+
...fixed.length === 0 ? [] : [`Now passing: ${fixed.join(", ")}.`],
|
|
26195
|
+
...broke.length === 0 ? [] : [`Newly failing: ${broke.join(", ")}.`],
|
|
26196
|
+
...fixed.length === 0 && broke.length === 0 ? ["No item changed since the last note."] : [],
|
|
26197
|
+
...input.previous.composite !== void 0 && verdict.composite !== void 0 ? [`Composite: ${format(input.previous.composite)} then ${format(verdict.composite)}.`] : []
|
|
26198
|
+
]);
|
|
26199
|
+
}
|
|
26200
|
+
}
|
|
26201
|
+
if (input.findings !== void 0) {
|
|
26202
|
+
const open = input.findings.filter((finding) => finding.resolvedAt === void 0);
|
|
26203
|
+
const resolved = input.findings.filter((finding) => finding.resolvedAt === input.continuation);
|
|
26204
|
+
section(profile.headings.findings, [...open.map((finding) => `- [hypothesis] ${finding.claim}` + (finding.items?.length ? ` (items: ${finding.items.join(", ")})` : "") + ` Evidence: ${finding.citations.map((citation) => citation.uri).join(", ")}`), ...resolved.map((finding) => `- [resolved] ${finding.claim}`)]);
|
|
26205
|
+
}
|
|
26206
|
+
if (input.bar !== void 0 && verdict !== void 0) {
|
|
26207
|
+
const body = [];
|
|
26208
|
+
if (profile.barRule?.trim()) body.push(fill(profile.barRule).trim());
|
|
26209
|
+
for (const [item, value] of Object.entries(items)) {
|
|
26210
|
+
const best = input.bar.best?.verdict.items?.[item];
|
|
26211
|
+
body.push(`- ${item}: ${value >= 1 ? "passes" : `fails (${format(value)})`}` + (best === void 0 ? "" : ` / ${input.bar.best?.label}: ${best >= 1 ? "passes" : `fails (${format(best)})`}`));
|
|
26212
|
+
}
|
|
26213
|
+
if (input.bar.best?.verdict.composite !== void 0) body.push(`Best version ${input.bar.best.label}: composite ${format(input.bar.best.verdict.composite)}.`);
|
|
26214
|
+
if (input.bar.reference?.trim()) body.push(`Reference result: ${input.bar.reference.trim()}`);
|
|
26215
|
+
if (verdict.review?.trim()) body.push(`The check's review: ${verdict.review.trim()}`);
|
|
26216
|
+
section(profile.headings.bar, body);
|
|
26217
|
+
}
|
|
26218
|
+
section(profile.headings.plan, profile.plan.trim() === "" ? [] : [fill(profile.plan).trim()]);
|
|
26219
|
+
section(profile.headings.rules, [...profile.rules.trim() === "" ? [] : [fill(profile.rules).trim()], ...input.sealed ? ["The score comes from cases you cannot see."] : []]);
|
|
26220
|
+
for (const appended of input.appended ?? []) section(appended.heading, appended.text.trim() === "" ? [] : [appended.text.trim()]);
|
|
26221
|
+
return sections.join("\n\n");
|
|
26222
|
+
}
|
|
26223
|
+
function summarizeVerdict(verdict) {
|
|
26224
|
+
if (verdict === void 0) return null;
|
|
26225
|
+
const total = Object.keys(verdict.items ?? {}).length;
|
|
26226
|
+
return {
|
|
26227
|
+
pass: verdict.pass,
|
|
26228
|
+
...verdict.composite === void 0 ? {} : { composite: verdict.composite },
|
|
26229
|
+
...total === 0 ? {} : {
|
|
26230
|
+
failed: failedItems(verdict).length,
|
|
26231
|
+
total
|
|
26232
|
+
}
|
|
26233
|
+
};
|
|
26234
|
+
}
|
|
26235
|
+
function noteDigest(note) {
|
|
26236
|
+
return `sha256:${createHash("sha256").update(note).digest("hex")}`;
|
|
26237
|
+
}
|
|
26238
|
+
/** A run directory's continuation files: the root's at `<runDir>/continuations/<n>/`, a nested
|
|
26239
|
+
* manager's at `<runDir>/continuations/managers/<owner>/<n>/`. */
|
|
26240
|
+
const CONTINUATIONS_DIR = "continuations";
|
|
26241
|
+
/**
|
|
26242
|
+
* Write one continuation's files under `<dir>/<n>/`: `note.md`, `verdict.json`, and
|
|
26243
|
+
* `panel.jsonl` when the panel ran. The director reads them through `read_continuation`, because
|
|
26244
|
+
* its box cannot read the driver's run directory.
|
|
26245
|
+
*/
|
|
26246
|
+
async function writeContinuationFiles(dir, continuation, files) {
|
|
26247
|
+
const at = join(dir, String(continuation));
|
|
26248
|
+
await mkdir(at, { recursive: true });
|
|
26249
|
+
await writeFile(join(at, "note.md"), `${files.note}\n`, "utf8");
|
|
26250
|
+
await writeFile(join(at, "verdict.json"), `${JSON.stringify(files.verdict ?? null, null, 2)}\n`, "utf8");
|
|
26251
|
+
if (files.panel !== void 0) await writeFile(join(at, "panel.jsonl"), files.panel.map((line) => JSON.stringify(line)).join("\n") + (files.panel.length ? "\n" : ""), "utf8");
|
|
26252
|
+
}
|
|
26253
|
+
/** The best composite across `reads`, or `undefined` when no read scored. */
|
|
26254
|
+
function bestComposite(reads) {
|
|
26255
|
+
let best;
|
|
26256
|
+
for (const read of reads) {
|
|
26257
|
+
const value = read.verdict?.composite;
|
|
26258
|
+
if (value !== void 0 && (best === void 0 || value > best)) best = value;
|
|
26259
|
+
}
|
|
26260
|
+
return best;
|
|
26261
|
+
}
|
|
26262
|
+
function finite(value) {
|
|
26263
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
26264
|
+
}
|
|
26265
|
+
function format(value) {
|
|
26266
|
+
return Number.isInteger(value) ? String(value) : value.toFixed(3).replace(/0+$/u, "");
|
|
26267
|
+
}
|
|
26268
|
+
/** Build the continuation state for one manager with a check. */
|
|
26269
|
+
function createContinuationKeeper(input) {
|
|
26270
|
+
const { policy } = input;
|
|
26271
|
+
const failures = input.feedback === "pass-only" ? "off" : policy.failures;
|
|
26272
|
+
const entries = [];
|
|
26273
|
+
const notes = [];
|
|
26274
|
+
let findings = [];
|
|
26275
|
+
let panelUsd = 0;
|
|
26276
|
+
let panelUsdKnown = true;
|
|
26277
|
+
const latestVerdict = () => {
|
|
26278
|
+
const reads = input.reads();
|
|
26279
|
+
for (let i = reads.length - 1; i >= 0; i -= 1) {
|
|
26280
|
+
const read = reads[i];
|
|
26281
|
+
if (read?.verdict !== void 0) return {
|
|
26282
|
+
verdict: read.verdict,
|
|
26283
|
+
read: read.read
|
|
26284
|
+
};
|
|
26285
|
+
}
|
|
26286
|
+
return { read: 0 };
|
|
26287
|
+
};
|
|
26288
|
+
const closePrevious = () => {
|
|
26289
|
+
const last = entries.at(-1);
|
|
26290
|
+
const lastNote = notes.at(-1);
|
|
26291
|
+
if (last === void 0 || lastNote === void 0) return;
|
|
26292
|
+
const latest = latestVerdict();
|
|
26293
|
+
entries[entries.length - 1] = {
|
|
26294
|
+
...last,
|
|
26295
|
+
after: latest.read > lastNote.read ? summarizeVerdict(latest.verdict) : null
|
|
26296
|
+
};
|
|
26297
|
+
};
|
|
26298
|
+
return {
|
|
26299
|
+
async compose(context) {
|
|
26300
|
+
closePrevious();
|
|
26301
|
+
const continuation = entries.length + 1;
|
|
26302
|
+
const { verdict, read } = latestVerdict();
|
|
26303
|
+
const failing = verdict === void 0 ? [] : failedItems(verdict);
|
|
26304
|
+
let panelRecord;
|
|
26305
|
+
let panelLines;
|
|
26306
|
+
if (policy.panel === "on" && policy.runPanel !== void 0 && policy.panelUsd !== void 0) {
|
|
26307
|
+
const workers = input.workers();
|
|
26308
|
+
const questions = expandQuestions(policy.profile.questions ?? [], failing, workers);
|
|
26309
|
+
const left = policy.panelUsd.perRun - panelUsd;
|
|
26310
|
+
const usdCap = Math.min(policy.panelUsd.perContinuation, left);
|
|
26311
|
+
if (questions.length > 0 && usdCap > 0 && panelUsdKnown) {
|
|
26312
|
+
const result = await policy.runPanel({
|
|
26313
|
+
continuation,
|
|
26314
|
+
task: input.task,
|
|
26315
|
+
...verdict === void 0 ? {} : { verdict },
|
|
26316
|
+
reads: input.reads(),
|
|
26317
|
+
questions,
|
|
26318
|
+
...input.rootStreamPath === void 0 ? {} : { rootStreamPath: input.rootStreamPath },
|
|
26319
|
+
workers,
|
|
26320
|
+
...policy.best === void 0 ? {} : { bar: policy.best },
|
|
26321
|
+
...policy.reference === void 0 ? {} : { reference: policy.reference },
|
|
26322
|
+
usdCap,
|
|
26323
|
+
signal: context.signal
|
|
26324
|
+
});
|
|
26325
|
+
if (result.usd === null) panelUsdKnown = false;
|
|
26326
|
+
else panelUsd += result.usd;
|
|
26327
|
+
findings = distillFindings(findings, result.findings, new Set(failing), continuation);
|
|
26328
|
+
panelRecord = {
|
|
26329
|
+
asked: questions.length,
|
|
26330
|
+
proposed: result.findings.length,
|
|
26331
|
+
admitted: findings.filter((finding) => finding.admittedAt === continuation).length,
|
|
26332
|
+
usd: result.usd
|
|
26333
|
+
};
|
|
26334
|
+
panelLines = [...result.findings.map((finding) => ({
|
|
26335
|
+
kind: "finding",
|
|
26336
|
+
admitted: admitFinding(finding),
|
|
26337
|
+
...finding
|
|
26338
|
+
})), ...result.receipts === void 0 ? [] : [{
|
|
26339
|
+
kind: "receipts",
|
|
26340
|
+
receipts: result.receipts
|
|
26341
|
+
}]];
|
|
26342
|
+
} else panelRecord = {
|
|
26343
|
+
asked: 0,
|
|
26344
|
+
proposed: 0,
|
|
26345
|
+
admitted: 0,
|
|
26346
|
+
usd: 0
|
|
26347
|
+
};
|
|
26348
|
+
}
|
|
26349
|
+
const appended = policy.append ? await policy.append({
|
|
26350
|
+
continuation,
|
|
26351
|
+
...verdict === void 0 ? {} : { verdict },
|
|
26352
|
+
reads: input.reads(),
|
|
26353
|
+
signal: context.signal
|
|
26354
|
+
}) : void 0;
|
|
26355
|
+
const note = composeContinuationNote({
|
|
26356
|
+
profile: policy.profile,
|
|
26357
|
+
continuation,
|
|
26358
|
+
...verdict === void 0 ? {} : { verdict },
|
|
26359
|
+
...notes.at(-1)?.verdict === void 0 ? {} : { previous: notes.at(-1)?.verdict },
|
|
26360
|
+
reads: input.reads().length,
|
|
26361
|
+
failures,
|
|
26362
|
+
...policy.panel === "on" ? { findings } : {},
|
|
26363
|
+
...policy.bar === "on" ? { bar: {
|
|
26364
|
+
...policy.best === void 0 ? {} : { best: policy.best },
|
|
26365
|
+
...policy.reference === void 0 ? {} : { reference: policy.reference }
|
|
26366
|
+
} } : {},
|
|
26367
|
+
...appended === void 0 ? {} : { appended: [appended] },
|
|
26368
|
+
...input.owed === void 0 ? {} : { owed: input.owed },
|
|
26369
|
+
progress: context.progress,
|
|
26370
|
+
canReadMore: input.canReadMore,
|
|
26371
|
+
...input.sealed === true ? { sealed: true } : {}
|
|
26372
|
+
});
|
|
26373
|
+
notes.push({
|
|
26374
|
+
note,
|
|
26375
|
+
...verdict === void 0 ? {} : { verdict },
|
|
26376
|
+
...panelLines === void 0 ? {} : { panel: panelLines },
|
|
26377
|
+
read
|
|
26378
|
+
});
|
|
26379
|
+
entries.push({
|
|
26380
|
+
continuation,
|
|
26381
|
+
attempt: context.attempt,
|
|
26382
|
+
noteDigest: noteDigest(note),
|
|
26383
|
+
profile: policy.profile.id,
|
|
26384
|
+
switches: {
|
|
26385
|
+
failures,
|
|
26386
|
+
panel: policy.panel,
|
|
26387
|
+
bar: policy.bar
|
|
26388
|
+
},
|
|
26389
|
+
before: summarizeVerdict(verdict),
|
|
26390
|
+
after: null,
|
|
26391
|
+
...panelRecord === void 0 ? {} : { panel: panelRecord },
|
|
26392
|
+
appended: appended === void 0 ? 0 : 1
|
|
26393
|
+
});
|
|
26394
|
+
if (input.dir !== void 0) await writeContinuationFiles(input.dir, continuation, {
|
|
26395
|
+
note,
|
|
26396
|
+
...verdict === void 0 ? {} : { verdict },
|
|
26397
|
+
...panelLines === void 0 ? {} : { panel: panelLines }
|
|
26398
|
+
});
|
|
26399
|
+
return note;
|
|
26400
|
+
},
|
|
26401
|
+
read(continuation) {
|
|
26402
|
+
const index = continuation === void 0 ? notes.length - 1 : continuation - 1;
|
|
26403
|
+
const entry = notes[index];
|
|
26404
|
+
if (entry === void 0) return {
|
|
26405
|
+
found: false,
|
|
26406
|
+
reason: notes.length === 0 ? "no continuation has been sent in this run" : `continuations run from 1 to ${notes.length}`
|
|
26407
|
+
};
|
|
26408
|
+
return {
|
|
26409
|
+
found: true,
|
|
26410
|
+
continuation: index + 1,
|
|
26411
|
+
note: entry.note,
|
|
26412
|
+
verdict: failures === "off" && entry.verdict !== void 0 ? { pass: entry.verdict.pass } : entry.verdict ?? null,
|
|
26413
|
+
findings: findings.filter((finding) => finding.admittedAt <= index + 1)
|
|
26414
|
+
};
|
|
26415
|
+
},
|
|
26416
|
+
entries() {
|
|
26417
|
+
closePrevious();
|
|
26418
|
+
return entries.map((entry) => ({ ...entry }));
|
|
26419
|
+
}
|
|
26420
|
+
};
|
|
26421
|
+
}
|
|
26422
|
+
//#endregion
|
|
25684
26423
|
//#region src/runtime/supervise/driver-retry.ts
|
|
25685
26424
|
/**
|
|
25686
26425
|
* Root-driver retry — the root gets the same second chance a worker's transport already has.
|
|
@@ -25728,22 +26467,21 @@ function unreportedSpend(total, prior) {
|
|
|
25728
26467
|
* driver that RETURNED with the contract unmet ended the run silently — 376 of 376 winning lab runs
|
|
25729
26468
|
* ended on this loop's own `stop: 'completed'`, with the completion gate left to label the result
|
|
25730
26469
|
* rather than to change it. A completed drive whose contract is unmet is now a first-class moment:
|
|
25731
|
-
* `
|
|
25732
|
-
* same budget, deadline, and abort bounds.
|
|
25733
|
-
* retry allowance.
|
|
26470
|
+
* the manager's `continuation` policy (`./continuation.ts`) re-enters the driver with Runtime's
|
|
26471
|
+
* continuation note, and every re-entry crosses the same budget, deadline, and abort bounds.
|
|
26472
|
+
* Successful continuations do not consume the failure retry allowance.
|
|
25734
26473
|
*
|
|
25735
26474
|
* This loop decides WHETHER to re-enter; it does not know WHERE the next drive runs. Whether the
|
|
25736
26475
|
* re-entered driver continues the same harness session, the same environment, or a replacement is
|
|
25737
26476
|
* the drive harness's fact, and the caller composes the re-entry task from it (see
|
|
25738
|
-
* `./reentry.ts`). A
|
|
26477
|
+
* `./reentry.ts`). A continuation re-enters the same session only on a backend that proves it.
|
|
25739
26478
|
*
|
|
25740
|
-
* Progress bounds the
|
|
25741
|
-
* counter decides whether a
|
|
25742
|
-
* re-entered drives that completed without
|
|
25743
|
-
* 'no-progress'`.
|
|
25744
|
-
*
|
|
25745
|
-
*
|
|
25746
|
-
* the old prompt-owned loop logged 896 of 1,011 rounds with no progress.
|
|
26479
|
+
* Progress bounds the continuations, and nothing else counts them. The same delivery reading that
|
|
26480
|
+
* resets the barren failure counter decides whether a continued drive earned another:
|
|
26481
|
+
* `continuation.maxBarren` consecutive re-entered drives that completed without progress end the
|
|
26482
|
+
* loop with `repromptRefusedBy: 'no-progress'`. Progress is a delivery or a rise in the check's
|
|
26483
|
+
* best composite. There is no count cap and no caller veto: the old prompt-owned loop logged 896
|
|
26484
|
+
* of 1,011 rounds with no progress, and 650 recorded inputs chose seven different re-prompt counts.
|
|
25747
26485
|
*
|
|
25748
26486
|
* A THIRD CLASS sits between the two: the upstream said "not now". A model provider's exhausted
|
|
25749
26487
|
* quota, a rate limit, or an overloaded service (HTTP 429, 503, 529, or the router's own codes for
|
|
@@ -25755,28 +26493,8 @@ function unreportedSpend(total, prior) {
|
|
|
25755
26493
|
* the router answered some turns in between (one lead spent 1.7M and 3.3M input tokens on two of
|
|
25756
26494
|
* them) and each run's budget and 8-hour deadline were almost untouched.
|
|
25757
26495
|
*/
|
|
25758
|
-
/**
|
|
25759
|
-
* The instruction a completed-but-undelivered drive is re-entered with when the caller supplies no
|
|
25760
|
-
* `onUnmetContract`. It states the verdict, names what is owed, reports the ledger, and gives the
|
|
25761
|
-
* three steps — the same shape `depthStrategy` re-prompts a resumed session with, said in the
|
|
25762
|
-
* driver's own terms.
|
|
25763
|
-
*/
|
|
25764
|
-
function defaultUnmetContractSteer(context) {
|
|
25765
|
-
const owed = context.describe?.trim();
|
|
25766
|
-
return [
|
|
25767
|
-
"The completion check has not passed. This run has delivered nothing yet.",
|
|
25768
|
-
owed === void 0 || owed.length === 0 ? "The deliverable this run owes is still missing." : `The deliverable this run owes: ${owed}`,
|
|
25769
|
-
`Workers settled: ${context.progress.settledCount}. Workers that passed the check: ${context.progress.deliveredCount ?? 0}.`,
|
|
25770
|
-
"Do the unfinished work with the tools.",
|
|
25771
|
-
"Verify that the check passes.",
|
|
25772
|
-
"Then submit the result.",
|
|
25773
|
-
"Do not restate work you already did."
|
|
25774
|
-
].join("\n");
|
|
25775
|
-
}
|
|
25776
26496
|
const DEFAULT_MAX_CONSECUTIVE_FAILURES = 3;
|
|
25777
26497
|
const DEFAULT_MAX_ATTEMPTS = 8;
|
|
25778
|
-
/** Two re-prompted drives in a row that deliver nothing end the re-prompts. */
|
|
25779
|
-
const DEFAULT_MAX_BARREN_REPROMPTS = 2;
|
|
25780
26498
|
const DEFAULT_INITIAL_BACKOFF_MS = 2e3;
|
|
25781
26499
|
const DEFAULT_MAX_BACKOFF_MS = 3e4;
|
|
25782
26500
|
/**
|
|
@@ -25822,6 +26540,7 @@ var HarnessTurnFailedError = class extends Error {
|
|
|
25822
26540
|
*/
|
|
25823
26541
|
function upstreamUnavailableSignal(error) {
|
|
25824
26542
|
if (!(error instanceof Error)) return void 0;
|
|
26543
|
+
if (error instanceof CheckUnavailableError) return "check-unavailable";
|
|
25825
26544
|
if (error instanceof HarnessTurnFailedError) return unavailableSignalOfFailure({
|
|
25826
26545
|
error: error.message,
|
|
25827
26546
|
...error.errorCode === void 0 ? {} : { errorCode: error.errorCode }
|
|
@@ -25905,13 +26624,15 @@ function contractOf(mark) {
|
|
|
25905
26624
|
/**
|
|
25906
26625
|
* Did this attempt move the run toward its DELIVERABLE?
|
|
25907
26626
|
*
|
|
25908
|
-
* A delivery always counts: an accepted submission, one more child that passed the check,
|
|
25909
|
-
* contract turning met
|
|
25910
|
-
* with a check unmet they are the burn-rate reading this
|
|
26627
|
+
* A delivery always counts: an accepted submission, one more child that passed the check, the
|
|
26628
|
+
* contract turning met, or a rise in the check's best composite. Spend and settlements count only
|
|
26629
|
+
* while no declared check is outstanding — with a check unmet they are the burn-rate reading this
|
|
26630
|
+
* module's header measures and rejects.
|
|
25911
26631
|
*/
|
|
25912
26632
|
function madeProgress(before, after) {
|
|
25913
26633
|
if (after.submitted && !before.submitted) return true;
|
|
25914
26634
|
if ((after.deliveredCount ?? 0) > (before.deliveredCount ?? 0)) return true;
|
|
26635
|
+
if (after.composite !== void 0 && after.composite > (before.composite ?? -Infinity)) return true;
|
|
25915
26636
|
if (contractOf(before) !== "met" && contractOf(after) === "met") return true;
|
|
25916
26637
|
if (contractOf(after) === "unmet") return false;
|
|
25917
26638
|
return after.poolTokensSpent > before.poolTokensSpent || after.settledCount > before.settledCount;
|
|
@@ -25957,10 +26678,11 @@ async function defaultSleep(ms, signal) {
|
|
|
25957
26678
|
/**
|
|
25958
26679
|
* Run the driver until it completes WITH ITS CONTRACT MET, or until the budget, the deadline, an
|
|
25959
26680
|
* abort, a terminal error, or a ceiling stops it. Transient failures are retried. A drive that
|
|
25960
|
-
* returns with its completion check unmet is re-entered
|
|
25961
|
-
*
|
|
25962
|
-
* real failure) when a FAILURE ends the loop; a
|
|
25963
|
-
* because deciding what an undelivered run is worth
|
|
26681
|
+
* returns with its completion check unmet is re-entered with Runtime's continuation note until the
|
|
26682
|
+
* continuation's deadline or `maxBarren` turns without progress. Throws
|
|
26683
|
+
* `DriverAttemptsExhaustedError` (cause = the last real failure) when a FAILURE ends the loop; a
|
|
26684
|
+
* completed drive returns, met contract or not, because deciding what an undelivered run is worth
|
|
26685
|
+
* belongs to the finalizer, not to this loop.
|
|
25964
26686
|
*/
|
|
25965
26687
|
async function runDriverWithRetry(run) {
|
|
25966
26688
|
const now = run.now ?? Date.now;
|
|
@@ -25971,19 +26693,18 @@ async function runDriverWithRetry(run) {
|
|
|
25971
26693
|
const maxAttempts = Math.max(1, policy.maxAttempts ?? DEFAULT_MAX_ATTEMPTS);
|
|
25972
26694
|
const initialBackoff = Math.max(0, policy.initialBackoffMs ?? DEFAULT_INITIAL_BACKOFF_MS);
|
|
25973
26695
|
const maxBackoff = Math.max(initialBackoff, policy.maxBackoffMs ?? DEFAULT_MAX_BACKOFF_MS);
|
|
25974
|
-
const
|
|
25975
|
-
if (
|
|
25976
|
-
|
|
25977
|
-
if (!Number.
|
|
26696
|
+
const continuation = run.continuation;
|
|
26697
|
+
if (continuation !== void 0) {
|
|
26698
|
+
if (!Number.isFinite(continuation.deadlineMs) || continuation.deadlineMs <= 0) throw new ValidationError$1("runDriverWithRetry: a continuation needs a finite positive deadline");
|
|
26699
|
+
if (!Number.isInteger(continuation.maxBarren) || continuation.maxBarren < 1) throw new ValidationError$1("runDriverWithRetry: continuation.maxBarren must be an integer >= 1");
|
|
25978
26700
|
}
|
|
25979
|
-
const maxBarren = Math.max(1, run.reprompt?.maxBarren ?? 2);
|
|
25980
26701
|
const attempts = [];
|
|
25981
26702
|
let consecutiveBarren = 0;
|
|
25982
26703
|
let barrenReentries = 0;
|
|
25983
26704
|
let failures = 0;
|
|
25984
26705
|
let consecutivePauses = 0;
|
|
25985
26706
|
let pauses = 0;
|
|
25986
|
-
let
|
|
26707
|
+
let continuations = 0;
|
|
25987
26708
|
let reentry;
|
|
25988
26709
|
const emit = async (record) => {
|
|
25989
26710
|
const entered = reentry === void 0 ? {} : { reentry: reentry.reason };
|
|
@@ -25995,32 +26716,33 @@ async function runDriverWithRetry(run) {
|
|
|
25995
26716
|
await run.onAttempt?.(stamped);
|
|
25996
26717
|
};
|
|
25997
26718
|
/**
|
|
25998
|
-
* Decide what a completed
|
|
25999
|
-
* is applied here too — that is the fix for `budgetStop` having lived only in the catch
|
|
26000
|
-
*
|
|
26719
|
+
* Decide what a completed drive with its check unmet does next. Every bound the FAILURE path
|
|
26720
|
+
* applies is applied here too — that is the fix for `budgetStop` having lived only in the catch
|
|
26721
|
+
* arm — and they are read again after the note is composed, because composing may run the
|
|
26722
|
+
* question panel.
|
|
26001
26723
|
*/
|
|
26002
|
-
const
|
|
26003
|
-
|
|
26004
|
-
|
|
26005
|
-
|
|
26006
|
-
|
|
26007
|
-
|
|
26008
|
-
|
|
26724
|
+
const decideContinuation = async (policy, attempt, after) => {
|
|
26725
|
+
const bounds = () => {
|
|
26726
|
+
if (policy.closed()) return "closed";
|
|
26727
|
+
if (run.signal.aborted) return "aborted";
|
|
26728
|
+
if (now() >= policy.deadlineMs) return "deadline";
|
|
26729
|
+
const byBudget = budgetStop(run.budget(), now());
|
|
26730
|
+
return byBudget === "deadline" || byBudget === "budget-exhausted" ? byBudget : void 0;
|
|
26731
|
+
};
|
|
26732
|
+
if (barrenReentries >= policy.maxBarren) return { refusedBy: "no-progress" };
|
|
26733
|
+
const before = bounds();
|
|
26734
|
+
if (before !== void 0) return { refusedBy: before };
|
|
26735
|
+
const steer = (await policy.compose({
|
|
26009
26736
|
attempt,
|
|
26010
|
-
|
|
26011
|
-
maxReprompts,
|
|
26737
|
+
continuations,
|
|
26012
26738
|
progress: after,
|
|
26013
26739
|
budget: run.budget(),
|
|
26014
|
-
|
|
26015
|
-
|
|
26016
|
-
};
|
|
26017
|
-
const
|
|
26018
|
-
if (
|
|
26019
|
-
if (
|
|
26020
|
-
const afterHook = budgetStop(run.budget(), now());
|
|
26021
|
-
if (afterHook === "deadline" || afterHook === "budget-exhausted") return { refusedBy: afterHook };
|
|
26022
|
-
const steer = typeof decision.steer === "string" ? decision.steer.trim() : "";
|
|
26023
|
-
if (steer.length === 0) throw new ValidationError$1("runDriverWithRetry: onUnmetContract returned an empty steer — return a non-empty instruction or 'stop'");
|
|
26740
|
+
barrenReentries,
|
|
26741
|
+
signal: run.signal
|
|
26742
|
+
})).trim();
|
|
26743
|
+
const afterCompose = bounds();
|
|
26744
|
+
if (afterCompose !== void 0) return { refusedBy: afterCompose };
|
|
26745
|
+
if (steer.length === 0) throw new ValidationError$1("runDriverWithRetry: the continuation note is empty");
|
|
26024
26746
|
return { steer };
|
|
26025
26747
|
};
|
|
26026
26748
|
for (let attempt = 1;; attempt += 1) {
|
|
@@ -26134,10 +26856,10 @@ async function runDriverWithRetry(run) {
|
|
|
26134
26856
|
const contractField = contract === "none" ? {} : { contract };
|
|
26135
26857
|
if (progressed) barrenReentries = 0;
|
|
26136
26858
|
else if (reentry !== void 0 && contract === "unmet") barrenReentries += 1;
|
|
26137
|
-
if (contract === "unmet" &&
|
|
26138
|
-
const decision = await
|
|
26859
|
+
if (contract === "unmet" && continuation !== void 0) {
|
|
26860
|
+
const decision = await decideContinuation(continuation, attempt, after);
|
|
26139
26861
|
if ("steer" in decision) {
|
|
26140
|
-
|
|
26862
|
+
continuations += 1;
|
|
26141
26863
|
await emit({
|
|
26142
26864
|
attempt,
|
|
26143
26865
|
durationMs,
|
|
@@ -26149,7 +26871,7 @@ async function runDriverWithRetry(run) {
|
|
|
26149
26871
|
reentry = {
|
|
26150
26872
|
reason: "unmet-contract",
|
|
26151
26873
|
steer: decision.steer,
|
|
26152
|
-
|
|
26874
|
+
continuation: continuations
|
|
26153
26875
|
};
|
|
26154
26876
|
continue;
|
|
26155
26877
|
}
|
|
@@ -26277,8 +26999,9 @@ async function runFinalizer(finalizer, args) {
|
|
|
26277
26999
|
if (candidate === void 0) return false;
|
|
26278
27000
|
if (args.deliverable === void 0) return true;
|
|
26279
27001
|
try {
|
|
26280
|
-
return await args.deliverable.check(candidate)
|
|
27002
|
+
return checkVerdictOf(await args.deliverable.check(candidate)).pass;
|
|
26281
27003
|
} catch (error) {
|
|
27004
|
+
if (error instanceof CheckUnavailableError) throw error;
|
|
26282
27005
|
throw new ValidationError$1(`finalizer: parent completion check threw: ${error instanceof Error ? error.message : String(error)}`);
|
|
26283
27006
|
}
|
|
26284
27007
|
};
|
|
@@ -26543,10 +27266,10 @@ function createSupervisor() {
|
|
|
26543
27266
|
pool = createBudgetPool(opts.budget, runEpochMs, restored.poolRestore);
|
|
26544
27267
|
} else {
|
|
26545
27268
|
pool = createBudgetPool(opts.budget, runStartedAtMs);
|
|
26546
|
-
await opts.journal.beginTree(opts.runId, runStartedAt);
|
|
27269
|
+
if (existing === void 0) await opts.journal.beginTree(opts.runId, runStartedAt);
|
|
26547
27270
|
const rootReceipt = rootMaterializationReceipt(opts);
|
|
26548
27271
|
const rootRuntime = opts.rootMaterialization?.runtime ?? "inline";
|
|
26549
|
-
|
|
27272
|
+
const rootEvents = [{
|
|
26550
27273
|
kind: "spawned",
|
|
26551
27274
|
id: opts.runId,
|
|
26552
27275
|
label: "root",
|
|
@@ -26556,14 +27279,15 @@ function createSupervisor() {
|
|
|
26556
27279
|
...opts.rootIdentity ? { identity: opts.rootIdentity } : {},
|
|
26557
27280
|
seq: 0,
|
|
26558
27281
|
at: runStartedAt
|
|
26559
|
-
}
|
|
26560
|
-
if (rootReceipt !== void 0)
|
|
27282
|
+
}];
|
|
27283
|
+
if (rootReceipt !== void 0) rootEvents.push({
|
|
26561
27284
|
kind: "materialized",
|
|
26562
27285
|
id: opts.runId,
|
|
26563
27286
|
receipt: rootReceipt,
|
|
26564
27287
|
seq: 0,
|
|
26565
27288
|
at: runStartedAt
|
|
26566
27289
|
});
|
|
27290
|
+
await appendSpawnEvents(opts.journal, opts.runId, rootEvents);
|
|
26567
27291
|
}
|
|
26568
27292
|
const stableRootReceipt = resuming ? prior?.find((event) => event.kind === "materialized" && event.id === opts.runId)?.receipt : rootMaterializationReceipt(opts);
|
|
26569
27293
|
if (stableRootReceipt !== void 0) {
|
|
@@ -26901,11 +27625,18 @@ function createIntensityBreaker(opts, trip) {
|
|
|
26901
27625
|
* settlement either (it writes no `settled` record then), so `downCount` stays what it was:
|
|
26902
27626
|
* ordinary downs only; `fleetYield.down` is where a retained child is counted. */
|
|
26903
27627
|
function wrapJournalForBreaker(journal, breaker) {
|
|
27628
|
+
const recordDown = (ev) => {
|
|
27629
|
+
if (ev.kind === "settled" && ev.status === "down" && ev.retainedExecution === void 0) breaker.recordDown(Date.parse(ev.at));
|
|
27630
|
+
};
|
|
26904
27631
|
return {
|
|
26905
27632
|
loadTree: (root) => journal.loadTree(root),
|
|
26906
27633
|
beginTree: (root, at) => journal.beginTree(root, at),
|
|
27634
|
+
...journal.appendEvents === void 0 ? {} : { appendEvents: (root, events) => {
|
|
27635
|
+
for (const event of events) recordDown(event);
|
|
27636
|
+
return journal.appendEvents?.(root, events) ?? Promise.resolve();
|
|
27637
|
+
} },
|
|
26907
27638
|
appendEvent: (root, ev) => {
|
|
26908
|
-
|
|
27639
|
+
recordDown(ev);
|
|
26909
27640
|
return journal.appendEvent(root, ev);
|
|
26910
27641
|
}
|
|
26911
27642
|
};
|
|
@@ -27199,6 +27930,6 @@ function isNonEmptySpend(s) {
|
|
|
27199
27930
|
return s.iterations > 0 || s.tokens.input > 0 || s.tokens.output > 0 || s.usd > 0 || s.ms > 0 || s.tokensKnown === false || s.usdKnown === false || Object.values(s.resources ?? {}).some((resource) => resource.amount > 0 || !resource.known);
|
|
27200
27931
|
}
|
|
27201
27932
|
//#endregion
|
|
27202
|
-
export {
|
|
27933
|
+
export { bindScopeRetainedOwnerProvider as $, detachedSnapshot as $i, providerAsExecutor as $n, runWorktreeHarness as $r, BudgetReconcileFault as $t, driverExecutorFactory as A, resourceTelemetry as Aa, readCommittedJsonLines as Ai, addHarnessUsage as An, createPropagatingTraceEmitter as Ar, snapshotExecutorConfig as At, recordScopeOwnerMaterialization as B, promptOptionsFromAgentTurnInput as Ba, providerAttemptEvidence as Bi, runAgentRounds as Bn, exportEvalRuns as Br, SpawnEventIndex as Bt, createContinuationKeeper as C, stringifySafe as Ca, sandboxActProfileMaterialization as Ci, peerMailTools as Cn, defaultRedactorIdentityMaterial as Cr, rollingDispatch as Ct, passedItems as D, withTimeout as Da, isNoEntError as Di, executorFailure as Dn, persistHarnessTranscript as Dr, cliWorktreeExecutor as Dt, failedItems as E, unmeteredSpend as Ea, worktreeCliProfileMaterialization as Ei, isTerminalNodeStatus as En, harnessTranscriptArtifact as Er, cliInPlaceExecutor as Et, beginScopeOwnerAttempt as F, DEFAULT_SUCCESSFUL_SHUTDOWN_MS as Fa, finalizeRuntimeOwnedPendingExecutor as Fi, bridgeStopSignalKey as Fn, buildLoopOtelSpans as Fr, createInPlaceCliExecutor as Ft, createWorkerSlots as G, runtimeOwnedExecutorProviderEvidence as Gi, readPromptOptions as Gn, padTraceId as Gr, materializeTreeView as Gt, restoreScopeOwnerAcceptedExecution as H, runtimeOwnedDriveHarnessProviderEvidence as Hi, probeSandboxCapabilities as Hn, generateSpanId as Hr, encodeResultBlob as Ht, createScope as I, armDeadlineTimer as Ia, inheritRuntimeOwnedExecutorAttestation as Ii, TERMINAL_DECISIONS as In, buildLoopSpanNodes as Ir, FileResultBlobStore as It, pollFor as J, unknownExecutionBindingReceipt as Ji, canonicalObservedModelParts as Jn, createRuntimeStreamEventCollector as Jr, WORKER_TOOL_TRACE_SCHEMA_VERSION as Jt, createWaitProbes as K, runtimeOwnedPendingExecutorMaterialization as Ki, routerBrain as Kn, toOtelAttributes as Kr, pendingWaits as Kt, deriveNodeExecutionIdentity as L, teardownExecutor as La, knownExecutionBindingReceipt as Li, createSandboxForSpec as Ln, buildRuntimeEventOtelSpans as Lr, FileSpawnJournal as Lt, withDriverExecutor as M, decodeHarnessUsage as Ma, attestRuntimeOwnedPendingExecutor as Mi, harnessUsageIsEmpty as Mn, readTraceContextFromEnv as Mr, DEFAULT_SANDBOX_STEERING_MAX_TURNS as Mt, SUBTREE_RESULT_LIMIT as N, abortError$2 as Na, attestRuntimeOwnedScopeOwner as Ni, readCodexRolloutSession as Nn, traceContextToEnv as Nr, createSteerableSandboxSession as Nt, verdictFromJudgeScore as O, zeroSpend as Oa, parseCommittedJsonLines as Oi, bridgeAdmissionRefusal as On, readHarnessTranscript as Or, createExecutor as Ot, assertRecursiveReservationPolicy as P, awaitAbortable$1 as Pa, authoredProfileDigest as Pi, bridgeRuntimeAttachmentsKey as Pn, INTELLIGENCE_WIRE_VERSION as Pr, createRouterTranscript as Pt, bindScopeRetainedOwnerEnvironmentId as Q, detachedFrozen as Qi, createAgentEnvironmentProviderRegistry as Qn, runSettledCommand as Qr, workerTraceAnalysisStore as Qt, meterRuntimeOwnedAccounting as R, teardownSurfaces as Ra, knownMaterializationReceipt as Ri, defaultSelectWinner as Rn, createOpenInferenceFileExporter as Rr, InMemoryResultBlobStore as Rt, composeContinuationNote as S, sleep as Sa, renderUnsupported as Si, isPeerMailEnvelope as Sn, defaultRedactor as Sr, queueOf as St, expandQuestions as T, throwIfAborted as Ta, validateProfileMaterialization as Ti, isLiveNodeStatus as Tn, captureHarnessTranscript as Tr, captureReusableExecutorConfig as Tt, scopeOwnerExecutorNodeContext as U, runtimeOwnedExecutorExecutionBinding as Ui, acquireSandbox as Un, loopEventToOtelSpan as Ur, insideCursorNamespace as Ut, recordScopeOwnerPause as V, providerMessageText as Va, recordRuntimeOwnedDriveHarnessProviderEvidence as Vi, createSandboxLineage as Vn, flatOtelSpan as Vr, assertContentAddress as Vt, settledToIteration as W, runtimeOwnedExecutorMaterialization as Wi, assertBoxlessPromptOptions as Wn, padSpanId as Wr, loadSpawnForest as Wt, validateWaitSpec as X, executableAgentProfileSnapshot as Xi, DEFAULT_SANDBOX_IDLE_TIMEOUT_SECONDS as Xn, sanitizeKnowledgeReadinessReport as Xr, isTraceAnalysisStore as Xt, timerAt as Y, unknownMaterializationReceipt as Yi, observedModelMatchesDeclared as Yn, sanitizeAgentRuntimeEvent as Yr, captureWorkerTraceEvidence as Yt, waitUntil as Z, executableAgentSpecSnapshot as Zi, LEAF_CONTINUATION_TASK as Zn, sanitizeRuntimeStreamEvent as Zr, parseWorkerToolTraceArtifact as Zt, CheckUnavailableError as _, deleteBoxSafe as _a, promptControlProfileMaterialization as _i, AUTHORITY_MARKERS as _n, environmentGone as _r, workerInteractiveBindingsDir as _t, collectDelivered as a, createSandboxUsageLedger as aa, harnessInvocation as ai, spendFromUsageEvents as an, createPushTraceSource as ar, scopeRetainedOwnerResourceReader as at, bestComposite as b, promptCacheTokenClasses as ba, promptResourceProfileMaterialization as bi, claimsAuthority as bn, linkAbort as br, startRetainedInteractiveRun as bt, runTree as c, mapSandboxEvent as ca, parseCodexTokenUsage as ci, readWorkerTraceContext as cn, registerRetainedExecutorPreparation as cr, environmentReader as ct, classifyDriverFailure as d, sandboxEventServedBackend as da, AGENT_PROFILE_MATERIALIZATION_AXES as di, workerTraceSeamKey as dn, reconnectRetainedRun as dr, interactiveAdmissionSeamKey as dt, projectSandboxOutcome as ea, captureWorktreeDiff as ei, ReservationWaitRefused as en, providerAsSandboxClient as er, consumeScopeRetainedOwnerResult as et, runDriverWithRetry as f, sandboxProgressEvents as fa, assertProfileMaterialization as fi, taskToPrompt as fn, recoverRetainedRun as fr, readWorkerInteractiveAdmissions as ft, CONTINUATION_FACTS as g, cloneSpend as ga, profileMaterializationAxes$1 as gi, createInbox as gn, destroyInteractiveEnvironment as gr, workerInteractiveBindingFile as gt, CONTINUATIONS_DIR as h, chargedTokens as ha, fullProfileMaterialization as hi, readWorkerProgress as hn, retainedCreateMaterial as hr, readWorkerInteractiveBinding as ht, bestDelivered as i, createSandboxToolPartState as ia, LOCAL_HARNESSES as ii, newUsageTotals as in, unavailableSignalOfFailure as ir, scopeRetainedOwnerPriorSpend as it, isDriverSpec as j, withBudgetResources as ja, writeAllBytes as ji, createCodexRolloutStoreReader as jn, mergeTraceEnv as jr, createWorktreeCliExecutor as jt, driverChild as k, addResourceSpend as ka, prepareJsonlAppend as ki, bridgeModelRouteRefusal as kn, contentAddress as kr, createExecutorRegistry as kt, DriverAttemptsExhaustedError as l, mapSandboxToolEvent as la, CodexExecutionDiagnosticError as li, workerTraceEnv as ln, retainedExecutorSeamKey as lr, hostDirectoryReader as lt, upstreamUnavailableSignal as m, addSpend as ma, defineProfileMaterializationContract as mi, createActivityLog as mn, startRetainedRunInEnvironment as mr, attachWorker as mt, createRootHandle as n, assertSandboxServedModel as na, removeWorktree as ni, createBudgetPool as nn, sandboxClientAsProvider as nr, reconcileScopeRetainedOwnerEnvironment as nt, pickBestDelivered as o, extractLlmCallEvent as oa, harnessSupportsReasoningEffort as oi, spendFromUsageTotals as on, decodeToolPart as or, scopeRetainedOwnerResult as ot, summarizeDriverAttempts as p, sumSandboxUsage as pa, controlProfileMaterialization as pi, DEFAULT_STALL_AFTER_MS as pn, startRetainedRun as pr, workerInteractiveAdmissionFile as pt, isWaitOutcome as q, runtimeOwnedScopeOwnerRuntime as qi, runBrainLoop as qn, createRuntimeEventCollector as qr, replaySpawnTree as qt, createSupervisor as r, canonicalStreamEventFromSandboxEvent as ra, DEFAULT_LOCAL_HARNESS as ri, meterUsageEvent as rn, unavailablePauseMs as rr, scopeRetainedOwnerContext as rt, runFinalizer as s, isSandboxTerminalEvent as sa, localHarnessExecutable as si, WORKER_TRACE_PROPAGATION as sn, sandboxSessionTraceSource as sr, SPAWN_RESOURCE_PATH_MAX_BYTES as st, DEFAULT_MAX_DEPTH as t, readSandboxOutcome as ta, createWorktree as ti, assertValidBudget as tn, resolveAgentEnvironmentProvider as tr, prepareScopeRetainedOwnerTask as tt, HarnessTurnFailedError as u, notifySandboxEventObserver as ua, terminateProcessTreeAndConfirm as ui, workerTraceHeaders as un, errMessage as ur, resolveSpawnResourcePaths as ut, admitContinuationPolicy as v, hasCompleteCacheBreakdown as va, promptModelProfileMaterialization as vi, DEFAULT_PEER_MAIL_LIMITS as vn, RunCancellationReason as vr, reconnectRetainedInteractiveRun as vt, distillFindings as w, throwAbort as wa, unsupportedProfileDimensions as wi, peerMailVerbNames as wn, resolveRedactor as wr, bindReusableExecutorExecutionId as wt, checkVerdictOf as x, randomSuffix as xa, renderProfileMaterializationIssues as xi, createPeerMailbox as xn, runAbortable as xr, freeSlots as xt, admitFinding as y, isAbortError$2 as ya, promptOnlyProfileMaterialization as yi, PEER_MAIL_WIRE_KEY as yn, abortError as yr, recoverRetainedInteractiveRun as yt, meterRuntimeOwnedProviderAttempt as z, promptFromAgentTurnInput as za, newExecutionAttemptId as zi, isTerminalDecision as zn, createOtelExporter as zr, InMemorySpawnJournal as zt };
|
|
27203
27934
|
|
|
27204
|
-
//# sourceMappingURL=supervisor-
|
|
27935
|
+
//# sourceMappingURL=supervisor-DdKPGluv.js.map
|