@tangle-network/agent-runtime 0.72.0 → 0.74.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.d.ts +34 -2
- package/dist/agent.js +5 -3
- package/dist/agent.js.map +1 -1
- package/dist/analyst-loop.d.ts +1 -1
- package/dist/analyst-loop.js +3 -2
- package/dist/{chunk-P5OKDSLB.js → chunk-IODKUOBA.js} +5 -3
- package/dist/{chunk-P5OKDSLB.js.map → chunk-IODKUOBA.js.map} +1 -1
- package/dist/chunk-JPURCA2O.js +266 -0
- package/dist/chunk-JPURCA2O.js.map +1 -0
- package/dist/{chunk-VYXBFWHZ.js → chunk-MRWXCFV5.js} +2 -2
- package/dist/chunk-NBV35BR6.js +68 -0
- package/dist/chunk-NBV35BR6.js.map +1 -0
- package/dist/chunk-O2UPHN7X.js +114 -0
- package/dist/chunk-O2UPHN7X.js.map +1 -0
- package/dist/{chunk-HXVMLRYU.js → chunk-QKNBYHMK.js} +7 -7
- package/dist/{chunk-PHKNOAOU.js → chunk-SA5GCF2X.js} +25 -7
- package/dist/chunk-SA5GCF2X.js.map +1 -0
- package/dist/{chunk-VLF5RHEQ.js → chunk-T2HVQVB4.js} +1 -66
- package/dist/chunk-T2HVQVB4.js.map +1 -0
- package/dist/{chunk-55WKGOGU.js → chunk-ZKMOIEOB.js} +123 -149
- package/dist/chunk-ZKMOIEOB.js.map +1 -0
- package/dist/{coordination-CFVF0OzX.d.ts → coordination-DEVknvQo.d.ts} +9 -2
- package/dist/generator-YkAQrOoD.d.ts +382 -0
- package/dist/index.d.ts +13 -167
- package/dist/index.js +21 -267
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +1 -1
- package/dist/lifecycle.d.ts +868 -0
- package/dist/lifecycle.js +979 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/local-harness-BE_h8szs.d.ts +93 -0
- package/dist/{loop-runner-bin-B7biH0Gk.d.ts → loop-runner-bin-BPthX22l.d.ts} +2 -2
- package/dist/loop-runner-bin.d.ts +6 -5
- package/dist/loop-runner-bin.js +7 -5
- package/dist/loops.d.ts +47 -10
- package/dist/loops.js +7 -3
- package/dist/mcp/bin.js +7 -5
- package/dist/mcp/bin.js.map +1 -1
- package/dist/mcp/index.d.ts +8 -6
- package/dist/mcp/index.js +8 -5
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp-serve-verifier-CT1KLTG_.d.ts +162 -0
- package/dist/{openai-tools-DOI5mKNw.d.ts → openai-tools-D-VCAEmw.d.ts} +1 -1
- package/dist/profiles.d.ts +1 -1
- package/dist/{types-K8-xkiw1.d.ts → types-YimN9PQP.d.ts} +80 -1
- package/dist/{worktree-JXGJ1MxQ.d.ts → worktree-CtuEQ7bZ.d.ts} +2 -93
- package/dist/{worktree-fanout-DJHQy7Ux.d.ts → worktree-fanout-Cdez8GR7.d.ts} +16 -5
- package/package.json +6 -1
- package/dist/chunk-55WKGOGU.js.map +0 -1
- package/dist/chunk-PHKNOAOU.js.map +0 -1
- package/dist/chunk-VLF5RHEQ.js.map +0 -1
- /package/dist/{chunk-VYXBFWHZ.js.map → chunk-MRWXCFV5.js.map} +0 -0
- /package/dist/{chunk-HXVMLRYU.js.map → chunk-QKNBYHMK.js.map} +0 -0
|
@@ -1,58 +1,3 @@
|
|
|
1
|
-
// src/errors.ts
|
|
2
|
-
import { AgentEvalError } from "@tangle-network/agent-eval";
|
|
3
|
-
import {
|
|
4
|
-
AgentEvalError as AgentEvalError2,
|
|
5
|
-
ConfigError,
|
|
6
|
-
JudgeError,
|
|
7
|
-
NotFoundError,
|
|
8
|
-
ValidationError
|
|
9
|
-
} from "@tangle-network/agent-eval";
|
|
10
|
-
var SessionMismatchError = class extends AgentEvalError {
|
|
11
|
-
sessionBackend;
|
|
12
|
-
requestedBackend;
|
|
13
|
-
constructor(sessionBackend, requestedBackend, options) {
|
|
14
|
-
super(
|
|
15
|
-
"validation",
|
|
16
|
-
`Cannot resume ${sessionBackend} session with ${requestedBackend} backend`,
|
|
17
|
-
options
|
|
18
|
-
);
|
|
19
|
-
this.sessionBackend = sessionBackend;
|
|
20
|
-
this.requestedBackend = requestedBackend;
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
var BackendTransportError = class extends AgentEvalError {
|
|
24
|
-
backend;
|
|
25
|
-
status;
|
|
26
|
-
/**
|
|
27
|
-
* Truncated upstream response body (≤2 KiB) when available. Diagnostic
|
|
28
|
-
* only — surfaces in `backend_error.error.body` and `final.error.body`
|
|
29
|
-
* so operators can see "free_tier_limit", "invalid_api_key", etc. without
|
|
30
|
-
* cracking the log line open.
|
|
31
|
-
*/
|
|
32
|
-
body;
|
|
33
|
-
constructor(backend, message, options) {
|
|
34
|
-
super("config", message, options);
|
|
35
|
-
this.backend = backend;
|
|
36
|
-
this.status = options?.status;
|
|
37
|
-
this.body = options?.body;
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
var RuntimeRunStateError = class extends AgentEvalError {
|
|
41
|
-
constructor(message, options) {
|
|
42
|
-
super("validation", message, options);
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
var PlannerError = class extends AgentEvalError {
|
|
46
|
-
constructor(message, options) {
|
|
47
|
-
super("validation", message, options);
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
var AnalystError = class extends AgentEvalError {
|
|
51
|
-
constructor(message, options) {
|
|
52
|
-
super("validation", message, options);
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
|
|
56
1
|
// src/runtime/sandbox-events.ts
|
|
57
2
|
function extractLlmCallEvent(event, agentRunName) {
|
|
58
3
|
if (!event || typeof event !== "object") return void 0;
|
|
@@ -127,17 +72,7 @@ function mapSandboxEvent(event, opts = {}) {
|
|
|
127
72
|
}
|
|
128
73
|
|
|
129
74
|
export {
|
|
130
|
-
SessionMismatchError,
|
|
131
|
-
BackendTransportError,
|
|
132
|
-
RuntimeRunStateError,
|
|
133
|
-
PlannerError,
|
|
134
|
-
AnalystError,
|
|
135
|
-
AgentEvalError2 as AgentEvalError,
|
|
136
|
-
ConfigError,
|
|
137
|
-
JudgeError,
|
|
138
|
-
NotFoundError,
|
|
139
|
-
ValidationError,
|
|
140
75
|
extractLlmCallEvent,
|
|
141
76
|
mapSandboxEvent
|
|
142
77
|
};
|
|
143
|
-
//# sourceMappingURL=chunk-
|
|
78
|
+
//# sourceMappingURL=chunk-T2HVQVB4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/sandbox-events.ts"],"sourcesContent":["/**\n * Sandbox-event → runtime-event mapping.\n *\n * The sandbox SDK emits a polymorphic `SandboxEvent = { type, data, id? }`\n * whose `type` vocabulary is backend-determined (opencode, etc.) rather than\n * enumerated by the SDK. Two consumers project it:\n * - the loop kernel's cost ledger (`extractLlmCallEvent`) — sums usage off\n * every cost-bearing event, regardless of stream shape;\n * - the `AgentRuntime.act` streaming contract (`mapSandboxEvent`) — projects\n * incremental events to the `RuntimeStreamEvent` chat-UX vocabulary.\n *\n * Both live here so the empirically-observed `type` vocabulary has one home.\n */\n\nimport type { SandboxEvent } from '@tangle-network/sandbox'\nimport type { RuntimeStreamEvent } from '../types'\n\n/**\n * Extract a `RuntimeStreamEvent`-shaped `llm_call` from a sandbox event when\n * the event carries usage/cost data. Returns `undefined` for non-cost events\n * so the kernel can iterate the full stream without branching.\n *\n * Canonical cost-carrying types observed in the wild:\n * - `llm_call` — `data: { model, tokensIn, tokensOut, costUsd, ... }`\n * - `message.completed` / `result` — `data: { usage: { inputTokens,\n * outputTokens, totalCostUsd? } }`\n * - `cost.usage` / `usage` — same shape under a dedicated type\n *\n * Numeric coercion is strict: `Number.isFinite` gates every accumulator write\n * so a sentinel `NaN` from a misbehaving backend cannot poison the ledger.\n */\nexport function extractLlmCallEvent(\n event: SandboxEvent,\n agentRunName: string,\n): (RuntimeStreamEvent & { type: 'llm_call' }) | undefined {\n if (!event || typeof event !== 'object') return undefined\n const type = String(event.type ?? '')\n const data =\n event.data && typeof event.data === 'object'\n ? (event.data as Record<string, unknown>)\n : ({} as Record<string, unknown>)\n\n if (type === 'llm_call' || type === 'cost.usage' || type === 'usage') {\n return buildLlmCall(data, agentRunName)\n }\n if (type === 'message.completed' || type === 'result' || type === 'final') {\n const usage = data.usage as Record<string, unknown> | undefined\n if (!usage || typeof usage !== 'object') return undefined\n return buildLlmCall({ ...usage, model: data.model ?? usage.model }, agentRunName)\n }\n // sandbox 0.4.0 terminal event: `data = { tokenUsage: { inputTokens, outputTokens,\n // reasoningTokens, cacheReadInputTokens }, totalCostUsd }`. Usage lives under\n // `tokenUsage` (not `usage`) and the cost is top-level — neither matched the\n // branches above, so an in-process loopDispatch run reported {0,0} and the\n // backend-integrity guard misread a real run as a stub. Reasoning tokens are\n // billed output (reasoning models), so they fold into the output count.\n if (type === 'done') {\n const usage = data.tokenUsage as Record<string, unknown> | undefined\n if (!usage || typeof usage !== 'object') return undefined\n const out = pickFiniteNumber(usage, ['outputTokens', 'completion_tokens', 'tokensOut'])\n const reasoning = pickFiniteNumber(usage, ['reasoningTokens'])\n const mergedOut =\n out !== undefined || reasoning !== undefined ? (out ?? 0) + (reasoning ?? 0) : undefined\n return buildLlmCall(\n {\n inputTokens: usage.inputTokens,\n outputTokens: mergedOut,\n totalCostUsd: data.totalCostUsd,\n model: data.model ?? usage.model,\n },\n agentRunName,\n )\n }\n return undefined\n}\n\nfunction buildLlmCall(\n data: Record<string, unknown>,\n agentRunName: string,\n): (RuntimeStreamEvent & { type: 'llm_call' }) | undefined {\n const tokensIn = pickFiniteNumber(data, ['tokensIn', 'inputTokens', 'prompt_tokens'])\n const tokensOut = pickFiniteNumber(data, ['tokensOut', 'outputTokens', 'completion_tokens'])\n const costUsd = pickFiniteNumber(data, ['costUsd', 'totalCostUsd', 'cost_usd', 'cost'])\n if (tokensIn === undefined && tokensOut === undefined && costUsd === undefined) {\n return undefined\n }\n const model = typeof data.model === 'string' && data.model.length > 0 ? data.model : agentRunName\n const event: RuntimeStreamEvent & { type: 'llm_call' } = {\n type: 'llm_call',\n model,\n }\n if (tokensIn !== undefined) event.tokensIn = tokensIn\n if (tokensOut !== undefined) event.tokensOut = tokensOut\n if (costUsd !== undefined) event.costUsd = costUsd\n return event\n}\n\nfunction pickFiniteNumber(data: Record<string, unknown>, keys: string[]): number | undefined {\n for (const key of keys) {\n const value = data[key]\n if (typeof value === 'number' && Number.isFinite(value)) return value\n }\n return undefined\n}\n\n/**\n * Project one `SandboxEvent` onto the `RuntimeStreamEvent` chat-UX vocabulary,\n * for runtimes that bridge a sandbox `streamPrompt` into the\n * `AgentRuntime.act` streaming contract. Returns `undefined` for events that\n * have no faithful projection — the raw stream is preserved separately for the\n * `OutputAdapter`, so an unmapped event never loses data.\n *\n * Mapped (the task-optional incremental variants — no synthesized task\n * lifecycle, no guessed tool-part shapes):\n * - `message.part.updated` text part → `text_delta`\n * - `message.part.updated` reasoning/thinking part → `reasoning_delta`\n * - cost-bearing events → `llm_call` (shared with the ledger extractor)\n *\n * The opencode backend emits incremental text as\n * `{ type: 'message.part.updated', data: { part: { type, text }, delta } }`;\n * `delta` is the increment, `part.text` the running accumulation.\n */\nexport function mapSandboxEvent(\n event: SandboxEvent,\n opts: { agentRunName?: string } = {},\n): RuntimeStreamEvent | undefined {\n if (!event || typeof event !== 'object') return undefined\n const type = String(event.type ?? '')\n const data =\n event.data && typeof event.data === 'object'\n ? (event.data as Record<string, unknown>)\n : ({} as Record<string, unknown>)\n\n if (type === 'message.part.updated') {\n const part =\n data.part && typeof data.part === 'object' ? (data.part as Record<string, unknown>) : {}\n const partType = String(part.type ?? '')\n const delta = typeof data.delta === 'string' ? data.delta : undefined\n const text = delta ?? (typeof part.text === 'string' ? part.text : undefined)\n if (text === undefined) return undefined\n if (partType === 'text') return { type: 'text_delta', text }\n if (partType === 'reasoning' || partType === 'thinking')\n return { type: 'reasoning_delta', text }\n return undefined\n }\n\n return extractLlmCallEvent(event, opts.agentRunName ?? 'agent')\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,127 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildLoopSpanNodes
|
|
3
3
|
} from "./chunk-VMNEQHJR.js";
|
|
4
|
+
import {
|
|
5
|
+
extractLlmCallEvent
|
|
6
|
+
} from "./chunk-T2HVQVB4.js";
|
|
7
|
+
import {
|
|
8
|
+
harnessInvocation,
|
|
9
|
+
runLocalHarness
|
|
10
|
+
} from "./chunk-O2UPHN7X.js";
|
|
4
11
|
import {
|
|
5
12
|
AgentEvalError,
|
|
6
13
|
ConfigError,
|
|
7
14
|
NotFoundError,
|
|
8
15
|
RuntimeRunStateError,
|
|
9
|
-
ValidationError
|
|
10
|
-
|
|
11
|
-
} from "./chunk-VLF5RHEQ.js";
|
|
16
|
+
ValidationError
|
|
17
|
+
} from "./chunk-NBV35BR6.js";
|
|
12
18
|
import {
|
|
13
19
|
UI_LENSES
|
|
14
20
|
} from "./chunk-WIR4HOOJ.js";
|
|
15
21
|
|
|
16
|
-
// src/mcp/local-harness.ts
|
|
17
|
-
import { spawn } from "child_process";
|
|
18
|
-
var HARNESS_INVOCATIONS = {
|
|
19
|
-
claude: {
|
|
20
|
-
command: "claude",
|
|
21
|
-
buildArgs: (taskPrompt) => ["--headless", "-p", taskPrompt],
|
|
22
|
-
modelArgs: (model) => ["-m", model]
|
|
23
|
-
},
|
|
24
|
-
codex: {
|
|
25
|
-
command: "codex",
|
|
26
|
-
buildArgs: (taskPrompt) => ["run", taskPrompt],
|
|
27
|
-
modelArgs: (model) => ["-m", model]
|
|
28
|
-
},
|
|
29
|
-
opencode: {
|
|
30
|
-
command: "opencode",
|
|
31
|
-
buildArgs: (taskPrompt) => ["run", taskPrompt],
|
|
32
|
-
modelArgs: (model) => ["-m", model]
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
function harnessInvocation(harness, profile, taskPrompt) {
|
|
36
|
-
const invocation = HARNESS_INVOCATIONS[harness];
|
|
37
|
-
if (!invocation) {
|
|
38
|
-
throw new Error(`harnessInvocation: unknown harness ${String(harness)}`);
|
|
39
|
-
}
|
|
40
|
-
const systemPrompt = profile.prompt?.systemPrompt;
|
|
41
|
-
const composedPrompt = typeof systemPrompt === "string" && systemPrompt.trim().length > 0 ? `${systemPrompt}
|
|
42
|
-
|
|
43
|
-
${taskPrompt}` : taskPrompt;
|
|
44
|
-
const args = invocation.buildArgs(composedPrompt);
|
|
45
|
-
const model = profile.model?.default;
|
|
46
|
-
if (typeof model === "string" && model.length > 0) {
|
|
47
|
-
args.push(...invocation.modelArgs(model));
|
|
48
|
-
}
|
|
49
|
-
return { command: invocation.command, args };
|
|
50
|
-
}
|
|
51
|
-
var DEFAULT_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
52
|
-
function runLocalHarness(options) {
|
|
53
|
-
const { harness, cwd, taskPrompt } = options;
|
|
54
|
-
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
55
|
-
const env = options.env ?? process.env;
|
|
56
|
-
const spawnImpl = options.spawn ?? spawn;
|
|
57
|
-
const invocation = HARNESS_INVOCATIONS[harness];
|
|
58
|
-
if (!invocation) {
|
|
59
|
-
return Promise.reject(new Error(`runLocalHarness: unknown harness ${String(harness)}`));
|
|
60
|
-
}
|
|
61
|
-
const startedAt = Date.now();
|
|
62
|
-
const command = options.invocation?.command ?? invocation.command;
|
|
63
|
-
const args = options.invocation ? [...options.invocation.args] : invocation.buildArgs(taskPrompt);
|
|
64
|
-
return new Promise((resolve, reject) => {
|
|
65
|
-
let child;
|
|
66
|
-
try {
|
|
67
|
-
child = spawnImpl(command, args, { cwd, env, stdio: "pipe" });
|
|
68
|
-
} catch (err) {
|
|
69
|
-
reject(err instanceof Error ? err : new Error(String(err)));
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
child.stdin?.end();
|
|
73
|
-
let stdout = "";
|
|
74
|
-
let stderr = "";
|
|
75
|
-
let timedOut = false;
|
|
76
|
-
let settled = false;
|
|
77
|
-
const timer = timeoutMs > 0 ? setTimeout(() => {
|
|
78
|
-
timedOut = true;
|
|
79
|
-
if (!child.killed) child.kill("SIGTERM");
|
|
80
|
-
}, timeoutMs) : null;
|
|
81
|
-
if (timer && typeof timer.unref === "function") {
|
|
82
|
-
;
|
|
83
|
-
timer.unref();
|
|
84
|
-
}
|
|
85
|
-
const onAbort = () => {
|
|
86
|
-
if (!child.killed) child.kill("SIGTERM");
|
|
87
|
-
};
|
|
88
|
-
if (options.signal) {
|
|
89
|
-
if (options.signal.aborted) onAbort();
|
|
90
|
-
else options.signal.addEventListener("abort", onAbort, { once: true });
|
|
91
|
-
}
|
|
92
|
-
child.stdout?.on("data", (chunk) => {
|
|
93
|
-
stdout += String(chunk);
|
|
94
|
-
});
|
|
95
|
-
child.stderr?.on("data", (chunk) => {
|
|
96
|
-
stderr += String(chunk);
|
|
97
|
-
});
|
|
98
|
-
const finalize3 = (result) => {
|
|
99
|
-
if (settled) return;
|
|
100
|
-
settled = true;
|
|
101
|
-
if (timer) clearTimeout(timer);
|
|
102
|
-
options.signal?.removeEventListener("abort", onAbort);
|
|
103
|
-
resolve(result);
|
|
104
|
-
};
|
|
105
|
-
child.on("error", (err) => {
|
|
106
|
-
if (settled) return;
|
|
107
|
-
settled = true;
|
|
108
|
-
if (timer) clearTimeout(timer);
|
|
109
|
-
options.signal?.removeEventListener("abort", onAbort);
|
|
110
|
-
reject(err);
|
|
111
|
-
});
|
|
112
|
-
child.on("close", (code, signal) => {
|
|
113
|
-
finalize3({
|
|
114
|
-
exitCode: code,
|
|
115
|
-
stdout,
|
|
116
|
-
stderr,
|
|
117
|
-
killedBySignal: signal,
|
|
118
|
-
durationMs: Date.now() - startedAt,
|
|
119
|
-
timedOut
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
|
|
125
22
|
// src/runtime/supervise/model-policy.ts
|
|
126
23
|
function assertModelAllowed(model, allowed) {
|
|
127
24
|
if (!allowed || model === void 0) return;
|
|
@@ -162,6 +59,9 @@ function throwAbort() {
|
|
|
162
59
|
function throwIfAborted(signal) {
|
|
163
60
|
if (signal?.aborted) throw abortError();
|
|
164
61
|
}
|
|
62
|
+
function isAbortError(err) {
|
|
63
|
+
return err instanceof Error && err.name === "AbortError";
|
|
64
|
+
}
|
|
165
65
|
function sleep(ms, signal) {
|
|
166
66
|
return new Promise((resolve) => {
|
|
167
67
|
if (signal?.aborted) {
|
|
@@ -564,6 +464,8 @@ function createSandboxLineage(client, capabilities, options = {}) {
|
|
|
564
464
|
throw new ValidationError("createSandboxLineage: client.create is required");
|
|
565
465
|
}
|
|
566
466
|
const streaming = options.streaming ?? "sse";
|
|
467
|
+
const recordMount = options.recordMount ?? (() => {
|
|
468
|
+
});
|
|
567
469
|
const forkConcurrency = Math.max(
|
|
568
470
|
1,
|
|
569
471
|
Math.floor(options.maxConcurrency ?? DEFAULT_FORK_CONCURRENCY)
|
|
@@ -573,7 +475,7 @@ function createSandboxLineage(client, capabilities, options = {}) {
|
|
|
573
475
|
if (signal.aborted) throwAbort();
|
|
574
476
|
const opts = buildBackendOptions(spec.profile, spec.sandboxOverrides);
|
|
575
477
|
const box = await acquireSandbox(client, opts, { signal });
|
|
576
|
-
await spec.prepareBox?.(box, { signal });
|
|
478
|
+
await spec.prepareBox?.(box, { signal, recordMount });
|
|
577
479
|
owned.push(box);
|
|
578
480
|
return box;
|
|
579
481
|
};
|
|
@@ -602,7 +504,7 @@ function createSandboxLineage(client, capabilities, options = {}) {
|
|
|
602
504
|
if (checkpointId !== void 0) {
|
|
603
505
|
const box2 = await forkFromCheckpoint(parent.box, checkpointId, signal);
|
|
604
506
|
owned.push(box2);
|
|
605
|
-
await spec.prepareBox?.(box2, { signal });
|
|
507
|
+
await spec.prepareBox?.(box2, { signal, recordMount });
|
|
606
508
|
const sessionId2 = mintSessionId();
|
|
607
509
|
return {
|
|
608
510
|
handle: { box: box2, sessionId: sessionId2 },
|
|
@@ -691,13 +593,17 @@ async function runLoop(options) {
|
|
|
691
593
|
const loopStart = now();
|
|
692
594
|
const driverName = options.driver.name ?? "driver";
|
|
693
595
|
const iterations = [];
|
|
596
|
+
const mounts = [];
|
|
597
|
+
const recordMount = (entry) => {
|
|
598
|
+
mounts.push(entry);
|
|
599
|
+
};
|
|
694
600
|
let round = 0;
|
|
695
601
|
const ownedBoxes = [];
|
|
696
602
|
const collectBox = options.onWorkerBox ? (box) => {
|
|
697
603
|
ownedBoxes.push(box);
|
|
698
604
|
options.onWorkerBox?.(box);
|
|
699
605
|
} : void 0;
|
|
700
|
-
const lineageState = await setUpLineage(options, maxConcurrency);
|
|
606
|
+
const lineageState = await setUpLineage(options, maxConcurrency, recordMount);
|
|
701
607
|
emitRunLoopHook(options, {
|
|
702
608
|
target: "agent.run",
|
|
703
609
|
phase: "before",
|
|
@@ -808,7 +714,8 @@ async function runLoop(options) {
|
|
|
808
714
|
parentIndex,
|
|
809
715
|
collectBox,
|
|
810
716
|
lineagePlan,
|
|
811
|
-
lineageState
|
|
717
|
+
lineageState,
|
|
718
|
+
recordMount
|
|
812
719
|
});
|
|
813
720
|
if (controller.signal.aborted) throwAbort();
|
|
814
721
|
emitRunLoopHook(options, {
|
|
@@ -835,11 +742,19 @@ async function runLoop(options) {
|
|
|
835
742
|
payload: { decision: stringifySafe(decision), historyLength: iterations.length }
|
|
836
743
|
});
|
|
837
744
|
if (isTerminalDecision(decision)) {
|
|
838
|
-
return await finalizeAndEmitEnded(
|
|
745
|
+
return await finalizeAndEmitEnded(
|
|
746
|
+
options,
|
|
747
|
+
decision,
|
|
748
|
+
iterations,
|
|
749
|
+
loopStart,
|
|
750
|
+
now,
|
|
751
|
+
runId,
|
|
752
|
+
mounts
|
|
753
|
+
);
|
|
839
754
|
}
|
|
840
755
|
if (lineageState) await pruneLineage(lineageState, iterations);
|
|
841
756
|
}
|
|
842
|
-
return await decideAndFinalize(options, iterations, loopStart, now, runId);
|
|
757
|
+
return await decideAndFinalize(options, iterations, loopStart, now, runId, mounts);
|
|
843
758
|
} finally {
|
|
844
759
|
if (options.ctx.signal) options.ctx.signal.removeEventListener("abort", onOuterAbort);
|
|
845
760
|
await Promise.allSettled(
|
|
@@ -849,7 +764,7 @@ async function runLoop(options) {
|
|
|
849
764
|
if (lineageState) await lineageState.lineage.teardown();
|
|
850
765
|
}
|
|
851
766
|
}
|
|
852
|
-
async function setUpLineage(options, maxConcurrency) {
|
|
767
|
+
async function setUpLineage(options, maxConcurrency, recordMount) {
|
|
853
768
|
const lineageOpts = options.lineage;
|
|
854
769
|
if (!lineageOpts || !lineageOpts.sessionContinuity && !lineageOpts.forkFanout) return void 0;
|
|
855
770
|
if (options.onWorkerBox) {
|
|
@@ -861,7 +776,8 @@ async function setUpLineage(options, maxConcurrency) {
|
|
|
861
776
|
return {
|
|
862
777
|
lineage: createSandboxLineage(options.ctx.sandboxClient, capabilities, {
|
|
863
778
|
maxConcurrency,
|
|
864
|
-
streaming: lineageOpts.streaming
|
|
779
|
+
streaming: lineageOpts.streaming,
|
|
780
|
+
recordMount
|
|
865
781
|
}),
|
|
866
782
|
options: lineageOpts,
|
|
867
783
|
handles: /* @__PURE__ */ new Map(),
|
|
@@ -991,7 +907,7 @@ async function executeIteration(args) {
|
|
|
991
907
|
args.lineageState?.handles.set(args.item.index, acquired.handle);
|
|
992
908
|
stream = acquired.events;
|
|
993
909
|
} else {
|
|
994
|
-
box = await createSandboxForSpec(args.ctx.sandboxClient, spec, args.signal);
|
|
910
|
+
box = await createSandboxForSpec(args.ctx.sandboxClient, spec, args.signal, args.recordMount);
|
|
995
911
|
const prompt = spec.taskToPrompt(args.item.task);
|
|
996
912
|
stream = args.streaming === "poll" ? promptEvents("poll", box, prompt, `${args.runId}-i${args.item.index}`, args.signal) : box.streamPrompt(prompt, { signal: args.signal });
|
|
997
913
|
}
|
|
@@ -1060,13 +976,13 @@ async function executeIteration(args) {
|
|
|
1060
976
|
await destroySandboxSafe(box, args.ctx.traceEmitter, args.runId, args.now);
|
|
1061
977
|
}
|
|
1062
978
|
}
|
|
1063
|
-
if (
|
|
979
|
+
if (isAbortError2(slot.error) || args.signal.aborted) {
|
|
1064
980
|
if (slot.error) throw slot.error;
|
|
1065
981
|
throwAbort();
|
|
1066
982
|
}
|
|
1067
983
|
if (slot.error instanceof ValidationError) throw slot.error;
|
|
1068
984
|
}
|
|
1069
|
-
function
|
|
985
|
+
function isAbortError2(err) {
|
|
1070
986
|
return err instanceof Error && err.name === "AbortError";
|
|
1071
987
|
}
|
|
1072
988
|
var TEARDOWN_TIMEOUT_MS2 = 15e3;
|
|
@@ -1120,15 +1036,35 @@ function readSandboxId(box) {
|
|
|
1120
1036
|
const raw = box.id;
|
|
1121
1037
|
return typeof raw === "string" && raw.length > 0 ? raw : void 0;
|
|
1122
1038
|
}
|
|
1123
|
-
async function createSandboxForSpec(client, spec, signal) {
|
|
1039
|
+
async function createSandboxForSpec(client, spec, signal, recordMount) {
|
|
1124
1040
|
const opts = buildBackendOptions(spec.profile, spec.sandboxOverrides);
|
|
1125
1041
|
if (signal.aborted) throwAbort();
|
|
1126
1042
|
const box = await acquireSandbox(client, opts, { signal });
|
|
1127
|
-
await spec
|
|
1043
|
+
await invokePrepareBox(spec, box, signal, recordMount);
|
|
1128
1044
|
return box;
|
|
1129
1045
|
}
|
|
1046
|
+
async function invokePrepareBox(spec, box, signal, recordMount) {
|
|
1047
|
+
if (!spec.prepareBox) return;
|
|
1048
|
+
await spec.prepareBox(box, { signal, recordMount: recordMount ?? noopMountRecorder });
|
|
1049
|
+
}
|
|
1050
|
+
var noopMountRecorder = () => {
|
|
1051
|
+
};
|
|
1130
1052
|
function finalize(args) {
|
|
1131
|
-
|
|
1053
|
+
let selector;
|
|
1054
|
+
let winner;
|
|
1055
|
+
if (args.options.selectWinner) {
|
|
1056
|
+
selector = "caller";
|
|
1057
|
+
winner = args.options.selectWinner(args.iterations);
|
|
1058
|
+
} else {
|
|
1059
|
+
const authored = args.options.driver.selectWinner?.(args.iterations);
|
|
1060
|
+
if (authored) {
|
|
1061
|
+
selector = "driver";
|
|
1062
|
+
winner = authored;
|
|
1063
|
+
} else {
|
|
1064
|
+
selector = "default";
|
|
1065
|
+
winner = defaultSelectWinner(args.iterations);
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1132
1068
|
const costUsd = args.iterations.reduce((sum, iter) => sum + (iter.costUsd || 0), 0);
|
|
1133
1069
|
const tokenUsage = args.iterations.reduce((acc, iter) => {
|
|
1134
1070
|
addTokenUsage(acc, iter.tokenUsage);
|
|
@@ -1140,11 +1076,36 @@ function finalize(args) {
|
|
|
1140
1076
|
winner,
|
|
1141
1077
|
durationMs: args.now() - args.startMs,
|
|
1142
1078
|
costUsd,
|
|
1143
|
-
tokenUsage
|
|
1079
|
+
tokenUsage,
|
|
1080
|
+
provenance: {
|
|
1081
|
+
mounts: args.mounts,
|
|
1082
|
+
selectionReceipts: buildSelectionReceipts(args.iterations, winner, selector)
|
|
1083
|
+
}
|
|
1144
1084
|
};
|
|
1145
1085
|
return result;
|
|
1146
1086
|
}
|
|
1147
|
-
|
|
1087
|
+
function buildSelectionReceipts(iterations, winner, selector) {
|
|
1088
|
+
const receipts = [];
|
|
1089
|
+
for (const iter of iterations) {
|
|
1090
|
+
if (iter.output === void 0 || iter.error) continue;
|
|
1091
|
+
const selected = winner?.iterationIndex === iter.index;
|
|
1092
|
+
const receipt = {
|
|
1093
|
+
candidateIndex: iter.index,
|
|
1094
|
+
selected,
|
|
1095
|
+
selector
|
|
1096
|
+
};
|
|
1097
|
+
if (iter.verdict?.score !== void 0) receipt.score = iter.verdict.score;
|
|
1098
|
+
if (selector === "default") receipt.reason = defaultSelectorReason(iter, selected);
|
|
1099
|
+
receipts.push(receipt);
|
|
1100
|
+
}
|
|
1101
|
+
return receipts;
|
|
1102
|
+
}
|
|
1103
|
+
function defaultSelectorReason(iter, selected) {
|
|
1104
|
+
const valid = iter.verdict?.valid === true;
|
|
1105
|
+
if (selected) return valid ? "best valid score" : "best non-errored score (no valid candidate)";
|
|
1106
|
+
return valid ? "valid but not top score" : "not selected";
|
|
1107
|
+
}
|
|
1108
|
+
async function decideAndFinalize(options, iterations, startMs, now, runId, mounts) {
|
|
1148
1109
|
emitRunLoopHook(options, {
|
|
1149
1110
|
target: "agent.decision",
|
|
1150
1111
|
phase: "before",
|
|
@@ -1166,10 +1127,10 @@ async function decideAndFinalize(options, iterations, startMs, now, runId) {
|
|
|
1166
1127
|
timestamp: now(),
|
|
1167
1128
|
payload: { decision: stringifySafe(decision), historyLength: iterations.length }
|
|
1168
1129
|
});
|
|
1169
|
-
return finalizeAndEmitEnded(options, decision, iterations, startMs, now, runId);
|
|
1130
|
+
return finalizeAndEmitEnded(options, decision, iterations, startMs, now, runId, mounts);
|
|
1170
1131
|
}
|
|
1171
|
-
async function finalizeAndEmitEnded(options, decision, iterations, startMs, now, runId) {
|
|
1172
|
-
const result = finalize({ options, decision, iterations, startMs, now, runId });
|
|
1132
|
+
async function finalizeAndEmitEnded(options, decision, iterations, startMs, now, runId, mounts) {
|
|
1133
|
+
const result = finalize({ options, decision, iterations, startMs, now, runId, mounts });
|
|
1173
1134
|
emitRunLoopHook(options, {
|
|
1174
1135
|
target: "agent.run",
|
|
1175
1136
|
phase: "after",
|
|
@@ -1293,7 +1254,7 @@ function createScope(args) {
|
|
|
1293
1254
|
let cursorSeq = 0;
|
|
1294
1255
|
let meterSeq = 0;
|
|
1295
1256
|
const now = args.now ?? Date.now;
|
|
1296
|
-
function
|
|
1257
|
+
function spawn4(agent, task, opts) {
|
|
1297
1258
|
if (args.maxDepth !== void 0 && args.depth >= args.maxDepth) {
|
|
1298
1259
|
return { ok: false, reason: "depth-exceeded" };
|
|
1299
1260
|
}
|
|
@@ -1444,7 +1405,7 @@ function createScope(args) {
|
|
|
1444
1405
|
);
|
|
1445
1406
|
}
|
|
1446
1407
|
return {
|
|
1447
|
-
spawn:
|
|
1408
|
+
spawn: spawn4,
|
|
1448
1409
|
next,
|
|
1449
1410
|
send,
|
|
1450
1411
|
signal: args.signal,
|
|
@@ -1605,7 +1566,7 @@ async function runChild(live, executor, childAbort, task, opts, pool, ticket, bl
|
|
|
1605
1566
|
} catch (err) {
|
|
1606
1567
|
reconcileOnce(live.spent);
|
|
1607
1568
|
await teardownSafe(executor, "brutalKill");
|
|
1608
|
-
const aborted = childAbort.signal.aborted ||
|
|
1569
|
+
const aborted = childAbort.signal.aborted || isAbortError3(err);
|
|
1609
1570
|
return downRecord(errMessage(err), aborted || isInfraError(err), executor.metered?.());
|
|
1610
1571
|
}
|
|
1611
1572
|
}
|
|
@@ -1707,7 +1668,7 @@ function isAgentSpec(value) {
|
|
|
1707
1668
|
const v = value;
|
|
1708
1669
|
return "profile" in v && "harness" in v;
|
|
1709
1670
|
}
|
|
1710
|
-
function
|
|
1671
|
+
function isAbortError3(err) {
|
|
1711
1672
|
return typeof err === "object" && err !== null && "name" in err && err.name === "AbortError";
|
|
1712
1673
|
}
|
|
1713
1674
|
function isInfraError(err) {
|
|
@@ -1916,11 +1877,11 @@ ${lines.join("\n")}`;
|
|
|
1916
1877
|
}
|
|
1917
1878
|
|
|
1918
1879
|
// src/mcp/worktree.ts
|
|
1919
|
-
import { spawn
|
|
1880
|
+
import { spawn } from "child_process";
|
|
1920
1881
|
async function runGitAsync(args, cwd, runner) {
|
|
1921
1882
|
if (runner) return runner(args, { cwd });
|
|
1922
1883
|
return new Promise((resolve, reject) => {
|
|
1923
|
-
const proc =
|
|
1884
|
+
const proc = spawn("git", args, { cwd, stdio: "pipe" });
|
|
1924
1885
|
let stdout = "";
|
|
1925
1886
|
let stderr = "";
|
|
1926
1887
|
proc.stdout?.on("data", (c) => {
|
|
@@ -2005,7 +1966,7 @@ async function removeWorktree(options) {
|
|
|
2005
1966
|
import { randomUUID } from "crypto";
|
|
2006
1967
|
|
|
2007
1968
|
// src/mcp/worktree-harness.ts
|
|
2008
|
-
import { spawn as
|
|
1969
|
+
import { spawn as spawn2 } from "child_process";
|
|
2009
1970
|
var defaultCheckOutputCap = 16e3;
|
|
2010
1971
|
async function runWorktreeHarness(opts) {
|
|
2011
1972
|
const runHarness = opts.runHarness ?? runLocalHarness;
|
|
@@ -2090,7 +2051,7 @@ async function runChecks(opts) {
|
|
|
2090
2051
|
}
|
|
2091
2052
|
function defaultRunCommand(opts) {
|
|
2092
2053
|
return new Promise((resolve, reject) => {
|
|
2093
|
-
const child =
|
|
2054
|
+
const child = spawn2("/bin/sh", ["-c", opts.command], {
|
|
2094
2055
|
cwd: opts.cwd,
|
|
2095
2056
|
stdio: ["ignore", "pipe", "pipe"]
|
|
2096
2057
|
});
|
|
@@ -2126,12 +2087,12 @@ function createWorktreeCliExecutor(options) {
|
|
|
2126
2087
|
}
|
|
2127
2088
|
const runId = options.runId ?? randomUUID();
|
|
2128
2089
|
const controller = new AbortController();
|
|
2090
|
+
const budgetExempt = options.budgetExempt ?? true;
|
|
2129
2091
|
let run;
|
|
2130
2092
|
let artifact;
|
|
2131
2093
|
return {
|
|
2132
2094
|
runtime: "cli",
|
|
2133
|
-
|
|
2134
|
-
budgetExempt: true,
|
|
2095
|
+
budgetExempt,
|
|
2135
2096
|
async execute(_task, signal) {
|
|
2136
2097
|
const linked = linkSignals(signal, controller.signal);
|
|
2137
2098
|
const started = Date.now();
|
|
@@ -2153,7 +2114,9 @@ function createWorktreeCliExecutor(options) {
|
|
|
2153
2114
|
});
|
|
2154
2115
|
const spent = {
|
|
2155
2116
|
iterations: 1,
|
|
2156
|
-
//
|
|
2117
|
+
// The worktree-harness core surfaces no token/usd usage, so tokens/usd are a genuine zero
|
|
2118
|
+
// (NOT a fabricated cost). When budgetExempt is true the pool ignores this spend entirely;
|
|
2119
|
+
// when explicitly false the scope debits exactly this captured spend — the real iteration.
|
|
2157
2120
|
tokens: zeroTokenUsage(),
|
|
2158
2121
|
usd: 0,
|
|
2159
2122
|
ms: Date.now() - started
|
|
@@ -2194,7 +2157,7 @@ function linkSignals(a, b) {
|
|
|
2194
2157
|
}
|
|
2195
2158
|
|
|
2196
2159
|
// src/runtime/supervise/runtime.ts
|
|
2197
|
-
import { spawn as
|
|
2160
|
+
import { spawn as spawn3 } from "child_process";
|
|
2198
2161
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
2199
2162
|
import { estimateCost as estimateCost2, isModelPriced as isModelPriced2 } from "@tangle-network/agent-eval";
|
|
2200
2163
|
var routerSeamKey = "router";
|
|
@@ -2585,7 +2548,7 @@ var cliExecutor = (_spec, ctx) => {
|
|
|
2585
2548
|
};
|
|
2586
2549
|
async function* streamCliLeaf(args) {
|
|
2587
2550
|
const prompt = taskToPrompt(args.task);
|
|
2588
|
-
const proc =
|
|
2551
|
+
const proc = spawn3(args.seam.bin, args.seam.args ?? [], {
|
|
2589
2552
|
...args.seam.cwd ? { cwd: args.seam.cwd } : {},
|
|
2590
2553
|
env: { ...process.env, ...args.seam.env ?? {} },
|
|
2591
2554
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -3769,10 +3732,14 @@ function createCoordinationTools(opts) {
|
|
|
3769
3732
|
return q.status !== "answered" && q.status !== "deferred";
|
|
3770
3733
|
});
|
|
3771
3734
|
};
|
|
3735
|
+
const maxLiveWorkers = opts.maxLiveWorkers;
|
|
3736
|
+
const liveWorkerCount = () => opts.scope.view.nodes.filter(
|
|
3737
|
+
(n) => n.status !== "done" && n.status !== "failed" && n.status !== "cancelled"
|
|
3738
|
+
).length;
|
|
3772
3739
|
const tools = [
|
|
3773
3740
|
{
|
|
3774
3741
|
name: "spawn_agent",
|
|
3775
|
-
description:
|
|
3742
|
+
description: 'Start a worker the driver will drive. `profile` is the worker or another driver; `task` is what it should do. Reserves budget from the conserved pool and fails closed. Pass an optional `budget` (per-field) to give a hard sub-task more than the default \u2014 it merges over the per-worker default; the conserved pool is still the hard fence. When a max-live-workers cap is set it also fails closed (`error: "max-live-workers"`) while that many workers are still in flight \u2014 settle or steer one before spawning another.',
|
|
3776
3743
|
inputSchema: {
|
|
3777
3744
|
type: "object",
|
|
3778
3745
|
properties: {
|
|
@@ -3794,6 +3761,8 @@ function createCoordinationTools(opts) {
|
|
|
3794
3761
|
},
|
|
3795
3762
|
handler: (raw) => {
|
|
3796
3763
|
const a = obj(raw);
|
|
3764
|
+
if (maxLiveWorkers !== void 0 && maxLiveWorkers > 0 && liveWorkerCount() >= maxLiveWorkers)
|
|
3765
|
+
return Promise.resolve({ error: "max-live-workers" });
|
|
3797
3766
|
const agent = opts.makeWorkerAgent(a.profile);
|
|
3798
3767
|
const budget = a.budget === void 0 ? opts.perWorker : mergeBudget(opts.perWorker, a.budget);
|
|
3799
3768
|
const res = opts.scope.spawn(agent, a.task, {
|
|
@@ -4073,7 +4042,8 @@ function driverAgent(opts) {
|
|
|
4073
4042
|
scope,
|
|
4074
4043
|
blobs: opts.blobs,
|
|
4075
4044
|
makeWorkerAgent: opts.makeWorkerAgent,
|
|
4076
|
-
perWorker: opts.perWorker
|
|
4045
|
+
perWorker: opts.perWorker,
|
|
4046
|
+
...opts.maxLiveWorkers !== void 0 ? { maxLiveWorkers: opts.maxLiveWorkers } : {}
|
|
4077
4047
|
});
|
|
4078
4048
|
const byName = new Map(coord.tools.map((t) => [t.name, t]));
|
|
4079
4049
|
const toolSpecs = [
|
|
@@ -5157,6 +5127,7 @@ function supervise(profile, task, opts) {
|
|
|
5157
5127
|
blobs,
|
|
5158
5128
|
makeWorkerAgent,
|
|
5159
5129
|
perWorker,
|
|
5130
|
+
...opts.maxLiveWorkers !== void 0 ? { maxLiveWorkers: opts.maxLiveWorkers } : {},
|
|
5160
5131
|
...opts.router ? { router: opts.router } : {},
|
|
5161
5132
|
...opts.brain ? { brain: opts.brain } : {},
|
|
5162
5133
|
...opts.driveHarness ? { driveHarness: opts.driveHarness } : {},
|
|
@@ -6036,6 +6007,7 @@ async function serveCoordinationMcp(opts) {
|
|
|
6036
6007
|
blobs: opts.blobs,
|
|
6037
6008
|
makeWorkerAgent: opts.makeWorkerAgent,
|
|
6038
6009
|
perWorker: opts.perWorker,
|
|
6010
|
+
...opts.maxLiveWorkers !== void 0 ? { maxLiveWorkers: opts.maxLiveWorkers } : {},
|
|
6039
6011
|
...opts.analysts ? { analysts: opts.analysts } : {},
|
|
6040
6012
|
...opts.analyzeOnSettle ? { analyzeOnSettle: opts.analyzeOnSettle } : {},
|
|
6041
6013
|
...opts.onEvent ? { onEvent: opts.onEvent } : {},
|
|
@@ -6112,6 +6084,7 @@ function supervisorAgent(profile, deps) {
|
|
|
6112
6084
|
makeWorkerAgent: deps.makeWorkerAgent,
|
|
6113
6085
|
perWorker: deps.perWorker,
|
|
6114
6086
|
systemPrompt,
|
|
6087
|
+
...deps.maxLiveWorkers !== void 0 ? { maxLiveWorkers: deps.maxLiveWorkers } : {},
|
|
6115
6088
|
...deps.extraTools ? { extraTools: deps.extraTools } : {},
|
|
6116
6089
|
...deps.executeExtraTool ? { executeExtraTool: deps.executeExtraTool } : {},
|
|
6117
6090
|
...deps.maxTurns !== void 0 ? { maxTurns: deps.maxTurns } : {}
|
|
@@ -6130,7 +6103,8 @@ function supervisorAgent(profile, deps) {
|
|
|
6130
6103
|
scope,
|
|
6131
6104
|
blobs: deps.blobs,
|
|
6132
6105
|
makeWorkerAgent: deps.makeWorkerAgent,
|
|
6133
|
-
perWorker: deps.perWorker
|
|
6106
|
+
perWorker: deps.perWorker,
|
|
6107
|
+
...deps.maxLiveWorkers !== void 0 ? { maxLiveWorkers: deps.maxLiveWorkers } : {}
|
|
6134
6108
|
});
|
|
6135
6109
|
try {
|
|
6136
6110
|
await driveHarness({ profile, task, scope, coordinationMcpUrl: mcp.url });
|
|
@@ -6151,12 +6125,12 @@ function routerBrainFromProfile(profile, deps) {
|
|
|
6151
6125
|
}
|
|
6152
6126
|
|
|
6153
6127
|
export {
|
|
6154
|
-
runLocalHarness,
|
|
6155
6128
|
assertModelAllowed,
|
|
6156
6129
|
deleteBoxSafe,
|
|
6157
6130
|
randomSuffix,
|
|
6158
6131
|
throwAbort,
|
|
6159
6132
|
throwIfAborted,
|
|
6133
|
+
isAbortError,
|
|
6160
6134
|
sleep,
|
|
6161
6135
|
stringifySafe,
|
|
6162
6136
|
zeroTokenUsage,
|
|
@@ -6253,4 +6227,4 @@ export {
|
|
|
6253
6227
|
createInProcessTransport,
|
|
6254
6228
|
serveCoordinationMcp
|
|
6255
6229
|
};
|
|
6256
|
-
//# sourceMappingURL=chunk-
|
|
6230
|
+
//# sourceMappingURL=chunk-ZKMOIEOB.js.map
|