@tangle-network/agent-runtime 0.301.0 → 0.306.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/dist/{activation-V6aaOlZV.js → activation-kaJzXM7Y.js} +3 -3
- package/dist/{activation-V6aaOlZV.js.map → activation-kaJzXM7Y.js.map} +1 -1
- package/dist/{activation-CRgEJutr.d.ts → activation-wZ-8vOjV.d.ts} +88 -13
- package/dist/agent.d.ts +2 -2
- package/dist/agent.js +2 -2
- package/dist/{bundle-C9v5TH_H.js → bundle-E6mbRX2P.js} +2 -2
- package/dist/{bundle-C9v5TH_H.js.map → bundle-E6mbRX2P.js.map} +1 -1
- package/dist/candidate-execution/index.d.ts +3 -26
- package/dist/candidate-execution/index.js +6 -6
- package/dist/{coordination-driver-vNrdQBSH.js → coordination-driver-Y2gf8pBT.js} +9 -16
- package/dist/coordination-driver-Y2gf8pBT.js.map +1 -0
- package/dist/{delegate-B-jFJcbW.js → delegate-B7bwEFQl.js} +2 -2
- package/dist/{delegate-B-jFJcbW.js.map → delegate-B7bwEFQl.js.map} +1 -1
- package/dist/durable.d.ts +3 -15
- package/dist/durable.js +158 -124
- package/dist/durable.js.map +1 -1
- package/dist/{graph-Dwv_hQB_.js → graph-VUwNFYff.js} +4 -5
- package/dist/graph-VUwNFYff.js.map +1 -0
- package/dist/{improvement-cycle-Cf37Kexd.js → improvement-cycle-DuIGusyA.js} +1129 -10
- package/dist/improvement-cycle-DuIGusyA.js.map +1 -0
- package/dist/{index-CxBVmgqL.d.ts → index-DflDZq_I.d.ts} +50 -688
- package/dist/index.d.ts +378 -12
- package/dist/index.js +223 -320
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +5 -5
- package/dist/intelligence.js +7 -8
- package/dist/intelligence.js.map +1 -1
- package/dist/kernel.d.ts +4 -4
- package/dist/kernel.js +9 -9
- package/dist/{loop-runner-bin-DiTNiJNs.d.ts → loop-runner-bin-DZfRUVWy.d.ts} +3 -3
- package/dist/{loop-runner-bin-C8MI8N1A.js → loop-runner-bin-Dp1V3P2W.js} +3 -3
- package/dist/{loop-runner-bin-C8MI8N1A.js.map → loop-runner-bin-Dp1V3P2W.js.map} +1 -1
- package/dist/loop-runner-bin.d.ts +1 -1
- package/dist/loop-runner-bin.js +1 -1
- package/dist/mcp/bin.js +3 -3
- package/dist/mcp/index.d.ts +6 -35
- package/dist/mcp/index.js +311 -364
- package/dist/mcp/index.js.map +1 -1
- package/dist/model-policy-DydyWTQg.js.map +1 -1
- package/dist/{openai-tools-BeogJ6V8.d.ts → openai-tools-YO30D2s3.d.ts} +2 -2
- package/dist/{prepare-CGVNMb1o.js → prepare-CulUz6Wm.js} +7 -13
- package/dist/prepare-CulUz6Wm.js.map +1 -0
- package/dist/{profile-BetOB4_Q.js → profile-DY9lT3gH.js} +2 -2
- package/dist/{profile-BetOB4_Q.js.map → profile-DY9lT3gH.js.map} +1 -1
- package/dist/profiles.d.ts +2 -94
- package/dist/profiles.js +2 -451
- package/dist/profiles.js.map +1 -1
- package/dist/{protected-model-port-CuVHkhti.js → protected-model-port-BT2iYAsU.js} +4 -4
- package/dist/{protected-model-port-CuVHkhti.js.map → protected-model-port-BT2iYAsU.js.map} +1 -1
- package/dist/{protected-model-port-CAa0t1MT.d.ts → protected-model-port-C9QtEf3y.d.ts} +2 -2
- package/dist/{provision-supervisor-CS0fBIhp.js → provision-supervisor-CfK8fla-.js} +4 -3
- package/dist/{provision-supervisor-CS0fBIhp.js.map → provision-supervisor-CfK8fla-.js.map} +1 -1
- package/dist/{runtime-6VPSJVeg.js → runtime-D452tieK.js} +67 -469
- package/dist/runtime-D452tieK.js.map +1 -0
- package/dist/{search-method-wTTS7mGG.js → search-executor-D3AT8_hb.js} +239 -1132
- package/dist/search-executor-D3AT8_hb.js.map +1 -0
- package/dist/{server-BfHD5iLD.js → server-D1Tfxo-v.js} +5 -12
- package/dist/server-D1Tfxo-v.js.map +1 -0
- package/dist/{stream-agent-turn-B1ipFtOc.d.ts → stream-agent-turn-B1giFgOg.d.ts} +2 -2
- package/dist/{substrate-DKBMd0Dl.d.ts → substrate-L_sC7jCD.d.ts} +2 -2
- package/dist/{supervise-BJrEC2Mh.js → supervise-CtewGpxh.js} +14 -24
- package/dist/supervise-CtewGpxh.js.map +1 -0
- package/dist/{supervisor-DA_nvF-h.js → supervisor-DYKPbcZa.js} +488 -1407
- package/dist/supervisor-DYKPbcZa.js.map +1 -0
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +14 -14
- package/dist/tui/index.d.ts +1 -1
- package/dist/tui/index.js +1 -1
- package/dist/{types-jD9mNnJM.d.ts → types-DeuEkBhI.d.ts} +114 -258
- package/dist/{workspace-archive-pz8YJ1fr.d.ts → workspace-streams-CpSmt3zx.d.ts} +67 -3
- package/dist/{workspace-streams-D5gHJdTb.js → workspace-streams-DaQceg2p.js} +699 -2
- package/dist/workspace-streams-DaQceg2p.js.map +1 -0
- package/package.json +8 -8
- package/skills/generate-eval/SKILL.md +1 -1
- package/skills/profile-authoring/SKILL.md +2 -2
- package/dist/coordination-driver-vNrdQBSH.js.map +0 -1
- package/dist/graph-Dwv_hQB_.js.map +0 -1
- package/dist/improvement-cycle-Cf37Kexd.js.map +0 -1
- package/dist/prepare-CGVNMb1o.js.map +0 -1
- package/dist/runtime-6VPSJVeg.js.map +0 -1
- package/dist/search-method-wTTS7mGG.js.map +0 -1
- package/dist/server-BfHD5iLD.js.map +0 -1
- package/dist/supervise-BJrEC2Mh.js.map +0 -1
- package/dist/supervisor-DA_nvF-h.js.map +0 -1
- package/dist/workspace-streams-D5gHJdTb.js.map +0 -1
package/dist/mcp/index.js
CHANGED
|
@@ -1,335 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $r as localHarnessExecutable, Cr as readTraceContextFromEnv, Gr as runWorktreeHarness, Jr as removeWorktree, Kr as captureWorktreeDiff, Qr as harnessSupportsReasoningEffort, Sr as mergeTraceEnv, Xr as LOCAL_HARNESSES, Yr as DEFAULT_LOCAL_HARNESS, an as runAgentRounds, at as environmentReader, ei as parseCodexTokenUsage, it as SPAWN_RESOURCE_PATH_MAX_BYTES, nn as createSandboxForSpec, ot as hostDirectoryReader, qr as createWorktree, st as resolveSpawnResourcePaths, ti as CodexExecutionDiagnosticError, un as assertBoxlessPromptOptions, wr as traceContextToEnv, xr as createPropagatingTraceEmitter } from "../supervisor-DYKPbcZa.js";
|
|
2
2
|
import { i as ConfigError, m as ValidationError } from "../errors-DodWX-cb.js";
|
|
3
|
+
import { W as deleteBoxSafe, it as throwIfAborted, rt as throwAbort, tt as sleep } from "../workspace-streams-DaQceg2p.js";
|
|
3
4
|
import { t as assertExecutableAgentProfile } from "../model-policy-DydyWTQg.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
5
|
+
import { E as runCoderChecks, at as selectValidWinner } from "../runtime-D452tieK.js";
|
|
6
|
+
import { A as analystToolGroupNames, F as downMessageRefusalReasons, L as parseAuthoredAnalystDefinition, N as createCoordinationTools, R as questionEscalationTargets, k as ANALYST_DEFINITION_BOUNDS } from "../coordination-driver-Y2gf8pBT.js";
|
|
6
7
|
import { n as SUPPORTED_PROTOCOL_VERSIONS, r as createStdioToolServer } from "../tool-server-Dqer2M4_.js";
|
|
7
8
|
import { t as createKbGate } from "../kb-gate-DpaSwXVx.js";
|
|
8
9
|
import { _ as InMemoryFeedbackStore, a as validateDelegationStatusArgs, c as DELEGATION_HISTORY_TOOL_NAME, d as delegationProfiles, f as DELEGATE_FEEDBACK_DESCRIPTION, g as validateDelegateFeedbackArgs, h as createDelegateFeedbackHandler, i as createDelegationStatusHandler, l as createDelegationHistoryHandler, m as DELEGATE_FEEDBACK_TOOL_NAME, n as DELEGATION_STATUS_INPUT_SCHEMA, o as DELEGATION_HISTORY_DESCRIPTION, p as DELEGATE_FEEDBACK_INPUT_SCHEMA, r as DELEGATION_STATUS_TOOL_NAME, s as DELEGATION_HISTORY_INPUT_SCHEMA, t as DELEGATION_STATUS_DESCRIPTION, u as validateDelegationHistoryArgs, v as eventToSnapshot } from "../delegation-status-CF4D0NZ_.js";
|
|
9
10
|
import { n as mcpToolsForRuntimeMcpSubset, t as mcpToolsForRuntimeMcp } from "../openai-tools-DoQ32vpe.js";
|
|
10
11
|
import { t as coderTaskToPrompt } from "../coder-yhVWbdWc.js";
|
|
11
|
-
import { C as composeLoopTraceEmitters, S as capDelegationTrace, _ as FileDelegationStore, a as DELEGATE_UI_AUDIT_TOOL_NAME, b as DELEGATION_TRACE_MAX_SPANS, c as DELEGATE_DESCRIPTION, d as createDelegateHandler, f as validateDelegateArgs, g as DelegationStateCorruptError, h as DelegationPersistenceError, i as DELEGATE_UI_AUDIT_INPUT_SCHEMA, l as DELEGATE_INPUT_SCHEMA, m as hashIdempotencyInput, n as createMcpServer, o as createDelegateUiAuditHandler, p as DelegationTaskQueue, r as DELEGATE_UI_AUDIT_DESCRIPTION, s as validateDelegateUiAuditArgs, t as createInProcessTransport, u as DELEGATE_TOOL_NAME, v as InMemoryDelegationStore, w as createDelegationTraceCollector, x as buildDelegationTraceSpans, y as DELEGATION_TRACE_MAX_BYTES } from "../server-
|
|
12
|
+
import { C as composeLoopTraceEmitters, S as capDelegationTrace, _ as FileDelegationStore, a as DELEGATE_UI_AUDIT_TOOL_NAME, b as DELEGATION_TRACE_MAX_SPANS, c as DELEGATE_DESCRIPTION, d as createDelegateHandler, f as validateDelegateArgs, g as DelegationStateCorruptError, h as DelegationPersistenceError, i as DELEGATE_UI_AUDIT_INPUT_SCHEMA, l as DELEGATE_INPUT_SCHEMA, m as hashIdempotencyInput, n as createMcpServer, o as createDelegateUiAuditHandler, p as DelegationTaskQueue, r as DELEGATE_UI_AUDIT_DESCRIPTION, s as validateDelegateUiAuditArgs, t as createInProcessTransport, u as DELEGATE_TOOL_NAME, v as InMemoryDelegationStore, w as createDelegationTraceCollector, x as buildDelegationTraceSpans, y as DELEGATION_TRACE_MAX_BYTES } from "../server-D1Tfxo-v.js";
|
|
12
13
|
import { a as createMemoryToolServer, c as resolveMemoryFromEnv, i as MEMORY_NAME_ENV, n as MEMORY_ITEMS_ENV, o as parseMemoryItems, r as MEMORY_LOG_ENV, s as readMemoryItemsFile, t as MEMORY_FILE_ENV } from "../memory-server-DXQ8IxGR.js";
|
|
13
14
|
import { agentProfileSchema } from "@tangle-network/agent-interface";
|
|
14
15
|
import { randomUUID } from "node:crypto";
|
|
15
|
-
//#region src/mcp/executor.ts
|
|
16
|
-
/**
|
|
17
|
-
* Wrap a raw sandbox SDK client so the kernel emits
|
|
18
|
-
* `loop.iteration.dispatch` events with `{ placement: 'sibling', sandboxId }`.
|
|
19
|
-
*
|
|
20
|
-
* The returned client `.create()` delegates to the underlying client; the
|
|
21
|
-
* only added behavior is a `describePlacement` tag the kernel reads.
|
|
22
|
-
*
|
|
23
|
-
* @experimental
|
|
24
|
-
*/
|
|
25
|
-
function createSiblingSandboxExecutor(options) {
|
|
26
|
-
const underlying = options.client;
|
|
27
|
-
return {
|
|
28
|
-
client: {
|
|
29
|
-
create(opts) {
|
|
30
|
-
return underlying.create(opts);
|
|
31
|
-
},
|
|
32
|
-
describePlacement(box) {
|
|
33
|
-
return {
|
|
34
|
-
kind: "sibling",
|
|
35
|
-
sandboxId: readId(box)
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
placement: "sibling",
|
|
40
|
-
describe() {
|
|
41
|
-
return "sibling-sandbox (each delegation = fresh sandbox via client.create)";
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Build an executor that resolves each delegated iteration to an existing
|
|
47
|
-
* machine in `fleet`. The fleet's shared-workspace policy means the worker
|
|
48
|
-
* machine sees the caller's filesystem — diffs land in-place with no
|
|
49
|
-
* cross-sandbox copy step.
|
|
50
|
-
*
|
|
51
|
-
* @experimental
|
|
52
|
-
*/
|
|
53
|
-
function createFleetWorkspaceExecutor(options) {
|
|
54
|
-
const fleet = options.fleet;
|
|
55
|
-
const exclude = new Set(options.excludeMachineIds ?? []);
|
|
56
|
-
let callIndex = 0;
|
|
57
|
-
const placementBySandboxId = /* @__PURE__ */ new Map();
|
|
58
|
-
return {
|
|
59
|
-
client: {
|
|
60
|
-
async create() {
|
|
61
|
-
const ids = fleet.ids.filter((id) => !exclude.has(id));
|
|
62
|
-
if (ids.length === 0) throw new Error(`agent-runtime: fleet ${fleet.fleetId} has no eligible worker machines (ids=[${fleet.ids.join(",")}], excluded=[${[...exclude].join(",")}])`);
|
|
63
|
-
const selector = options.selectMachine;
|
|
64
|
-
const machineId = selector ? selector({
|
|
65
|
-
callIndex,
|
|
66
|
-
ids
|
|
67
|
-
}) : ids[callIndex % ids.length];
|
|
68
|
-
callIndex += 1;
|
|
69
|
-
if (typeof machineId !== "string" || machineId.length === 0) throw new Error("agent-runtime: fleet executor selectMachine returned an empty machine id");
|
|
70
|
-
const box = await fleet.sandbox(machineId);
|
|
71
|
-
const sandboxId = readId(box);
|
|
72
|
-
if (sandboxId) placementBySandboxId.set(sandboxId, { machineId });
|
|
73
|
-
return box;
|
|
74
|
-
},
|
|
75
|
-
describePlacement(box) {
|
|
76
|
-
const sandboxId = readId(box);
|
|
77
|
-
const recorded = sandboxId ? placementBySandboxId.get(sandboxId) : void 0;
|
|
78
|
-
return {
|
|
79
|
-
kind: "fleet",
|
|
80
|
-
sandboxId,
|
|
81
|
-
fleetId: fleet.fleetId,
|
|
82
|
-
machineId: recorded?.machineId
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
placement: "fleet",
|
|
87
|
-
describe() {
|
|
88
|
-
const excluded = exclude.size > 0 ? ` (excluded=[${[...exclude].join(",")}])` : "";
|
|
89
|
-
return `fleet-workspace (fleetId=${fleet.fleetId}, machines=[${fleet.ids.join(",")}]${excluded})`;
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
function readId(box) {
|
|
94
|
-
const raw = box.id;
|
|
95
|
-
return typeof raw === "string" && raw.length > 0 ? raw : void 0;
|
|
96
|
-
}
|
|
97
|
-
//#endregion
|
|
98
|
-
//#region src/mcp/in-process-executor.ts
|
|
99
|
-
/**
|
|
100
|
-
*
|
|
101
|
-
* In-process delegation executor — when `agent-runtime-mcp` runs inside a sandbox whose image
|
|
102
|
-
* carries the local coding-harness CLIs (claude / codex / opencode), delegations spawn the harness
|
|
103
|
-
* AS A SUBPROCESS against a git worktree on the SAME filesystem instead of provisioning a sibling
|
|
104
|
-
* sandbox. Zero provisioning latency; worker diffs land in-place; multi-harness fanout = N parallel
|
|
105
|
-
* subprocesses in N parallel worktrees. Each authored profile selects its own harness.
|
|
106
|
-
*
|
|
107
|
-
* This is a THIN adapter over `runWorktreeHarness` (`./worktree-harness`) — the SAME core the
|
|
108
|
-
* `Scope` leaf `createWorktreeCliExecutor` uses. It only adapts the core to the `SandboxClient`
|
|
109
|
-
* port: `create()` reads the authored profile from `CreateSandboxOptions.backend.profile`, and
|
|
110
|
-
* `streamPrompt` runs the core then emits its raw `WorktreeHarnessResult` (the content-addressed
|
|
111
|
-
* patch artifact) on the `result` event. The sandbox-session decode layer
|
|
112
|
-
* (`./detached-coder`) projects that artifact onto `CoderOutput`; the generic `Scope` path settles
|
|
113
|
-
* the artifact directly. The §1.5 payload (systemPrompt + model) reaches the harness inside the core.
|
|
114
|
-
*
|
|
115
|
-
* @experimental
|
|
116
|
-
*/
|
|
117
|
-
const DEFAULT_POSTCHECK_TIMEOUT_MS = 120 * 1e3;
|
|
118
|
-
/**
|
|
119
|
-
* Build an in-process executor. Returns a {@link DelegationExecutor} whose `client.create()`
|
|
120
|
-
* returns a minimal virtual `SandboxInstance`; the kernel calls `streamPrompt(msg)` on it, which
|
|
121
|
-
* runs the shared worktree-harness core and emits one `result` event whose `data.result` is the
|
|
122
|
-
* raw `WorktreeHarnessResult` (the content-addressed patch artifact). The authored profile
|
|
123
|
-
* (`backend.profile`) threads its systemPrompt + model into the harness via the core.
|
|
124
|
-
*
|
|
125
|
-
* There is no box, so a per-prompt `backend` or `model` override is refused rather than dropped;
|
|
126
|
-
* other per-prompt options (`timeoutMs`, `context`) are accepted and ignored.
|
|
127
|
-
*
|
|
128
|
-
* @experimental
|
|
129
|
-
*/
|
|
130
|
-
function createInProcessExecutor(options) {
|
|
131
|
-
const runPostCheck = options.runPostCheck ?? defaultRunPostCheck;
|
|
132
|
-
const runCommand = async ({ command, cwd, signal }) => {
|
|
133
|
-
try {
|
|
134
|
-
const r = await runPostCheck(command, cwd, signal);
|
|
135
|
-
return {
|
|
136
|
-
exitCode: r.exitCode,
|
|
137
|
-
output: r.stderr || r.stdout
|
|
138
|
-
};
|
|
139
|
-
} catch (err) {
|
|
140
|
-
return {
|
|
141
|
-
exitCode: -1,
|
|
142
|
-
output: err instanceof Error ? err.message : String(err)
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
return {
|
|
147
|
-
client: {
|
|
148
|
-
async create(opts) {
|
|
149
|
-
const rawProfile = (opts?.backend)?.profile;
|
|
150
|
-
if (rawProfile === void 0) throw new ConfigError("in-process executor: backend.profile is required and must select the exact harness, provider, and model");
|
|
151
|
-
const profile = agentProfileSchema.parse(rawProfile);
|
|
152
|
-
assertExecutableAgentProfile(profile, "in-process executor");
|
|
153
|
-
const harness = profile.harness;
|
|
154
|
-
if (!LOCAL_HARNESSES.includes(harness)) throw new ConfigError(`in-process executor: AgentProfile.harness ${JSON.stringify(harness)} is not a local harness; expected ${LOCAL_HARNESSES.join(", ")}`);
|
|
155
|
-
if (opts?.backend?.type !== void 0 && opts.backend.type !== harness) throw new ConfigError(`in-process executor: backend.type ${JSON.stringify(opts.backend.type)} conflicts with AgentProfile.harness ${JSON.stringify(harness)}`);
|
|
156
|
-
const localHarness = harness;
|
|
157
|
-
const runId = randomUUID();
|
|
158
|
-
return {
|
|
159
|
-
id: `in-process-${runId}`,
|
|
160
|
-
__inProcess: {
|
|
161
|
-
runId,
|
|
162
|
-
harness: localHarness
|
|
163
|
-
},
|
|
164
|
-
async *streamPrompt(message, promptOpts) {
|
|
165
|
-
assertBoxlessPromptOptions(promptOpts, "in-process executor");
|
|
166
|
-
const taskPrompt = typeof message === "string" ? message : message.map((p) => typeof p === "object" && p && "text" in p ? String(p.text) : "").join("\n");
|
|
167
|
-
const run = await runWorktreeHarness({
|
|
168
|
-
repoRoot: options.repoRoot,
|
|
169
|
-
profile,
|
|
170
|
-
harness: localHarness,
|
|
171
|
-
taskPrompt,
|
|
172
|
-
runId,
|
|
173
|
-
...options.harnessTimeoutMs !== void 0 ? { harnessTimeoutMs: options.harnessTimeoutMs } : {},
|
|
174
|
-
checkTimeoutMs: options.postCheckTimeoutMs ?? DEFAULT_POSTCHECK_TIMEOUT_MS,
|
|
175
|
-
...options.testCmd !== void 0 ? { testCmd: options.testCmd } : {},
|
|
176
|
-
...options.typecheckCmd !== void 0 ? { typecheckCmd: options.typecheckCmd } : {},
|
|
177
|
-
...options.runGit ? { runGit: options.runGit } : {},
|
|
178
|
-
...options.runHarness ? { runHarness: options.runHarness } : {},
|
|
179
|
-
runCommand,
|
|
180
|
-
...promptOpts?.signal ? { signal: promptOpts.signal } : {}
|
|
181
|
-
});
|
|
182
|
-
this.__inProcess.worktree = run.worktree;
|
|
183
|
-
try {
|
|
184
|
-
yield {
|
|
185
|
-
type: "in_process.harness.started",
|
|
186
|
-
data: {
|
|
187
|
-
runId,
|
|
188
|
-
harness: localHarness,
|
|
189
|
-
worktreePath: run.worktree.path,
|
|
190
|
-
command: localHarness
|
|
191
|
-
}
|
|
192
|
-
};
|
|
193
|
-
const h = run.result.harness;
|
|
194
|
-
yield {
|
|
195
|
-
type: "in_process.harness.ended",
|
|
196
|
-
data: {
|
|
197
|
-
runId,
|
|
198
|
-
exitCode: h.exitCode,
|
|
199
|
-
durationMs: h.durationMs,
|
|
200
|
-
killedBySignal: h.killedBySignal,
|
|
201
|
-
timedOut: h.timedOut,
|
|
202
|
-
stdoutBytes: h.stdout.length,
|
|
203
|
-
stderrBytes: h.stderr.length
|
|
204
|
-
}
|
|
205
|
-
};
|
|
206
|
-
yield {
|
|
207
|
-
type: "result",
|
|
208
|
-
data: {
|
|
209
|
-
result: run.result,
|
|
210
|
-
source: "in-process-executor",
|
|
211
|
-
harness: localHarness,
|
|
212
|
-
runId
|
|
213
|
-
}
|
|
214
|
-
};
|
|
215
|
-
} finally {
|
|
216
|
-
await run.cleanup();
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
},
|
|
221
|
-
describePlacement(box) {
|
|
222
|
-
const sandboxId = box.id;
|
|
223
|
-
const meta = box.__inProcess;
|
|
224
|
-
return {
|
|
225
|
-
kind: "in-process",
|
|
226
|
-
sandboxId,
|
|
227
|
-
worktreePath: meta?.worktree?.path,
|
|
228
|
-
harness: meta?.harness
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
},
|
|
232
|
-
placement: "in-process",
|
|
233
|
-
describe() {
|
|
234
|
-
return `in-process (repoRoot=${options.repoRoot}, harness=profile-selected${options.testCmd ? `, testCmd="${options.testCmd}"` : ""}${options.typecheckCmd ? `, typecheckCmd="${options.typecheckCmd}"` : ""})`;
|
|
235
|
-
}
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
async function defaultRunPostCheck(cmd, cwd, signal) {
|
|
239
|
-
const { spawn } = await import("node:child_process");
|
|
240
|
-
return new Promise((resolve, reject) => {
|
|
241
|
-
const child = spawn("sh", ["-c", cmd], {
|
|
242
|
-
cwd,
|
|
243
|
-
stdio: "pipe"
|
|
244
|
-
});
|
|
245
|
-
let stdout = "";
|
|
246
|
-
let stderr = "";
|
|
247
|
-
child.stdout?.on("data", (c) => {
|
|
248
|
-
stdout += String(c);
|
|
249
|
-
});
|
|
250
|
-
child.stderr?.on("data", (c) => {
|
|
251
|
-
stderr += String(c);
|
|
252
|
-
});
|
|
253
|
-
if (signal) {
|
|
254
|
-
const onAbort = () => {
|
|
255
|
-
if (!child.killed) child.kill("SIGTERM");
|
|
256
|
-
};
|
|
257
|
-
if (signal.aborted) onAbort();
|
|
258
|
-
else signal.addEventListener("abort", onAbort, { once: true });
|
|
259
|
-
}
|
|
260
|
-
const killTimer = setTimeout(() => {
|
|
261
|
-
if (!child.killed) child.kill("SIGTERM");
|
|
262
|
-
}, DEFAULT_POSTCHECK_TIMEOUT_MS);
|
|
263
|
-
if (typeof killTimer.unref === "function") killTimer.unref();
|
|
264
|
-
child.on("error", (err) => {
|
|
265
|
-
clearTimeout(killTimer);
|
|
266
|
-
reject(err);
|
|
267
|
-
});
|
|
268
|
-
child.on("close", (code) => {
|
|
269
|
-
clearTimeout(killTimer);
|
|
270
|
-
resolve({
|
|
271
|
-
exitCode: code ?? -1,
|
|
272
|
-
stdout,
|
|
273
|
-
stderr
|
|
274
|
-
});
|
|
275
|
-
});
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
//#endregion
|
|
279
|
-
//#region src/mcp/bin-helpers.ts
|
|
280
|
-
/**
|
|
281
|
-
* Pick the right executor for an MCP server invocation based on env vars.
|
|
282
|
-
*
|
|
283
|
-
* - `TANGLE_FLEET_ID` set → fleet-workspace placement; resolves the handle
|
|
284
|
-
* via `sandboxClient.fleets.get(...)`.
|
|
285
|
-
* - Otherwise → sibling-sandbox placement; each delegation creates a fresh
|
|
286
|
-
* sandbox via `sandboxClient.create(...)`.
|
|
287
|
-
*
|
|
288
|
-
* Fails loud (throws) when fleet mode is requested but the SDK shape is
|
|
289
|
-
* incompatible — the operator chose fleet semantics, silently degrading to
|
|
290
|
-
* sibling mode would lie about workspace topology.
|
|
291
|
-
*
|
|
292
|
-
* @experimental
|
|
293
|
-
*/
|
|
294
|
-
async function detectExecutor(args) {
|
|
295
|
-
const env = args.env ?? process.env;
|
|
296
|
-
if (env.AGENT_RUNTIME_IN_SANDBOX === "1") {
|
|
297
|
-
const repoRoot = env.AGENT_RUNTIME_REPO_ROOT?.trim();
|
|
298
|
-
if (!repoRoot) throw new Error("agent-runtime-mcp: AGENT_RUNTIME_IN_SANDBOX=1 requires AGENT_RUNTIME_REPO_ROOT to point at the workspace root");
|
|
299
|
-
return createInProcessExecutor({
|
|
300
|
-
repoRoot,
|
|
301
|
-
testCmd: env.AGENT_RUNTIME_TEST_CMD?.trim() || void 0,
|
|
302
|
-
typecheckCmd: env.AGENT_RUNTIME_TYPECHECK_CMD?.trim() || void 0
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
const fleetId = parseFleetId(env.TANGLE_FLEET_ID);
|
|
306
|
-
if (!fleetId) return createSiblingSandboxExecutor({ client: args.sandboxClient });
|
|
307
|
-
return createFleetWorkspaceExecutor({
|
|
308
|
-
fleet: await (args.resolveFleet ?? defaultResolveFleet)(args.sandboxClient, fleetId),
|
|
309
|
-
excludeMachineIds: parseList(env.TANGLE_FLEET_EXCLUDE_MACHINES)
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
async function defaultResolveFleet(sandboxClient, fleetId) {
|
|
313
|
-
const fleets = sandboxClient.fleets;
|
|
314
|
-
if (!fleets || typeof fleets.get !== "function") throw new Error("agent-runtime-mcp: the configured sandbox client does not expose `.fleets.get`; upgrade @tangle-network/sandbox to >= 0.2.1 or unset TANGLE_FLEET_ID.");
|
|
315
|
-
const raw = await fleets.get(fleetId);
|
|
316
|
-
if (!raw || typeof raw !== "object") throw new Error(`agent-runtime-mcp: fleets.get(${fleetId}) returned no handle`);
|
|
317
|
-
const handle = raw;
|
|
318
|
-
if (typeof handle.fleetId !== "string" || !Array.isArray(handle.ids)) throw new Error(`agent-runtime-mcp: fleet handle for ${fleetId} is missing fleetId/ids — incompatible sandbox SDK shape`);
|
|
319
|
-
if (typeof handle.sandbox !== "function") throw new Error(`agent-runtime-mcp: fleet handle for ${fleetId} is missing sandbox(machineId) — incompatible sandbox SDK shape`);
|
|
320
|
-
return handle;
|
|
321
|
-
}
|
|
322
|
-
function parseFleetId(raw) {
|
|
323
|
-
if (typeof raw !== "string") return void 0;
|
|
324
|
-
const trimmed = raw.trim();
|
|
325
|
-
return trimmed.length > 0 ? trimmed : void 0;
|
|
326
|
-
}
|
|
327
|
-
function parseList(raw) {
|
|
328
|
-
if (!raw) return void 0;
|
|
329
|
-
const list = raw.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
330
|
-
return list.length > 0 ? list : void 0;
|
|
331
|
-
}
|
|
332
|
-
//#endregion
|
|
333
16
|
//#region src/mcp/detached-coder.ts
|
|
334
17
|
/**
|
|
335
18
|
*
|
|
@@ -819,51 +502,134 @@ function detachedRunningPhase(elapsedMs) {
|
|
|
819
502
|
function createDetachedTurnResumeDriver(options) {
|
|
820
503
|
const cancelHooked = /* @__PURE__ */ new Set();
|
|
821
504
|
return {
|
|
822
|
-
intervalMs: options.intervalMs ?? DEFAULT_TICK_INTERVAL_MS,
|
|
823
|
-
async tick({ record, detachedSessionRef }, ctx) {
|
|
824
|
-
const ref = parseDetachedSessionRef(detachedSessionRef);
|
|
825
|
-
if (ref.sandboxId === void 0) return {
|
|
826
|
-
state: "failed",
|
|
827
|
-
error: {
|
|
828
|
-
message: `detached session "${ref.sessionId}" was never bound to a sandbox — the previous process died before the box was acquired, so the turn was never dispatched and cannot be resumed`,
|
|
829
|
-
kind: "DetachedSessionUnboundError"
|
|
830
|
-
}
|
|
831
|
-
};
|
|
832
|
-
const box = await options.resolveSandbox(ref.sandboxId);
|
|
833
|
-
if (!cancelHooked.has(record.taskId)) {
|
|
834
|
-
cancelHooked.add(record.taskId);
|
|
835
|
-
ctx.signal.addEventListener("abort", () => {
|
|
836
|
-
box._sessionCancel?.(ref.sessionId).catch(() => {});
|
|
837
|
-
}, { once: true });
|
|
505
|
+
intervalMs: options.intervalMs ?? DEFAULT_TICK_INTERVAL_MS,
|
|
506
|
+
async tick({ record, detachedSessionRef }, ctx) {
|
|
507
|
+
const ref = parseDetachedSessionRef(detachedSessionRef);
|
|
508
|
+
if (ref.sandboxId === void 0) return {
|
|
509
|
+
state: "failed",
|
|
510
|
+
error: {
|
|
511
|
+
message: `detached session "${ref.sessionId}" was never bound to a sandbox — the previous process died before the box was acquired, so the turn was never dispatched and cannot be resumed`,
|
|
512
|
+
kind: "DetachedSessionUnboundError"
|
|
513
|
+
}
|
|
514
|
+
};
|
|
515
|
+
const box = await options.resolveSandbox(ref.sandboxId);
|
|
516
|
+
if (!cancelHooked.has(record.taskId)) {
|
|
517
|
+
cancelHooked.add(record.taskId);
|
|
518
|
+
ctx.signal.addEventListener("abort", () => {
|
|
519
|
+
box._sessionCancel?.(ref.sessionId).catch(() => {});
|
|
520
|
+
}, { once: true });
|
|
521
|
+
}
|
|
522
|
+
if (ctx.signal.aborted) throwAbort();
|
|
523
|
+
const tick = await box.driveTurn(options.buildMessage(record), {
|
|
524
|
+
sessionId: ref.sessionId,
|
|
525
|
+
turnId: ref.sessionId,
|
|
526
|
+
...options.wallCapMs !== void 0 ? { wallCapMs: options.wallCapMs } : {}
|
|
527
|
+
});
|
|
528
|
+
if (tick.state === "completed") return {
|
|
529
|
+
state: "completed",
|
|
530
|
+
output: await options.settleOutput({
|
|
531
|
+
text: tick.text,
|
|
532
|
+
result: tick.result
|
|
533
|
+
}, record, { signal: ctx.signal })
|
|
534
|
+
};
|
|
535
|
+
if (tick.state === "failed") return {
|
|
536
|
+
state: "failed",
|
|
537
|
+
error: {
|
|
538
|
+
message: `detached turn ${ref.sessionId} failed: ${tick.error}`,
|
|
539
|
+
kind: "DetachedTurnFailedError"
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
ctx.report({
|
|
543
|
+
iteration: 0,
|
|
544
|
+
phase: detachedRunningPhase(tick.elapsedMs)
|
|
545
|
+
});
|
|
546
|
+
return { state: "running" };
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
//#endregion
|
|
551
|
+
//#region src/mcp/executor.ts
|
|
552
|
+
/**
|
|
553
|
+
* Wrap a raw sandbox SDK client so the kernel emits
|
|
554
|
+
* `loop.iteration.dispatch` events with `{ placement: 'sibling', sandboxId }`.
|
|
555
|
+
*
|
|
556
|
+
* The returned client `.create()` delegates to the underlying client; the
|
|
557
|
+
* only added behavior is a `describePlacement` tag the kernel reads.
|
|
558
|
+
*
|
|
559
|
+
* @experimental
|
|
560
|
+
*/
|
|
561
|
+
function createSiblingSandboxExecutor(options) {
|
|
562
|
+
const underlying = options.client;
|
|
563
|
+
return {
|
|
564
|
+
client: {
|
|
565
|
+
create(opts) {
|
|
566
|
+
return underlying.create(opts);
|
|
567
|
+
},
|
|
568
|
+
describePlacement(box) {
|
|
569
|
+
return {
|
|
570
|
+
kind: "sibling",
|
|
571
|
+
sandboxId: readId(box)
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
},
|
|
575
|
+
placement: "sibling",
|
|
576
|
+
describe() {
|
|
577
|
+
return "sibling-sandbox (each delegation = fresh sandbox via client.create)";
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Build an executor that resolves each delegated iteration to an existing
|
|
583
|
+
* machine in `fleet`. The fleet's shared-workspace policy means the worker
|
|
584
|
+
* machine sees the caller's filesystem — diffs land in-place with no
|
|
585
|
+
* cross-sandbox copy step.
|
|
586
|
+
*
|
|
587
|
+
* @experimental
|
|
588
|
+
*/
|
|
589
|
+
function createFleetWorkspaceExecutor(options) {
|
|
590
|
+
const fleet = options.fleet;
|
|
591
|
+
const exclude = new Set(options.excludeMachineIds ?? []);
|
|
592
|
+
let callIndex = 0;
|
|
593
|
+
const placementBySandboxId = /* @__PURE__ */ new Map();
|
|
594
|
+
return {
|
|
595
|
+
client: {
|
|
596
|
+
async create() {
|
|
597
|
+
const ids = fleet.ids.filter((id) => !exclude.has(id));
|
|
598
|
+
if (ids.length === 0) throw new Error(`agent-runtime: fleet ${fleet.fleetId} has no eligible worker machines (ids=[${fleet.ids.join(",")}], excluded=[${[...exclude].join(",")}])`);
|
|
599
|
+
const selector = options.selectMachine;
|
|
600
|
+
const machineId = selector ? selector({
|
|
601
|
+
callIndex,
|
|
602
|
+
ids
|
|
603
|
+
}) : ids[callIndex % ids.length];
|
|
604
|
+
callIndex += 1;
|
|
605
|
+
if (typeof machineId !== "string" || machineId.length === 0) throw new Error("agent-runtime: fleet executor selectMachine returned an empty machine id");
|
|
606
|
+
const box = await fleet.sandbox(machineId);
|
|
607
|
+
const sandboxId = readId(box);
|
|
608
|
+
if (sandboxId) placementBySandboxId.set(sandboxId, { machineId });
|
|
609
|
+
return box;
|
|
610
|
+
},
|
|
611
|
+
describePlacement(box) {
|
|
612
|
+
const sandboxId = readId(box);
|
|
613
|
+
const recorded = sandboxId ? placementBySandboxId.get(sandboxId) : void 0;
|
|
614
|
+
return {
|
|
615
|
+
kind: "fleet",
|
|
616
|
+
sandboxId,
|
|
617
|
+
fleetId: fleet.fleetId,
|
|
618
|
+
machineId: recorded?.machineId
|
|
619
|
+
};
|
|
838
620
|
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
});
|
|
845
|
-
if (tick.state === "completed") return {
|
|
846
|
-
state: "completed",
|
|
847
|
-
output: await options.settleOutput({
|
|
848
|
-
text: tick.text,
|
|
849
|
-
result: tick.result
|
|
850
|
-
}, record, { signal: ctx.signal })
|
|
851
|
-
};
|
|
852
|
-
if (tick.state === "failed") return {
|
|
853
|
-
state: "failed",
|
|
854
|
-
error: {
|
|
855
|
-
message: `detached turn ${ref.sessionId} failed: ${tick.error}`,
|
|
856
|
-
kind: "DetachedTurnFailedError"
|
|
857
|
-
}
|
|
858
|
-
};
|
|
859
|
-
ctx.report({
|
|
860
|
-
iteration: 0,
|
|
861
|
-
phase: detachedRunningPhase(tick.elapsedMs)
|
|
862
|
-
});
|
|
863
|
-
return { state: "running" };
|
|
621
|
+
},
|
|
622
|
+
placement: "fleet",
|
|
623
|
+
describe() {
|
|
624
|
+
const excluded = exclude.size > 0 ? ` (excluded=[${[...exclude].join(",")}])` : "";
|
|
625
|
+
return `fleet-workspace (fleetId=${fleet.fleetId}, machines=[${fleet.ids.join(",")}]${excluded})`;
|
|
864
626
|
}
|
|
865
627
|
};
|
|
866
628
|
}
|
|
629
|
+
function readId(box) {
|
|
630
|
+
const raw = box.id;
|
|
631
|
+
return typeof raw === "string" && raw.length > 0 ? raw : void 0;
|
|
632
|
+
}
|
|
867
633
|
//#endregion
|
|
868
634
|
//#region src/mcp/delegates.ts
|
|
869
635
|
/**
|
|
@@ -1169,6 +935,187 @@ function collidesWithHarnessNativeTool(name) {
|
|
|
1169
935
|
return sourcedHarnesses.filter((harness) => harnessNativeTools[harness].some((native) => native.toLowerCase() === wanted));
|
|
1170
936
|
}
|
|
1171
937
|
//#endregion
|
|
1172
|
-
|
|
938
|
+
//#region src/mcp/in-process-executor.ts
|
|
939
|
+
/**
|
|
940
|
+
*
|
|
941
|
+
* In-process delegation executor — when `agent-runtime-mcp` runs inside a sandbox whose image
|
|
942
|
+
* carries the local coding-harness CLIs (claude / codex / opencode), delegations spawn the harness
|
|
943
|
+
* AS A SUBPROCESS against a git worktree on the SAME filesystem instead of provisioning a sibling
|
|
944
|
+
* sandbox. Zero provisioning latency; worker diffs land in-place; multi-harness fanout = N parallel
|
|
945
|
+
* subprocesses in N parallel worktrees. Each authored profile selects its own harness.
|
|
946
|
+
*
|
|
947
|
+
* This is a THIN adapter over `runWorktreeHarness` (`./worktree-harness`) — the SAME core the
|
|
948
|
+
* `Scope` leaf `createWorktreeCliExecutor` uses. It only adapts the core to the `SandboxClient`
|
|
949
|
+
* port: `create()` reads the authored profile from `CreateSandboxOptions.backend.profile`, and
|
|
950
|
+
* `streamPrompt` runs the core then emits its raw `WorktreeHarnessResult` (the content-addressed
|
|
951
|
+
* patch artifact) on the `result` event. The sandbox-session decode layer
|
|
952
|
+
* (`./detached-coder`) projects that artifact onto `CoderOutput`; the generic `Scope` path settles
|
|
953
|
+
* the artifact directly. The §1.5 payload (systemPrompt + model) reaches the harness inside the core.
|
|
954
|
+
*
|
|
955
|
+
* @experimental
|
|
956
|
+
*/
|
|
957
|
+
const DEFAULT_POSTCHECK_TIMEOUT_MS = 120 * 1e3;
|
|
958
|
+
/**
|
|
959
|
+
* Build an in-process executor. Returns a {@link DelegationExecutor} whose `client.create()`
|
|
960
|
+
* returns a minimal virtual `SandboxInstance`; the kernel calls `streamPrompt(msg)` on it, which
|
|
961
|
+
* runs the shared worktree-harness core and emits one `result` event whose `data.result` is the
|
|
962
|
+
* raw `WorktreeHarnessResult` (the content-addressed patch artifact). The authored profile
|
|
963
|
+
* (`backend.profile`) threads its systemPrompt + model into the harness via the core.
|
|
964
|
+
*
|
|
965
|
+
* There is no box, so a per-prompt `backend` or `model` override is refused rather than dropped;
|
|
966
|
+
* other per-prompt options (`timeoutMs`, `context`) are accepted and ignored.
|
|
967
|
+
*
|
|
968
|
+
* @experimental
|
|
969
|
+
*/
|
|
970
|
+
function createInProcessExecutor(options) {
|
|
971
|
+
const runPostCheck = options.runPostCheck ?? defaultRunPostCheck;
|
|
972
|
+
const runCommand = async ({ command, cwd, signal }) => {
|
|
973
|
+
try {
|
|
974
|
+
const r = await runPostCheck(command, cwd, signal);
|
|
975
|
+
return {
|
|
976
|
+
exitCode: r.exitCode,
|
|
977
|
+
output: r.stderr || r.stdout
|
|
978
|
+
};
|
|
979
|
+
} catch (err) {
|
|
980
|
+
return {
|
|
981
|
+
exitCode: -1,
|
|
982
|
+
output: err instanceof Error ? err.message : String(err)
|
|
983
|
+
};
|
|
984
|
+
}
|
|
985
|
+
};
|
|
986
|
+
return {
|
|
987
|
+
client: {
|
|
988
|
+
async create(opts) {
|
|
989
|
+
const rawProfile = (opts?.backend)?.profile;
|
|
990
|
+
if (rawProfile === void 0) throw new ConfigError("in-process executor: backend.profile is required and must select the exact harness, provider, and model");
|
|
991
|
+
const profile = agentProfileSchema.parse(rawProfile);
|
|
992
|
+
assertExecutableAgentProfile(profile, "in-process executor");
|
|
993
|
+
const harness = profile.harness;
|
|
994
|
+
if (!LOCAL_HARNESSES.includes(harness)) throw new ConfigError(`in-process executor: AgentProfile.harness ${JSON.stringify(harness)} is not a local harness; expected ${LOCAL_HARNESSES.join(", ")}`);
|
|
995
|
+
if (opts?.backend?.type !== void 0 && opts.backend.type !== harness) throw new ConfigError(`in-process executor: backend.type ${JSON.stringify(opts.backend.type)} conflicts with AgentProfile.harness ${JSON.stringify(harness)}`);
|
|
996
|
+
const localHarness = harness;
|
|
997
|
+
const runId = randomUUID();
|
|
998
|
+
return {
|
|
999
|
+
id: `in-process-${runId}`,
|
|
1000
|
+
__inProcess: {
|
|
1001
|
+
runId,
|
|
1002
|
+
harness: localHarness
|
|
1003
|
+
},
|
|
1004
|
+
async *streamPrompt(message, promptOpts) {
|
|
1005
|
+
assertBoxlessPromptOptions(promptOpts, "in-process executor");
|
|
1006
|
+
const taskPrompt = typeof message === "string" ? message : message.map((p) => typeof p === "object" && p && "text" in p ? String(p.text) : "").join("\n");
|
|
1007
|
+
const run = await runWorktreeHarness({
|
|
1008
|
+
repoRoot: options.repoRoot,
|
|
1009
|
+
profile,
|
|
1010
|
+
harness: localHarness,
|
|
1011
|
+
taskPrompt,
|
|
1012
|
+
runId,
|
|
1013
|
+
...options.harnessTimeoutMs !== void 0 ? { harnessTimeoutMs: options.harnessTimeoutMs } : {},
|
|
1014
|
+
checkTimeoutMs: options.postCheckTimeoutMs ?? DEFAULT_POSTCHECK_TIMEOUT_MS,
|
|
1015
|
+
...options.testCmd !== void 0 ? { testCmd: options.testCmd } : {},
|
|
1016
|
+
...options.typecheckCmd !== void 0 ? { typecheckCmd: options.typecheckCmd } : {},
|
|
1017
|
+
...options.runGit ? { runGit: options.runGit } : {},
|
|
1018
|
+
...options.runHarness ? { runHarness: options.runHarness } : {},
|
|
1019
|
+
runCommand,
|
|
1020
|
+
...promptOpts?.signal ? { signal: promptOpts.signal } : {}
|
|
1021
|
+
});
|
|
1022
|
+
this.__inProcess.worktree = run.worktree;
|
|
1023
|
+
try {
|
|
1024
|
+
yield {
|
|
1025
|
+
type: "in_process.harness.started",
|
|
1026
|
+
data: {
|
|
1027
|
+
runId,
|
|
1028
|
+
harness: localHarness,
|
|
1029
|
+
worktreePath: run.worktree.path,
|
|
1030
|
+
command: localHarness
|
|
1031
|
+
}
|
|
1032
|
+
};
|
|
1033
|
+
const h = run.result.harness;
|
|
1034
|
+
yield {
|
|
1035
|
+
type: "in_process.harness.ended",
|
|
1036
|
+
data: {
|
|
1037
|
+
runId,
|
|
1038
|
+
exitCode: h.exitCode,
|
|
1039
|
+
durationMs: h.durationMs,
|
|
1040
|
+
killedBySignal: h.killedBySignal,
|
|
1041
|
+
timedOut: h.timedOut,
|
|
1042
|
+
stdoutBytes: h.stdout.length,
|
|
1043
|
+
stderrBytes: h.stderr.length
|
|
1044
|
+
}
|
|
1045
|
+
};
|
|
1046
|
+
yield {
|
|
1047
|
+
type: "result",
|
|
1048
|
+
data: {
|
|
1049
|
+
result: run.result,
|
|
1050
|
+
source: "in-process-executor",
|
|
1051
|
+
harness: localHarness,
|
|
1052
|
+
runId
|
|
1053
|
+
}
|
|
1054
|
+
};
|
|
1055
|
+
} finally {
|
|
1056
|
+
await run.cleanup();
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
};
|
|
1060
|
+
},
|
|
1061
|
+
describePlacement(box) {
|
|
1062
|
+
const sandboxId = box.id;
|
|
1063
|
+
const meta = box.__inProcess;
|
|
1064
|
+
return {
|
|
1065
|
+
kind: "in-process",
|
|
1066
|
+
sandboxId,
|
|
1067
|
+
worktreePath: meta?.worktree?.path,
|
|
1068
|
+
harness: meta?.harness
|
|
1069
|
+
};
|
|
1070
|
+
}
|
|
1071
|
+
},
|
|
1072
|
+
placement: "in-process",
|
|
1073
|
+
describe() {
|
|
1074
|
+
return `in-process (repoRoot=${options.repoRoot}, harness=profile-selected${options.testCmd ? `, testCmd="${options.testCmd}"` : ""}${options.typecheckCmd ? `, typecheckCmd="${options.typecheckCmd}"` : ""})`;
|
|
1075
|
+
}
|
|
1076
|
+
};
|
|
1077
|
+
}
|
|
1078
|
+
async function defaultRunPostCheck(cmd, cwd, signal) {
|
|
1079
|
+
const { spawn } = await import("node:child_process");
|
|
1080
|
+
return new Promise((resolve, reject) => {
|
|
1081
|
+
const child = spawn("sh", ["-c", cmd], {
|
|
1082
|
+
cwd,
|
|
1083
|
+
stdio: "pipe"
|
|
1084
|
+
});
|
|
1085
|
+
let stdout = "";
|
|
1086
|
+
let stderr = "";
|
|
1087
|
+
child.stdout?.on("data", (c) => {
|
|
1088
|
+
stdout += String(c);
|
|
1089
|
+
});
|
|
1090
|
+
child.stderr?.on("data", (c) => {
|
|
1091
|
+
stderr += String(c);
|
|
1092
|
+
});
|
|
1093
|
+
if (signal) {
|
|
1094
|
+
const onAbort = () => {
|
|
1095
|
+
if (!child.killed) child.kill("SIGTERM");
|
|
1096
|
+
};
|
|
1097
|
+
if (signal.aborted) onAbort();
|
|
1098
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
1099
|
+
}
|
|
1100
|
+
const killTimer = setTimeout(() => {
|
|
1101
|
+
if (!child.killed) child.kill("SIGTERM");
|
|
1102
|
+
}, DEFAULT_POSTCHECK_TIMEOUT_MS);
|
|
1103
|
+
if (typeof killTimer.unref === "function") killTimer.unref();
|
|
1104
|
+
child.on("error", (err) => {
|
|
1105
|
+
clearTimeout(killTimer);
|
|
1106
|
+
reject(err);
|
|
1107
|
+
});
|
|
1108
|
+
child.on("close", (code) => {
|
|
1109
|
+
clearTimeout(killTimer);
|
|
1110
|
+
resolve({
|
|
1111
|
+
exitCode: code ?? -1,
|
|
1112
|
+
stdout,
|
|
1113
|
+
stderr
|
|
1114
|
+
});
|
|
1115
|
+
});
|
|
1116
|
+
});
|
|
1117
|
+
}
|
|
1118
|
+
//#endregion
|
|
1119
|
+
export { ANALYST_DEFINITION_BOUNDS, CodexExecutionDiagnosticError, DEFAULT_LOCAL_HARNESS, DELEGATE_DESCRIPTION, DELEGATE_FEEDBACK_DESCRIPTION, DELEGATE_FEEDBACK_INPUT_SCHEMA, DELEGATE_FEEDBACK_TOOL_NAME, DELEGATE_INPUT_SCHEMA, DELEGATE_TOOL_NAME, DELEGATE_UI_AUDIT_DESCRIPTION, DELEGATE_UI_AUDIT_INPUT_SCHEMA, DELEGATE_UI_AUDIT_TOOL_NAME, DELEGATION_HISTORY_DESCRIPTION, DELEGATION_HISTORY_INPUT_SCHEMA, DELEGATION_HISTORY_TOOL_NAME, DELEGATION_STATUS_DESCRIPTION, DELEGATION_STATUS_INPUT_SCHEMA, DELEGATION_STATUS_TOOL_NAME, DELEGATION_TRACE_MAX_BYTES, DELEGATION_TRACE_MAX_SPANS, DelegationPersistenceError, DelegationStateCorruptError, DelegationTaskQueue, FileDelegationStore, InMemoryDelegationStore, InMemoryFeedbackStore, LOCAL_HARNESSES, MEMORY_FILE_ENV, MEMORY_ITEMS_ENV, MEMORY_LOG_ENV, MEMORY_NAME_ENV, SPAWN_RESOURCE_PATH_MAX_BYTES, SUPPORTED_PROTOCOL_VERSIONS, analystToolGroupNames, buildDelegationTraceSpans, capDelegationTrace, captureWorktreeDiff, coderTaskFromArgs, collidesWithHarnessNativeTool, composeLoopTraceEmitters, createCoordinationTools, createDelegateFeedbackHandler, createDelegateHandler, createDelegateUiAuditHandler, createDelegationHistoryHandler, createDelegationStatusHandler, createDelegationTraceCollector, createDetachedTurnResumeDriver, createFleetWorkspaceExecutor, createInProcessExecutor, createInProcessTransport, createKbGate, createMcpServer, createMemoryToolServer, createPropagatingTraceEmitter, createSiblingSandboxExecutor, createStdioToolServer, createWorktree, delegationProfiles, detachedSessionDelegate, detachedTurnEvents, downMessageRefusalReasons, environmentReader, eventToSnapshot, formatDetachedSessionRef, harnessNativeToolNames, harnessNativeTools, harnessSupportsReasoningEffort, hashIdempotencyInput, hostDirectoryReader, localHarnessExecutable, mcpToolsForRuntimeMcp, mcpToolsForRuntimeMcpSubset, mergeTraceEnv, parseAuthoredAnalystDefinition, parseCodexTokenUsage, parseDetachedSessionRef, parseMemoryItems, questionEscalationTargets, readMemoryItemsFile, readTraceContextFromEnv, removeWorktree, resolveMemoryFromEnv, resolveSpawnResourcePaths, runDetachedTurn, settleDetachedCoderTurn, sourcedHarnesses, traceContextToEnv, validateDelegateArgs, validateDelegateFeedbackArgs, validateDelegateUiAuditArgs, validateDelegationHistoryArgs, validateDelegationStatusArgs };
|
|
1173
1120
|
|
|
1174
1121
|
//# sourceMappingURL=index.js.map
|