@tangle-network/agent-runtime 0.71.1 → 0.72.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.
Files changed (55) hide show
  1. package/README.md +8 -8
  2. package/dist/agent.d.ts +27 -17
  3. package/dist/agent.js +19 -8
  4. package/dist/agent.js.map +1 -1
  5. package/dist/analyst-loop.d.ts +1 -1
  6. package/dist/{chunk-5ISW5JUF.js → chunk-55WKGOGU.js} +1907 -6534
  7. package/dist/chunk-55WKGOGU.js.map +1 -0
  8. package/dist/{chunk-K3RM4MPM.js → chunk-HXVMLRYU.js} +5 -20
  9. package/dist/chunk-HXVMLRYU.js.map +1 -0
  10. package/dist/chunk-PBE35ULD.js +52 -0
  11. package/dist/chunk-PBE35ULD.js.map +1 -0
  12. package/dist/chunk-PHKNOAOU.js +4021 -0
  13. package/dist/chunk-PHKNOAOU.js.map +1 -0
  14. package/dist/chunk-UZ5SODU7.js +29 -0
  15. package/dist/chunk-UZ5SODU7.js.map +1 -0
  16. package/dist/{chunk-4KGQHS7U.js → chunk-VYXBFWHZ.js} +2 -18
  17. package/dist/chunk-VYXBFWHZ.js.map +1 -0
  18. package/dist/{delegates-CsXJPZDH.d.ts → coordination-CFVF0OzX.d.ts} +869 -1099
  19. package/dist/index.d.ts +7 -8
  20. package/dist/index.js +4 -7
  21. package/dist/index.js.map +1 -1
  22. package/dist/intelligence.d.ts +1 -1
  23. package/dist/{loop-runner-bin-DLM_bVQO.d.ts → loop-runner-bin-B7biH0Gk.d.ts} +10 -27
  24. package/dist/loop-runner-bin.d.ts +5 -6
  25. package/dist/loop-runner-bin.js +3 -4
  26. package/dist/loops.d.ts +10 -9
  27. package/dist/loops.js +43 -41
  28. package/dist/mcp/bin.js +13 -326
  29. package/dist/mcp/bin.js.map +1 -1
  30. package/dist/mcp/index.d.ts +10 -190
  31. package/dist/mcp/index.js +948 -47
  32. package/dist/mcp/index.js.map +1 -1
  33. package/dist/{openai-tools-kdCS-T12.d.ts → openai-tools-DOI5mKNw.d.ts} +11 -13
  34. package/dist/otel-export-BKmNwiCb.d.ts +180 -0
  35. package/dist/profiles.d.ts +3 -3
  36. package/dist/profiles.js +1 -5
  37. package/dist/profiles.js.map +1 -1
  38. package/dist/{substrate-BoRXgvka.d.ts → substrate-rNj6TDc3.d.ts} +7 -23
  39. package/dist/{types-CdnEAE3U.d.ts → types-K8-xkiw1.d.ts} +1 -1
  40. package/dist/worktree-JXGJ1MxQ.d.ts +702 -0
  41. package/dist/{worktree-fanout-CK2ypmEm.d.ts → worktree-fanout-DJHQy7Ux.d.ts} +2 -2
  42. package/package.json +1 -1
  43. package/dist/chunk-4KGQHS7U.js.map +0 -1
  44. package/dist/chunk-5ISW5JUF.js.map +0 -1
  45. package/dist/chunk-74UAWZXE.js +0 -278
  46. package/dist/chunk-74UAWZXE.js.map +0 -1
  47. package/dist/chunk-DVQGYDN5.js +0 -59
  48. package/dist/chunk-DVQGYDN5.js.map +0 -1
  49. package/dist/chunk-INXDNX2W.js +0 -475
  50. package/dist/chunk-INXDNX2W.js.map +0 -1
  51. package/dist/chunk-K3RM4MPM.js.map +0 -1
  52. package/dist/chunk-XRYEZPR6.js +0 -88
  53. package/dist/chunk-XRYEZPR6.js.map +0 -1
  54. package/dist/coordination-BPQmuwv8.d.ts +0 -666
  55. package/dist/delegation-profile-Bvfro2m1.d.ts +0 -99
package/dist/mcp/index.js CHANGED
@@ -1,41 +1,26 @@
1
1
  import {
2
- createInProcessExecutor,
3
2
  createPropagatingTraceEmitter,
4
- detectExecutor,
5
3
  readTraceContextFromEnv,
6
4
  traceContextToEnv
7
- } from "../chunk-74UAWZXE.js";
5
+ } from "../chunk-PBE35ULD.js";
8
6
  import {
9
7
  mcpToolsForRuntimeMcp,
10
8
  mcpToolsForRuntimeMcpSubset
11
- } from "../chunk-4KGQHS7U.js";
9
+ } from "../chunk-VYXBFWHZ.js";
12
10
  import {
13
11
  createKbGate
14
12
  } from "../chunk-FNMGYYSS.js";
15
13
  import {
16
- coderTaskFromArgs,
17
- createFleetWorkspaceExecutor,
18
- createSiblingSandboxExecutor,
19
- detachedSessionDelegate,
20
- settleDetachedCoderTurn
21
- } from "../chunk-INXDNX2W.js";
22
- import {
23
- DELEGATION_MCP_SERVER_KEY,
24
- buildDelegationMcpServer,
25
- composeProductionAgentProfile
26
- } from "../chunk-XRYEZPR6.js";
14
+ assertTraceDerivedFindings,
15
+ runCoderChecks,
16
+ selectValidWinner
17
+ } from "../chunk-PHKNOAOU.js";
27
18
  import {
28
- DELEGATE_CODE_DESCRIPTION,
29
- DELEGATE_CODE_INPUT_SCHEMA,
30
- DELEGATE_CODE_TOOL_NAME,
31
19
  DELEGATE_DESCRIPTION,
32
20
  DELEGATE_FEEDBACK_DESCRIPTION,
33
21
  DELEGATE_FEEDBACK_INPUT_SCHEMA,
34
22
  DELEGATE_FEEDBACK_TOOL_NAME,
35
23
  DELEGATE_INPUT_SCHEMA,
36
- DELEGATE_RESEARCH_DESCRIPTION,
37
- DELEGATE_RESEARCH_INPUT_SCHEMA,
38
- DELEGATE_RESEARCH_TOOL_NAME,
39
24
  DELEGATE_TOOL_NAME,
40
25
  DELEGATE_UI_AUDIT_DESCRIPTION,
41
26
  DELEGATE_UI_AUDIT_INPUT_SCHEMA,
@@ -54,46 +39,975 @@ import {
54
39
  FileDelegationStore,
55
40
  InMemoryDelegationStore,
56
41
  InMemoryFeedbackStore,
57
- assertTraceDerivedFindings,
58
42
  buildDelegationTraceSpans,
59
43
  capDelegationTrace,
60
44
  captureWorktreeDiff,
61
45
  composeLoopTraceEmitters,
62
46
  createCoordinationTools,
63
- createDelegateCodeHandler,
64
47
  createDelegateFeedbackHandler,
65
48
  createDelegateHandler,
66
- createDelegateResearchHandler,
67
49
  createDelegateUiAuditHandler,
68
50
  createDelegationHistoryHandler,
69
51
  createDelegationStatusHandler,
70
52
  createDelegationTraceCollector,
71
- createDetachedTurnResumeDriver,
72
53
  createInProcessTransport,
73
54
  createMcpServer,
55
+ createSandboxForSpec,
74
56
  createWorktree,
75
- detachedTurnEvents,
57
+ deleteBoxSafe,
76
58
  eventToSnapshot,
77
- formatDetachedSessionRef,
78
59
  hashIdempotencyInput,
79
- parseDetachedSessionRef,
80
60
  removeWorktree,
81
- runDetachedTurn,
82
61
  runLocalHarness,
62
+ runLoop,
63
+ runWorktreeHarness,
64
+ sleep,
65
+ throwAbort,
66
+ throwIfAborted,
83
67
  validateDelegateArgs,
84
- validateDelegateCodeArgs,
85
68
  validateDelegateFeedbackArgs,
86
- validateDelegateResearchArgs,
87
69
  validateDelegateUiAuditArgs,
88
70
  validateDelegationHistoryArgs,
89
71
  validateDelegationStatusArgs
90
- } from "../chunk-5ISW5JUF.js";
72
+ } from "../chunk-55WKGOGU.js";
91
73
  import "../chunk-VMNEQHJR.js";
92
- import "../chunk-VLF5RHEQ.js";
93
- import "../chunk-DVQGYDN5.js";
74
+ import {
75
+ ValidationError
76
+ } from "../chunk-VLF5RHEQ.js";
77
+ import {
78
+ coderTaskToPrompt
79
+ } from "../chunk-UZ5SODU7.js";
94
80
  import "../chunk-WIR4HOOJ.js";
95
81
  import "../chunk-DGUM43GV.js";
96
82
 
83
+ // src/mcp/executor.ts
84
+ function createSiblingSandboxExecutor(options) {
85
+ const underlying = options.client;
86
+ const client = {
87
+ create(opts) {
88
+ return underlying.create(opts);
89
+ },
90
+ describePlacement(box) {
91
+ return { kind: "sibling", sandboxId: readId(box) };
92
+ }
93
+ };
94
+ return {
95
+ client,
96
+ placement: "sibling",
97
+ describe() {
98
+ return "sibling-sandbox (each delegation = fresh sandbox via client.create)";
99
+ }
100
+ };
101
+ }
102
+ function createFleetWorkspaceExecutor(options) {
103
+ const fleet = options.fleet;
104
+ const exclude = new Set(options.excludeMachineIds ?? []);
105
+ let callIndex = 0;
106
+ const placementBySandboxId = /* @__PURE__ */ new Map();
107
+ const client = {
108
+ async create() {
109
+ const ids = fleet.ids.filter((id) => !exclude.has(id));
110
+ if (ids.length === 0) {
111
+ throw new Error(
112
+ `agent-runtime: fleet ${fleet.fleetId} has no eligible worker machines (ids=[${fleet.ids.join(",")}], excluded=[${[...exclude].join(",")}])`
113
+ );
114
+ }
115
+ const selector = options.selectMachine;
116
+ const machineId = selector ? selector({ callIndex, ids }) : ids[callIndex % ids.length];
117
+ callIndex += 1;
118
+ if (typeof machineId !== "string" || machineId.length === 0) {
119
+ throw new Error("agent-runtime: fleet executor selectMachine returned an empty machine id");
120
+ }
121
+ const box = await fleet.sandbox(machineId);
122
+ const sandboxId = readId(box);
123
+ if (sandboxId) placementBySandboxId.set(sandboxId, { machineId });
124
+ return box;
125
+ },
126
+ describePlacement(box) {
127
+ const sandboxId = readId(box);
128
+ const recorded = sandboxId ? placementBySandboxId.get(sandboxId) : void 0;
129
+ return {
130
+ kind: "fleet",
131
+ sandboxId,
132
+ fleetId: fleet.fleetId,
133
+ machineId: recorded?.machineId
134
+ };
135
+ }
136
+ };
137
+ return {
138
+ client,
139
+ placement: "fleet",
140
+ describe() {
141
+ const excluded = exclude.size > 0 ? ` (excluded=[${[...exclude].join(",")}])` : "";
142
+ return `fleet-workspace (fleetId=${fleet.fleetId}, machines=[${fleet.ids.join(",")}]${excluded})`;
143
+ }
144
+ };
145
+ }
146
+ function readId(box) {
147
+ const raw = box.id;
148
+ return typeof raw === "string" && raw.length > 0 ? raw : void 0;
149
+ }
150
+
151
+ // src/mcp/in-process-executor.ts
152
+ import { randomUUID } from "crypto";
153
+ var DEFAULT_HARNESS_TIMEOUT_MS = 5 * 60 * 1e3;
154
+ var DEFAULT_POSTCHECK_TIMEOUT_MS = 2 * 60 * 1e3;
155
+ function createInProcessExecutor(options) {
156
+ const harnesses = options.harnesses && options.harnesses.length > 0 ? [...options.harnesses] : ["claude"];
157
+ const runPostCheck = options.runPostCheck ?? defaultRunPostCheck;
158
+ const runCommand = async ({
159
+ command,
160
+ cwd,
161
+ signal
162
+ }) => {
163
+ try {
164
+ const r = await runPostCheck(command, cwd, signal);
165
+ return { exitCode: r.exitCode, output: r.stderr || r.stdout };
166
+ } catch (err) {
167
+ return { exitCode: -1, output: err instanceof Error ? err.message : String(err) };
168
+ }
169
+ };
170
+ let callIndex = 0;
171
+ const client = {
172
+ async create(opts) {
173
+ const runId = randomUUID();
174
+ const harness = harnesses[callIndex % harnesses.length];
175
+ callIndex += 1;
176
+ const profile = opts?.backend?.profile ?? { name: `in-process-${harness}` };
177
+ const virtual = {
178
+ id: `in-process-${runId}`,
179
+ __inProcess: { runId, harness },
180
+ async *streamPrompt(message, promptOpts) {
181
+ const taskPrompt = typeof message === "string" ? message : message.map(
182
+ (p) => typeof p === "object" && p && "text" in p ? String(p.text) : ""
183
+ ).join("\n");
184
+ const run = await runWorktreeHarness({
185
+ repoRoot: options.repoRoot,
186
+ profile,
187
+ harness,
188
+ taskPrompt,
189
+ runId,
190
+ harnessTimeoutMs: options.harnessTimeoutMs ?? DEFAULT_HARNESS_TIMEOUT_MS,
191
+ checkTimeoutMs: options.postCheckTimeoutMs ?? DEFAULT_POSTCHECK_TIMEOUT_MS,
192
+ ...options.testCmd !== void 0 ? { testCmd: options.testCmd } : {},
193
+ ...options.typecheckCmd !== void 0 ? { typecheckCmd: options.typecheckCmd } : {},
194
+ ...options.runGit ? { runGit: options.runGit } : {},
195
+ ...options.runHarness ? { runHarness: options.runHarness } : {},
196
+ runCommand,
197
+ ...promptOpts?.signal ? { signal: promptOpts.signal } : {}
198
+ });
199
+ this.__inProcess.worktree = run.worktree;
200
+ try {
201
+ yield {
202
+ type: "in_process.harness.started",
203
+ data: { runId, harness, worktreePath: run.worktree.path, command: harness }
204
+ };
205
+ const h = run.result.harness;
206
+ yield {
207
+ type: "in_process.harness.ended",
208
+ data: {
209
+ runId,
210
+ exitCode: h.exitCode,
211
+ durationMs: h.durationMs,
212
+ killedBySignal: h.killedBySignal,
213
+ timedOut: h.timedOut,
214
+ stdoutBytes: h.stdout.length,
215
+ stderrBytes: h.stderr.length
216
+ }
217
+ };
218
+ yield {
219
+ type: "result",
220
+ data: {
221
+ result: run.result,
222
+ source: "in-process-executor",
223
+ harness,
224
+ runId
225
+ }
226
+ };
227
+ } finally {
228
+ await run.cleanup();
229
+ }
230
+ }
231
+ };
232
+ return virtual;
233
+ },
234
+ describePlacement(box) {
235
+ const sandboxId = box.id;
236
+ const meta = box.__inProcess;
237
+ return {
238
+ kind: "sibling",
239
+ sandboxId,
240
+ worktreePath: meta?.worktree?.path,
241
+ harness: meta?.harness
242
+ };
243
+ }
244
+ };
245
+ return {
246
+ client,
247
+ placement: "in-process",
248
+ describe() {
249
+ return `in-process (repoRoot=${options.repoRoot}, harnesses=[${harnesses.join(",")}]${options.testCmd ? `, testCmd="${options.testCmd}"` : ""}${options.typecheckCmd ? `, typecheckCmd="${options.typecheckCmd}"` : ""})`;
250
+ }
251
+ };
252
+ }
253
+ async function defaultRunPostCheck(cmd, cwd, signal) {
254
+ const { spawn } = await import("child_process");
255
+ return new Promise((resolve, reject) => {
256
+ const child = spawn("sh", ["-c", cmd], { cwd, stdio: "pipe" });
257
+ let stdout = "";
258
+ let stderr = "";
259
+ child.stdout?.on("data", (c) => {
260
+ stdout += String(c);
261
+ });
262
+ child.stderr?.on("data", (c) => {
263
+ stderr += String(c);
264
+ });
265
+ if (signal) {
266
+ const onAbort = () => {
267
+ if (!child.killed) child.kill("SIGTERM");
268
+ };
269
+ if (signal.aborted) onAbort();
270
+ else signal.addEventListener("abort", onAbort, { once: true });
271
+ }
272
+ const killTimer = setTimeout(() => {
273
+ if (!child.killed) child.kill("SIGTERM");
274
+ }, DEFAULT_POSTCHECK_TIMEOUT_MS);
275
+ if (typeof killTimer.unref === "function") {
276
+ ;
277
+ killTimer.unref();
278
+ }
279
+ child.on("error", (err) => {
280
+ clearTimeout(killTimer);
281
+ reject(err);
282
+ });
283
+ child.on("close", (code) => {
284
+ clearTimeout(killTimer);
285
+ resolve({ exitCode: code ?? -1, stdout, stderr });
286
+ });
287
+ });
288
+ }
289
+
290
+ // src/mcp/bin-helpers.ts
291
+ async function detectExecutor(args) {
292
+ const env = args.env ?? process.env;
293
+ if (env.AGENT_RUNTIME_IN_SANDBOX === "1") {
294
+ const repoRoot = env.AGENT_RUNTIME_REPO_ROOT?.trim();
295
+ if (!repoRoot) {
296
+ throw new Error(
297
+ "agent-runtime-mcp: AGENT_RUNTIME_IN_SANDBOX=1 requires AGENT_RUNTIME_REPO_ROOT to point at the workspace root"
298
+ );
299
+ }
300
+ return createInProcessExecutor({
301
+ repoRoot,
302
+ harnesses: parseHarnesses(env.AGENT_RUNTIME_LOCAL_HARNESSES),
303
+ testCmd: env.AGENT_RUNTIME_TEST_CMD?.trim() || void 0,
304
+ typecheckCmd: env.AGENT_RUNTIME_TYPECHECK_CMD?.trim() || void 0
305
+ });
306
+ }
307
+ const fleetId = parseFleetId(env.TANGLE_FLEET_ID);
308
+ if (!fleetId) {
309
+ return createSiblingSandboxExecutor({ client: args.sandboxClient });
310
+ }
311
+ const resolveFleet = args.resolveFleet ?? defaultResolveFleet;
312
+ const fleet = await resolveFleet(args.sandboxClient, fleetId);
313
+ const excludeMachineIds = parseList(env.TANGLE_FLEET_EXCLUDE_MACHINES);
314
+ return createFleetWorkspaceExecutor({
315
+ fleet,
316
+ excludeMachineIds
317
+ });
318
+ }
319
+ var KNOWN_HARNESSES = ["claude", "codex", "opencode"];
320
+ function parseHarnesses(raw) {
321
+ if (!raw) return void 0;
322
+ const parts = raw.split(",").map((s) => s.trim()).filter(Boolean);
323
+ if (parts.length === 0) return void 0;
324
+ for (const part of parts) {
325
+ if (!KNOWN_HARNESSES.includes(part)) {
326
+ throw new Error(
327
+ `agent-runtime-mcp: AGENT_RUNTIME_LOCAL_HARNESSES contains unknown harness "${part}". Expected: ${KNOWN_HARNESSES.join(", ")}.`
328
+ );
329
+ }
330
+ }
331
+ return parts;
332
+ }
333
+ async function defaultResolveFleet(sandboxClient, fleetId) {
334
+ const fleets = sandboxClient.fleets;
335
+ if (!fleets || typeof fleets.get !== "function") {
336
+ throw new Error(
337
+ "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."
338
+ );
339
+ }
340
+ const raw = await fleets.get(fleetId);
341
+ if (!raw || typeof raw !== "object") {
342
+ throw new Error(`agent-runtime-mcp: fleets.get(${fleetId}) returned no handle`);
343
+ }
344
+ const handle = raw;
345
+ if (typeof handle.fleetId !== "string" || !Array.isArray(handle.ids)) {
346
+ throw new Error(
347
+ `agent-runtime-mcp: fleet handle for ${fleetId} is missing fleetId/ids \u2014 incompatible sandbox SDK shape`
348
+ );
349
+ }
350
+ if (typeof handle.sandbox !== "function") {
351
+ throw new Error(
352
+ `agent-runtime-mcp: fleet handle for ${fleetId} is missing sandbox(machineId) \u2014 incompatible sandbox SDK shape`
353
+ );
354
+ }
355
+ return handle;
356
+ }
357
+ function parseFleetId(raw) {
358
+ if (typeof raw !== "string") return void 0;
359
+ const trimmed = raw.trim();
360
+ return trimmed.length > 0 ? trimmed : void 0;
361
+ }
362
+ function parseList(raw) {
363
+ if (!raw) return void 0;
364
+ const list = raw.split(",").map((entry) => entry.trim()).filter(Boolean);
365
+ return list.length > 0 ? list : void 0;
366
+ }
367
+
368
+ // src/mcp/detached-coder.ts
369
+ var DEFAULT_MAX_DIFF_LINES = 400;
370
+ function minimalCoderProfile() {
371
+ return { name: "coder" };
372
+ }
373
+ function coderRunProfile(options) {
374
+ const harness = options.harness ?? "claude-code";
375
+ const name = options.name ?? `coder-${harness}`;
376
+ const base = options.profile ?? minimalCoderProfile();
377
+ return {
378
+ ...base,
379
+ name,
380
+ ...options.systemPrompt ? { prompt: { systemPrompt: options.systemPrompt } } : {},
381
+ model: options.model ? { default: options.model } : base.model,
382
+ metadata: { ...base.metadata, backendType: harness }
383
+ };
384
+ }
385
+ function coderRunSpec(options = {}) {
386
+ return {
387
+ name: options.name ?? `coder-${options.harness ?? "claude-code"}`,
388
+ profile: coderRunProfile(options),
389
+ taskToPrompt: coderTaskToPrompt
390
+ };
391
+ }
392
+ var coderOutputAdapter = { parse: parseCoderEvents };
393
+ function multiHarnessCoderFanout(options = {}) {
394
+ const harnesses = options.harnesses && options.harnesses.length > 0 ? options.harnesses : ["claude-code", "codex", "opencode/zai-coding-plan/glm-5.1"];
395
+ const models = options.models ?? [];
396
+ const agentRuns = harnesses.map(
397
+ (harness, i) => coderRunSpec({
398
+ ...options.profile ? { profile: options.profile } : {},
399
+ harness,
400
+ model: models[i]
401
+ })
402
+ );
403
+ const driver = {
404
+ name: "fanout",
405
+ plan: async (task, history) => history.length === 0 ? agentRuns.map(() => task) : [],
406
+ decide: (history) => history.some((i) => i.verdict?.valid === true) ? "pick-winner" : "fail"
407
+ };
408
+ return { agentRuns, output: coderOutputAdapter, validator: defaultCoderValidator(), driver };
409
+ }
410
+ function createCoderValidator(task) {
411
+ const constraints = {
412
+ maxDiffLines: task.maxDiffLines ?? DEFAULT_MAX_DIFF_LINES,
413
+ forbiddenPaths: task.forbiddenPaths ?? []
414
+ };
415
+ return {
416
+ async validate(output) {
417
+ return runCoderChecks(
418
+ {
419
+ patch: output.patch,
420
+ testsPassed: output.testResult.passed,
421
+ typecheckPassed: output.typecheckResult.passed
422
+ },
423
+ constraints
424
+ );
425
+ }
426
+ };
427
+ }
428
+ function defaultCoderValidator() {
429
+ return createCoderValidator({
430
+ goal: "",
431
+ repoRoot: "",
432
+ forbiddenPaths: [],
433
+ maxDiffLines: DEFAULT_MAX_DIFF_LINES
434
+ });
435
+ }
436
+ function parseCoderEvents(events) {
437
+ for (let i = events.length - 1; i >= 0; i -= 1) {
438
+ const event = events[i];
439
+ if (!event) continue;
440
+ const type = String(event.type ?? "");
441
+ const data = isRecord(event.data) ? event.data : {};
442
+ if (type === "result" || type === "final" || type === "coder.result") {
443
+ const payload = data.result ?? data.output ?? data;
444
+ const projected = projectWorktreeArtifact(payload);
445
+ if (projected) return projected;
446
+ const direct = coerceCoderOutput(payload);
447
+ if (direct) return direct;
448
+ }
449
+ }
450
+ const transcript = collectAssistantText(events);
451
+ for (const candidate of fencedJsonBlocks(transcript)) {
452
+ const coerced = coerceCoderOutput(candidate);
453
+ if (coerced) return coerced;
454
+ }
455
+ return {
456
+ branch: "",
457
+ patch: "",
458
+ testResult: { passed: false, output: "" },
459
+ typecheckResult: { passed: false, output: "" },
460
+ diffStats: { filesChanged: 0, insertions: 0, deletions: 0 }
461
+ };
462
+ }
463
+ function projectWorktreeArtifact(value) {
464
+ if (!isRecord(value)) return void 0;
465
+ const stats = value.stats;
466
+ if (!isRecord(stats)) return void 0;
467
+ const branch = pickString(value.branch) ?? "";
468
+ const patch = pickString(value.patch) ?? "";
469
+ const checks = isRecord(value.checks) ? value.checks : {};
470
+ const tests = isRecord(checks.tests) ? checks.tests : void 0;
471
+ const typecheck = isRecord(checks.typecheck) ? checks.typecheck : void 0;
472
+ const harness = isRecord(value.harness) ? value.harness : void 0;
473
+ const exitCode = harness ? toFiniteInt(harness.exitCode) : 0;
474
+ const timedOut = harness?.timedOut === true;
475
+ const harnessName = harness ? pickString(harness.name) ?? "harness" : "harness";
476
+ return {
477
+ branch,
478
+ patch,
479
+ testResult: {
480
+ passed: tests ? tests.passed === true : true,
481
+ output: tail(pickString(tests?.output) ?? "", 4e3)
482
+ },
483
+ typecheckResult: {
484
+ passed: typecheck ? typecheck.passed === true : true,
485
+ output: tail(pickString(typecheck?.output) ?? "", 4e3)
486
+ },
487
+ diffStats: {
488
+ filesChanged: toFiniteInt(stats.filesChanged),
489
+ insertions: toFiniteInt(stats.insertions),
490
+ deletions: toFiniteInt(stats.deletions)
491
+ },
492
+ ...exitCode !== 0 ? {
493
+ reviewerNotes: `harness ${harnessName} exited ${exitCode}${timedOut ? " (timed out)" : ""}`
494
+ } : {}
495
+ };
496
+ }
497
+ function isRecord(value) {
498
+ return value !== null && typeof value === "object" && !Array.isArray(value);
499
+ }
500
+ function tail(text, max) {
501
+ return text.length <= max ? text : text.slice(text.length - max);
502
+ }
503
+ function pickString(value) {
504
+ return typeof value === "string" && value.length > 0 ? value : void 0;
505
+ }
506
+ function collectAssistantText(events) {
507
+ const chunks = [];
508
+ for (const event of events) {
509
+ if (!event) continue;
510
+ const data = isRecord(event.data) ? event.data : {};
511
+ if (String(event.type ?? "") === "message.part.updated") {
512
+ const part = isRecord(data.part) ? data.part : {};
513
+ const partType = String(part.type ?? "");
514
+ if (partType !== "text" && partType !== "") continue;
515
+ const text2 = pickString(data.delta) ?? pickString(part.text);
516
+ if (text2) chunks.push(text2);
517
+ continue;
518
+ }
519
+ const text = pickString(data.text) ?? pickString(data.delta);
520
+ if (text) chunks.push(text);
521
+ }
522
+ return chunks.join("");
523
+ }
524
+ function fencedJsonBlocks(text) {
525
+ const out = [];
526
+ const matches = [...text.matchAll(/```(?:json)?\s*([\s\S]*?)```/gi)];
527
+ for (let i = matches.length - 1; i >= 0; i -= 1) {
528
+ const body = (matches[i]?.[1] ?? "").trim();
529
+ if (!body) continue;
530
+ try {
531
+ out.push(JSON.parse(body));
532
+ } catch {
533
+ }
534
+ }
535
+ return out;
536
+ }
537
+ function coerceCoderOutput(value) {
538
+ if (!isRecord(value)) return void 0;
539
+ const branch = pickString(value.branch);
540
+ const patch = pickString(value.patch) ?? "";
541
+ if (branch === void 0) return void 0;
542
+ return {
543
+ branch,
544
+ patch,
545
+ testResult: coerceCmdResult(value.testResult),
546
+ typecheckResult: coerceCmdResult(value.typecheckResult),
547
+ diffStats: coerceDiffStats(value.diffStats),
548
+ reviewerNotes: pickString(value.reviewerNotes)
549
+ };
550
+ }
551
+ function coerceCmdResult(value) {
552
+ if (!isRecord(value)) return { passed: false, output: "" };
553
+ return { passed: value.passed === true, output: pickString(value.output) ?? "" };
554
+ }
555
+ function coerceDiffStats(value) {
556
+ if (!isRecord(value)) return { filesChanged: 0, insertions: 0, deletions: 0 };
557
+ return {
558
+ filesChanged: toFiniteInt(value.filesChanged),
559
+ insertions: toFiniteInt(value.insertions),
560
+ deletions: toFiniteInt(value.deletions)
561
+ };
562
+ }
563
+ function toFiniteInt(value) {
564
+ if (typeof value !== "number") return 0;
565
+ if (!Number.isFinite(value)) return 0;
566
+ return Math.max(0, Math.trunc(value));
567
+ }
568
+
569
+ // src/mcp/detached-turn.ts
570
+ var DEFAULT_TICK_INTERVAL_MS = 5e3;
571
+ function formatDetachedSessionRef(parts) {
572
+ assertRefComponent("sessionId", parts.sessionId);
573
+ if (parts.sandboxId === void 0) return `session=${parts.sessionId}`;
574
+ assertRefComponent("sandboxId", parts.sandboxId);
575
+ return `sandbox=${parts.sandboxId};session=${parts.sessionId}`;
576
+ }
577
+ function parseDetachedSessionRef(raw) {
578
+ const fields = /* @__PURE__ */ new Map();
579
+ for (const pair of raw.split(";")) {
580
+ const eq = pair.indexOf("=");
581
+ const key = eq === -1 ? "" : pair.slice(0, eq);
582
+ const value = eq === -1 ? "" : pair.slice(eq + 1);
583
+ if (key !== "session" && key !== "sandbox" || value.length === 0 || fields.has(key)) {
584
+ throw new ValidationError(
585
+ `parseDetachedSessionRef: malformed detachedSessionRef ${JSON.stringify(raw)} \u2014 expected "session=<id>" or "sandbox=<id>;session=<id>"`
586
+ );
587
+ }
588
+ fields.set(key, value);
589
+ }
590
+ const sessionId = fields.get("session");
591
+ if (!sessionId) {
592
+ throw new ValidationError(
593
+ `parseDetachedSessionRef: detachedSessionRef ${JSON.stringify(raw)} carries no session id`
594
+ );
595
+ }
596
+ const sandboxId = fields.get("sandbox");
597
+ return { sessionId, ...sandboxId !== void 0 ? { sandboxId } : {} };
598
+ }
599
+ function assertRefComponent(name, value) {
600
+ if (value.length === 0 || value.includes(";") || value.includes("=")) {
601
+ throw new ValidationError(
602
+ `formatDetachedSessionRef: ${name} ${JSON.stringify(value)} must be non-empty and free of ";" / "="`
603
+ );
604
+ }
605
+ }
606
+ function detachedTurnEvents(sessionId, turn) {
607
+ return [
608
+ {
609
+ type: "result",
610
+ id: sessionId,
611
+ data: {
612
+ text: turn.text,
613
+ finalText: turn.text,
614
+ success: true,
615
+ result: turn.result
616
+ }
617
+ }
618
+ ];
619
+ }
620
+ async function runDetachedTurn(options) {
621
+ const intervalMs = options.tickIntervalMs ?? DEFAULT_TICK_INTERVAL_MS;
622
+ const trace = createDetachedTurnTrace(options);
623
+ trace.started();
624
+ const box = await createSandboxForSpec(options.client, options.spec, options.signal).catch(
625
+ (err) => {
626
+ trace.ended(err instanceof Error ? err.message : String(err));
627
+ throw err;
628
+ }
629
+ );
630
+ const drive = box;
631
+ const onAbort = () => {
632
+ void drive._sessionCancel?.(options.sessionId).catch(() => {
633
+ });
634
+ };
635
+ try {
636
+ if (typeof drive.driveTurn !== "function") {
637
+ throw new ValidationError(
638
+ "runDetachedTurn: the acquired sandbox exposes no driveTurn(message, { sessionId }) \u2014 detached dispatch requires @tangle-network/sandbox >= 0.6 and a session-backed placement (sibling/fleet); disable detached dispatch for this executor."
639
+ );
640
+ }
641
+ const sandboxId = box.id;
642
+ if (typeof sandboxId !== "string" || sandboxId.length === 0) {
643
+ throw new ValidationError(
644
+ "runDetachedTurn: the acquired sandbox carries no id \u2014 without it the detached run cannot be resumed after a restart, so refusing to dispatch detached."
645
+ );
646
+ }
647
+ options.bindSandbox(sandboxId);
648
+ trace.dispatched(sandboxId);
649
+ options.signal.addEventListener("abort", onAbort, { once: true });
650
+ for (; ; ) {
651
+ throwIfAborted(options.signal);
652
+ const tick = await drive.driveTurn(options.prompt, {
653
+ sessionId: options.sessionId,
654
+ turnId: options.sessionId,
655
+ ...options.wallCapMs !== void 0 ? { wallCapMs: options.wallCapMs } : {}
656
+ });
657
+ throwIfAborted(options.signal);
658
+ if (tick.state === "completed") {
659
+ trace.ended();
660
+ return { text: tick.text, result: tick.result };
661
+ }
662
+ if (tick.state === "failed") {
663
+ throw new Error(`detached turn ${options.sessionId} failed: ${tick.error}`);
664
+ }
665
+ options.report({ iteration: 0, phase: detachedRunningPhase(tick.elapsedMs) });
666
+ await sleep(intervalMs, options.signal);
667
+ }
668
+ } catch (err) {
669
+ trace.ended(err instanceof Error ? err.message : String(err));
670
+ throw err;
671
+ } finally {
672
+ options.signal.removeEventListener("abort", onAbort);
673
+ if (options.signal.aborted) onAbort();
674
+ await deleteBoxSafe(box);
675
+ }
676
+ }
677
+ function createDetachedTurnTrace(options) {
678
+ const emitter = options.traceEmitter;
679
+ if (!emitter) {
680
+ return { started() {
681
+ }, dispatched() {
682
+ }, ended() {
683
+ } };
684
+ }
685
+ const runId = options.sessionId;
686
+ const agentRunName = options.spec.name ?? options.spec.profile.name ?? "detached-turn";
687
+ const startMs = Date.now();
688
+ let done = false;
689
+ const emit = (event) => {
690
+ void emitter.emit(event);
691
+ };
692
+ return {
693
+ started() {
694
+ emit({
695
+ kind: "loop.started",
696
+ runId,
697
+ timestamp: startMs,
698
+ payload: {
699
+ driver: "detached-turn",
700
+ agentRunNames: [agentRunName],
701
+ maxIterations: 1,
702
+ maxConcurrency: 1
703
+ }
704
+ });
705
+ emit({
706
+ kind: "loop.iteration.started",
707
+ runId,
708
+ timestamp: startMs,
709
+ payload: { iterationIndex: 0, agentRunName, taskHash: options.sessionId }
710
+ });
711
+ },
712
+ dispatched(sandboxId) {
713
+ emit({
714
+ kind: "loop.iteration.dispatch",
715
+ runId,
716
+ timestamp: Date.now(),
717
+ payload: {
718
+ iterationIndex: 0,
719
+ agentRunName,
720
+ placement: options.placement ?? "sibling",
721
+ sandboxId
722
+ }
723
+ });
724
+ },
725
+ ended(error) {
726
+ if (done) return;
727
+ done = true;
728
+ const endMs = Date.now();
729
+ emit({
730
+ kind: "loop.iteration.ended",
731
+ runId,
732
+ timestamp: endMs,
733
+ payload: {
734
+ iterationIndex: 0,
735
+ agentRunName,
736
+ costUsd: 0,
737
+ durationMs: endMs - startMs,
738
+ ...error !== void 0 ? { error } : {}
739
+ }
740
+ });
741
+ emit({
742
+ kind: "loop.ended",
743
+ runId,
744
+ timestamp: endMs,
745
+ payload: {
746
+ ...error === void 0 ? { winnerIterationIndex: 0 } : {},
747
+ totalCostUsd: 0,
748
+ durationMs: endMs - startMs,
749
+ iterations: 1
750
+ }
751
+ });
752
+ }
753
+ };
754
+ }
755
+ function detachedRunningPhase(elapsedMs) {
756
+ return elapsedMs === void 0 ? "detached-running" : `detached-running ${Math.round(elapsedMs / 1e3)}s`;
757
+ }
758
+ function createDetachedTurnResumeDriver(options) {
759
+ const cancelHooked = /* @__PURE__ */ new Set();
760
+ return {
761
+ intervalMs: options.intervalMs ?? DEFAULT_TICK_INTERVAL_MS,
762
+ async tick({ record, detachedSessionRef }, ctx) {
763
+ const ref = parseDetachedSessionRef(detachedSessionRef);
764
+ if (ref.sandboxId === void 0) {
765
+ return {
766
+ state: "failed",
767
+ error: {
768
+ message: `detached session "${ref.sessionId}" was never bound to a sandbox \u2014 the previous process died before the box was acquired, so the turn was never dispatched and cannot be resumed`,
769
+ kind: "DetachedSessionUnboundError"
770
+ }
771
+ };
772
+ }
773
+ const box = await options.resolveSandbox(ref.sandboxId);
774
+ if (!cancelHooked.has(record.taskId)) {
775
+ cancelHooked.add(record.taskId);
776
+ ctx.signal.addEventListener(
777
+ "abort",
778
+ () => {
779
+ void box._sessionCancel?.(ref.sessionId).catch(() => {
780
+ });
781
+ },
782
+ { once: true }
783
+ );
784
+ }
785
+ if (ctx.signal.aborted) throwAbort();
786
+ const tick = await box.driveTurn(options.buildMessage(record), {
787
+ sessionId: ref.sessionId,
788
+ turnId: ref.sessionId,
789
+ ...options.wallCapMs !== void 0 ? { wallCapMs: options.wallCapMs } : {}
790
+ });
791
+ if (tick.state === "completed") {
792
+ const output = await options.settleOutput(
793
+ { text: tick.text, result: tick.result },
794
+ record,
795
+ {
796
+ signal: ctx.signal
797
+ }
798
+ );
799
+ return { state: "completed", output };
800
+ }
801
+ if (tick.state === "failed") {
802
+ return {
803
+ state: "failed",
804
+ error: {
805
+ message: `detached turn ${ref.sessionId} failed: ${tick.error}`,
806
+ kind: "DetachedTurnFailedError"
807
+ }
808
+ };
809
+ }
810
+ ctx.report({ iteration: 0, phase: detachedRunningPhase(tick.elapsedMs) });
811
+ return { state: "running" };
812
+ }
813
+ };
814
+ }
815
+
816
+ // src/mcp/delegates.ts
817
+ function detachedSessionDelegate(options) {
818
+ const executor = resolveExecutor(options);
819
+ const sandboxClient = executor.client;
820
+ const fanoutHarnesses = options.fanoutHarnesses;
821
+ const maxConcurrency = options.maxConcurrency ?? 4;
822
+ const traceEmitter = options.traceEmitter;
823
+ return async (args, ctx) => {
824
+ const task = coderTaskFromArgs(args);
825
+ const variants = Math.max(1, Math.trunc(args.variants ?? 1));
826
+ const loopEmitter = composeLoopTraceEmitters(traceEmitter, ctx.traceEmitter);
827
+ ctx.report({ iteration: 0, phase: "starting" });
828
+ if (variants <= 1) {
829
+ const agentRunSpec = coderRunSpec({
830
+ ...options.workerProfile ? { profile: options.workerProfile } : {},
831
+ ...options.harness ? { harness: options.harness } : {},
832
+ ...options.model ? { model: options.model } : {},
833
+ ...options.systemPrompt ? { systemPrompt: options.systemPrompt } : {}
834
+ });
835
+ const output = coderOutputAdapter;
836
+ const validator = createCoderValidator(task);
837
+ if (ctx.detachedSessionRef !== void 0 && ctx.updateDetachedSessionRef) {
838
+ const { sessionId } = parseDetachedSessionRef(ctx.detachedSessionRef);
839
+ const rebind = ctx.updateDetachedSessionRef;
840
+ const turn = await runDetachedTurn({
841
+ client: sandboxClient,
842
+ spec: agentRunSpec,
843
+ prompt: agentRunSpec.taskToPrompt(task),
844
+ sessionId,
845
+ bindSandbox: (sandboxId) => rebind(formatDetachedSessionRef({ sandboxId, sessionId })),
846
+ signal: ctx.signal,
847
+ report: ctx.report,
848
+ ...loopEmitter ? { traceEmitter: loopEmitter } : {},
849
+ ...executor.placement === "fleet" ? { placement: "fleet" } : {},
850
+ ...options.detachedTickIntervalMs !== void 0 ? { tickIntervalMs: options.detachedTickIntervalMs } : {},
851
+ ...options.detachedWallCapMs !== void 0 ? { wallCapMs: options.detachedWallCapMs } : {}
852
+ });
853
+ const chosen3 = await settleDetachedCoderTurn(turn, {
854
+ task,
855
+ sessionId,
856
+ signal: ctx.signal,
857
+ ...options.harness ? { harness: options.harness } : {},
858
+ ...options.model ? { model: options.model } : {},
859
+ ...options.reviewer ? { reviewer: options.reviewer } : {}
860
+ });
861
+ ctx.report({ iteration: 1, phase: "completed" });
862
+ return chosen3;
863
+ }
864
+ const result2 = await runLoop({
865
+ driver: singleShotDriver,
866
+ agentRun: agentRunSpec,
867
+ output,
868
+ validator,
869
+ task,
870
+ ctx: {
871
+ sandboxClient,
872
+ signal: ctx.signal,
873
+ ...loopEmitter ? { traceEmitter: loopEmitter } : {}
874
+ },
875
+ maxIterations: 1,
876
+ maxConcurrency
877
+ });
878
+ const chosen2 = await pickCoderWinner({
879
+ iterations: result2.iterations,
880
+ reviewer: options.reviewer,
881
+ selection: options.winnerSelection ?? "highest-score",
882
+ task,
883
+ signal: ctx.signal
884
+ });
885
+ if (!chosen2) throw new Error(noWinnerMessage(options.reviewer));
886
+ ctx.report({ iteration: 1, phase: "completed" });
887
+ return chosen2;
888
+ }
889
+ const fanout = multiHarnessCoderFanout({
890
+ ...options.workerProfile ? { profile: options.workerProfile } : {},
891
+ ...fanoutHarnesses && fanoutHarnesses.length > 0 ? { harnesses: fanoutHarnesses.slice(0, variants) } : {},
892
+ ...options.fanoutModels ? { models: options.fanoutModels.slice(0, variants) } : {}
893
+ });
894
+ const agentRuns = fanout.agentRuns.slice(0, variants);
895
+ const result = await runLoop({
896
+ driver: fanout.driver,
897
+ agentRuns,
898
+ output: fanout.output,
899
+ validator: fanout.validator,
900
+ task,
901
+ ctx: {
902
+ sandboxClient,
903
+ signal: ctx.signal,
904
+ ...loopEmitter ? { traceEmitter: loopEmitter } : {}
905
+ },
906
+ maxIterations: variants,
907
+ maxConcurrency: Math.min(maxConcurrency, variants)
908
+ });
909
+ const chosen = await pickCoderWinner({
910
+ iterations: result.iterations,
911
+ reviewer: options.reviewer,
912
+ selection: options.winnerSelection ?? "highest-score",
913
+ task,
914
+ signal: ctx.signal
915
+ });
916
+ if (!chosen) throw new Error(noWinnerMessage(options.reviewer));
917
+ ctx.report({ iteration: agentRuns.length, phase: "completed" });
918
+ return chosen;
919
+ };
920
+ }
921
+ async function pickCoderWinner(args) {
922
+ const eligible = [];
923
+ for (const iter of args.iterations) {
924
+ if (iter.output === void 0 || iter.error || iter.verdict?.valid !== true) continue;
925
+ const readiness = iter.verdict.score ?? 0;
926
+ if (args.reviewer) {
927
+ const review = await args.reviewer(iter.output, args.task, { signal: args.signal });
928
+ if (!review.approved) continue;
929
+ eligible.push({ iter, readiness: review.readiness });
930
+ } else {
931
+ eligible.push({ iter, readiness });
932
+ }
933
+ }
934
+ if (eligible.length === 0) return void 0;
935
+ if (args.selection === "highest-readiness") {
936
+ const sorted = [...eligible].sort(
937
+ (a, b) => b.readiness - a.readiness || a.iter.index - b.iter.index
938
+ );
939
+ return sorted[0].iter.output;
940
+ }
941
+ const wrapped = eligible.map(({ iter }) => ({
942
+ ...iter,
943
+ output: { kind: "done", deliverable: iter.output }
944
+ }));
945
+ const winner = selectValidWinner({
946
+ strategy: baseStrategy(args.selection),
947
+ sizeOf: (o) => o.diffStats.insertions + o.diffStats.deletions
948
+ })(wrapped);
949
+ const out = winner?.output;
950
+ if (!out || out.kind !== "done") return void 0;
951
+ return out.deliverable;
952
+ }
953
+ function baseStrategy(selection) {
954
+ switch (selection) {
955
+ case "smallest-diff":
956
+ return "smallest-artifact";
957
+ case "first-approved":
958
+ return "first-valid";
959
+ default:
960
+ return "highest-score";
961
+ }
962
+ }
963
+ function noWinnerMessage(reviewer) {
964
+ return reviewer ? "coder delegate: no candidate passed validation + review" : "coder delegate: no candidate passed validation";
965
+ }
966
+ function coderTaskFromArgs(args) {
967
+ return {
968
+ goal: buildCoderGoal(args),
969
+ repoRoot: args.repoRoot,
970
+ testCmd: args.config?.testCmd,
971
+ typecheckCmd: args.config?.typecheckCmd,
972
+ forbiddenPaths: args.config?.forbiddenPaths,
973
+ maxDiffLines: args.config?.maxDiffLines
974
+ };
975
+ }
976
+ async function settleDetachedCoderTurn(turn, options) {
977
+ const parsed = coderOutputAdapter.parse(detachedTurnEvents(options.sessionId, turn));
978
+ const validator = createCoderValidator(options.task);
979
+ const verdict = await validator.validate(parsed, { iteration: 0, signal: options.signal });
980
+ if (verdict.valid !== true) throw new Error(noWinnerMessage(options.reviewer));
981
+ if (options.reviewer) {
982
+ const review = await options.reviewer(parsed, options.task, { signal: options.signal });
983
+ if (!review.approved) throw new Error(noWinnerMessage(options.reviewer));
984
+ }
985
+ return parsed;
986
+ }
987
+ function buildCoderGoal(args) {
988
+ if (!args.contextHint) return args.goal;
989
+ return [args.goal, "", "## Context", args.contextHint].join("\n");
990
+ }
991
+ function resolveExecutor(options) {
992
+ if (options.executor && options.sandboxClient) {
993
+ throw new Error("detachedSessionDelegate: pass exactly one of `executor` or `sandboxClient`");
994
+ }
995
+ if (options.executor) return options.executor;
996
+ if (options.sandboxClient) {
997
+ return createSiblingSandboxExecutor({ client: options.sandboxClient });
998
+ }
999
+ throw new Error("detachedSessionDelegate: `executor` or `sandboxClient` is required");
1000
+ }
1001
+ var singleShotDriver = {
1002
+ name: "mcp-single-shot",
1003
+ async plan(task, history) {
1004
+ return history.length === 0 ? [task] : [];
1005
+ },
1006
+ decide(history) {
1007
+ return history.length > 0 ? "pick-winner" : "fail";
1008
+ }
1009
+ };
1010
+
97
1011
  // src/mcp/tools/checks.ts
98
1012
  import {
99
1013
  makeFinding
@@ -261,17 +1175,11 @@ function makeCheckRunner(kinds, opts) {
261
1175
  };
262
1176
  }
263
1177
  export {
264
- DELEGATE_CODE_DESCRIPTION,
265
- DELEGATE_CODE_INPUT_SCHEMA,
266
- DELEGATE_CODE_TOOL_NAME,
267
1178
  DELEGATE_DESCRIPTION,
268
1179
  DELEGATE_FEEDBACK_DESCRIPTION,
269
1180
  DELEGATE_FEEDBACK_INPUT_SCHEMA,
270
1181
  DELEGATE_FEEDBACK_TOOL_NAME,
271
1182
  DELEGATE_INPUT_SCHEMA,
272
- DELEGATE_RESEARCH_DESCRIPTION,
273
- DELEGATE_RESEARCH_INPUT_SCHEMA,
274
- DELEGATE_RESEARCH_TOOL_NAME,
275
1183
  DELEGATE_TOOL_NAME,
276
1184
  DELEGATE_UI_AUDIT_DESCRIPTION,
277
1185
  DELEGATE_UI_AUDIT_INPUT_SCHEMA,
@@ -279,7 +1187,6 @@ export {
279
1187
  DELEGATION_HISTORY_DESCRIPTION,
280
1188
  DELEGATION_HISTORY_INPUT_SCHEMA,
281
1189
  DELEGATION_HISTORY_TOOL_NAME,
282
- DELEGATION_MCP_SERVER_KEY,
283
1190
  DELEGATION_STATUS_DESCRIPTION,
284
1191
  DELEGATION_STATUS_INPUT_SCHEMA,
285
1192
  DELEGATION_STATUS_TOOL_NAME,
@@ -291,18 +1198,14 @@ export {
291
1198
  FileDelegationStore,
292
1199
  InMemoryDelegationStore,
293
1200
  InMemoryFeedbackStore,
294
- buildDelegationMcpServer,
295
1201
  buildDelegationTraceSpans,
296
1202
  capDelegationTrace,
297
1203
  captureWorktreeDiff,
298
1204
  coderTaskFromArgs,
299
1205
  composeLoopTraceEmitters,
300
- composeProductionAgentProfile,
301
1206
  createCoordinationTools,
302
- createDelegateCodeHandler,
303
1207
  createDelegateFeedbackHandler,
304
1208
  createDelegateHandler,
305
- createDelegateResearchHandler,
306
1209
  createDelegateUiAuditHandler,
307
1210
  createDelegationHistoryHandler,
308
1211
  createDelegationStatusHandler,
@@ -337,9 +1240,7 @@ export {
337
1240
  settleDetachedCoderTurn,
338
1241
  traceContextToEnv,
339
1242
  validateDelegateArgs,
340
- validateDelegateCodeArgs,
341
1243
  validateDelegateFeedbackArgs,
342
- validateDelegateResearchArgs,
343
1244
  validateDelegateUiAuditArgs,
344
1245
  validateDelegationHistoryArgs,
345
1246
  validateDelegationStatusArgs