@tangle-network/agent-runtime 0.143.0 → 0.153.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -0
- package/dist/{activation-mi8TgSLM.js → activation-Bbic0THc.js} +3 -3
- package/dist/{activation-mi8TgSLM.js.map → activation-Bbic0THc.js.map} +1 -1
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +3 -3
- package/dist/{analyst-loop-CvkmfhUB.js → analyst-loop-Bouu53-l.js} +2 -2
- package/dist/{analyst-loop-CvkmfhUB.js.map → analyst-loop-Bouu53-l.js.map} +1 -1
- package/dist/analyst-loop.js +1 -1
- package/dist/{authoring-DuyShLdw.js → authoring-CcVhJ1lP.js} +2 -2
- package/dist/{authoring-DuyShLdw.js.map → authoring-CcVhJ1lP.js.map} +1 -1
- package/dist/candidate-execution/index.js +4 -4
- package/dist/{candidate-execution-CD5PoNmC.js → candidate-execution-DYOB1juU.js} +4 -4
- package/dist/{candidate-execution-CD5PoNmC.js.map → candidate-execution-DYOB1juU.js.map} +1 -1
- package/dist/{conversation-1hNtDeMM.js → conversation-BHMwAiMo.js} +28 -13
- package/dist/{conversation-1hNtDeMM.js.map → conversation-BHMwAiMo.js.map} +1 -1
- package/dist/conversation.d.ts +1 -1
- package/dist/conversation.js +1 -1
- package/dist/durable.d.ts +102 -4
- package/dist/durable.js +259 -13
- package/dist/durable.js.map +1 -1
- package/dist/{environment-provider-DCBJ13VP.js → environment-provider-3eCszBEm.js} +218 -34
- package/dist/environment-provider-3eCszBEm.js.map +1 -0
- package/dist/{environment-provider-B8eZ85Ga.d.ts → environment-provider-DJG0yIYl.d.ts} +2 -2
- package/dist/environment-provider.d.ts +1 -1
- package/dist/environment-provider.js +1 -1
- package/dist/executable-spec-BUcUcEPk.js +73 -0
- package/dist/executable-spec-BUcUcEPk.js.map +1 -0
- package/dist/{graph-De_XEsfH.js → graph-CIh2HDmH.js} +4 -4
- package/dist/{graph-De_XEsfH.js.map → graph-CIh2HDmH.js.map} +1 -1
- package/dist/{improvement-cycle-Bi-Tf4QF.js → improvement-cycle-GCDSsTN6.js} +7 -7
- package/dist/{improvement-cycle-Bi-Tf4QF.js.map → improvement-cycle-GCDSsTN6.js.map} +1 -1
- package/dist/{index-C2caGomG.d.ts → index-DLn9WI-f.d.ts} +342 -505
- package/dist/{index-B8rKtH3U.d.ts → index-lMADJLfq.d.ts} +4 -4
- package/dist/{index-D4sLkOPY.d.ts → index-rxVSm9-z.d.ts} +6 -4
- package/dist/index.d.ts +7 -7
- package/dist/index.js +13 -13
- package/dist/intelligence.d.ts +4 -4
- package/dist/intelligence.js +6 -6
- package/dist/jsonl-file-CDfsCI5s.js +59 -0
- package/dist/jsonl-file-CDfsCI5s.js.map +1 -0
- package/dist/kernel.d.ts +6 -6
- package/dist/kernel.js +13 -13
- package/dist/{knowledge-CVE6Wk1i.js → knowledge-CaY53BW2.js} +10 -7
- package/dist/{knowledge-CVE6Wk1i.js.map → knowledge-CaY53BW2.js.map} +1 -1
- package/dist/knowledge.d.ts +1 -1
- package/dist/knowledge.js +1 -1
- package/dist/{loop-runner-bin-BoHdQqLm.d.ts → loop-runner-bin-BwPqxKhR.d.ts} +3 -3
- package/dist/{loop-runner-bin-DdaI1nLL.js → loop-runner-bin-Dw43kB_-.js} +4 -4
- package/dist/{loop-runner-bin-DdaI1nLL.js.map → loop-runner-bin-Dw43kB_-.js.map} +1 -1
- package/dist/loop-runner-bin.d.ts +1 -1
- package/dist/loop-runner-bin.js +1 -1
- package/dist/{materialization-P86EciBw.js → materialization-Dl9J8ek4.js} +279 -58
- package/dist/materialization-Dl9J8ek4.js.map +1 -0
- package/dist/mcp/bin.js +3 -3
- package/dist/mcp/index.d.ts +3 -3
- package/dist/mcp/index.js +6 -6
- package/dist/{model-policy-DgRJIJse.js → model-policy-Sw4ywhtL.js} +68 -6
- package/dist/model-policy-Sw4ywhtL.js.map +1 -0
- package/dist/{openai-tools-BiAWKjh6.js → openai-tools-C4XKuK4t.js} +2 -2
- package/dist/{openai-tools-BiAWKjh6.js.map → openai-tools-C4XKuK4t.js.map} +1 -1
- package/dist/{prepare-D3n7cA39.js → prepare-C5tI-H4o.js} +2 -2
- package/dist/{prepare-D3n7cA39.js.map → prepare-C5tI-H4o.js.map} +1 -1
- package/dist/primeintellect/index.d.ts +1 -1
- package/dist/profiles.js +1 -1
- package/dist/{protected-model-port-bq6bD9YX.js → protected-model-port-DHDKNeY7.js} +2 -2
- package/dist/{protected-model-port-bq6bD9YX.js.map → protected-model-port-DHDKNeY7.js.map} +1 -1
- package/dist/{redact-DexTuAiX.d.ts → redact-NAptmqKw.d.ts} +3 -3
- package/dist/{researcher-CiSY6Wzb.js → researcher-BMFFPwKb.js} +2 -2
- package/dist/{researcher-CiSY6Wzb.js.map → researcher-BMFFPwKb.js.map} +1 -1
- package/dist/{run-layout-Be_Z0dF8.js → run-layout-C2jgwsCq.js} +111 -6
- package/dist/run-layout-C2jgwsCq.js.map +1 -0
- package/dist/{runtime-BnqjbOGX.js → runtime--Jsq8JCC.js} +118 -97
- package/dist/runtime--Jsq8JCC.js.map +1 -0
- package/dist/{runtime-J6Toky8K.d.ts → runtime-B-5dp5Iz.d.ts} +214 -14
- package/dist/{sandbox-events-COwCWUVB.js → sandbox-events-BVjstFgb.js} +70 -3
- package/dist/sandbox-events-BVjstFgb.js.map +1 -0
- package/dist/{spawn-journal-D2HKUImC.js → spawn-journal-BLnveCRS.js} +34 -104
- package/dist/spawn-journal-BLnveCRS.js.map +1 -0
- package/dist/{stream-agent-turn-C1Vs_3B9.d.ts → stream-agent-turn-BGyszuPH.d.ts} +2 -2
- package/dist/{stream-agent-turn-CXRugSGO.js → stream-agent-turn-DYi8ymsU.js} +91 -16
- package/dist/stream-agent-turn-DYi8ymsU.js.map +1 -0
- package/dist/{structural-rollout-CJgj9YXH.js → structural-rollout-D7V-HgXJ.js} +30 -13
- package/dist/structural-rollout-D7V-HgXJ.js.map +1 -0
- package/dist/{supervise-hCgG6ROJ.js → supervise-k_8VOASb.js} +2499 -2171
- package/dist/supervise-k_8VOASb.js.map +1 -0
- package/dist/{supervisor-s8SfZYbW.js → supervisor-CMZsJ7Wn.js} +673 -446
- package/dist/supervisor-CMZsJ7Wn.js.map +1 -0
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +12 -12
- package/dist/{top-app-BMOSKK06.js → top-app-3rYfFPTW.js} +192 -147
- package/dist/top-app-3rYfFPTW.js.map +1 -0
- package/dist/tui/bin.js +1 -1
- package/dist/tui/index.d.ts +32 -5
- package/dist/tui/index.js +1 -1
- package/dist/{types-Df9vulGc.d.ts → types-BPQhQRrC.d.ts} +507 -10
- package/dist/{util-C1bv6yog.js → util-D6ZEuBMi.js} +71 -2
- package/dist/util-D6ZEuBMi.js.map +1 -0
- package/dist/{workspace-archive-C52LjkeN.js → workspace-archive-B9ui4rrR.js} +2 -2
- package/dist/{workspace-archive-C52LjkeN.js.map → workspace-archive-B9ui4rrR.js.map} +1 -1
- package/package.json +7 -7
- package/dist/environment-provider-DCBJ13VP.js.map +0 -1
- package/dist/materialization-P86EciBw.js.map +0 -1
- package/dist/model-policy-DgRJIJse.js.map +0 -1
- package/dist/retained-run-binding-Dp2e8xne.js +0 -268
- package/dist/retained-run-binding-Dp2e8xne.js.map +0 -1
- package/dist/run-layout-Be_Z0dF8.js.map +0 -1
- package/dist/runtime-BnqjbOGX.js.map +0 -1
- package/dist/sandbox-events-COwCWUVB.js.map +0 -1
- package/dist/spawn-journal-D2HKUImC.js.map +0 -1
- package/dist/stream-agent-turn-CXRugSGO.js.map +0 -1
- package/dist/structural-rollout-CJgj9YXH.js.map +0 -1
- package/dist/supervise-hCgG6ROJ.js.map +0 -1
- package/dist/supervisor-s8SfZYbW.js.map +0 -1
- package/dist/top-app-BMOSKK06.js.map +0 -1
- package/dist/util-C1bv6yog.js.map +0 -1
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { C as unknownExecutionBindingReceipt, S as runtimeOwnedScopeOwnerRuntime, a as authoredProfileDigest, b as runtimeOwnedExecutorProviderEvidence, c as knownExecutionBindingReceipt, f as recordRuntimeOwnedProviderAttemptStart, g as runtimeOwnedDeferredExecutorRuntime, h as recordRuntimeOwnedProviderModel, l as knownMaterializationReceipt, m as recordRuntimeOwnedProviderIdentityConflict, n as attestRuntimeOwnedExecutor, o as finalizeRuntimeOwnedPendingExecutor, p as recordRuntimeOwnedProviderDispatchNotStarted, r as attestRuntimeOwnedPendingExecutor, s as inheritRuntimeOwnedExecutorAttestation, t as attestRuntimeOwnedDeferredExecutor, u as newExecutionAttemptId, v as runtimeOwnedExecutorExecutionBinding, w as unknownMaterializationReceipt, x as runtimeOwnedPendingExecutorMaterialization, y as runtimeOwnedExecutorMaterialization } from "./materialization-Dl9J8ek4.js";
|
|
1
2
|
import { f as RuntimeRunStateError, m as ValidationError, r as BackendTransportError } from "./errors-CDZ8XsVj.js";
|
|
2
3
|
import { t as detachedSnapshot } from "./snapshot-cK9K420n.js";
|
|
3
|
-
import {
|
|
4
|
-
import { _ as
|
|
5
|
-
import { i as extractLlmCallEvent,
|
|
6
|
-
import {
|
|
7
|
-
import { a as concreteProfileModel,
|
|
8
|
-
import { i as resolveAgentEnvironmentProvider, n as providerAsExecutor, r as providerAsSandboxClient } from "./environment-provider-
|
|
4
|
+
import { _ as captureWorkerTraceEvidence, a as aggregateProviderModelEvidence, c as loadSpawnForest, d as replaySpawnTree, f as attestNestedDriverTreeOwner, h as runtimeOwnedNestedDriverTreeRoot, l as materializeTreeView, m as nestedDriverTreeRoot, o as closesCursorSlot, p as driverRuntime, u as pendingWaits, x as contentAddress } from "./spawn-journal-BLnveCRS.js";
|
|
5
|
+
import { _ as unmeteredSpend, a as cloneTokenUsage, b as zeroTokenUsage, d as randomSuffix, f as randomUuid, g as throwIfAborted, h as throwAbort, l as mapWithConcurrency, m as stringifySafe, n as addTokenUsage, o as deleteBoxSafe, p as sleep, r as chargedTokens, s as hasCompleteCacheBreakdown, t as addSpend, u as promptCacheTokenClasses, v as withTimeout, y as zeroSpend } from "./util-D6ZEuBMi.js";
|
|
6
|
+
import { c as notifySandboxEventObserver, i as extractLlmCallEvent, l as sandboxEventServedBackend, r as createSandboxToolPartState, s as mapSandboxToolEvent, t as assertSandboxServedModel, u as sandboxProgressEvents } from "./sandbox-events-BVjstFgb.js";
|
|
7
|
+
import { n as executableAgentSpecSnapshot, r as projectSandboxOutcome, t as executableAgentProfileSnapshot } from "./executable-spec-BUcUcEPk.js";
|
|
8
|
+
import { a as concreteProfileModel, c as profileModelExecutionSettings, d as agentHarness, o as enforceTokenLimits, s as profileBridgeWireModel, t as assertExecutableAgentProfile, u as resolveRouterRetryPolicy } from "./model-policy-Sw4ywhtL.js";
|
|
9
|
+
import { c as linkAbort, i as resolveAgentEnvironmentProvider, l as runAbortable, n as providerAsExecutor, r as providerAsSandboxClient, s as abortError } from "./environment-provider-3eCszBEm.js";
|
|
9
10
|
import { i as notifyRuntimeHookEvent } from "./runtime-hooks-tXpAarhW.js";
|
|
10
11
|
import { AGENT_PROFILE_MATERIALIZATION_AXES, AgentTurnInputSchema, REASONING_EFFORTS, agentProfileSchema, canonicalAgentProfileDigest, canonicalCandidateDigest, profileMaterializationAxes, profileMaterializationAxes as profileMaterializationAxes$1, renderInputPartsAsText, sha256DigestSchema } from "@tangle-network/agent-interface";
|
|
11
12
|
import { estimateCost, isModelPriced } from "@tangle-network/agent-eval";
|
|
@@ -218,6 +219,43 @@ function assertProfileMaterialization(options) {
|
|
|
218
219
|
if (issues.length === 0) return;
|
|
219
220
|
throw new ValidationError(renderProfileMaterializationIssues(issues, options.context));
|
|
220
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* Throw when the CHOSEN HARNESS has no control for a dimension the profile asks for.
|
|
224
|
+
*
|
|
225
|
+
* The contract above answers which axes a run path carries; this answers whether the harness can
|
|
226
|
+
* execute them. `materializeProfile` is pure, so the verdict costs no process and no IO.
|
|
227
|
+
*
|
|
228
|
+
* `skip` must mirror what the EXECUTING caller skips, or this refuses a profile that would have
|
|
229
|
+
* run: a dimension handled by the executor's own native control is not unsupported, it is simply
|
|
230
|
+
* not the plan's to lower.
|
|
231
|
+
*/
|
|
232
|
+
function assertProfileMaterializes(profile, harness, context, skip) {
|
|
233
|
+
const plan = materializeProfile(profile, harness, skip ? { skip: [...skip] } : void 0);
|
|
234
|
+
if (plan.unsupported.length > 0) throw new ValidationError(`${context}: ${harness} cannot materialize the profile: ${renderUnsupported(plan.unsupported)}`);
|
|
235
|
+
return plan;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Ask the materializer which of `dimensions` this harness has no control for, without executing
|
|
239
|
+
* the profile's own `resources.failOnError` policy.
|
|
240
|
+
*
|
|
241
|
+
* A caller that gates only SOME dimensions needs the verdict as data, not as a throw: the
|
|
242
|
+
* materializer throws while planning when `failOnError` is set (its strict default), which hides
|
|
243
|
+
* the dimension list and would conflate a gated dimension with an ungated one. The query copy sets
|
|
244
|
+
* `failOnError: false` so every dimension comes back on `plan.unsupported` and the caller decides.
|
|
245
|
+
*/
|
|
246
|
+
function unsupportedProfileDimensions(profile, harness, dimensions, skip) {
|
|
247
|
+
return materializeProfile({
|
|
248
|
+
...profile,
|
|
249
|
+
resources: {
|
|
250
|
+
...profile.resources,
|
|
251
|
+
failOnError: false
|
|
252
|
+
}
|
|
253
|
+
}, harness, skip ? { skip: [...skip] } : void 0).unsupported.filter((entry) => dimensions.includes(entry.dimension));
|
|
254
|
+
}
|
|
255
|
+
/** One clause per dimension the harness cannot execute, carrying the materializer's own reason. */
|
|
256
|
+
function renderUnsupported(unsupported) {
|
|
257
|
+
return unsupported.map(({ dimension, reason }) => `${dimension}: ${reason}`).join("; ");
|
|
258
|
+
}
|
|
221
259
|
/** Format profile-axis drop issues into a concise operator-facing error. */
|
|
222
260
|
function renderProfileMaterializationIssues(issues, context) {
|
|
223
261
|
if (issues.length === 0) return "";
|
|
@@ -1803,8 +1841,7 @@ function prepareWorktreeProfile(profile, harness) {
|
|
|
1803
1841
|
const workspaceProfile = materializationOnlyProfile(profile);
|
|
1804
1842
|
assertSupportedWorktreeProfile(profile, harness);
|
|
1805
1843
|
assertSafeProfileResourcePaths(profile);
|
|
1806
|
-
const plan =
|
|
1807
|
-
if (plan.unsupported.length > 0) throw new Error(`runWorktreeHarness: profile cannot be materialized for ${harness}: ${plan.unsupported.map(({ dimension, reason }) => `${dimension}: ${reason}`).join("; ")}`);
|
|
1844
|
+
const plan = assertProfileMaterializes(workspaceProfile, harness, "runWorktreeHarness");
|
|
1808
1845
|
assertSafeMaterializedPaths(plan);
|
|
1809
1846
|
return {
|
|
1810
1847
|
plan,
|
|
@@ -3328,12 +3365,14 @@ async function routerChatWithUsage(cfg, messages, opts) {
|
|
|
3328
3365
|
const headers = routerRequestHeaders(cfg, opts);
|
|
3329
3366
|
const temperature = opts?.temperature;
|
|
3330
3367
|
const maxTokens = opts?.maxTokens ?? cfg.maxTokens;
|
|
3368
|
+
const maxCompletionTokens = opts?.maxCompletionTokens ?? cfg.maxCompletionTokens;
|
|
3331
3369
|
const body = () => ({
|
|
3332
3370
|
...providerRequestExtras(opts?.extraBody, [
|
|
3333
3371
|
"model",
|
|
3334
3372
|
"messages",
|
|
3335
3373
|
"temperature",
|
|
3336
3374
|
"max_tokens",
|
|
3375
|
+
"max_completion_tokens",
|
|
3337
3376
|
"seed",
|
|
3338
3377
|
"reasoning_effort",
|
|
3339
3378
|
"stream",
|
|
@@ -3343,6 +3382,7 @@ async function routerChatWithUsage(cfg, messages, opts) {
|
|
|
3343
3382
|
messages,
|
|
3344
3383
|
...temperature !== void 0 ? { temperature } : {},
|
|
3345
3384
|
...maxTokens !== void 0 ? { max_tokens: maxTokens } : {},
|
|
3385
|
+
...maxCompletionTokens !== void 0 ? { max_completion_tokens: maxCompletionTokens } : {},
|
|
3346
3386
|
...opts?.seed !== void 0 ? { seed: opts.seed } : {},
|
|
3347
3387
|
...opts?.reasoningEffort ? { reasoning_effort: opts.reasoningEffort } : {}
|
|
3348
3388
|
});
|
|
@@ -3457,6 +3497,7 @@ async function routerChatWithTools(cfg, messages, tools, opts) {
|
|
|
3457
3497
|
/** The OpenAI-shape request body both tool-calling transports send. One builder so the streamed
|
|
3458
3498
|
* turn cannot drift from the buffered one on model, temperature, tool_choice, or the ceiling. */
|
|
3459
3499
|
function toolCompletionBody(cfg, messages, tools, opts) {
|
|
3500
|
+
const maxCompletionTokens = opts?.maxCompletionTokens ?? cfg.maxCompletionTokens;
|
|
3460
3501
|
return {
|
|
3461
3502
|
...providerRequestExtras(opts?.extraBody, [
|
|
3462
3503
|
"model",
|
|
@@ -3465,6 +3506,7 @@ function toolCompletionBody(cfg, messages, tools, opts) {
|
|
|
3465
3506
|
"tool_choice",
|
|
3466
3507
|
"temperature",
|
|
3467
3508
|
"max_tokens",
|
|
3509
|
+
"max_completion_tokens",
|
|
3468
3510
|
"seed",
|
|
3469
3511
|
"reasoning_effort",
|
|
3470
3512
|
"stream",
|
|
@@ -3478,6 +3520,7 @@ function toolCompletionBody(cfg, messages, tools, opts) {
|
|
|
3478
3520
|
} : {},
|
|
3479
3521
|
...opts?.temperature !== void 0 ? { temperature: opts.temperature } : {},
|
|
3480
3522
|
...opts?.maxTokens ? { max_tokens: opts.maxTokens } : {},
|
|
3523
|
+
...maxCompletionTokens !== void 0 ? { max_completion_tokens: maxCompletionTokens } : {},
|
|
3481
3524
|
...opts?.seed !== void 0 ? { seed: opts.seed } : {},
|
|
3482
3525
|
...opts?.reasoningEffort ? { reasoning_effort: opts.reasoningEffort } : {}
|
|
3483
3526
|
};
|
|
@@ -5141,14 +5184,47 @@ function hashJson(value) {
|
|
|
5141
5184
|
//#region src/runtime/sandbox-executor-output.ts
|
|
5142
5185
|
/** Project the complete Sandbox event stream into the standard executor result shape. */
|
|
5143
5186
|
function sandboxLeafOutputFromEvents(events) {
|
|
5144
|
-
const content = collectAgentFinalMessageText(events) ?? collectAgentResponseText(events)
|
|
5187
|
+
const content = collectAgentFinalMessageText(events) ?? collectAgentResponseText(events);
|
|
5145
5188
|
const toolCalls = sandboxToolCalls(events);
|
|
5189
|
+
const servedBackend = lastServedBackend(events);
|
|
5146
5190
|
return {
|
|
5147
5191
|
events,
|
|
5148
5192
|
content,
|
|
5193
|
+
output: sandboxOutputMarker(content, events.some(carriesText)),
|
|
5194
|
+
...servedBackend === void 0 ? {} : { servedBackend },
|
|
5149
5195
|
...toolCalls.length === 0 ? {} : { toolCalls }
|
|
5150
5196
|
};
|
|
5151
5197
|
}
|
|
5198
|
+
/**
|
|
5199
|
+
* Classify observed text into the explicit output marker. `sawTextEvent` says whether the stream
|
|
5200
|
+
* carried a text-bearing event at all, which is what separates a box that answered nothing from a
|
|
5201
|
+
* box whose answer was never observed.
|
|
5202
|
+
*/
|
|
5203
|
+
function sandboxOutputMarker(content, sawTextEvent = content !== void 0) {
|
|
5204
|
+
if (content !== void 0 && content.length > 0) return {
|
|
5205
|
+
kind: "text",
|
|
5206
|
+
bytes: Buffer.byteLength(content, "utf8")
|
|
5207
|
+
};
|
|
5208
|
+
return sawTextEvent ? { kind: "empty" } : { kind: "absent" };
|
|
5209
|
+
}
|
|
5210
|
+
/** True when the event carries a text field a turn's answer could come from, empty or not. */
|
|
5211
|
+
function carriesText(event) {
|
|
5212
|
+
if (!event || typeof event !== "object") return false;
|
|
5213
|
+
const data = event.data && typeof event.data === "object" ? event.data : {};
|
|
5214
|
+
if (typeof data.finalText === "string" || typeof data.text === "string") return true;
|
|
5215
|
+
if (typeof data.delta === "string") return true;
|
|
5216
|
+
const part = data.part && typeof data.part === "object" ? data.part : void 0;
|
|
5217
|
+
return part !== void 0 && part.type === "text" && typeof part.text === "string";
|
|
5218
|
+
}
|
|
5219
|
+
/** The last served identity the platform reported across a turn's events, or `undefined`. */
|
|
5220
|
+
function lastServedBackend(events) {
|
|
5221
|
+
let served;
|
|
5222
|
+
for (const event of events) {
|
|
5223
|
+
const next = sandboxEventServedBackend(event);
|
|
5224
|
+
if (next !== void 0) served = next;
|
|
5225
|
+
}
|
|
5226
|
+
return served;
|
|
5227
|
+
}
|
|
5152
5228
|
function sandboxToolCalls(events) {
|
|
5153
5229
|
const state = createSandboxToolPartState();
|
|
5154
5230
|
return events.flatMap((event) => mapSandboxToolEvent(event, state).flatMap((projected) => projected.type === "tool_call" ? [{
|
|
@@ -5180,7 +5256,8 @@ function priceUnreceiptedWork(work) {
|
|
|
5180
5256
|
const unknown = {
|
|
5181
5257
|
kind: "cost",
|
|
5182
5258
|
usd: 0,
|
|
5183
|
-
usdKnown: false
|
|
5259
|
+
usdKnown: false,
|
|
5260
|
+
provenance: "uncaptured"
|
|
5184
5261
|
};
|
|
5185
5262
|
const { inputTokens, outputTokens, model } = work;
|
|
5186
5263
|
if (model === void 0 || !isModelPriced(model)) return unknown;
|
|
@@ -5192,10 +5269,41 @@ function priceUnreceiptedWork(work) {
|
|
|
5192
5269
|
kind: "cost",
|
|
5193
5270
|
usd,
|
|
5194
5271
|
usdKnown: false,
|
|
5195
|
-
usdEstimated: usd
|
|
5272
|
+
usdEstimated: usd,
|
|
5273
|
+
provenance: "catalog-estimate"
|
|
5196
5274
|
};
|
|
5197
5275
|
}
|
|
5198
5276
|
//#endregion
|
|
5277
|
+
//#region src/runtime/supervise/node-status.ts
|
|
5278
|
+
/**
|
|
5279
|
+
* Which {@link NodeStatus} values mean the node is finished.
|
|
5280
|
+
*
|
|
5281
|
+
* `'waiting'` is deliberately NOT terminal: a wait-state node holds no executor, no box and no
|
|
5282
|
+
* conserved budget, so it is neither in flight nor settled. Callers that must also exclude it say
|
|
5283
|
+
* so at their own site, because "finished" and "not a live worker" are different questions.
|
|
5284
|
+
*/
|
|
5285
|
+
const terminalNodeStatuses = /* @__PURE__ */ new Set([
|
|
5286
|
+
"done",
|
|
5287
|
+
"failed",
|
|
5288
|
+
"cancelled"
|
|
5289
|
+
]);
|
|
5290
|
+
/**
|
|
5291
|
+
* True once a node has reached a terminal status.
|
|
5292
|
+
*
|
|
5293
|
+
* The single owner of this rule. Written per call site it drifts silently: a status added to
|
|
5294
|
+
* `NodeStatus` is classified by whichever sites the author remembered, and the ones they missed
|
|
5295
|
+
* keep a dead node in the live set — a stop rule that never fires, mail delivered to a worker that
|
|
5296
|
+
* cannot read it, or a cancel answered `not_live` for a node that is still running.
|
|
5297
|
+
*/
|
|
5298
|
+
function isTerminalNodeStatus(status) {
|
|
5299
|
+
return terminalNodeStatuses.has(status);
|
|
5300
|
+
}
|
|
5301
|
+
/** True while a node has not yet reached a terminal status. The complement of
|
|
5302
|
+
* {@link isTerminalNodeStatus}, so the two can never disagree. */
|
|
5303
|
+
function isLiveNodeStatus(status) {
|
|
5304
|
+
return !terminalNodeStatuses.has(status);
|
|
5305
|
+
}
|
|
5306
|
+
//#endregion
|
|
5199
5307
|
//#region src/runtime/supervise/peer-mail.ts
|
|
5200
5308
|
/**
|
|
5201
5309
|
*
|
|
@@ -5281,7 +5389,6 @@ function isPeerMailEnvelope(value) {
|
|
|
5281
5389
|
function isPeerMailKind(value) {
|
|
5282
5390
|
return value === "ask" || value === "tell" || value === "challenge" || value === "answer";
|
|
5283
5391
|
}
|
|
5284
|
-
const isLiveStatus = (status) => status !== "done" && status !== "failed" && status !== "cancelled";
|
|
5285
5392
|
/** Create the run's post office. One per manager scope; the manager's siblings are its addresses. */
|
|
5286
5393
|
function createPeerMailbox(opts) {
|
|
5287
5394
|
const limits = Object.freeze({
|
|
@@ -5321,7 +5428,7 @@ function createPeerMailbox(opts) {
|
|
|
5321
5428
|
await opts.publish(event);
|
|
5322
5429
|
return event;
|
|
5323
5430
|
};
|
|
5324
|
-
const liveNodes = () => opts.scope.view.nodes.filter((node) =>
|
|
5431
|
+
const liveNodes = () => opts.scope.view.nodes.filter((node) => isLiveNodeStatus(node.status));
|
|
5325
5432
|
const mailbox = {
|
|
5326
5433
|
limits,
|
|
5327
5434
|
setEndpoint(baseUrl) {
|
|
@@ -5396,7 +5503,7 @@ function createPeerMailbox(opts) {
|
|
|
5396
5503
|
if (opts.scope.signal.aborted) return record(envelope, "scope-stopped");
|
|
5397
5504
|
const node = opts.scope.view.nodes.find((candidate) => candidate.id === to);
|
|
5398
5505
|
if (node === void 0) return record(envelope, "unknown-worker");
|
|
5399
|
-
if (!
|
|
5506
|
+
if (!isLiveNodeStatus(node.status)) return record(envelope, "already-settled");
|
|
5400
5507
|
let delivered = false;
|
|
5401
5508
|
try {
|
|
5402
5509
|
delivered = opts.scope.send(to, { [PEER_MAIL_WIRE_KEY]: envelope });
|
|
@@ -5623,6 +5730,29 @@ function createInbox() {
|
|
|
5623
5730
|
}
|
|
5624
5731
|
//#endregion
|
|
5625
5732
|
//#region src/runtime/supervise/progress.ts
|
|
5733
|
+
/**
|
|
5734
|
+
*
|
|
5735
|
+
* The LIVE read-model of a still-RUNNING worker — what a driver can see BEFORE the worker settles.
|
|
5736
|
+
*
|
|
5737
|
+
* Until this existed, `observe_agent` on a running worker returned `{status:'running', spent:{0,0},
|
|
5738
|
+
* outRef:null, output:null}`: nothing a brain could act on, so a brain that wanted to steer had no
|
|
5739
|
+
* evidence to steer FROM. This is the other half of the steering wire (the first half is
|
|
5740
|
+
* `Executor.deliver`): a supervisor cannot correct a worker it cannot watch.
|
|
5741
|
+
*
|
|
5742
|
+
* Two layers, both pull-based — no timer, no background task, so it is safe to leave on:
|
|
5743
|
+
*
|
|
5744
|
+
* - The SCOPE layer, available for EVERY executor with no executor cooperation at all: usage
|
|
5745
|
+
* events are timestamped as they arrive, so `lastActivityAt` / `idleMs` / `stalled` /
|
|
5746
|
+
* `tokens` / `turns` are derived from the stream the conserved pool already meters.
|
|
5747
|
+
* - The EXECUTOR layer, optional enrichment via `Executor.progress()`: the tool/file activity
|
|
5748
|
+
* the harness exposes, its own turn count, and how many steers are queued but unread.
|
|
5749
|
+
*
|
|
5750
|
+
* `stalled` is a DERIVED read, computed at observation time against `stallAfterMs` — never a
|
|
5751
|
+
* background watchdog. A worker that has produced no metered activity for longer than the
|
|
5752
|
+
* threshold reads `stalled: true`; nothing is killed, nothing is retried. The driver decides.
|
|
5753
|
+
*
|
|
5754
|
+
* @experimental
|
|
5755
|
+
*/
|
|
5626
5756
|
/** How long a worker may produce no metered activity before a `progress()` read calls it stalled.
|
|
5627
5757
|
* Deliberately generous: a coding harness routinely spends minutes inside one tool call, and a
|
|
5628
5758
|
* false stall that provokes a steer is worse than a late one. */
|
|
@@ -5665,7 +5795,7 @@ function createActivityLog(limit = 12) {
|
|
|
5665
5795
|
/** Fold the scope-derived facts and the executor's optional enrichment into one read. Pure: the
|
|
5666
5796
|
* caller supplies `now`, so a test can observe a stall without waiting for one. */
|
|
5667
5797
|
function readWorkerProgress(scope, executor, now, stallAfterMs = DEFAULT_STALL_AFTER_MS) {
|
|
5668
|
-
const live = scope.status
|
|
5798
|
+
const live = isLiveNodeStatus(scope.status);
|
|
5669
5799
|
const executorActivityAt = executor?.recentActivity?.length ? executor.recentActivity[executor.recentActivity.length - 1].at : 0;
|
|
5670
5800
|
const lastActivityAt = Math.max(scope.lastActivityAt, executorActivityAt);
|
|
5671
5801
|
const idleMs = Math.max(0, now - lastActivityAt);
|
|
@@ -5915,13 +6045,21 @@ function createSteerableSandboxSession(args) {
|
|
|
5915
6045
|
});
|
|
5916
6046
|
const state = {
|
|
5917
6047
|
turns: 0,
|
|
5918
|
-
|
|
6048
|
+
/** `undefined` until a text-bearing terminal event is observed; never seeded with `''`. */
|
|
6049
|
+
lastText: void 0,
|
|
6050
|
+
servedBackend: void 0,
|
|
5919
6051
|
seenToolCalls: /* @__PURE__ */ new Set(),
|
|
6052
|
+
toolCalls: [],
|
|
5920
6053
|
artifact: void 0,
|
|
5921
6054
|
latestOutcome: void 0,
|
|
6055
|
+
/** Reads the live lineage handle once a box and session exist, for exact cancellation. */
|
|
6056
|
+
session: void 0,
|
|
5922
6057
|
teardown: void 0,
|
|
5923
6058
|
note: "starting"
|
|
5924
6059
|
};
|
|
6060
|
+
const toolParts = createSandboxToolPartState();
|
|
6061
|
+
/** Record one box event for the trace and the activity window, and return the live output it
|
|
6062
|
+
* carries so the caller can publish it to the turn stream. */
|
|
5925
6063
|
const recordEvent = (event) => {
|
|
5926
6064
|
const at = now();
|
|
5927
6065
|
const data = event.data;
|
|
@@ -5945,7 +6083,19 @@ function createSteerableSandboxSession(args) {
|
|
|
5945
6083
|
}
|
|
5946
6084
|
}
|
|
5947
6085
|
const text = readFinalText(event);
|
|
5948
|
-
if (text) state.lastText = text;
|
|
6086
|
+
if (text !== void 0) state.lastText = text;
|
|
6087
|
+
const served = sandboxEventServedBackend(event);
|
|
6088
|
+
if (served !== void 0) state.servedBackend = served;
|
|
6089
|
+
const progress = sandboxProgressEvents(event, toolParts);
|
|
6090
|
+
for (const item of progress) {
|
|
6091
|
+
if (item.kind !== "tool_call") continue;
|
|
6092
|
+
state.toolCalls.push({
|
|
6093
|
+
...item.toolCallId === void 0 ? {} : { id: item.toolCallId },
|
|
6094
|
+
name: item.toolName,
|
|
6095
|
+
arguments: item.args ?? {}
|
|
6096
|
+
});
|
|
6097
|
+
}
|
|
6098
|
+
return progress;
|
|
5949
6099
|
};
|
|
5950
6100
|
async function* stream(task, signal) {
|
|
5951
6101
|
const capabilities = await probeSandboxCapabilities(args.sandboxClient);
|
|
@@ -5971,6 +6121,7 @@ function createSteerableSandboxSession(args) {
|
|
|
5971
6121
|
let tokensKnown = true;
|
|
5972
6122
|
let usd = 0;
|
|
5973
6123
|
let handle;
|
|
6124
|
+
state.session = () => handle;
|
|
5974
6125
|
let nextPrompt = args.taskToPrompt(task);
|
|
5975
6126
|
try {
|
|
5976
6127
|
for (let turn = 0; maxTurns === 0 || turn < maxTurns; turn += 1) {
|
|
@@ -6016,7 +6167,10 @@ function createSteerableSandboxSession(args) {
|
|
|
6016
6167
|
} else events = await lineage.continue(handle, prompt, turnController.signal, promptOptions);
|
|
6017
6168
|
for await (const event of events) {
|
|
6018
6169
|
outcomeTracker.observe(event);
|
|
6019
|
-
recordEvent(event)
|
|
6170
|
+
for (const progress of recordEvent(event)) yield {
|
|
6171
|
+
kind: "progress",
|
|
6172
|
+
progress
|
|
6173
|
+
};
|
|
6020
6174
|
const call = extractLlmCallEvent(event, spec.name ?? String(args.harness));
|
|
6021
6175
|
if (call) {
|
|
6022
6176
|
sawLlmCall = true;
|
|
@@ -6040,7 +6194,8 @@ function createSteerableSandboxSession(args) {
|
|
|
6040
6194
|
yield {
|
|
6041
6195
|
kind: "cost",
|
|
6042
6196
|
usd: call.costUsd,
|
|
6043
|
-
usdKnown: false
|
|
6197
|
+
usdKnown: false,
|
|
6198
|
+
provenance: "uncaptured"
|
|
6044
6199
|
};
|
|
6045
6200
|
}
|
|
6046
6201
|
}
|
|
@@ -6087,7 +6242,8 @@ function createSteerableSandboxSession(args) {
|
|
|
6087
6242
|
if (state.turns > 0) yield {
|
|
6088
6243
|
kind: "cost",
|
|
6089
6244
|
usd: 0,
|
|
6090
|
-
usdKnown: false
|
|
6245
|
+
usdKnown: false,
|
|
6246
|
+
provenance: "uncaptured"
|
|
6091
6247
|
};
|
|
6092
6248
|
const spent = {
|
|
6093
6249
|
iterations: state.turns,
|
|
@@ -6099,8 +6255,10 @@ function createSteerableSandboxSession(args) {
|
|
|
6099
6255
|
};
|
|
6100
6256
|
const out = {
|
|
6101
6257
|
content: state.lastText,
|
|
6258
|
+
output: sandboxOutputMarker(state.lastText),
|
|
6259
|
+
...state.servedBackend === void 0 ? {} : { servedBackend: state.servedBackend },
|
|
6102
6260
|
turns: state.turns,
|
|
6103
|
-
toolCalls:
|
|
6261
|
+
toolCalls: state.toolCalls,
|
|
6104
6262
|
...state.latestOutcome ? { outcome: state.latestOutcome } : {}
|
|
6105
6263
|
};
|
|
6106
6264
|
const verdict = state.latestOutcome ? projectSandboxOutcome(state.latestOutcome).verdict : void 0;
|
|
@@ -6116,6 +6274,60 @@ function createSteerableSandboxSession(args) {
|
|
|
6116
6274
|
}
|
|
6117
6275
|
return {
|
|
6118
6276
|
stream,
|
|
6277
|
+
async cancel(request) {
|
|
6278
|
+
const live = state.session?.();
|
|
6279
|
+
const observedAt = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
6280
|
+
if (!live) return {
|
|
6281
|
+
status: "unknown",
|
|
6282
|
+
effect: "cancel_requested",
|
|
6283
|
+
observedAt: observedAt(),
|
|
6284
|
+
detail: "no box session exists yet for this worker; nothing remote could be asked"
|
|
6285
|
+
};
|
|
6286
|
+
const session = live.box.session?.(live.sessionId);
|
|
6287
|
+
if (!session || typeof session.interrupt !== "function") return {
|
|
6288
|
+
status: "unknown",
|
|
6289
|
+
effect: "cancel_requested",
|
|
6290
|
+
observedAt: observedAt(),
|
|
6291
|
+
detail: "the sandbox client exposes no session interrupt operation",
|
|
6292
|
+
evidence: { sessionId: live.sessionId }
|
|
6293
|
+
};
|
|
6294
|
+
try {
|
|
6295
|
+
const result = await session.interrupt();
|
|
6296
|
+
const evidence = {
|
|
6297
|
+
sessionId: live.sessionId,
|
|
6298
|
+
operationId: request.operationId,
|
|
6299
|
+
result
|
|
6300
|
+
};
|
|
6301
|
+
if (result?.cancelled === true) {
|
|
6302
|
+
args.controller.abort("executor cancelled");
|
|
6303
|
+
return {
|
|
6304
|
+
status: "accepted",
|
|
6305
|
+
effect: "cancelled",
|
|
6306
|
+
observedAt: observedAt(),
|
|
6307
|
+
detail: "the box reported the running execution cancelled",
|
|
6308
|
+
evidence
|
|
6309
|
+
};
|
|
6310
|
+
}
|
|
6311
|
+
return {
|
|
6312
|
+
status: "already-terminal",
|
|
6313
|
+
effect: "not_live",
|
|
6314
|
+
observedAt: observedAt(),
|
|
6315
|
+
detail: "the box reported no running execution on this session",
|
|
6316
|
+
evidence
|
|
6317
|
+
};
|
|
6318
|
+
} catch (error) {
|
|
6319
|
+
return {
|
|
6320
|
+
status: "unknown",
|
|
6321
|
+
effect: "cancel_requested",
|
|
6322
|
+
observedAt: observedAt(),
|
|
6323
|
+
detail: `the box interrupt failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
6324
|
+
evidence: {
|
|
6325
|
+
sessionId: live.sessionId,
|
|
6326
|
+
operationId: request.operationId
|
|
6327
|
+
}
|
|
6328
|
+
};
|
|
6329
|
+
}
|
|
6330
|
+
},
|
|
6119
6331
|
progress: () => ({
|
|
6120
6332
|
turns: state.turns,
|
|
6121
6333
|
pendingMessages: args.inbox.pending(),
|
|
@@ -6133,14 +6345,16 @@ function createSteerableSandboxSession(args) {
|
|
|
6133
6345
|
function isInterruptAbort(err, interrupt, external, owned) {
|
|
6134
6346
|
return (err instanceof DOMException && err.name === "AbortError" || typeof err === "object" && err !== null && err.name === "AbortError") && interrupt.aborted && !external.aborted && !owned.aborted;
|
|
6135
6347
|
}
|
|
6136
|
-
/** The terminal text a sandbox `result` event carries, when it carries one.
|
|
6348
|
+
/** The terminal text a sandbox `result` event carries, when it carries one. An observed empty
|
|
6349
|
+
* string is returned as `''`, because "the box answered nothing" is not "the box never
|
|
6350
|
+
* answered". */
|
|
6137
6351
|
function readFinalText(event) {
|
|
6138
6352
|
const data = event.data;
|
|
6139
6353
|
if (!data || typeof data !== "object") return void 0;
|
|
6140
6354
|
const text = data.finalText;
|
|
6141
|
-
if (typeof text === "string"
|
|
6355
|
+
if (typeof text === "string") return text;
|
|
6142
6356
|
const alt = data.text;
|
|
6143
|
-
return typeof alt === "string"
|
|
6357
|
+
return typeof alt === "string" ? alt : void 0;
|
|
6144
6358
|
}
|
|
6145
6359
|
/** Prompt options the composed loop context already carries (agent profile / cwd), forwarded so
|
|
6146
6360
|
* a steerable worker runs with the same box configuration as the single-shot path. */
|
|
@@ -6341,7 +6555,7 @@ function createWorktreeCliExecutor(options) {
|
|
|
6341
6555
|
runtime: "cli",
|
|
6342
6556
|
budgetExempt,
|
|
6343
6557
|
async execute(task, signal) {
|
|
6344
|
-
const linked = linkSignals
|
|
6558
|
+
const linked = linkSignals(signal, controller.signal);
|
|
6345
6559
|
const started = Date.now();
|
|
6346
6560
|
const taskPrompt = executionTaskPrompt(task, options.taskPrompt);
|
|
6347
6561
|
run = await runWorktreeHarness({
|
|
@@ -6468,7 +6682,7 @@ function executionTaskPrompt(task, configuredPrompt) {
|
|
|
6468
6682
|
}
|
|
6469
6683
|
/** Link two abort signals into one that fires when either does. Returns `undefined` when neither
|
|
6470
6684
|
* is present so the harness runner gets no signal at all. */
|
|
6471
|
-
function linkSignals
|
|
6685
|
+
function linkSignals(a, b) {
|
|
6472
6686
|
if (a.aborted || b.aborted) {
|
|
6473
6687
|
const c = new AbortController();
|
|
6474
6688
|
c.abort();
|
|
@@ -6548,6 +6762,11 @@ const bridgeSeamKey = "bridge";
|
|
|
6548
6762
|
/** Internal control seam used by Runtime-owned external supervisors. A completion request stops
|
|
6549
6763
|
* the next bridge turn; it must not abort the paid request that is already streaming. */
|
|
6550
6764
|
const bridgeStopSignalKey = "__bridge_stop_signal";
|
|
6765
|
+
/** Internal attachment seam used by Runtime-owned external supervisors. The named MCP servers ride
|
|
6766
|
+
* beside the AgentProfile as `runtime_attachments`, so the bridge mounts them for the run and keeps
|
|
6767
|
+
* them out of its session profile binding. A rebound coordination port therefore cannot move the
|
|
6768
|
+
* authored profile digest that binds a durable session. */
|
|
6769
|
+
const bridgeRuntimeAttachmentsKey = "__bridge_runtime_attachments";
|
|
6551
6770
|
const maxBridgeTimeoutMs = 2147483647;
|
|
6552
6771
|
const bridgeModelCredentialHeader = "x-cli-bridge-model-credential";
|
|
6553
6772
|
const bridgeModelBaseUrlHeader = "x-cli-bridge-model-base-url";
|
|
@@ -6646,36 +6865,6 @@ function contentRef(prefix, value) {
|
|
|
6646
6865
|
return `${prefix}:${(h >>> 0).toString(16).padStart(8, "0")}`;
|
|
6647
6866
|
}
|
|
6648
6867
|
/**
|
|
6649
|
-
* The spend of work that HAPPENED and reported no usage receipt.
|
|
6650
|
-
*
|
|
6651
|
-
* Not the same value as a plain zero even though both carry `{0,0}` tokens and `$0`. A bare zero
|
|
6652
|
-
* asserts a MEASUREMENT — "this ran and cost nothing" — and every consumer downstream reads it that
|
|
6653
|
-
* way: the pool keeps reporting `readout().tokensKnown === true`, the journal totals stay clean, the
|
|
6654
|
-
* OTEL span records a priced zero, and a caller's token-denominated ceiling can never fire no matter
|
|
6655
|
-
* how much the work really burned. A ceiling that cannot fire is worse than no ceiling, because it
|
|
6656
|
-
* reads as protection.
|
|
6657
|
-
*
|
|
6658
|
-
* `Spend.tokensKnown` is the marker the substrate already threads end to end for exactly this case
|
|
6659
|
-
* (`budget.ts`, `otel-spans.ts`, `spawn-journal.ts`, `supervisor.ts`): the work is recorded, the
|
|
6660
|
-
* zero is labelled a floor rather than a total, and every rollup that touches it reports its balance
|
|
6661
|
-
* as a ceiling rather than a measurement. Use this — never a bare zero — whenever a runtime cannot
|
|
6662
|
-
* see what its worker spent.
|
|
6663
|
-
*
|
|
6664
|
-
* The same rule applies to dollars. A dollar-capped run must refuse an executor whose billed spend
|
|
6665
|
-
* is unknowable; `budgetExempt` does not authorize Runtime to relabel unknown spend as a measured
|
|
6666
|
-
* zero. Callers that require dollar accounting must use a backend with a trusted billing receipt.
|
|
6667
|
-
*/
|
|
6668
|
-
function unmeteredSpend(ms) {
|
|
6669
|
-
return {
|
|
6670
|
-
iterations: 0,
|
|
6671
|
-
tokens: zeroTokenUsage(),
|
|
6672
|
-
tokensKnown: false,
|
|
6673
|
-
usd: 0,
|
|
6674
|
-
usdKnown: false,
|
|
6675
|
-
ms
|
|
6676
|
-
};
|
|
6677
|
-
}
|
|
6678
|
-
/**
|
|
6679
6868
|
* A direct OpenAI-compatible Router chat-completion. One-shot: resolves a
|
|
6680
6869
|
* `ExecutorResult` and reports its terminal usage as `UsageEvent`s through the
|
|
6681
6870
|
* conserved pool. Reports REAL token usage — when the provider omits `usage`,
|
|
@@ -6686,18 +6875,26 @@ function unmeteredSpend(ms) {
|
|
|
6686
6875
|
* failures (429/5xx/Cloudflare-origin) retry with backoff before the executor
|
|
6687
6876
|
* fails the task.
|
|
6688
6877
|
*/
|
|
6878
|
+
/**
|
|
6879
|
+
* The honest answer for a backend with no cancel operation: the local request stopped, and
|
|
6880
|
+
* nothing about the remote run is known. Never `accepted` — a client that advertises provider
|
|
6881
|
+
* cancellation from this would claim more than Runtime observed.
|
|
6882
|
+
*/
|
|
6883
|
+
function localAbortCancellation(detail) {
|
|
6884
|
+
return {
|
|
6885
|
+
status: "unknown",
|
|
6886
|
+
effect: "cancel_requested",
|
|
6887
|
+
observedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6888
|
+
detail
|
|
6889
|
+
};
|
|
6890
|
+
}
|
|
6689
6891
|
const routerInlineExecutor = (spec, ctx) => {
|
|
6690
6892
|
const seam = readSeam(ctx, routerSeamKey, "router/inline");
|
|
6691
6893
|
const model = exactRouterModel(spec.profile, "routerInlineExecutor");
|
|
6692
6894
|
if (!seam.routerBaseUrl || !seam.routerKey) throw new ValidationError("routerInlineExecutor: RouterSeam.routerBaseUrl + routerKey required");
|
|
6693
6895
|
const profileExecution = routerProfileExecution(spec.profile, seam, { multiTurn: false });
|
|
6694
6896
|
const requestIdentity = routerRequestIdentity(ctx);
|
|
6695
|
-
const controller =
|
|
6696
|
-
const abortIfSignalled = () => {
|
|
6697
|
-
if (ctx.signal.aborted) controller.abort();
|
|
6698
|
-
};
|
|
6699
|
-
abortIfSignalled();
|
|
6700
|
-
if (!ctx.signal.aborted) ctx.signal.addEventListener("abort", abortIfSignalled, { once: true });
|
|
6897
|
+
const controller = linkAbort(ctx.signal);
|
|
6701
6898
|
let artifact;
|
|
6702
6899
|
const executionId = ctx.node?.nodeId ?? `router-request-${randomUUID()}`;
|
|
6703
6900
|
const attemptId = ctx.node?.attemptId ?? newExecutionAttemptId(executionId);
|
|
@@ -6707,7 +6904,7 @@ const routerInlineExecutor = (spec, ctx) => {
|
|
|
6707
6904
|
async execute(task, signal) {
|
|
6708
6905
|
const messages = taskToMessages(task, spec, profileExecution.systemPrompt);
|
|
6709
6906
|
const started = Date.now();
|
|
6710
|
-
const linked =
|
|
6907
|
+
const linked = linkAbort(signal, controller.signal).signal;
|
|
6711
6908
|
const extraBody = {
|
|
6712
6909
|
...profileExecution.extraBody ?? {},
|
|
6713
6910
|
...profileExecution.reasoningEffort ? { reasoning_effort: profileExecution.reasoningEffort } : {}
|
|
@@ -6723,7 +6920,7 @@ const routerInlineExecutor = (spec, ctx) => {
|
|
|
6723
6920
|
...profileExecution.temperature !== void 0 ? { temperature: profileExecution.temperature } : {},
|
|
6724
6921
|
...linked ? { signal: linked } : {},
|
|
6725
6922
|
...profileExecution.toolChoice ? { toolChoice: profileExecution.toolChoice } : {},
|
|
6726
|
-
...profileExecution.
|
|
6923
|
+
...profileExecution.tokenLimits.applied,
|
|
6727
6924
|
...profileExecution.seed !== void 0 ? { seed: profileExecution.seed } : {},
|
|
6728
6925
|
...Object.keys(extraBody).length > 0 ? { extraBody } : {},
|
|
6729
6926
|
...requestIdentity
|
|
@@ -6736,7 +6933,7 @@ const routerInlineExecutor = (spec, ctx) => {
|
|
|
6736
6933
|
}, messages, {
|
|
6737
6934
|
...profileExecution.temperature !== void 0 ? { temperature: profileExecution.temperature } : {},
|
|
6738
6935
|
...linked ? { signal: linked } : {},
|
|
6739
|
-
...profileExecution.
|
|
6936
|
+
...profileExecution.tokenLimits.applied,
|
|
6740
6937
|
...profileExecution.seed !== void 0 ? { seed: profileExecution.seed } : {},
|
|
6741
6938
|
...profileExecution.reasoningEffort ? { reasoningEffort: profileExecution.reasoningEffort } : {},
|
|
6742
6939
|
...profileExecution.extraBody ? { extraBody: profileExecution.extraBody } : {},
|
|
@@ -6748,7 +6945,7 @@ const routerInlineExecutor = (spec, ctx) => {
|
|
|
6748
6945
|
tokens: r.usage ? cloneTokenUsage({
|
|
6749
6946
|
input: r.usage.input,
|
|
6750
6947
|
output: r.usage.output,
|
|
6751
|
-
...
|
|
6948
|
+
...promptCacheTokenClasses(r.usage.input, r.cache)
|
|
6752
6949
|
}) : zeroTokenUsage(),
|
|
6753
6950
|
usd: r.billedCostUsd ?? 0,
|
|
6754
6951
|
...r.usage ? {} : { tokensKnown: false },
|
|
@@ -6777,6 +6974,10 @@ const routerInlineExecutor = (spec, ctx) => {
|
|
|
6777
6974
|
};
|
|
6778
6975
|
return artifact;
|
|
6779
6976
|
},
|
|
6977
|
+
cancel(_request) {
|
|
6978
|
+
controller.abort("executor cancelled");
|
|
6979
|
+
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"));
|
|
6980
|
+
},
|
|
6780
6981
|
teardown(_grace) {
|
|
6781
6982
|
controller.abort("executor torn down");
|
|
6782
6983
|
return Promise.resolve({ destroyed: true });
|
|
@@ -6805,7 +7006,7 @@ const routerInlineExecutor = (spec, ctx) => {
|
|
|
6805
7006
|
model,
|
|
6806
7007
|
provider: spec.profile.model?.provider ?? null,
|
|
6807
7008
|
temperature: profileExecution.temperature ?? null,
|
|
6808
|
-
|
|
7009
|
+
tokenLimits: profileExecution.tokenLimits,
|
|
6809
7010
|
retry: profileExecution.retry ?? null,
|
|
6810
7011
|
seed: profileExecution.seed ?? null,
|
|
6811
7012
|
reasoningEffort: profileExecution.reasoningEffort ?? null,
|
|
@@ -6843,22 +7044,6 @@ function mergePromptCache(target, cache) {
|
|
|
6843
7044
|
}
|
|
6844
7045
|
if (cache.status !== void 0) target.status = cache.status;
|
|
6845
7046
|
}
|
|
6846
|
-
/** Preserve a complete Router cache split; an incomplete provider receipt stays unknown. */
|
|
6847
|
-
function routerPromptCacheUsage(input, cache) {
|
|
6848
|
-
if (cache === void 0) return {};
|
|
6849
|
-
const read = cache.readTokens;
|
|
6850
|
-
const write = cache.writeTokens;
|
|
6851
|
-
if (read === void 0 && write === void 0) return {};
|
|
6852
|
-
if (input === void 0 || !isCacheTokenCount(read) || !isCacheTokenCount(write) || read + write > input) return { cacheBreakdownKnown: false };
|
|
6853
|
-
return {
|
|
6854
|
-
freshInput: input - read - write,
|
|
6855
|
-
cacheRead: read,
|
|
6856
|
-
cacheWrite: write
|
|
6857
|
-
};
|
|
6858
|
-
}
|
|
6859
|
-
function isCacheTokenCount(value) {
|
|
6860
|
-
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
6861
|
-
}
|
|
6862
7047
|
async function runRouterTransport(context, call) {
|
|
6863
7048
|
try {
|
|
6864
7049
|
return await call();
|
|
@@ -6886,12 +7071,7 @@ const routerToolsInlineExecutor = (spec, ctx) => {
|
|
|
6886
7071
|
const enabledToolNames = new Set(seam.tools.map((tool) => tool.function.name));
|
|
6887
7072
|
const maxTurns = profileExecution.maxTurns ?? 0;
|
|
6888
7073
|
const requestIdentity = routerRequestIdentity(ctx);
|
|
6889
|
-
const controller =
|
|
6890
|
-
const abortIfSignalled = () => {
|
|
6891
|
-
if (ctx.signal.aborted) controller.abort();
|
|
6892
|
-
};
|
|
6893
|
-
abortIfSignalled();
|
|
6894
|
-
if (!ctx.signal.aborted) ctx.signal.addEventListener("abort", abortIfSignalled, { once: true });
|
|
7074
|
+
const controller = linkAbort(ctx.signal);
|
|
6895
7075
|
const inbox = createInbox();
|
|
6896
7076
|
let artifact;
|
|
6897
7077
|
const executionId = ctx.node?.nodeId ?? `router-tools-run-${randomUUID()}`;
|
|
@@ -6917,6 +7097,7 @@ const routerToolsInlineExecutor = (spec, ctx) => {
|
|
|
6917
7097
|
let reasoningKnown = true;
|
|
6918
7098
|
const promptCache = {};
|
|
6919
7099
|
let lastText = "";
|
|
7100
|
+
const executedToolCalls = [];
|
|
6920
7101
|
const flush = () => {
|
|
6921
7102
|
const pending = inbox.drain();
|
|
6922
7103
|
if (pending.length) messages.push({
|
|
@@ -6925,7 +7106,7 @@ const routerToolsInlineExecutor = (spec, ctx) => {
|
|
|
6925
7106
|
});
|
|
6926
7107
|
return pending.length > 0;
|
|
6927
7108
|
};
|
|
6928
|
-
const external =
|
|
7109
|
+
const external = linkAbort(signal, controller.signal).signal;
|
|
6929
7110
|
try {
|
|
6930
7111
|
for (let t = 0; maxTurns === 0 || t < maxTurns; t += 1) {
|
|
6931
7112
|
flush();
|
|
@@ -6949,7 +7130,7 @@ const routerToolsInlineExecutor = (spec, ctx) => {
|
|
|
6949
7130
|
...profileExecution.temperature !== void 0 ? { temperature: profileExecution.temperature } : {},
|
|
6950
7131
|
signal: turnController.signal,
|
|
6951
7132
|
...profileExecution.toolChoice ? { toolChoice: profileExecution.toolChoice } : {},
|
|
6952
|
-
...profileExecution.
|
|
7133
|
+
...profileExecution.tokenLimits.applied,
|
|
6953
7134
|
...profileExecution.seed !== void 0 ? { seed: profileExecution.seed } : {},
|
|
6954
7135
|
...profileExecution.reasoningEffort ? { reasoningEffort: profileExecution.reasoningEffort } : {},
|
|
6955
7136
|
...profileExecution.extraBody ? { extraBody: profileExecution.extraBody } : {},
|
|
@@ -6978,12 +7159,12 @@ const routerToolsInlineExecutor = (spec, ctx) => {
|
|
|
6978
7159
|
addTokenUsage(tokens, {
|
|
6979
7160
|
input: res.usage.input,
|
|
6980
7161
|
output: res.usage.output,
|
|
6981
|
-
...
|
|
7162
|
+
...promptCacheTokenClasses(res.usage.input, res.cache)
|
|
6982
7163
|
});
|
|
6983
7164
|
if (res.usage.reasoning !== void 0) reasoningTokens += res.usage.reasoning;
|
|
6984
7165
|
else reasoningKnown = false;
|
|
6985
7166
|
} else {
|
|
6986
|
-
addTokenUsage(tokens,
|
|
7167
|
+
addTokenUsage(tokens, promptCacheTokenClasses(void 0, res.cache));
|
|
6987
7168
|
tokensKnown = false;
|
|
6988
7169
|
reasoningKnown = false;
|
|
6989
7170
|
}
|
|
@@ -7015,6 +7196,11 @@ const routerToolsInlineExecutor = (spec, ctx) => {
|
|
|
7015
7196
|
const tc = toolCalls[i];
|
|
7016
7197
|
const id = tc?.id ?? `call_${i}`;
|
|
7017
7198
|
const toolName = tc?.name ?? "";
|
|
7199
|
+
executedToolCalls.push({
|
|
7200
|
+
id,
|
|
7201
|
+
name: toolName,
|
|
7202
|
+
arguments: tc?.arguments ?? ""
|
|
7203
|
+
});
|
|
7018
7204
|
if (!enabledToolNames.has(toolName)) {
|
|
7019
7205
|
messages.push({
|
|
7020
7206
|
role: "tool",
|
|
@@ -7085,7 +7271,7 @@ const routerToolsInlineExecutor = (spec, ctx) => {
|
|
|
7085
7271
|
...observedModel !== void 0 ? { model: observedModel } : {},
|
|
7086
7272
|
messages,
|
|
7087
7273
|
turns,
|
|
7088
|
-
toolCalls:
|
|
7274
|
+
toolCalls: executedToolCalls,
|
|
7089
7275
|
transportAttempts,
|
|
7090
7276
|
...estimatedUsd !== void 0 ? { estimatedCostUsd: estimatedUsd } : {},
|
|
7091
7277
|
...Object.keys(promptCache).length > 0 ? { promptCache } : {},
|
|
@@ -7101,6 +7287,10 @@ const routerToolsInlineExecutor = (spec, ctx) => {
|
|
|
7101
7287
|
};
|
|
7102
7288
|
return artifact;
|
|
7103
7289
|
},
|
|
7290
|
+
cancel(_request) {
|
|
7291
|
+
controller.abort("executor cancelled");
|
|
7292
|
+
return Promise.resolve(localAbortCancellation("the Router chat-completions API exposes no cancel operation; the in-flight turn was aborted and the provider may still bill it"));
|
|
7293
|
+
},
|
|
7104
7294
|
teardown(_grace) {
|
|
7105
7295
|
controller.abort("executor torn down");
|
|
7106
7296
|
return Promise.resolve({ destroyed: true });
|
|
@@ -7131,7 +7321,7 @@ const routerToolsInlineExecutor = (spec, ctx) => {
|
|
|
7131
7321
|
maxTurns,
|
|
7132
7322
|
tools: seam.tools,
|
|
7133
7323
|
temperature: profileExecution.temperature ?? null,
|
|
7134
|
-
|
|
7324
|
+
tokenLimits: profileExecution.tokenLimits,
|
|
7135
7325
|
retry: profileExecution.retry ?? null,
|
|
7136
7326
|
toolChoice: profileExecution.toolChoice ?? null,
|
|
7137
7327
|
extraBody: profileExecution.extraBody ?? null,
|
|
@@ -7190,13 +7380,9 @@ const sandboxExecutor = (spec, ctx) => {
|
|
|
7190
7380
|
if (!seam.sandboxClient || typeof seam.sandboxClient.create !== "function") throw new ValidationError("sandboxExecutor: SandboxSeam.sandboxClient.create required");
|
|
7191
7381
|
const maxIterations = seam.maxIterations ?? 1;
|
|
7192
7382
|
if (!Number.isFinite(maxIterations) || maxIterations <= 0) throw new ValidationError("sandboxExecutor: maxIterations must be > 0");
|
|
7383
|
+
const sandboxTokenLimits = enforceTokenLimits(profileModelExecutionSettings(spec.profile, "sandboxExecutor").tokenLimits, "sandbox", "sandboxExecutor");
|
|
7193
7384
|
const traceEnv = workerTraceEnv(ctx);
|
|
7194
|
-
const controller =
|
|
7195
|
-
const abortIfSignalled = () => {
|
|
7196
|
-
if (ctx.signal.aborted) controller.abort();
|
|
7197
|
-
};
|
|
7198
|
-
abortIfSignalled();
|
|
7199
|
-
if (!ctx.signal.aborted) ctx.signal.addEventListener("abort", abortIfSignalled, { once: true });
|
|
7385
|
+
const controller = linkAbort(ctx.signal);
|
|
7200
7386
|
let artifact;
|
|
7201
7387
|
const executionId = ctx.node?.nodeId ?? `sandbox-run-${randomUUID()}`;
|
|
7202
7388
|
const attemptId = ctx.node?.attemptId ?? newExecutionAttemptId(executionId);
|
|
@@ -7220,7 +7406,8 @@ const sandboxExecutor = (spec, ctx) => {
|
|
|
7220
7406
|
kind: "sandbox-agent-rounds",
|
|
7221
7407
|
harness,
|
|
7222
7408
|
maxIterations,
|
|
7223
|
-
steering: seam.steering !== void 0
|
|
7409
|
+
steering: seam.steering !== void 0,
|
|
7410
|
+
tokenLimits: sandboxTokenLimits
|
|
7224
7411
|
}
|
|
7225
7412
|
};
|
|
7226
7413
|
const sandboxBinding = {
|
|
@@ -7255,6 +7442,7 @@ const sandboxExecutor = (spec, ctx) => {
|
|
|
7255
7442
|
runtime: "sandbox",
|
|
7256
7443
|
deliver: (m) => inbox.deliver(m),
|
|
7257
7444
|
progress: () => session.progress(),
|
|
7445
|
+
cancel: (request) => session.cancel(request),
|
|
7258
7446
|
traceSource: () => session.traceSource(),
|
|
7259
7447
|
execute(task, signal) {
|
|
7260
7448
|
return session.stream(task, signal);
|
|
@@ -7296,6 +7484,10 @@ const sandboxExecutor = (spec, ctx) => {
|
|
|
7296
7484
|
}
|
|
7297
7485
|
});
|
|
7298
7486
|
},
|
|
7487
|
+
cancel(_request) {
|
|
7488
|
+
controller.abort("executor cancelled");
|
|
7489
|
+
return Promise.resolve(localAbortCancellation("the composed sandbox run owns its boxes, so this executor retains no exact session control reference to cancel against"));
|
|
7490
|
+
},
|
|
7299
7491
|
teardown(_grace) {
|
|
7300
7492
|
controller.abort();
|
|
7301
7493
|
return Promise.resolve({ destroyed: true });
|
|
@@ -7307,14 +7499,7 @@ const sandboxExecutor = (spec, ctx) => {
|
|
|
7307
7499
|
}, sandboxMaterialization, sandboxBinding);
|
|
7308
7500
|
};
|
|
7309
7501
|
async function* streamSandboxLeaf(args) {
|
|
7310
|
-
const linked =
|
|
7311
|
-
const cascadeExternal = () => linked.abort(abortReasonOf(args.signal));
|
|
7312
|
-
const cascadeScope = () => linked.abort(abortReasonOf(args.controller.signal));
|
|
7313
|
-
if (args.signal.aborted || args.controller.signal.aborted) linked.abort(abortReasonOf(args.signal.aborted ? args.signal : args.controller.signal));
|
|
7314
|
-
else {
|
|
7315
|
-
args.signal.addEventListener("abort", cascadeExternal, { once: true });
|
|
7316
|
-
args.controller.signal.addEventListener("abort", cascadeScope, { once: true });
|
|
7317
|
-
}
|
|
7502
|
+
const linked = linkAbort(args.signal, args.controller.signal);
|
|
7318
7503
|
const agentRun = {
|
|
7319
7504
|
profile: args.spec.profile,
|
|
7320
7505
|
taskToPrompt: (t) => taskToPrompt(t),
|
|
@@ -7390,14 +7575,19 @@ async function* streamSandboxLeaf(args) {
|
|
|
7390
7575
|
...result.tokenUsage.cacheWrite !== void 0 ? { cacheWrite: result.tokenUsage.cacheWrite } : {},
|
|
7391
7576
|
...result.tokenUsage.cacheBreakdownKnown === false ? { cacheBreakdownKnown: false } : {}
|
|
7392
7577
|
};
|
|
7393
|
-
if (result.iterations.length > 0 || result.costUsd) yield {
|
|
7578
|
+
if (result.iterations.length > 0 || result.costUsd) yield usdKnown ? {
|
|
7394
7579
|
kind: "cost",
|
|
7580
|
+
usdKnown: true,
|
|
7395
7581
|
usd: result.costUsd,
|
|
7396
|
-
|
|
7582
|
+
provenance: "provider-receipt"
|
|
7583
|
+
} : {
|
|
7584
|
+
kind: "cost",
|
|
7585
|
+
usdKnown: false,
|
|
7586
|
+
usd: result.costUsd,
|
|
7587
|
+
provenance: "uncaptured"
|
|
7397
7588
|
};
|
|
7398
7589
|
} finally {
|
|
7399
|
-
|
|
7400
|
-
args.controller.signal.removeEventListener("abort", cascadeScope);
|
|
7590
|
+
linked.release();
|
|
7401
7591
|
}
|
|
7402
7592
|
}
|
|
7403
7593
|
/** The loop's own failure, when NO iteration produced an output: the first error it
|
|
@@ -7443,12 +7633,7 @@ const cliExecutor = (_spec, ctx) => {
|
|
|
7443
7633
|
const seam = readSeam(ctx, cliSeamKey, "cli");
|
|
7444
7634
|
if (!seam.bin) throw new ValidationError("cliExecutor: CliSeam.bin required");
|
|
7445
7635
|
const traceEnv = workerTraceEnv(ctx);
|
|
7446
|
-
const controller =
|
|
7447
|
-
const abortIfSignalled = () => {
|
|
7448
|
-
if (ctx.signal.aborted) controller.abort();
|
|
7449
|
-
};
|
|
7450
|
-
abortIfSignalled();
|
|
7451
|
-
if (!ctx.signal.aborted) ctx.signal.addEventListener("abort", abortIfSignalled, { once: true });
|
|
7636
|
+
const controller = linkAbort(ctx.signal);
|
|
7452
7637
|
let proc;
|
|
7453
7638
|
let artifact;
|
|
7454
7639
|
const executionId = ctx.node?.nodeId ?? `cli-process-${randomUUID()}`;
|
|
@@ -7592,18 +7777,20 @@ function bridgeProfileModel(profile, context) {
|
|
|
7592
7777
|
const bridgeExecutor = (spec, ctx) => {
|
|
7593
7778
|
const base = readSeam(ctx, bridgeSeamKey, "bridge");
|
|
7594
7779
|
const stopSignal = readOptionalAbortSignal(ctx, bridgeStopSignalKey, "bridge");
|
|
7780
|
+
const runtimeAttachments = readOptionalMcpAttachments(ctx, bridgeRuntimeAttachmentsKey, "bridge");
|
|
7595
7781
|
const modelCredential = validateBridgeModelCredential(base.modelCredential, base.bridgeUrl, "bridgeExecutor");
|
|
7596
7782
|
const effectiveProfile = agentProfileSchema.parse(spec.profile);
|
|
7597
7783
|
const model = bridgeProfileModel(effectiveProfile, "bridgeExecutor");
|
|
7598
7784
|
const harness = agentHarness(effectiveProfile.harness);
|
|
7599
7785
|
const providerModel = harness !== void 0 && model.startsWith(`${harness}/`) ? model.slice(harness.length + 1) : model;
|
|
7600
7786
|
const profileExecution = profileModelExecutionSettings(effectiveProfile, "bridgeExecutor");
|
|
7787
|
+
const bridgeTokenLimits = enforceTokenLimits(profileExecution.tokenLimits, "bridge", "bridgeExecutor");
|
|
7601
7788
|
const seam = {
|
|
7602
7789
|
...base,
|
|
7603
7790
|
...modelCredential === void 0 ? {} : { modelCredential },
|
|
7604
7791
|
model,
|
|
7605
7792
|
providerModel,
|
|
7606
|
-
...
|
|
7793
|
+
...bridgeTokenLimits.applied.maxTokens !== void 0 ? { maxTokens: bridgeTokenLimits.applied.maxTokens } : {}
|
|
7607
7794
|
};
|
|
7608
7795
|
if (!seam.bridgeUrl || !seam.bridgeBearer) throw new ValidationError("bridgeExecutor: bridgeUrl + bridgeBearer are required");
|
|
7609
7796
|
if (seam.timeoutMs !== void 0 && (!Number.isSafeInteger(seam.timeoutMs) || seam.timeoutMs < 1 || seam.timeoutMs > maxBridgeTimeoutMs)) throw new ValidationError(`bridgeExecutor: timeoutMs must be an integer from 1 to ${maxBridgeTimeoutMs}`);
|
|
@@ -7613,12 +7800,7 @@ const bridgeExecutor = (spec, ctx) => {
|
|
|
7613
7800
|
const sessionId = seam.sessionId ?? `bridge-${spec.profile.name ?? "worker"}-${randomUUID()}`;
|
|
7614
7801
|
const attemptId = ctx.node?.attemptId ?? newExecutionAttemptId(sessionId);
|
|
7615
7802
|
const traceHeaders = workerTraceHeaders(ctx);
|
|
7616
|
-
const controller =
|
|
7617
|
-
const abortIfSignalled = () => {
|
|
7618
|
-
if (ctx.signal.aborted) controller.abort();
|
|
7619
|
-
};
|
|
7620
|
-
abortIfSignalled();
|
|
7621
|
-
if (!ctx.signal.aborted) ctx.signal.addEventListener("abort", abortIfSignalled, { once: true });
|
|
7803
|
+
const controller = linkAbort(ctx.signal);
|
|
7622
7804
|
const inbox = createInbox();
|
|
7623
7805
|
let artifact;
|
|
7624
7806
|
const activeRuns = /* @__PURE__ */ new Map();
|
|
@@ -7651,7 +7833,7 @@ const bridgeExecutor = (spec, ctx) => {
|
|
|
7651
7833
|
maxReconnects,
|
|
7652
7834
|
timeoutMs: seam.timeoutMs ?? null,
|
|
7653
7835
|
streaming: true,
|
|
7654
|
-
|
|
7836
|
+
tokenLimits: bridgeTokenLimits,
|
|
7655
7837
|
terminalAcknowledgement: null
|
|
7656
7838
|
}
|
|
7657
7839
|
};
|
|
@@ -7697,11 +7879,16 @@ const bridgeExecutor = (spec, ctx) => {
|
|
|
7697
7879
|
}
|
|
7698
7880
|
},
|
|
7699
7881
|
traceSource: () => trace.source,
|
|
7882
|
+
interactive: () => Object.freeze({
|
|
7883
|
+
status: "unavailable",
|
|
7884
|
+
reason: "provider-has-no-interactive-contract"
|
|
7885
|
+
}),
|
|
7700
7886
|
execute(task, signal) {
|
|
7701
7887
|
return streamBridgeSession({
|
|
7702
7888
|
task,
|
|
7703
7889
|
signal,
|
|
7704
7890
|
...stopSignal === void 0 ? {} : { stopSignal },
|
|
7891
|
+
...runtimeAttachments === void 0 ? {} : { runtimeAttachments },
|
|
7705
7892
|
profile: effectiveProfile,
|
|
7706
7893
|
seam,
|
|
7707
7894
|
sessionId,
|
|
@@ -7738,6 +7925,41 @@ const bridgeExecutor = (spec, ctx) => {
|
|
|
7738
7925
|
}
|
|
7739
7926
|
});
|
|
7740
7927
|
},
|
|
7928
|
+
async cancel(request) {
|
|
7929
|
+
const live = [...activeRuns.values()].filter((run) => !run.terminal);
|
|
7930
|
+
const observedAt = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
7931
|
+
if (live.length === 0) return {
|
|
7932
|
+
status: "already-terminal",
|
|
7933
|
+
effect: "not_live",
|
|
7934
|
+
observedAt: observedAt(),
|
|
7935
|
+
detail: "every bridge run for this session was already terminal",
|
|
7936
|
+
evidence: { runs: [...activeRuns.keys()] }
|
|
7937
|
+
};
|
|
7938
|
+
controller.abort("executor cancelled");
|
|
7939
|
+
const grace = request.signal === void 0 ? "infinity" : BRIDGE_CANCEL_LONG_POLL_MS;
|
|
7940
|
+
const terminal = await Promise.all(live.map((run) => cancelBridgeRunToTerminal(seam, run, grace, request.signal)));
|
|
7941
|
+
const evidence = {
|
|
7942
|
+
operationId: request.operationId,
|
|
7943
|
+
runs: live.map((run, index) => ({
|
|
7944
|
+
id: run.id,
|
|
7945
|
+
terminal: terminal[index] === true
|
|
7946
|
+
}))
|
|
7947
|
+
};
|
|
7948
|
+
if (terminal.every(Boolean)) return {
|
|
7949
|
+
status: "accepted",
|
|
7950
|
+
effect: "cancelled",
|
|
7951
|
+
observedAt: observedAt(),
|
|
7952
|
+
detail: "the bridge reported every run terminal after the cancel operation",
|
|
7953
|
+
evidence
|
|
7954
|
+
};
|
|
7955
|
+
return {
|
|
7956
|
+
status: "unknown",
|
|
7957
|
+
effect: "cancel_requested",
|
|
7958
|
+
observedAt: observedAt(),
|
|
7959
|
+
detail: "the bridge accepted the cancel operation but a run had not reached terminal state within the deadline",
|
|
7960
|
+
evidence
|
|
7961
|
+
};
|
|
7962
|
+
},
|
|
7741
7963
|
async teardown(grace) {
|
|
7742
7964
|
controller.abort();
|
|
7743
7965
|
const remaining = [...activeRuns.values()].filter((run) => !run.terminal);
|
|
@@ -7803,6 +8025,78 @@ function scheduleBridgeRunStateRefresh(seam, activeRuns, observation) {
|
|
|
7803
8025
|
}
|
|
7804
8026
|
})();
|
|
7805
8027
|
}
|
|
8028
|
+
/** One bridge GET over the `node:http(s)` core client — the same transport every other bridge
|
|
8029
|
+
* read uses, so a computed provider endpoint never reaches global `fetch`. Resolves the status
|
|
8030
|
+
* and the body text; a transport failure rejects. */
|
|
8031
|
+
function bridgeGet(seam, path, timeoutMs) {
|
|
8032
|
+
const target = new URL(`${seam.bridgeUrl.replace(/\/$/, "")}${path}`);
|
|
8033
|
+
const requestFn = target.protocol === "https:" ? request$1 : request;
|
|
8034
|
+
return new Promise((resolve, reject) => {
|
|
8035
|
+
const req = requestFn(target, {
|
|
8036
|
+
method: "GET",
|
|
8037
|
+
headers: { authorization: `Bearer ${seam.bridgeBearer}` },
|
|
8038
|
+
timeout: timeoutMs
|
|
8039
|
+
}, (res) => {
|
|
8040
|
+
(async () => {
|
|
8041
|
+
const chunks = [];
|
|
8042
|
+
for await (const chunk of res) chunks.push(Buffer.from(chunk));
|
|
8043
|
+
resolve({
|
|
8044
|
+
status: res.statusCode ?? 0,
|
|
8045
|
+
body: Buffer.concat(chunks).toString("utf8")
|
|
8046
|
+
});
|
|
8047
|
+
})().catch(reject);
|
|
8048
|
+
});
|
|
8049
|
+
req.on("timeout", () => req.destroy(/* @__PURE__ */ new Error(`bridge GET ${path} timed out`)));
|
|
8050
|
+
req.on("error", reject);
|
|
8051
|
+
req.end();
|
|
8052
|
+
});
|
|
8053
|
+
}
|
|
8054
|
+
/**
|
|
8055
|
+
* `GET /v1/capabilities?model=<wire id>` — does this bridge route this model AT ALL.
|
|
8056
|
+
*
|
|
8057
|
+
* The bridge answers exactly this question and 404s `no backend matches model "…"`, which is the
|
|
8058
|
+
* error a child would otherwise discover after it was spawned and metered. Returns `undefined`
|
|
8059
|
+
* when the route resolves; otherwise the operator-facing reason it did not. FAIL CLOSED: a
|
|
8060
|
+
* transport error and an unexpected status are both reasons, never a silent pass.
|
|
8061
|
+
*/
|
|
8062
|
+
async function bridgeModelRouteRefusal(seam, wireModel) {
|
|
8063
|
+
const base = seam.bridgeUrl.replace(/\/$/, "");
|
|
8064
|
+
let answer;
|
|
8065
|
+
try {
|
|
8066
|
+
answer = await bridgeGet(seam, `/v1/capabilities?model=${encodeURIComponent(wireModel)}`, BRIDGE_RUN_STATE_TIMEOUT_MS);
|
|
8067
|
+
} catch (error) {
|
|
8068
|
+
return `bridge ${base} did not answer for model ${JSON.stringify(wireModel)}: ${error instanceof Error ? error.message : String(error)}`;
|
|
8069
|
+
}
|
|
8070
|
+
if (answer.status === 200) return void 0;
|
|
8071
|
+
return answer.status === 404 ? `bridge ${base} routes no backend for model ${JSON.stringify(wireModel)}` : `bridge ${base} answered ${answer.status} for model ${JSON.stringify(wireModel)}`;
|
|
8072
|
+
}
|
|
8073
|
+
/**
|
|
8074
|
+
* `GET /health` → `admission.{active,maxActive}`, or `undefined` when the bridge does not report
|
|
8075
|
+
* them. ADVISORY by nature — admission fills and drains — so an unanswered or admission-less
|
|
8076
|
+
* `/health` is not evidence about capacity and must not be read as one.
|
|
8077
|
+
*/
|
|
8078
|
+
async function bridgeAdmissionRead(seam) {
|
|
8079
|
+
let answer;
|
|
8080
|
+
try {
|
|
8081
|
+
answer = await bridgeGet(seam, "/health", BRIDGE_RUN_STATE_TIMEOUT_MS);
|
|
8082
|
+
} catch {
|
|
8083
|
+
return;
|
|
8084
|
+
}
|
|
8085
|
+
let parsed;
|
|
8086
|
+
try {
|
|
8087
|
+
parsed = JSON.parse(answer.body);
|
|
8088
|
+
} catch {
|
|
8089
|
+
return;
|
|
8090
|
+
}
|
|
8091
|
+
const admission = parsed?.admission;
|
|
8092
|
+
const active = admission?.active;
|
|
8093
|
+
const maxActive = admission?.maxActive;
|
|
8094
|
+
if (typeof active !== "number" || typeof maxActive !== "number" || maxActive <= 0) return;
|
|
8095
|
+
return {
|
|
8096
|
+
active,
|
|
8097
|
+
maxActive
|
|
8098
|
+
};
|
|
8099
|
+
}
|
|
7806
8100
|
/** `GET /v1/runs/:id` — the bridge's durable-run registry read. Resolves `undefined` for any
|
|
7807
8101
|
* non-200 or non-conforming body rather than throwing: this is only ever an observability read. */
|
|
7808
8102
|
function bridgeRunStateGet(seam, runId) {
|
|
@@ -7861,7 +8155,7 @@ function readBridgeRunState(runId, body) {
|
|
|
7861
8155
|
async function* streamBridgeSession(args) {
|
|
7862
8156
|
const { seam, inbox, observation } = args;
|
|
7863
8157
|
const started = Date.now();
|
|
7864
|
-
const external =
|
|
8158
|
+
const external = linkAbort(args.signal, args.controller.signal).signal;
|
|
7865
8159
|
const tokens = zeroTokenUsage();
|
|
7866
8160
|
let tokensKnown = true;
|
|
7867
8161
|
let usd = 0;
|
|
@@ -7935,6 +8229,7 @@ async function* streamBridgeSession(args) {
|
|
|
7935
8229
|
...seam.timeoutMs !== void 0 ? { timeoutMs: seam.timeoutMs } : {}
|
|
7936
8230
|
},
|
|
7937
8231
|
agent_profile: args.profile,
|
|
8232
|
+
...args.runtimeAttachments === void 0 ? {} : { runtime_attachments: { mcp: args.runtimeAttachments } },
|
|
7938
8233
|
messages
|
|
7939
8234
|
};
|
|
7940
8235
|
let turnText = "";
|
|
@@ -7943,6 +8238,7 @@ async function* streamBridgeSession(args) {
|
|
|
7943
8238
|
let sawTurnCostStatus = false;
|
|
7944
8239
|
let turnUsdKnown = true;
|
|
7945
8240
|
let turnKnownCostSubtotal = 0;
|
|
8241
|
+
let turnCostProvenance;
|
|
7946
8242
|
let turnEstimatedCostSubtotal = 0;
|
|
7947
8243
|
let turnInputTokens = 0;
|
|
7948
8244
|
let turnOutputTokens = 0;
|
|
@@ -7965,6 +8261,7 @@ async function* streamBridgeSession(args) {
|
|
|
7965
8261
|
profile: args.profile,
|
|
7966
8262
|
sessionId: args.sessionId,
|
|
7967
8263
|
body: requestBody,
|
|
8264
|
+
requiresRuntimeAttachments: args.runtimeAttachments !== void 0,
|
|
7968
8265
|
signal: turnController.signal,
|
|
7969
8266
|
run: activeRun,
|
|
7970
8267
|
maxReconnects: args.maxReconnects,
|
|
@@ -7989,9 +8286,22 @@ async function* streamBridgeSession(args) {
|
|
|
7989
8286
|
}
|
|
7990
8287
|
observedSystemFingerprint = chunk.systemFingerprint;
|
|
7991
8288
|
}
|
|
7992
|
-
if (chunk.content)
|
|
8289
|
+
if (chunk.content) {
|
|
8290
|
+
turnText += chunk.content;
|
|
8291
|
+
yield {
|
|
8292
|
+
kind: "progress",
|
|
8293
|
+
progress: {
|
|
8294
|
+
kind: "text_delta",
|
|
8295
|
+
text: chunk.content
|
|
8296
|
+
}
|
|
8297
|
+
};
|
|
8298
|
+
}
|
|
7993
8299
|
for (const step of chunk.toolCalls ?? []) {
|
|
7994
|
-
toolCalls.push(
|
|
8300
|
+
toolCalls.push({
|
|
8301
|
+
...step.callId === void 0 ? {} : { id: step.callId },
|
|
8302
|
+
name: step.toolName,
|
|
8303
|
+
arguments: step.args
|
|
8304
|
+
});
|
|
7995
8305
|
observation.activity.push({
|
|
7996
8306
|
at: Date.now(),
|
|
7997
8307
|
kind: "tool",
|
|
@@ -7999,6 +8309,15 @@ async function* streamBridgeSession(args) {
|
|
|
7999
8309
|
...describeToolArgs(step.args) ? { detail: describeToolArgs(step.args) } : {}
|
|
8000
8310
|
});
|
|
8001
8311
|
args.record(step);
|
|
8312
|
+
yield {
|
|
8313
|
+
kind: "progress",
|
|
8314
|
+
progress: {
|
|
8315
|
+
kind: "tool_call",
|
|
8316
|
+
toolName: step.toolName,
|
|
8317
|
+
...step.callId === void 0 ? {} : { toolCallId: step.callId },
|
|
8318
|
+
args: step.args
|
|
8319
|
+
}
|
|
8320
|
+
};
|
|
8002
8321
|
}
|
|
8003
8322
|
if (chunk.usage) {
|
|
8004
8323
|
sawTurnTokenUsage = true;
|
|
@@ -8022,6 +8341,7 @@ async function* streamBridgeSession(args) {
|
|
|
8022
8341
|
if (chunk.usage.promptCache.writeInput !== void 0) promptCache.writeTokens = (promptCache.writeTokens ?? 0) + chunk.usage.promptCache.writeInput;
|
|
8023
8342
|
}
|
|
8024
8343
|
}
|
|
8344
|
+
if (chunk.costProvenance !== void 0) turnCostProvenance = chunk.costProvenance;
|
|
8025
8345
|
if (chunk.costKnown !== void 0) {
|
|
8026
8346
|
sawTurnCostStatus = true;
|
|
8027
8347
|
if (!chunk.costKnown) turnUsdKnown = false;
|
|
@@ -8035,7 +8355,9 @@ async function* streamBridgeSession(args) {
|
|
|
8035
8355
|
usd += increment;
|
|
8036
8356
|
yield {
|
|
8037
8357
|
kind: "cost",
|
|
8038
|
-
|
|
8358
|
+
usdKnown: true,
|
|
8359
|
+
usd: increment,
|
|
8360
|
+
provenance: turnCostProvenance ?? "provider-receipt"
|
|
8039
8361
|
};
|
|
8040
8362
|
}
|
|
8041
8363
|
}
|
|
@@ -8080,9 +8402,10 @@ async function* streamBridgeSession(args) {
|
|
|
8080
8402
|
}) : {
|
|
8081
8403
|
kind: "cost",
|
|
8082
8404
|
usd: 0,
|
|
8083
|
-
usdKnown: false
|
|
8405
|
+
usdKnown: false,
|
|
8406
|
+
provenance: "uncaptured"
|
|
8084
8407
|
};
|
|
8085
|
-
if (priced.usdEstimated !== void 0) estimatedUsdCharged += priced.usdEstimated;
|
|
8408
|
+
if (priced.usdKnown === false && priced.usdEstimated !== void 0) estimatedUsdCharged += priced.usdEstimated;
|
|
8086
8409
|
usd += priced.usd;
|
|
8087
8410
|
yield priced;
|
|
8088
8411
|
}
|
|
@@ -8136,7 +8459,7 @@ const BRIDGE_BRUTAL_KILL_WAIT_MS = 150;
|
|
|
8136
8459
|
* cannot prove continuity fails instead of returning a plausible partial answer.
|
|
8137
8460
|
*/
|
|
8138
8461
|
async function* streamDurableBridgeRun(args) {
|
|
8139
|
-
await assertBridgeExecutionCapabilities(args.seam, args.signal);
|
|
8462
|
+
await assertBridgeExecutionCapabilities(args.seam, args.signal, args.requiresRuntimeAttachments);
|
|
8140
8463
|
let reconnects = 0;
|
|
8141
8464
|
let pendingUpstreamError;
|
|
8142
8465
|
for (;;) {
|
|
@@ -8215,7 +8538,7 @@ async function* streamDurableBridgeRun(args) {
|
|
|
8215
8538
|
* a process may restart behind the same URL, and a remembered capability from the prior process
|
|
8216
8539
|
* is not evidence about the process that will receive the next POST. The terminal receipt remains
|
|
8217
8540
|
* mandatory because the bridge can still restart between this GET and the run request. */
|
|
8218
|
-
async function assertBridgeExecutionCapabilities(seam, signal) {
|
|
8541
|
+
async function assertBridgeExecutionCapabilities(seam, signal, requiresRuntimeAttachments) {
|
|
8219
8542
|
const target = new URL(`${seam.bridgeUrl.replace(/\/$/, "")}/`);
|
|
8220
8543
|
const requestFn = target.protocol === "https:" ? request$1 : request;
|
|
8221
8544
|
const response = await new Promise((resolve, reject) => {
|
|
@@ -8256,6 +8579,10 @@ async function assertBridgeExecutionCapabilities(seam, signal) {
|
|
|
8256
8579
|
}
|
|
8257
8580
|
if (body.capabilities?.profileMaterialization !== bridgeProfileMaterializationSchema) throw new ValidationError(`bridgeExecutor: bridge does not advertise ${bridgeProfileMaterializationSchema}`);
|
|
8258
8581
|
if (body.capabilities?.usageCostProvenance !== bridgeUsageCostSchema) throw new ValidationError(`bridgeExecutor: bridge does not advertise ${bridgeUsageCostSchema}`);
|
|
8582
|
+
if (requiresRuntimeAttachments) {
|
|
8583
|
+
const attachments = body.capabilities?.runtimeAttachments;
|
|
8584
|
+
if (attachments === null || typeof attachments !== "object" || attachments.mcp !== true) throw new ValidationError(`bridgeExecutor: bridge at ${seam.bridgeUrl} does not advertise capabilities.runtimeAttachments.mcp; upgrade cli-bridge to a version that carries Runtime MCP attachments outside the bound AgentProfile`);
|
|
8585
|
+
}
|
|
8259
8586
|
}
|
|
8260
8587
|
/**
|
|
8261
8588
|
* POST one streamed turn to the cli-bridge over the `node:http(s)` core client
|
|
@@ -8865,6 +9192,7 @@ function applyBridgeCostReceipt(out, usage) {
|
|
|
8865
9192
|
if (cost === void 0 || provenance !== "provider-receipt" && provenance !== "billing-receipt" || estimatedCost !== void 0) throw new ValidationError("bridgeExecutor: known cost requires cost plus provider-receipt or billing-receipt provenance");
|
|
8866
9193
|
out.costKnown = true;
|
|
8867
9194
|
out.cost = cost;
|
|
9195
|
+
out.costProvenance = provenance;
|
|
8868
9196
|
return;
|
|
8869
9197
|
}
|
|
8870
9198
|
if (cost !== void 0) throw new ValidationError("bridgeExecutor: unknown cost cannot carry billed cost");
|
|
@@ -8955,7 +9283,7 @@ function bridgeWorktreeExecutor(spec, ctx, seam) {
|
|
|
8955
9283
|
execute(task, signal) {
|
|
8956
9284
|
return (async function* bridgeWorktreeStream() {
|
|
8957
9285
|
const started = Date.now();
|
|
8958
|
-
const linked =
|
|
9286
|
+
const linked = linkAbort(signal, controller.signal).signal;
|
|
8959
9287
|
let bridgeArtifact;
|
|
8960
9288
|
try {
|
|
8961
9289
|
worktree = await createWorktree({
|
|
@@ -9315,13 +9643,14 @@ function createExecutor(config) {
|
|
|
9315
9643
|
}
|
|
9316
9644
|
}
|
|
9317
9645
|
};
|
|
9318
|
-
|
|
9319
|
-
...
|
|
9320
|
-
|
|
9321
|
-
|
|
9322
|
-
|
|
9646
|
+
const executor = sandboxExecutor({
|
|
9647
|
+
...spec,
|
|
9648
|
+
harness
|
|
9649
|
+
}, providerCtx);
|
|
9650
|
+
return inheritRuntimeOwnedExecutorAttestation(executor, {
|
|
9651
|
+
...executor,
|
|
9323
9652
|
runtime: providerSeam.runtime ?? provider.name
|
|
9324
|
-
};
|
|
9653
|
+
});
|
|
9325
9654
|
}
|
|
9326
9655
|
const profileForCreate = providerSeam.profileForCreate;
|
|
9327
9656
|
return providerAsExecutor(provider, {
|
|
@@ -9423,6 +9752,15 @@ function readOptionalAbortSignal(ctx, key, who) {
|
|
|
9423
9752
|
if (value === null || typeof value !== "object" || typeof value.aborted !== "boolean" || typeof value.addEventListener !== "function") throw new ValidationError(`${who} executor: seam "${key}" must be an AbortSignal`);
|
|
9424
9753
|
return value;
|
|
9425
9754
|
}
|
|
9755
|
+
/** Narrow the Runtime-owned MCP attachment seam. Absent means the run mounts nothing; a present
|
|
9756
|
+
* value must be a named map of MCP servers, never an empty one that would silently mount nothing. */
|
|
9757
|
+
function readOptionalMcpAttachments(ctx, key, who) {
|
|
9758
|
+
const value = ctx.seams[key];
|
|
9759
|
+
if (value === void 0) return void 0;
|
|
9760
|
+
const entries = value !== null && typeof value === "object" && !Array.isArray(value) ? Object.entries(value) : void 0;
|
|
9761
|
+
if (entries === void 0 || entries.length === 0 || entries.some(([, server]) => server === null || typeof server !== "object")) throw new ValidationError(`${who} executor: seam ${JSON.stringify(key)} must be a non-empty map of MCP servers`);
|
|
9762
|
+
return value;
|
|
9763
|
+
}
|
|
9426
9764
|
/** A leaf task is opaque (`unknown`). A string is the prompt verbatim; an object
|
|
9427
9765
|
* with a `prompt`/`content`/`task` string field uses it; otherwise it serializes.
|
|
9428
9766
|
* Module-exported (not package surface) so sibling leaf executors read a task
|
|
@@ -9472,10 +9810,12 @@ function routerProfileExecution(profile, seam, mode) {
|
|
|
9472
9810
|
if (enabled && !suppliedNames.has(name)) throw new ValidationError(`routerInlineExecutor: AgentProfile enables tool ${JSON.stringify(name)} but the caller supplied no matching schema`);
|
|
9473
9811
|
if (!enabled && suppliedNames.has(name)) throw new ValidationError(`routerInlineExecutor: AgentProfile disables tool ${JSON.stringify(name)}`);
|
|
9474
9812
|
}
|
|
9813
|
+
const { tokenLimits, ...rest } = settings;
|
|
9475
9814
|
return {
|
|
9476
9815
|
systemPrompt: renderRouterProfilePrompt(profile),
|
|
9477
9816
|
...profileEffort ? { reasoningEffort: profileEffort } : {},
|
|
9478
|
-
...
|
|
9817
|
+
...rest,
|
|
9818
|
+
tokenLimits: enforceTokenLimits(tokenLimits, "router", "routerInlineExecutor")
|
|
9479
9819
|
};
|
|
9480
9820
|
}
|
|
9481
9821
|
/** Resolve the one model id that will cross the Router boundary from the exact profile only. */
|
|
@@ -9555,113 +9895,6 @@ function singleShotDriver(maxIterations) {
|
|
|
9555
9895
|
}
|
|
9556
9896
|
};
|
|
9557
9897
|
}
|
|
9558
|
-
/** Link two abort signals into one that fires when either does. Returns
|
|
9559
|
-
* `undefined` when neither is present so `fetch` gets no signal at all. */
|
|
9560
|
-
function linkSignals(a, b) {
|
|
9561
|
-
if (a.aborted || b.aborted) {
|
|
9562
|
-
const c = new AbortController();
|
|
9563
|
-
c.abort(abortReasonOf(a.aborted ? a : b));
|
|
9564
|
-
return c.signal;
|
|
9565
|
-
}
|
|
9566
|
-
const c = new AbortController();
|
|
9567
|
-
a.addEventListener("abort", () => c.abort(abortReasonOf(a)), { once: true });
|
|
9568
|
-
b.addEventListener("abort", () => c.abort(abortReasonOf(b)), { once: true });
|
|
9569
|
-
return c.signal;
|
|
9570
|
-
}
|
|
9571
|
-
/** The reason a signal carries, or a named fallback. A cascade that drops the upstream reason
|
|
9572
|
-
* turns every downstream death into the generic "execution aborted": the worker's `down`
|
|
9573
|
-
* record then says nothing about WHY, which is what makes a whole class of child mortality
|
|
9574
|
-
* undiagnosable from the journal alone. */
|
|
9575
|
-
function abortReasonOf(signal, fallback = "aborted by parent scope") {
|
|
9576
|
-
const reason = signal.reason;
|
|
9577
|
-
if (typeof reason === "string" && reason.length > 0) return reason;
|
|
9578
|
-
if (reason instanceof Error && reason.name !== "AbortError" && reason.message.length > 0) return reason.message;
|
|
9579
|
-
return fallback;
|
|
9580
|
-
}
|
|
9581
|
-
/** Combine N abort signals into one that fires when ANY does. Node-portable (no `AbortSignal.any`,
|
|
9582
|
-
* which needs >=20.3 — the package floor is >=20). Module-exported (not package surface) so
|
|
9583
|
-
* sibling leaf executors share the one portable implementation. */
|
|
9584
|
-
function mergeAbortSignals(...signals) {
|
|
9585
|
-
const c = new AbortController();
|
|
9586
|
-
const onAbort = () => c.abort();
|
|
9587
|
-
for (const s of signals) {
|
|
9588
|
-
if (s.aborted) {
|
|
9589
|
-
c.abort();
|
|
9590
|
-
break;
|
|
9591
|
-
}
|
|
9592
|
-
s.addEventListener("abort", onAbort, { once: true });
|
|
9593
|
-
}
|
|
9594
|
-
return c.signal;
|
|
9595
|
-
}
|
|
9596
|
-
//#endregion
|
|
9597
|
-
//#region src/runtime/supervise/abortable.ts
|
|
9598
|
-
/**
|
|
9599
|
-
* One abort race for the supervision tree.
|
|
9600
|
-
*
|
|
9601
|
-
* Every layer that can be cancelled needs the same two things: an `AbortError` that
|
|
9602
|
-
* carries the signal's own reason, and a settle-once race between the work and the
|
|
9603
|
-
* signal. Written per layer, the race drifts — the listener stops being removed on
|
|
9604
|
-
* one path, or a late resolution overwrites a cancellation that already won.
|
|
9605
|
-
*
|
|
9606
|
-
* The fallback message is the only thing a layer supplies, so the error still names
|
|
9607
|
-
* which layer cancelled.
|
|
9608
|
-
*/
|
|
9609
|
-
/** An `AbortError` carrying the signal's own string reason, or `fallback` when it states none. */
|
|
9610
|
-
function abortError(signal, fallback) {
|
|
9611
|
-
const reason = signal.reason;
|
|
9612
|
-
const error = new Error(typeof reason === "string" && reason.length > 0 ? reason : fallback);
|
|
9613
|
-
error.name = "AbortError";
|
|
9614
|
-
return error;
|
|
9615
|
-
}
|
|
9616
|
-
/**
|
|
9617
|
-
* Settle `act()` against `signal`. The first outcome wins and the listener is always
|
|
9618
|
-
* removed, so neither a late resolution nor a late abort can settle the promise twice.
|
|
9619
|
-
* The losing promise stays observed, so a late rejection cannot surface as an unhandled
|
|
9620
|
-
* process error.
|
|
9621
|
-
*
|
|
9622
|
-
* The abort rejection is deferred one microtask so a result the action had ALREADY
|
|
9623
|
-
* produced still wins. It does not hand the race to a listener the action registers
|
|
9624
|
-
* from inside `act()`: this function subscribes before it calls `act()`, so its own
|
|
9625
|
-
* abort handler runs first and settles the promise. A caller that must let the action
|
|
9626
|
-
* observe the abort itself has to hold a live promise and await that instead.
|
|
9627
|
-
*
|
|
9628
|
-
* A synchronous throw from `act()` propagates as the rejection, not as an abort.
|
|
9629
|
-
*/
|
|
9630
|
-
async function runAbortable(act, signal, fallback) {
|
|
9631
|
-
if (signal.aborted) throw abortError(signal, fallback);
|
|
9632
|
-
return await new Promise((resolve, reject) => {
|
|
9633
|
-
let settled = false;
|
|
9634
|
-
const cleanup = () => signal.removeEventListener("abort", onAbort);
|
|
9635
|
-
const onAbort = () => {
|
|
9636
|
-
queueMicrotask(() => {
|
|
9637
|
-
if (settled) return;
|
|
9638
|
-
settled = true;
|
|
9639
|
-
cleanup();
|
|
9640
|
-
reject(abortError(signal, fallback));
|
|
9641
|
-
});
|
|
9642
|
-
};
|
|
9643
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
9644
|
-
let work;
|
|
9645
|
-
try {
|
|
9646
|
-
work = Promise.resolve(act());
|
|
9647
|
-
} catch (error) {
|
|
9648
|
-
cleanup();
|
|
9649
|
-
reject(error);
|
|
9650
|
-
return;
|
|
9651
|
-
}
|
|
9652
|
-
work.then((value) => {
|
|
9653
|
-
if (settled) return;
|
|
9654
|
-
settled = true;
|
|
9655
|
-
cleanup();
|
|
9656
|
-
resolve(value);
|
|
9657
|
-
}, (error) => {
|
|
9658
|
-
if (settled) return;
|
|
9659
|
-
settled = true;
|
|
9660
|
-
cleanup();
|
|
9661
|
-
reject(error);
|
|
9662
|
-
});
|
|
9663
|
-
});
|
|
9664
|
-
}
|
|
9665
9898
|
//#endregion
|
|
9666
9899
|
//#region src/runtime/supervise/budget.ts
|
|
9667
9900
|
/**
|
|
@@ -9758,56 +9991,61 @@ function assertValidSpend(spend, label) {
|
|
|
9758
9991
|
* channels; iterations come from `'iteration'` events. Pure; `ms` stays zero (the
|
|
9759
9992
|
* pool does not read wall-clock). */
|
|
9760
9993
|
function spendFromUsageEvents(events) {
|
|
9761
|
-
const
|
|
9762
|
-
|
|
9763
|
-
|
|
9764
|
-
|
|
9765
|
-
|
|
9766
|
-
|
|
9767
|
-
for (const ev of events) if (ev.kind === "tokens") {
|
|
9768
|
-
addTokenUsage(tokens, ev);
|
|
9769
|
-
if (ev.tokensKnown === false) tokensKnown = false;
|
|
9770
|
-
} else if (ev.kind === "cost") {
|
|
9771
|
-
usd += ev.usd;
|
|
9772
|
-
usdEstimated += ev.usdEstimated ?? 0;
|
|
9773
|
-
if (ev.usdKnown === false) usdKnown = false;
|
|
9774
|
-
} else iterations += 1;
|
|
9994
|
+
const totals = newUsageTotals();
|
|
9995
|
+
for (const ev of events) meterUsageEvent(totals, ev);
|
|
9996
|
+
return spendFromUsageTotals(totals);
|
|
9997
|
+
}
|
|
9998
|
+
/** Fresh zeroed {@link UsageTotals}. */
|
|
9999
|
+
function newUsageTotals() {
|
|
9775
10000
|
return {
|
|
9776
|
-
|
|
9777
|
-
|
|
9778
|
-
|
|
9779
|
-
|
|
9780
|
-
|
|
9781
|
-
|
|
9782
|
-
ms: 0
|
|
10001
|
+
tokens: zeroTokenUsage(),
|
|
10002
|
+
tokensKnown: true,
|
|
10003
|
+
usd: 0,
|
|
10004
|
+
usdEstimated: 0,
|
|
10005
|
+
usdKnown: true,
|
|
10006
|
+
iterations: 0
|
|
9783
10007
|
};
|
|
9784
10008
|
}
|
|
9785
|
-
|
|
9786
|
-
|
|
9787
|
-
|
|
9788
|
-
|
|
9789
|
-
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
|
|
9793
|
-
|
|
9794
|
-
|
|
9795
|
-
|
|
9796
|
-
|
|
9797
|
-
usd += ev.usd;
|
|
9798
|
-
|
|
9799
|
-
|
|
9800
|
-
|
|
10009
|
+
/**
|
|
10010
|
+
* Fold ONE usage event into running totals — the single place that decides which event kinds
|
|
10011
|
+
* meter. `progress` carries observed output rather than accounting, so it meters nothing; only
|
|
10012
|
+
* `iteration` advances the iteration count.
|
|
10013
|
+
*/
|
|
10014
|
+
function meterUsageEvent(totals, ev) {
|
|
10015
|
+
if (ev.kind === "tokens") {
|
|
10016
|
+
addTokenUsage(totals.tokens, ev);
|
|
10017
|
+
if (ev.tokensKnown === false) totals.tokensKnown = false;
|
|
10018
|
+
return;
|
|
10019
|
+
}
|
|
10020
|
+
if (ev.kind === "cost") {
|
|
10021
|
+
totals.usd += ev.usd;
|
|
10022
|
+
if (ev.usdKnown === false) {
|
|
10023
|
+
totals.usdEstimated += ev.usdEstimated ?? 0;
|
|
10024
|
+
totals.usdKnown = false;
|
|
10025
|
+
}
|
|
10026
|
+
return;
|
|
10027
|
+
}
|
|
10028
|
+
if (ev.kind === "iteration") totals.iterations += 1;
|
|
10029
|
+
}
|
|
10030
|
+
/** Project folded totals onto the conserved-pool `Spend`. `ms` stays zero — the pool does not
|
|
10031
|
+
* read wall-clock. */
|
|
10032
|
+
function spendFromUsageTotals(totals) {
|
|
9801
10033
|
return {
|
|
9802
|
-
iterations,
|
|
9803
|
-
tokens,
|
|
9804
|
-
...tokensKnown ? {} : { tokensKnown: false },
|
|
9805
|
-
usd,
|
|
9806
|
-
...usdKnown ? {} : { usdKnown: false },
|
|
9807
|
-
...usdEstimated > 0 ? { usdEstimated } : {},
|
|
10034
|
+
iterations: totals.iterations,
|
|
10035
|
+
tokens: totals.tokens,
|
|
10036
|
+
...totals.tokensKnown ? {} : { tokensKnown: false },
|
|
10037
|
+
usd: totals.usd,
|
|
10038
|
+
...totals.usdKnown ? {} : { usdKnown: false },
|
|
10039
|
+
...totals.usdEstimated > 0 ? { usdEstimated: totals.usdEstimated } : {},
|
|
9808
10040
|
ms: 0
|
|
9809
10041
|
};
|
|
9810
10042
|
}
|
|
10043
|
+
async function foldUsage(events) {
|
|
10044
|
+
if (Array.isArray(events)) return spendFromUsageEvents(events);
|
|
10045
|
+
const totals = newUsageTotals();
|
|
10046
|
+
for await (const ev of events) meterUsageEvent(totals, ev);
|
|
10047
|
+
return spendFromUsageTotals(totals);
|
|
10048
|
+
}
|
|
9811
10049
|
/**
|
|
9812
10050
|
* Create a conserved reservation pool from a root `Budget`. `now()` is injected so the
|
|
9813
10051
|
* deadline readout is deterministic; defaults to `Date.now` for non-test callers. The
|
|
@@ -10610,7 +10848,7 @@ function createScope(args) {
|
|
|
10610
10848
|
spec = prepared.spec;
|
|
10611
10849
|
identity = prepared.identity;
|
|
10612
10850
|
if (opts.key !== void 0 && !isCompleteIdentity(identity)) {
|
|
10613
|
-
args.pool.reconcile(reservation.ticket, zeroSpend
|
|
10851
|
+
args.pool.reconcile(reservation.ticket, zeroSpend());
|
|
10614
10852
|
permit.release();
|
|
10615
10853
|
return {
|
|
10616
10854
|
ok: false,
|
|
@@ -10621,7 +10859,7 @@ function createScope(args) {
|
|
|
10621
10859
|
if (!outcome.succeeded) throw new ValidationError(`scope.spawn: ${outcome.error}`);
|
|
10622
10860
|
resolved = outcome;
|
|
10623
10861
|
} catch (error) {
|
|
10624
|
-
args.pool.reconcile(reservation.ticket, zeroSpend
|
|
10862
|
+
args.pool.reconcile(reservation.ticket, zeroSpend());
|
|
10625
10863
|
permit.release();
|
|
10626
10864
|
throw error;
|
|
10627
10865
|
}
|
|
@@ -10686,7 +10924,7 @@ function createScope(args) {
|
|
|
10686
10924
|
label: opts.label,
|
|
10687
10925
|
...opts.assignmentId === void 0 ? {} : { assignmentId: opts.assignmentId },
|
|
10688
10926
|
...opts.key !== void 0 ? { key: opts.key } : {},
|
|
10689
|
-
spent: zeroSpend
|
|
10927
|
+
spent: zeroSpend(),
|
|
10690
10928
|
settled: void 0,
|
|
10691
10929
|
delivered: false,
|
|
10692
10930
|
executorDone: false,
|
|
@@ -10696,7 +10934,10 @@ function createScope(args) {
|
|
|
10696
10934
|
lastActivityAt: startedAt,
|
|
10697
10935
|
...executor.deliver ? { deliver: (message) => executor.deliver?.(message) !== false } : {},
|
|
10698
10936
|
...executor.progress ? { readProgress: executor.progress.bind(executor) } : {},
|
|
10699
|
-
...executor.traceSource ? { readTraceSource: executor.traceSource.bind(executor) } : {}
|
|
10937
|
+
...executor.traceSource ? { readTraceSource: executor.traceSource.bind(executor) } : {},
|
|
10938
|
+
...executor.interactive ? { readInteractive: executor.interactive.bind(executor) } : {},
|
|
10939
|
+
...executor.cancel ? { requestCancel: executor.cancel.bind(executor) } : {},
|
|
10940
|
+
abortChild: (reason) => controller.abort(reason)
|
|
10700
10941
|
};
|
|
10701
10942
|
children.set(id, live);
|
|
10702
10943
|
if (opts.key !== void 0) keyed.set(opts.key, {
|
|
@@ -10704,7 +10945,8 @@ function createScope(args) {
|
|
|
10704
10945
|
id,
|
|
10705
10946
|
identity
|
|
10706
10947
|
});
|
|
10707
|
-
const
|
|
10948
|
+
const profileRef = contentAddress(spec.profile);
|
|
10949
|
+
const spawnCommitted = args.blobs.put(profileRef, spec.profile).then(() => args.journal.appendEvent(args.root, {
|
|
10708
10950
|
kind: "spawned",
|
|
10709
10951
|
id,
|
|
10710
10952
|
parent: args.parentId,
|
|
@@ -10715,9 +10957,10 @@ function createScope(args) {
|
|
|
10715
10957
|
runtime: executor.runtime,
|
|
10716
10958
|
...ownedTreeRoot === void 0 ? {} : { ownedTreeRoot },
|
|
10717
10959
|
...identity ? { identity } : {},
|
|
10960
|
+
profileRef,
|
|
10718
10961
|
seq: ordinal,
|
|
10719
10962
|
at: new Date(now()).toISOString()
|
|
10720
|
-
}).then(async () => {
|
|
10963
|
+
})).then(async () => {
|
|
10721
10964
|
if (args.workerTraceUnpropagated === void 0 || workerTrace === void 0) return;
|
|
10722
10965
|
await args.journal.appendEvent(args.root, {
|
|
10723
10966
|
kind: "trace-unpropagated",
|
|
@@ -10850,7 +11093,9 @@ function createScope(args) {
|
|
|
10850
11093
|
runtime: executor.runtime,
|
|
10851
11094
|
...identity ? { identity } : {},
|
|
10852
11095
|
budget: opts.budget,
|
|
10853
|
-
depth: args.depth
|
|
11096
|
+
depth: args.depth,
|
|
11097
|
+
attemptId,
|
|
11098
|
+
startedAt
|
|
10854
11099
|
}
|
|
10855
11100
|
}, { signal: args.signal });
|
|
10856
11101
|
live.settled = runChild(live, executor, controller, task, opts, args.pool, reservation.ticket, args.blobs, now, materializationCommitted, {
|
|
@@ -10873,7 +11118,7 @@ function createScope(args) {
|
|
|
10873
11118
|
permit.release();
|
|
10874
11119
|
clearChildDeadline?.();
|
|
10875
11120
|
if (cascadeAbort) args.signal.removeEventListener("abort", cascadeAbort);
|
|
10876
|
-
args.pool.reconcile(reservation.ticket, zeroSpend
|
|
11121
|
+
args.pool.reconcile(reservation.ticket, zeroSpend());
|
|
10877
11122
|
throw err;
|
|
10878
11123
|
}
|
|
10879
11124
|
}
|
|
@@ -10967,12 +11212,13 @@ function createScope(args) {
|
|
|
10967
11212
|
id,
|
|
10968
11213
|
status: "waiting",
|
|
10969
11214
|
runtime: "wait",
|
|
11215
|
+
abortChild: (reason) => waitAbort.abort(reason),
|
|
10970
11216
|
budget: {
|
|
10971
11217
|
maxIterations: 0,
|
|
10972
11218
|
maxTokens: 0
|
|
10973
11219
|
},
|
|
10974
11220
|
label: opts.label,
|
|
10975
|
-
spent: zeroSpend
|
|
11221
|
+
spent: zeroSpend(),
|
|
10976
11222
|
settled: void 0,
|
|
10977
11223
|
delivered: false,
|
|
10978
11224
|
executorDone: false,
|
|
@@ -11045,7 +11291,7 @@ function createScope(args) {
|
|
|
11045
11291
|
kind: "done",
|
|
11046
11292
|
out: resolution.outcome,
|
|
11047
11293
|
outRef,
|
|
11048
|
-
spent: zeroSpend
|
|
11294
|
+
spent: zeroSpend(),
|
|
11049
11295
|
trace: {
|
|
11050
11296
|
status: "unavailable",
|
|
11051
11297
|
reason: "not-an-executor"
|
|
@@ -11096,6 +11342,18 @@ function createScope(args) {
|
|
|
11096
11342
|
...child.spent.usdKnown === false ? { usdKnown: false } : {}
|
|
11097
11343
|
}, fromExecutor, opts.now ?? now(), opts.stallAfterMs ?? 18e4);
|
|
11098
11344
|
}
|
|
11345
|
+
async function cancel(nodeId, request) {
|
|
11346
|
+
const child = children.get(nodeId);
|
|
11347
|
+
if (!child) throw new ValidationError(`scope.cancel: unknown node ${JSON.stringify(nodeId)}`);
|
|
11348
|
+
if (child.requestCancel) return await child.requestCancel(request);
|
|
11349
|
+
child.abortChild("cancelled");
|
|
11350
|
+
return {
|
|
11351
|
+
status: "unknown",
|
|
11352
|
+
effect: "cancel_requested",
|
|
11353
|
+
observedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
11354
|
+
detail: `executor runtime ${JSON.stringify(child.runtime ?? "unknown")} exposes no cancellation operation; the child was aborted locally`
|
|
11355
|
+
};
|
|
11356
|
+
}
|
|
11099
11357
|
function traceSource(nodeId) {
|
|
11100
11358
|
const child = children.get(nodeId);
|
|
11101
11359
|
if (!child) return void 0;
|
|
@@ -11105,6 +11363,21 @@ function createScope(args) {
|
|
|
11105
11363
|
return;
|
|
11106
11364
|
}
|
|
11107
11365
|
}
|
|
11366
|
+
function interactive(nodeId) {
|
|
11367
|
+
const child = children.get(nodeId);
|
|
11368
|
+
if (!child) return noInteractiveSession("unknown-node");
|
|
11369
|
+
if (child.wait || child.executorDone || isTerminalNodeStatus(child.status)) return noInteractiveSession("not-live");
|
|
11370
|
+
if (!child.readInteractive) return noInteractiveSession("executor-exposes-no-interactive-session");
|
|
11371
|
+
let reported;
|
|
11372
|
+
try {
|
|
11373
|
+
reported = child.readInteractive();
|
|
11374
|
+
} catch {
|
|
11375
|
+
return noInteractiveSession("executor-exposes-no-interactive-session");
|
|
11376
|
+
}
|
|
11377
|
+
if (reported?.status === "unavailable" && reported.reason) return reported;
|
|
11378
|
+
if (reported?.status === "available" && reported.handle) return reported;
|
|
11379
|
+
return noInteractiveSession("executor-exposes-no-interactive-session");
|
|
11380
|
+
}
|
|
11108
11381
|
async function meterInternal(spend, detail, providerModel, accountingOnly = false) {
|
|
11109
11382
|
if (args.signal.aborted) throw new ValidationError("scope.meter: cannot record new driver work after scope abort");
|
|
11110
11383
|
const seq = meterSeq++;
|
|
@@ -11152,6 +11425,8 @@ function createScope(args) {
|
|
|
11152
11425
|
wait,
|
|
11153
11426
|
progress,
|
|
11154
11427
|
traceSource,
|
|
11428
|
+
interactive,
|
|
11429
|
+
cancel,
|
|
11155
11430
|
signal: args.signal,
|
|
11156
11431
|
meter: (spend, detail) => meterInternal(spend, detail),
|
|
11157
11432
|
...resume ? { resume } : {},
|
|
@@ -11164,7 +11439,13 @@ function createScope(args) {
|
|
|
11164
11439
|
get workerCapacity() {
|
|
11165
11440
|
return {
|
|
11166
11441
|
live: liveWorkerCapacity.live,
|
|
11167
|
-
freeSlots: freeSlots(liveWorkerCapacity.live, liveWorkerCapacity.max)
|
|
11442
|
+
freeSlots: freeSlots(liveWorkerCapacity.live, liveWorkerCapacity.max),
|
|
11443
|
+
unconfirmed: Object.freeze([...children.values()].filter((child) => isTerminalNodeStatus(child.status) && !child.cleanupConfirmed).map((child) => Object.freeze({
|
|
11444
|
+
id: child.id,
|
|
11445
|
+
label: child.label,
|
|
11446
|
+
runtime: child.runtime,
|
|
11447
|
+
status: child.status
|
|
11448
|
+
})))
|
|
11168
11449
|
};
|
|
11169
11450
|
}
|
|
11170
11451
|
};
|
|
@@ -11404,7 +11685,9 @@ async function finalizeSettlement(child, settlement, seq, args, now) {
|
|
|
11404
11685
|
status: "down",
|
|
11405
11686
|
reason: settlement.reason,
|
|
11406
11687
|
infra: settlement.infra,
|
|
11407
|
-
spent: child.spent
|
|
11688
|
+
spent: child.spent,
|
|
11689
|
+
restartCount: settlement.restartCount,
|
|
11690
|
+
...settledNodeEvidence(child, settlement, settledAt)
|
|
11408
11691
|
}
|
|
11409
11692
|
}, { signal: args.signal });
|
|
11410
11693
|
return {
|
|
@@ -11457,7 +11740,8 @@ async function finalizeSettlement(child, settlement, seq, args, now) {
|
|
|
11457
11740
|
outRef: settlement.outRef,
|
|
11458
11741
|
score: settlement.verdict?.score,
|
|
11459
11742
|
valid: settlement.verdict?.valid,
|
|
11460
|
-
spent: settlement.spent
|
|
11743
|
+
spent: settlement.spent,
|
|
11744
|
+
...settledNodeEvidence(child, settlement, settledAt)
|
|
11461
11745
|
}
|
|
11462
11746
|
}, { signal: args.signal });
|
|
11463
11747
|
return {
|
|
@@ -11473,6 +11757,26 @@ async function finalizeSettlement(child, settlement, seq, args, now) {
|
|
|
11473
11757
|
seq
|
|
11474
11758
|
};
|
|
11475
11759
|
}
|
|
11760
|
+
/**
|
|
11761
|
+
* The evidence a settled node carries beyond its status: the receipts that name what actually
|
|
11762
|
+
* ran, the own-inference spend the parent tree re-homes as a `metered` event, and the wall-clock
|
|
11763
|
+
* window. One builder feeds BOTH terminal paths, so an observer never sees a `down` node
|
|
11764
|
+
* described in different terms from a `done` one. Every field is omitted when the fact is
|
|
11765
|
+
* absent — an unreported receipt must not read as an empty one. Snapshots are detached because
|
|
11766
|
+
* an observer may serialize them after the live child has moved on.
|
|
11767
|
+
*/
|
|
11768
|
+
function settledNodeEvidence(child, settlement, settledAt) {
|
|
11769
|
+
return {
|
|
11770
|
+
runtime: child.runtime,
|
|
11771
|
+
startedAt: child.startedAt,
|
|
11772
|
+
settledAt,
|
|
11773
|
+
...settlement.metered ? { metered: detachedSnapshot(settlement.metered, "metered") } : {},
|
|
11774
|
+
...child.providerModel ? { providerModel: detachedSnapshot(child.providerModel, "provider model evidence") } : {},
|
|
11775
|
+
...child.materialization ? { materialization: detachedSnapshot(child.materialization, "materialization receipt") } : {},
|
|
11776
|
+
...child.executionBindings.length > 0 ? { executionBindings: detachedSnapshot([...child.executionBindings], "execution binding receipts") } : {},
|
|
11777
|
+
trace: detachedSnapshot(settlement.trace, "worker trace evidence")
|
|
11778
|
+
};
|
|
11779
|
+
}
|
|
11476
11780
|
/** Journal a wait-state's settlement as a `woken` event and project it onto the same `Settled`
|
|
11477
11781
|
* the driver branches on. `by` names WHY it woke — `fired` / `timeout` / `cancelled` — which is
|
|
11478
11782
|
* the fact a resumed reader needs and cannot recover from a payload it may never fetch. */
|
|
@@ -11784,30 +12088,20 @@ function freezeCorrelation(value) {
|
|
|
11784
12088
|
* now reconciles its real partial spend instead of refunding work the provider already billed.
|
|
11785
12089
|
*/
|
|
11786
12090
|
async function foldStream(stream, onProgress, signal) {
|
|
11787
|
-
const
|
|
11788
|
-
let tokensKnown = true;
|
|
11789
|
-
let usd = 0;
|
|
11790
|
-
let usdKnown = true;
|
|
11791
|
-
let iterations = 0;
|
|
12091
|
+
const totals = newUsageTotals();
|
|
11792
12092
|
const iterator = stream[Symbol.asyncIterator]();
|
|
11793
12093
|
try {
|
|
11794
12094
|
for (;;) {
|
|
11795
12095
|
const next = signal ? await awaitAbortable(Promise.resolve(iterator.next()), signal) : await iterator.next();
|
|
11796
12096
|
if (next.done) break;
|
|
11797
12097
|
const ev = next.value;
|
|
11798
|
-
|
|
11799
|
-
addTokenUsage(tokens, ev);
|
|
11800
|
-
if (ev.tokensKnown === false) tokensKnown = false;
|
|
11801
|
-
} else if (ev.kind === "cost") {
|
|
11802
|
-
usd += ev.usd;
|
|
11803
|
-
if (ev.usdKnown === false) usdKnown = false;
|
|
11804
|
-
} else iterations += 1;
|
|
12098
|
+
meterUsageEvent(totals, ev);
|
|
11805
12099
|
onProgress?.({
|
|
11806
|
-
iterations,
|
|
11807
|
-
tokens: cloneTokenUsage(tokens),
|
|
11808
|
-
...tokensKnown ? {} : { tokensKnown: false },
|
|
11809
|
-
usd,
|
|
11810
|
-
...usdKnown ? {} : { usdKnown: false },
|
|
12100
|
+
iterations: totals.iterations,
|
|
12101
|
+
tokens: cloneTokenUsage(totals.tokens),
|
|
12102
|
+
...totals.tokensKnown ? {} : { tokensKnown: false },
|
|
12103
|
+
usd: totals.usd,
|
|
12104
|
+
...totals.usdKnown ? {} : { usdKnown: false },
|
|
11811
12105
|
ms: 0
|
|
11812
12106
|
});
|
|
11813
12107
|
}
|
|
@@ -11815,14 +12109,7 @@ async function foldStream(stream, onProgress, signal) {
|
|
|
11815
12109
|
Promise.resolve(iterator.return?.()).catch(() => void 0);
|
|
11816
12110
|
throw error;
|
|
11817
12111
|
}
|
|
11818
|
-
return
|
|
11819
|
-
iterations,
|
|
11820
|
-
tokens,
|
|
11821
|
-
...tokensKnown ? {} : { tokensKnown: false },
|
|
11822
|
-
usd,
|
|
11823
|
-
...usdKnown ? {} : { usdKnown: false },
|
|
11824
|
-
ms: 0
|
|
11825
|
-
};
|
|
12112
|
+
return spendFromUsageTotals(totals);
|
|
11826
12113
|
}
|
|
11827
12114
|
/** Usage events carry measured increments; the terminal artifact carries whether a provider omitted
|
|
11828
12115
|
* a whole accounting channel. Preserve those unknowns on the common streaming path. */
|
|
@@ -11883,13 +12170,12 @@ function downRecord(reason, infra, trace, metered, providerModel) {
|
|
|
11883
12170
|
...metered ? { metered } : {}
|
|
11884
12171
|
};
|
|
11885
12172
|
}
|
|
11886
|
-
|
|
11887
|
-
|
|
11888
|
-
|
|
11889
|
-
|
|
11890
|
-
|
|
11891
|
-
|
|
11892
|
-
};
|
|
12173
|
+
/** The one place an absent interactive process is spelled, so every refusal reads the same. */
|
|
12174
|
+
function noInteractiveSession(reason) {
|
|
12175
|
+
return Object.freeze({
|
|
12176
|
+
status: "unavailable",
|
|
12177
|
+
reason
|
|
12178
|
+
});
|
|
11893
12179
|
}
|
|
11894
12180
|
function isAsyncIterable(value) {
|
|
11895
12181
|
return typeof value === "object" && value !== null && typeof value[Symbol.asyncIterator] === "function";
|
|
@@ -12008,7 +12294,7 @@ const driverExecutorFactory = (rawSpec, ctx) => {
|
|
|
12008
12294
|
meteredSpend = nonZeroOrUndef(sumMetered(events));
|
|
12009
12295
|
accounting = {
|
|
12010
12296
|
reported: childWork,
|
|
12011
|
-
reservation: addSpend
|
|
12297
|
+
reservation: addSpend(childWork, meteredSpend ?? zeroSpend())
|
|
12012
12298
|
};
|
|
12013
12299
|
const verdict = deriveDeliveryVerdict(settled, out);
|
|
12014
12300
|
artifact = {
|
|
@@ -12092,64 +12378,13 @@ function isSettled(ev) {
|
|
|
12092
12378
|
/** Sum the conserved spend over the nested tree's settled events — the honest per-channel
|
|
12093
12379
|
* roll-up of the whole sub-tree's child WORK. */
|
|
12094
12380
|
function sumSpend(settled) {
|
|
12095
|
-
|
|
12096
|
-
iterations: 0,
|
|
12097
|
-
tokens: zeroTokenUsage(),
|
|
12098
|
-
usd: 0,
|
|
12099
|
-
ms: 0
|
|
12100
|
-
};
|
|
12101
|
-
for (const ev of settled) {
|
|
12102
|
-
total.iterations += ev.spent.iterations;
|
|
12103
|
-
addTokenUsage(total.tokens, ev.spent.tokens);
|
|
12104
|
-
if (ev.spent.tokensKnown === false) total.tokensKnown = false;
|
|
12105
|
-
total.usd += ev.spent.usd;
|
|
12106
|
-
if (ev.spent.usdKnown === false) total.usdKnown = false;
|
|
12107
|
-
total.ms += ev.spent.ms;
|
|
12108
|
-
}
|
|
12109
|
-
return total;
|
|
12381
|
+
return settled.reduce((total, ev) => addSpend(total, ev.spent), zeroSpend());
|
|
12110
12382
|
}
|
|
12111
12383
|
/** Sum the nested tree's `metered` events — the sub-tree's whole driver INFERENCE (this driver's
|
|
12112
12384
|
* own turns + any sub-driver inference already re-homed into this tree). Re-homed up to the parent
|
|
12113
12385
|
* as one `metered` event; never reconciled (already pool-debited live via `observe`). */
|
|
12114
12386
|
function sumMetered(events) {
|
|
12115
|
-
|
|
12116
|
-
iterations: 0,
|
|
12117
|
-
tokens: zeroTokenUsage(),
|
|
12118
|
-
usd: 0,
|
|
12119
|
-
ms: 0
|
|
12120
|
-
};
|
|
12121
|
-
for (const ev of events) {
|
|
12122
|
-
if (ev.kind !== "metered") continue;
|
|
12123
|
-
total.iterations += ev.spend.iterations;
|
|
12124
|
-
addTokenUsage(total.tokens, ev.spend.tokens);
|
|
12125
|
-
if (ev.spend.tokensKnown === false) total.tokensKnown = false;
|
|
12126
|
-
total.usd += ev.spend.usd;
|
|
12127
|
-
if (ev.spend.usdKnown === false) total.usdKnown = false;
|
|
12128
|
-
total.ms += ev.spend.ms;
|
|
12129
|
-
}
|
|
12130
|
-
return total;
|
|
12131
|
-
}
|
|
12132
|
-
function zeroSpend() {
|
|
12133
|
-
return {
|
|
12134
|
-
iterations: 0,
|
|
12135
|
-
tokens: zeroTokenUsage(),
|
|
12136
|
-
usd: 0,
|
|
12137
|
-
ms: 0
|
|
12138
|
-
};
|
|
12139
|
-
}
|
|
12140
|
-
function addSpend$1(a, b) {
|
|
12141
|
-
return {
|
|
12142
|
-
iterations: a.iterations + b.iterations,
|
|
12143
|
-
tokens: (() => {
|
|
12144
|
-
const tokens = cloneTokenUsage(a.tokens);
|
|
12145
|
-
addTokenUsage(tokens, b.tokens);
|
|
12146
|
-
return tokens;
|
|
12147
|
-
})(),
|
|
12148
|
-
...a.tokensKnown === false || b.tokensKnown === false ? { tokensKnown: false } : {},
|
|
12149
|
-
usd: a.usd + b.usd,
|
|
12150
|
-
...a.usdKnown === false || b.usdKnown === false ? { usdKnown: false } : {},
|
|
12151
|
-
ms: a.ms + b.ms
|
|
12152
|
-
};
|
|
12387
|
+
return events.reduce((total, ev) => ev.kind === "metered" ? addSpend(total, ev.spend) : total, zeroSpend());
|
|
12153
12388
|
}
|
|
12154
12389
|
/** An all-zero spend that carries an UNKNOWN marker counts as non-zero: a sub-driver whose turns
|
|
12155
12390
|
* went unmeasured did real work, and dropping its `metered` event here would re-hide upstream the
|
|
@@ -12173,7 +12408,7 @@ async function safeRollup(journal, nestedRoot) {
|
|
|
12173
12408
|
metered,
|
|
12174
12409
|
accounting: {
|
|
12175
12410
|
reported: childWork,
|
|
12176
|
-
reservation: addSpend
|
|
12411
|
+
reservation: addSpend(childWork, metered ?? zeroSpend())
|
|
12177
12412
|
}
|
|
12178
12413
|
};
|
|
12179
12414
|
} catch {
|
|
@@ -12491,7 +12726,7 @@ function rootDeadline(root) {
|
|
|
12491
12726
|
}
|
|
12492
12727
|
/** Child reservations whose spawn was durable but whose terminal record never landed. */
|
|
12493
12728
|
function uncertainSpawnBudgets(events) {
|
|
12494
|
-
const terminal = new Set(events.filter(
|
|
12729
|
+
const terminal = new Set(events.filter(closesCursorSlot).map((event) => event.id));
|
|
12495
12730
|
return events.filter((event) => event.kind === "spawned" && event.parent !== void 0 && !terminal.has(event.id)).map((event) => event.budget);
|
|
12496
12731
|
}
|
|
12497
12732
|
/** Highest `seq` among events matching `pred`, or `-1` when none match (so a resumed scope's
|
|
@@ -12591,7 +12826,7 @@ function createSupervisor() {
|
|
|
12591
12826
|
settled,
|
|
12592
12827
|
view: materializeTreeView(prior),
|
|
12593
12828
|
maxSpawnOrdinal: maxSeqOf(prior, (ev) => ev.kind === "spawned"),
|
|
12594
|
-
maxCursorSeq: maxSeqOf(prior,
|
|
12829
|
+
maxCursorSeq: maxSeqOf(prior, closesCursorSlot),
|
|
12595
12830
|
maxWaitOrdinal: maxSeqOf(prior, (ev) => ev.kind === "waiting"),
|
|
12596
12831
|
waits: pendingWaits(prior),
|
|
12597
12832
|
keys: keyedAssignments(prior, settled),
|
|
@@ -12686,6 +12921,8 @@ function createSupervisor() {
|
|
|
12686
12921
|
ok: false,
|
|
12687
12922
|
error: new RuntimeRunStateError("supervisor: root execution did not start")
|
|
12688
12923
|
};
|
|
12924
|
+
let teardownUnconfirmed = [];
|
|
12925
|
+
let teardownSeq = 0;
|
|
12689
12926
|
let executionAborted = controller.signal.aborted;
|
|
12690
12927
|
let allChildrenDownAtSettle = false;
|
|
12691
12928
|
let downCountAtSettle = 0;
|
|
@@ -12707,7 +12944,16 @@ function createSupervisor() {
|
|
|
12707
12944
|
clearRootDeadline?.();
|
|
12708
12945
|
const settleGraceMs = actOutcome.ok === false && !controller.signal.aborted ? boundedSettleGrace(opts.childSettleGraceMs, rootDeadlineAtMs, now) : 0;
|
|
12709
12946
|
try {
|
|
12710
|
-
await drainLiveChildren(openScope, controller, settleGraceMs);
|
|
12947
|
+
teardownUnconfirmed = await drainLiveChildren(openScope, controller, settleGraceMs);
|
|
12948
|
+
for (const node of teardownUnconfirmed) await opts.journal.appendEvent(opts.runId, {
|
|
12949
|
+
kind: "teardown-unconfirmed",
|
|
12950
|
+
id: node.id,
|
|
12951
|
+
label: node.label,
|
|
12952
|
+
runtime: node.runtime,
|
|
12953
|
+
status: node.status,
|
|
12954
|
+
seq: teardownSeq++,
|
|
12955
|
+
at: new Date(now()).toISOString()
|
|
12956
|
+
});
|
|
12711
12957
|
} catch (error) {
|
|
12712
12958
|
if (actOutcome?.ok !== false) actOutcome = {
|
|
12713
12959
|
ok: false,
|
|
@@ -12741,6 +12987,7 @@ function createSupervisor() {
|
|
|
12741
12987
|
tree,
|
|
12742
12988
|
spentTotal,
|
|
12743
12989
|
providerModel,
|
|
12990
|
+
...teardownUnconfirmed.length > 0 ? { teardownUnconfirmed } : {},
|
|
12744
12991
|
...gaps.length > 0 ? { spendGaps: gaps } : {},
|
|
12745
12992
|
...isNonEmptySpend(driverInference) ? { spentBreakdown: {
|
|
12746
12993
|
driverInference,
|
|
@@ -12759,6 +13006,7 @@ function createSupervisor() {
|
|
|
12759
13006
|
downCount: breaker.downCount(),
|
|
12760
13007
|
spentTotal,
|
|
12761
13008
|
providerModel,
|
|
13009
|
+
...teardownUnconfirmed.length > 0 ? { teardownUnconfirmed } : {},
|
|
12762
13010
|
...gaps.length > 0 ? { spendGaps: gaps } : {}
|
|
12763
13011
|
};
|
|
12764
13012
|
const lifecycle = classifyNoWinner(executionAborted, pool, opts, breaker, deadlineExceeded, allChildrenDownAtSettle, downCountAtSettle);
|
|
@@ -12903,10 +13151,7 @@ function wrapJournalForBreaker(journal, breaker) {
|
|
|
12903
13151
|
*/
|
|
12904
13152
|
async function drainLiveChildren(scope, controller, settleGraceMs = 0) {
|
|
12905
13153
|
const view = scope.view;
|
|
12906
|
-
if (!(view.inFlight > 0 || view.waiting > 0))
|
|
12907
|
-
if (scope.workerCapacity.live > 0) throw new RuntimeRunStateError(`supervisor: cleanup ended with ${scope.workerCapacity.live} executor resource(s) not confirmed destroyed`);
|
|
12908
|
-
return;
|
|
12909
|
-
}
|
|
13154
|
+
if (!(view.inFlight > 0 || view.waiting > 0)) return unconfirmedTeardowns(scope);
|
|
12910
13155
|
let graceTimer;
|
|
12911
13156
|
if (settleGraceMs > 0 && !controller.signal.aborted) {
|
|
12912
13157
|
graceTimer = setTimeout(() => controller.abort("root driver failed; child settle grace expired"), settleGraceMs);
|
|
@@ -12918,7 +13163,26 @@ async function drainLiveChildren(scope, controller, settleGraceMs = 0) {
|
|
|
12918
13163
|
if (graceTimer !== void 0) clearTimeout(graceTimer);
|
|
12919
13164
|
}
|
|
12920
13165
|
const after = scope.view;
|
|
12921
|
-
if (after.inFlight > 0 || after.waiting > 0
|
|
13166
|
+
if (after.inFlight > 0 || after.waiting > 0) throw new RuntimeRunStateError(`supervisor: cleanup ended with ${after.inFlight} running, ${after.waiting} waiting, and ` + describeUnconfirmed(scope));
|
|
13167
|
+
return unconfirmedTeardowns(scope);
|
|
13168
|
+
}
|
|
13169
|
+
/**
|
|
13170
|
+
* The settled children whose executor teardown was never acknowledged.
|
|
13171
|
+
*
|
|
13172
|
+
* They still hold their capacity slot — the ledger stays poisoned, so replacement work can never
|
|
13173
|
+
* exceed the physical live count — but every one of them has already reached a terminal state and
|
|
13174
|
+
* journaled its work. That is evidence about an EXECUTOR, not a cause of run failure, so the
|
|
13175
|
+
* barrier NAMES them and lets the run reach its real terminal state. Live work after the drain is
|
|
13176
|
+
* a different fault and still fails loud.
|
|
13177
|
+
*/
|
|
13178
|
+
function unconfirmedTeardowns(scope) {
|
|
13179
|
+
return scope.workerCapacity.unconfirmed;
|
|
13180
|
+
}
|
|
13181
|
+
/** The unconfirmed set as one error clause: the count plus the node ids behind it. One integer is
|
|
13182
|
+
* not actionable after a six-hour run. */
|
|
13183
|
+
function describeUnconfirmed(scope) {
|
|
13184
|
+
const named = scope.workerCapacity.unconfirmed.map((node) => `${node.id} (${node.label}, ${node.runtime}, ${node.status})`).join(", ");
|
|
13185
|
+
return `${scope.workerCapacity.live} executor resource(s) not confirmed destroyed${named.length > 0 ? `: ${named}` : ""}`;
|
|
12922
13186
|
}
|
|
12923
13187
|
/** The settle window a failed driver's children actually get: the caller's grace, never past the
|
|
12924
13188
|
* run's own deadline. `0` (the default) keeps the historical immediate cascade. */
|
|
@@ -13002,7 +13266,7 @@ function spendGapsFromEvents(events) {
|
|
|
13002
13266
|
const labels = /* @__PURE__ */ new Map();
|
|
13003
13267
|
const terminal = /* @__PURE__ */ new Set();
|
|
13004
13268
|
for (const ev of events) if (ev.kind === "spawned") labels.set(ev.id, ev.label);
|
|
13005
|
-
else if (ev
|
|
13269
|
+
else if (closesCursorSlot(ev)) terminal.add(ev.id);
|
|
13006
13270
|
const gaps = /* @__PURE__ */ new Map();
|
|
13007
13271
|
const record = (id, kind, channels) => {
|
|
13008
13272
|
if (channels.length === 0) return;
|
|
@@ -13054,52 +13318,15 @@ function sumSpendFromEvents(events) {
|
|
|
13054
13318
|
return totals;
|
|
13055
13319
|
}
|
|
13056
13320
|
function sumMeasuredSpendFromEvents(events) {
|
|
13057
|
-
|
|
13058
|
-
|
|
13059
|
-
|
|
13060
|
-
|
|
13061
|
-
ms: 0
|
|
13062
|
-
};
|
|
13063
|
-
const driverInference = {
|
|
13064
|
-
iterations: 0,
|
|
13065
|
-
tokens: zeroTokenUsage(),
|
|
13066
|
-
usd: 0,
|
|
13067
|
-
ms: 0
|
|
13068
|
-
};
|
|
13069
|
-
for (const ev of events) if (ev.kind === "settled") accumulate(childWork, ev.spent);
|
|
13070
|
-
else if (ev.kind === "metered") accumulate(driverInference, ev.spend);
|
|
13321
|
+
let childWork = zeroSpend();
|
|
13322
|
+
let driverInference = zeroSpend();
|
|
13323
|
+
for (const ev of events) if (ev.kind === "settled") childWork = addSpend(childWork, ev.spent);
|
|
13324
|
+
else if (ev.kind === "metered") driverInference = addSpend(driverInference, ev.spend);
|
|
13071
13325
|
return {
|
|
13072
13326
|
childWork,
|
|
13073
13327
|
driverInference
|
|
13074
13328
|
};
|
|
13075
13329
|
}
|
|
13076
|
-
/** Add `b` into `a` in place, per channel. */
|
|
13077
|
-
function accumulate(a, b) {
|
|
13078
|
-
a.iterations += b.iterations;
|
|
13079
|
-
addTokenUsage(a.tokens, b.tokens);
|
|
13080
|
-
if (b.tokensKnown === false) a.tokensKnown = false;
|
|
13081
|
-
a.usd += b.usd;
|
|
13082
|
-
if (b.usdKnown === false) a.usdKnown = false;
|
|
13083
|
-
if (b.usdEstimated !== void 0) a.usdEstimated = (a.usdEstimated ?? 0) + b.usdEstimated;
|
|
13084
|
-
a.ms += b.ms;
|
|
13085
|
-
}
|
|
13086
|
-
/** Sum two conserved-spend tallies per channel — the child-work journal sum + the drivers' own
|
|
13087
|
-
* metered inference, so `spentTotal` is the true cost of the run. */
|
|
13088
|
-
function addSpend(a, b) {
|
|
13089
|
-
return {
|
|
13090
|
-
iterations: a.iterations + b.iterations,
|
|
13091
|
-
tokens: (() => {
|
|
13092
|
-
const tokens = cloneTokenUsage(a.tokens);
|
|
13093
|
-
addTokenUsage(tokens, b.tokens);
|
|
13094
|
-
return tokens;
|
|
13095
|
-
})(),
|
|
13096
|
-
...a.tokensKnown === false || b.tokensKnown === false ? { tokensKnown: false } : {},
|
|
13097
|
-
usd: a.usd + b.usd,
|
|
13098
|
-
...a.usdKnown === false || b.usdKnown === false ? { usdKnown: false } : {},
|
|
13099
|
-
...usdEstimatedOf(a, b),
|
|
13100
|
-
ms: a.ms + b.ms
|
|
13101
|
-
};
|
|
13102
|
-
}
|
|
13103
13330
|
/** True when any driver metered inference this run (so the winner carries a `spentBreakdown`).
|
|
13104
13331
|
* Checks every channel `addSpend` sums — including `ms` — so the gate stays consistent with the
|
|
13105
13332
|
* total even though the coordination driver currently stamps `ms: 0`. */
|
|
@@ -13107,6 +13334,6 @@ function isNonEmptySpend(s) {
|
|
|
13107
13334
|
return s.iterations > 0 || s.tokens.input > 0 || s.tokens.output > 0 || s.usd > 0 || s.ms > 0 || s.tokensKnown === false || s.usdKnown === false;
|
|
13108
13335
|
}
|
|
13109
13336
|
//#endregion
|
|
13110
|
-
export {
|
|
13337
|
+
export { DEFAULT_STALL_AFTER_MS as $, LOCAL_HARNESSES as $t, createBudgetPool as A, buildLoopOtelSpans as At, createExecutorRegistry as B, padTraceId as Bt, effectiveConcurrency as C, canonicalObservedModel as Ct, DEFAULT_SUCCESSFUL_SHUTDOWN_MS as D, readTraceContextFromEnv as Dt, rollingDispatch as E, mergeTraceEnv as Et, bridgeRuntimeAttachmentsKey as F, exportEvalRuns as Ft, workerTraceEnv as G, sanitizeKnowledgeReadinessReport as Gt, createWorktreeCliExecutor as H, createRuntimeEventCollector as Ht, bridgeStopSignalKey as I, flatOtelSpan as It, DEFAULT_SANDBOX_STEERING_MAX_TURNS as J, runWorktreeHarness as Jt, workerTraceHeaders as K, sanitizeRuntimeStreamEvent as Kt, captureReusableExecutorConfig as L, generateSpanId as Lt, bindReusableExecutorExecutionId as M, buildRuntimeEventOtelSpans as Mt, bridgeAdmissionRead as N, createOpenInferenceFileExporter as Nt, teardownExecutor as O, traceContextToEnv as Ot, bridgeModelRouteRefusal as P, createOtelExporter as Pt, sandboxSessionTraceSource as Q, DEFAULT_LOCAL_HARNESS as Qt, cliWorktreeExecutor as R, loopEventToOtelSpan as Rt, waitUntil as S, runBrainLoop as St, queueOf as T, createPropagatingTraceEmitter as Tt, WORKER_TRACE_PROPAGATION as U, createRuntimeStreamEventCollector as Ut, snapshotExecutorConfig as V, toOtelAttributes as Vt, readWorkerTraceContext as W, sanitizeAgentRuntimeEvent as Wt, createPushTraceSource as X, createWorktree as Xt, createSteerableSandboxSession as Y, captureWorktreeDiff as Yt, decodeToolPart as Z, removeWorktree as Zt, createWaitProbes as _, unsupportedProfileDimensions as _n, runAgentRounds as _t, pickBestDelivered as a, assertProfileMaterialization as an, PEER_MAIL_WIRE_KEY as at, timerAt as b, acquireSandbox as bt, driverChild as c, fullProfileMaterialization as cn, isPeerMailEnvelope as ct, deriveNodeExecutionIdentity as d, promptModelProfileMaterialization as dn, isLiveNodeStatus as dt, harnessSupportsReasoningEffort as en, createActivityLog as et, meterRuntimeOwnedAccounting as f, promptOnlyProfileMaterialization as fn, isTerminalNodeStatus as ft, settledToIteration as g, sandboxActProfileMaterialization as gn, isTerminalDecision as gt, scopeOwnerExecutorNodeContext as h, renderUnsupported as hn, defaultSelectWinner as ht, collectDelivered as i, AGENT_PROFILE_MATERIALIZATION_AXES as in, DEFAULT_PEER_MAIL_LIMITS as it, spendFromUsageEvents as j, buildLoopSpanNodes as jt, assertValidBudget as k, INTELLIGENCE_WIRE_VERSION as kt, withDriverExecutor as l, profileMaterializationAxes$1 as ln, peerMailTools as lt, recordScopeOwnerMaterialization as m, renderProfileMaterializationIssues as mn, createSandboxForSpec as mt, createSupervisor as n, parseCodexTokenUsage as nn, createInbox as nt, runFinalizer as o, controlProfileMaterialization as on, claimsAuthority as ot, meterRuntimeOwnedProviderAttempt as p, promptResourceProfileMaterialization as pn, TERMINAL_DECISIONS as pt, workerTraceSeamKey as q, runSettledCommand as qt, bestDelivered as r, CodexExecutionDiagnosticError as rn, AUTHORITY_MARKERS as rt, runTree as s, defineProfileMaterializationContract as sn, createPeerMailbox as st, createRootHandle as t, localHarnessExecutable as tn, readWorkerProgress as tt, createScope as u, promptControlProfileMaterialization as un, peerMailVerbNames as ut, isWaitOutcome as v, validateProfileMaterialization as vn, createSandboxLineage as vt, freeSlots as w, observedModelMatchesDeclared as wt, validateWaitSpec as x, routerBrain as xt, pollFor as y, worktreeCliProfileMaterialization as yn, probeSandboxCapabilities as yt, createExecutor as z, padSpanId as zt };
|
|
13111
13338
|
|
|
13112
|
-
//# sourceMappingURL=supervisor-
|
|
13339
|
+
//# sourceMappingURL=supervisor-CMZsJ7Wn.js.map
|