@tangle-network/agent-runtime 0.156.0 → 0.158.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 (81) hide show
  1. package/dist/{activation-B4fRz8QL.js → activation-CLicee7D.js} +3 -3
  2. package/dist/{activation-B4fRz8QL.js.map → activation-CLicee7D.js.map} +1 -1
  3. package/dist/agent.d.ts +2 -2
  4. package/dist/agent.js +2 -2
  5. package/dist/analyst-loop.d.ts +1 -1
  6. package/dist/{authoring-C4uCoDmO.js → authoring-rIDPzwYY.js} +2 -2
  7. package/dist/{authoring-C4uCoDmO.js.map → authoring-rIDPzwYY.js.map} +1 -1
  8. package/dist/candidate-execution/index.js +4 -4
  9. package/dist/{candidate-execution-Ic92NMl9.js → candidate-execution-izJj02pU.js} +4 -4
  10. package/dist/{candidate-execution-Ic92NMl9.js.map → candidate-execution-izJj02pU.js.map} +1 -1
  11. package/dist/conversation.d.ts +1 -1
  12. package/dist/durable.d.ts +11 -8
  13. package/dist/durable.js +2 -4
  14. package/dist/durable.js.map +1 -1
  15. package/dist/{environment-provider-Dz9JB-X_.js → environment-provider-Bn3652YU.js} +2 -2
  16. package/dist/{environment-provider-Dz9JB-X_.js.map → environment-provider-Bn3652YU.js.map} +1 -1
  17. package/dist/{environment-provider-C_QI6VCG.d.ts → environment-provider-BobKk46F.d.ts} +3 -3
  18. package/dist/environment-provider.d.ts +1 -1
  19. package/dist/environment-provider.js +1 -1
  20. package/dist/{graph-BibNm6a-.js → graph-BGPO6z_u.js} +4 -3
  21. package/dist/graph-BGPO6z_u.js.map +1 -0
  22. package/dist/{improvement-cycle-g6RsxGbg.js → improvement-cycle-BEENaoCb.js} +11 -7
  23. package/dist/improvement-cycle-BEENaoCb.js.map +1 -0
  24. package/dist/{index-DPFUNEdU.d.ts → index-CLt9zpuD.d.ts} +3 -3
  25. package/dist/{index-B2A_KtAZ.d.ts → index-Dto3D25e.d.ts} +16 -12
  26. package/dist/{index-BYGBIxtx.d.ts → index-W5WVBUlZ.d.ts} +4 -4
  27. package/dist/index.d.ts +9 -9
  28. package/dist/index.js +11 -11
  29. package/dist/intelligence.d.ts +7 -11
  30. package/dist/intelligence.js +6 -6
  31. package/dist/intelligence.js.map +1 -1
  32. package/dist/kernel.d.ts +7 -7
  33. package/dist/kernel.js +8 -8
  34. package/dist/{knowledge-DeP-wG8l.js → knowledge-HDCUV1kZ.js} +5 -5
  35. package/dist/{knowledge-DeP-wG8l.js.map → knowledge-HDCUV1kZ.js.map} +1 -1
  36. package/dist/knowledge.d.ts +1 -1
  37. package/dist/knowledge.js +1 -1
  38. package/dist/{loop-runner-bin-9VUQihh7.d.ts → loop-runner-bin-BEzvqbgg.d.ts} +3 -3
  39. package/dist/{loop-runner-bin-LvaprzUz.js → loop-runner-bin-UNn0NLv2.js} +3 -3
  40. package/dist/{loop-runner-bin-LvaprzUz.js.map → loop-runner-bin-UNn0NLv2.js.map} +1 -1
  41. package/dist/loop-runner-bin.d.ts +1 -1
  42. package/dist/loop-runner-bin.js +1 -1
  43. package/dist/mcp/bin.js +3 -3
  44. package/dist/mcp/index.d.ts +6 -6
  45. package/dist/mcp/index.js +5 -5
  46. package/dist/mcp/index.js.map +1 -1
  47. package/dist/{openai-tools-CkSQJppW.js → openai-tools-D1VQ5e9p.js} +2 -2
  48. package/dist/{openai-tools-CkSQJppW.js.map → openai-tools-D1VQ5e9p.js.map} +1 -1
  49. package/dist/{openai-tools-z-whdYNC.d.ts → openai-tools-wkxQ2aEw.d.ts} +2 -2
  50. package/dist/{prepare-DcMjMdj-.js → prepare-VLGnSyav.js} +2 -2
  51. package/dist/{prepare-DcMjMdj-.js.map → prepare-VLGnSyav.js.map} +1 -1
  52. package/dist/primeintellect/index.d.ts +1 -1
  53. package/dist/profiles.d.ts +2 -166
  54. package/dist/{protected-model-port-BzUkspPP.js → protected-model-port-CcCH0Uji.js} +2 -2
  55. package/dist/{protected-model-port-BzUkspPP.js.map → protected-model-port-CcCH0Uji.js.map} +1 -1
  56. package/dist/{redact-BT7-mX8G.d.ts → redact-0AK8JmHW.d.ts} +13 -10
  57. package/dist/researcher-BMFFPwKb.js.map +1 -1
  58. package/dist/{runtime-DuueBLeO.d.ts → runtime-BzY66cd6.d.ts} +4 -4
  59. package/dist/{runtime-D-NDRp4y.js → runtime-CTs2JsG9.js} +8 -8
  60. package/dist/{runtime-D-NDRp4y.js.map → runtime-CTs2JsG9.js.map} +1 -1
  61. package/dist/{spawn-journal-duo0EkOp.js → spawn-journal-oewq1g2h.js} +1 -4
  62. package/dist/{spawn-journal-duo0EkOp.js.map → spawn-journal-oewq1g2h.js.map} +1 -1
  63. package/dist/{stream-agent-turn-BbcwWw_J.d.ts → stream-agent-turn-jaaFaSXM.d.ts} +3 -3
  64. package/dist/{structural-rollout-B1TocSdq.js → structural-rollout-Cj58xALQ.js} +3 -3
  65. package/dist/{structural-rollout-B1TocSdq.js.map → structural-rollout-Cj58xALQ.js.map} +1 -1
  66. package/dist/substrate-AJoT4HIz.d.ts +284 -0
  67. package/dist/{supervise-BVE0XAJa.js → supervise-CqwjiXlX.js} +3 -3
  68. package/dist/{supervise-BVE0XAJa.js.map → supervise-CqwjiXlX.js.map} +1 -1
  69. package/dist/{supervisor-BmXD0WCJ.js → supervisor-ZlQy5Fwl.js} +6 -33
  70. package/dist/supervisor-ZlQy5Fwl.js.map +1 -0
  71. package/dist/testing.d.ts +2 -2
  72. package/dist/testing.js +12 -12
  73. package/dist/{types-Cz5mCGlY.d.ts → types-BBXdSns1.d.ts} +8 -8
  74. package/dist/{types-DeX8ibLc.d.ts → types-DpdfZoQ3.d.ts} +6 -3
  75. package/dist/{workspace-archive-bugA3OwU.js → workspace-archive-BptlGCEU.js} +2 -2
  76. package/dist/{workspace-archive-bugA3OwU.js.map → workspace-archive-BptlGCEU.js.map} +1 -1
  77. package/package.json +3 -3
  78. package/dist/graph-BibNm6a-.js.map +0 -1
  79. package/dist/improvement-cycle-g6RsxGbg.js.map +0 -1
  80. package/dist/substrate-BcnuSHXm.d.ts +0 -117
  81. package/dist/supervisor-BmXD0WCJ.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/mcp/executor.ts","../../src/mcp/in-process-executor.ts","../../src/mcp/bin-helpers.ts","../../src/mcp/detached-coder.ts","../../src/mcp/detached-turn.ts","../../src/mcp/delegates.ts"],"sourcesContent":["/**\n *\n * Delegation executors — the layer between MCP delegates and the sandbox\n * substrate. Each executor exposes a {@link SandboxClient} the kernel\n * consumes plus a placement tag so the trace pipeline can correlate workers\n * with their physical placement.\n *\n * Two implementations ship in-box:\n *\n * - {@link createSiblingSandboxExecutor} — every delegation spawns a fresh\n * sandbox sibling to the caller. Default when the MCP server runs as a\n * standalone CLI mounted outside a fleet.\n *\n * - {@link createFleetWorkspaceExecutor} — delegations dispatch onto machines\n * in the caller's existing fleet so worker diffs land directly on the\n * caller's filesystem (the fleet's shared workspace). Selected when the\n * parent sandbox passes `TANGLE_FLEET_ID` into the MCP server's env.\n *\n * @experimental\n */\n\nimport type { CreateSandboxOptions, SandboxInstance } from '@tangle-network/sandbox'\nimport type { LoopSandboxPlacement, SandboxClient } from '../runtime'\n\n/** @experimental */\nexport interface DelegationExecutor {\n /** Sandbox client the kernel calls. Returned with `describePlacement` set. */\n readonly client: SandboxClient\n /** Best-effort one-liner used in stderr boot logs and diagnostics. */\n describe(): string\n /**\n * Where delegated work physically runs. `sibling` and `fleet` placements are\n * session-backed (boxes expose `driveTurn`, so detached dispatch + resume\n * apply); `in-process` spawns local harness CLIs with no sandbox session to\n * detach. Optional so consumer-implemented executors stay source-compatible;\n * absent means \"unknown\" and detached dispatch is not enabled for it.\n */\n readonly placement?: 'sibling' | 'fleet' | 'in-process'\n}\n\n/** @experimental */\nexport interface SiblingSandboxExecutorOptions {\n client: SandboxClient\n}\n\n/**\n * Wrap a raw sandbox SDK client so the kernel emits\n * `loop.iteration.dispatch` events with `{ placement: 'sibling', sandboxId }`.\n *\n * The returned client `.create()` delegates to the underlying client; the\n * only added behavior is a `describePlacement` tag the kernel reads.\n *\n * @experimental\n */\nexport function createSiblingSandboxExecutor(\n options: SiblingSandboxExecutorOptions,\n): DelegationExecutor {\n const underlying = options.client\n const client: SandboxClient = {\n create(opts?: CreateSandboxOptions): Promise<SandboxInstance> {\n return underlying.create(opts)\n },\n describePlacement(box: SandboxInstance): LoopSandboxPlacement {\n return { kind: 'sibling', sandboxId: readId(box) }\n },\n }\n return {\n client,\n placement: 'sibling',\n describe(): string {\n return 'sibling-sandbox (each delegation = fresh sandbox via client.create)'\n },\n }\n}\n\n/**\n * Minimal `SandboxFleet` surface the fleet executor calls. Declared\n * structurally so tests can pass an in-memory stub without instantiating the\n * sandbox SDK.\n *\n * @experimental\n */\nexport interface FleetHandle {\n readonly fleetId: string\n /** Machine ids in dispatch-eligible order. The executor round-robins. */\n readonly ids: ReadonlyArray<string>\n /** Resolve a machine id to its `SandboxInstance` — that machine is mounted\n * on the fleet's shared workspace, so any diff the worker writes lands on\n * every other fleet machine's filesystem too. */\n sandbox(machineId: string): Promise<SandboxInstance>\n}\n\n/** @experimental */\nexport interface FleetWorkspaceExecutorOptions {\n fleet: FleetHandle\n /**\n * Override the machine-selection policy. Default = round-robin across\n * `fleet.ids`, skipping the optional `excludeMachineIds` set (typically the\n * coordinator machine the MCP server is running on).\n */\n selectMachine?: (call: { callIndex: number; ids: ReadonlyArray<string> }) => string\n /**\n * Machine ids to skip during default round-robin. Set to the caller's own\n * machineId so workers don't compete with the orchestrator on the same VM.\n */\n excludeMachineIds?: ReadonlyArray<string>\n}\n\n/**\n * Build an executor that resolves each delegated iteration to an existing\n * machine in `fleet`. The fleet's shared-workspace policy means the worker\n * machine sees the caller's filesystem — diffs land in-place with no\n * cross-sandbox copy step.\n *\n * @experimental\n */\nexport function createFleetWorkspaceExecutor(\n options: FleetWorkspaceExecutorOptions,\n): DelegationExecutor {\n const fleet = options.fleet\n const exclude = new Set(options.excludeMachineIds ?? [])\n let callIndex = 0\n // machineId-by-sandboxId, populated as we resolve machines so\n // `describePlacement` can recover the assignment from the SandboxInstance\n // the kernel hands back.\n const placementBySandboxId = new Map<string, { machineId: string }>()\n\n const client: SandboxClient = {\n async create(): Promise<SandboxInstance> {\n const ids = fleet.ids.filter((id) => !exclude.has(id))\n if (ids.length === 0) {\n throw new Error(\n `agent-runtime: fleet ${fleet.fleetId} has no eligible worker machines (ids=[${fleet.ids.join(',')}], excluded=[${[...exclude].join(',')}])`,\n )\n }\n const selector = options.selectMachine\n const machineId = selector ? selector({ callIndex, ids }) : ids[callIndex % ids.length]\n callIndex += 1\n if (typeof machineId !== 'string' || machineId.length === 0) {\n throw new Error('agent-runtime: fleet executor selectMachine returned an empty machine id')\n }\n const box = await fleet.sandbox(machineId)\n const sandboxId = readId(box)\n if (sandboxId) placementBySandboxId.set(sandboxId, { machineId })\n return box\n },\n describePlacement(box: SandboxInstance): LoopSandboxPlacement {\n const sandboxId = readId(box)\n const recorded = sandboxId ? placementBySandboxId.get(sandboxId) : undefined\n return {\n kind: 'fleet',\n sandboxId,\n fleetId: fleet.fleetId,\n machineId: recorded?.machineId,\n }\n },\n }\n\n return {\n client,\n placement: 'fleet',\n describe(): string {\n const excluded = exclude.size > 0 ? ` (excluded=[${[...exclude].join(',')}])` : ''\n return `fleet-workspace (fleetId=${fleet.fleetId}, machines=[${fleet.ids.join(',')}]${excluded})`\n },\n }\n}\n\nfunction readId(box: SandboxInstance): string | undefined {\n const raw = (box as unknown as { id?: unknown }).id\n return typeof raw === 'string' && raw.length > 0 ? raw : undefined\n}\n","/**\n *\n * In-process delegation executor — when `agent-runtime-mcp` runs inside a sandbox whose image\n * carries the local coding-harness CLIs (claude / codex / opencode), delegations spawn the harness\n * AS A SUBPROCESS against a git worktree on the SAME filesystem instead of provisioning a sibling\n * sandbox. Zero provisioning latency; worker diffs land in-place; multi-harness fanout = N parallel\n * subprocesses in N parallel worktrees. Each authored profile selects its own harness.\n *\n * This is a THIN adapter over `runWorktreeHarness` (`./worktree-harness`) — the SAME core the\n * `Scope` leaf `createWorktreeCliExecutor` uses. It only adapts the core to the `SandboxClient`\n * port: `create()` reads the authored profile from `CreateSandboxOptions.backend.profile`, and\n * `streamPrompt` runs the core then emits its raw `WorktreeHarnessResult` (the content-addressed\n * patch artifact) on the `result` event. The sandbox-session decode layer\n * (`./detached-coder`) projects that artifact onto `CoderOutput`; the generic `Scope` path settles\n * the artifact directly. The §1.5 payload (systemPrompt + model) reaches the harness inside the core.\n *\n * @experimental\n */\n\nimport { randomUUID } from 'node:crypto'\nimport { type AgentProfile, agentProfileSchema } from '@tangle-network/agent-interface'\nimport type { CreateSandboxOptions, SandboxEvent, SandboxInstance } from '@tangle-network/sandbox'\nimport { ConfigError } from '../errors'\nimport type { LoopSandboxPlacement, SandboxClient } from '../runtime'\nimport { assertExecutableAgentProfile } from '../runtime/supervise/model-policy'\nimport type { DelegationExecutor } from './executor'\nimport { LOCAL_HARNESSES, type LocalHarness } from './local-harness'\nimport type { GitRunner, WorktreeHandle } from './worktree'\nimport { runWorktreeHarness } from './worktree-harness'\n\n/** @experimental */\nexport interface InProcessExecutorOptions {\n /** Absolute path to the git repo (the workspace). Worktrees go under `<repoRoot>/.agent-worktrees/`. */\n repoRoot: string\n /** Optional per-delegation test command run in the worktree after the harness exits. */\n testCmd?: string\n /** Optional per-delegation typecheck command. Same shape as `testCmd`. */\n typecheckCmd?: string\n /** Wall-clock cap per harness subprocess (ms). Default 5min. */\n harnessTimeoutMs?: number\n /** Wall-clock cap per test/typecheck subprocess (ms). Default 2min. */\n postCheckTimeoutMs?: number\n /** Test seam — override the git runner used by the worktree helpers. */\n runGit?: GitRunner\n /** Test seam — override the harness runner (defaults to the real CLI via `runLocalHarness`). */\n runHarness?: typeof import('./local-harness').runLocalHarness\n /** Test seam — override the post-check runner (defaults to a `sh -c` spawn). A throw is folded\n * into a non-fatal `{exitCode:-1}` so a broken check command fails the signal, not the run. */\n runPostCheck?: (\n cmd: string,\n cwd: string,\n signal?: AbortSignal,\n ) => Promise<{ exitCode: number; stdout: string; stderr: string }>\n}\n\n/** @experimental */\nexport interface InProcessExecutorDescribePlacement extends LoopSandboxPlacement {\n /** Worktree path in the parent sandbox's filesystem (set so traces correlate to on-disk artifacts). */\n worktreePath?: string\n /** Which harness handled this delegation. */\n harness?: LocalHarness\n}\n\ninterface VirtualSandbox extends SandboxInstance {\n __inProcess: {\n runId: string\n harness: LocalHarness\n worktree?: WorktreeHandle\n }\n}\n\nconst DEFAULT_HARNESS_TIMEOUT_MS = 5 * 60 * 1000\nconst DEFAULT_POSTCHECK_TIMEOUT_MS = 2 * 60 * 1000\n\n/**\n * Build an in-process executor. Returns a {@link DelegationExecutor} whose `client.create()`\n * returns a minimal virtual `SandboxInstance`; the kernel calls `streamPrompt(msg)` on it, which\n * runs the shared worktree-harness core and emits one `result` event whose `data.result` is the\n * raw `WorktreeHarnessResult` (the content-addressed patch artifact). The authored profile\n * (`backend.profile`) threads its systemPrompt + model into the harness via the core.\n *\n * @experimental\n */\nexport function createInProcessExecutor(options: InProcessExecutorOptions): DelegationExecutor {\n const runPostCheck = options.runPostCheck ?? defaultRunPostCheck\n // The core speaks one `runCommand` seam ({exitCode, output}); adapt the post-check seam\n // ({exitCode, stdout, stderr}) onto it, folding a throw into a non-fatal failure signal so a\n // broken check command fails the signal rather than aborting the whole delegation.\n const runCommand = async ({\n command,\n cwd,\n signal,\n }: {\n command: string\n cwd: string\n timeoutMs: number\n signal?: AbortSignal\n }): Promise<{ exitCode: number | null; output: string }> => {\n try {\n const r = await runPostCheck(command, cwd, signal)\n return { exitCode: r.exitCode, output: r.stderr || r.stdout }\n } catch (err) {\n return { exitCode: -1, output: err instanceof Error ? err.message : String(err) }\n }\n }\n\n const client: SandboxClient = {\n async create(opts?: CreateSandboxOptions): Promise<SandboxInstance> {\n // The authored profile is the sole execution authority. Refuse before creating a run id or\n // worktree: ambient executor configuration must never choose a worker's harness or model.\n const rawProfile = (opts?.backend as { profile?: unknown } | undefined)?.profile\n if (rawProfile === undefined) {\n throw new ConfigError(\n 'in-process executor: backend.profile is required and must select the exact harness, provider, and model',\n )\n }\n const profile = agentProfileSchema.parse(rawProfile) as AgentProfile\n assertExecutableAgentProfile(profile, 'in-process executor')\n const harness = profile.harness\n if (!LOCAL_HARNESSES.includes(harness as LocalHarness)) {\n throw new ConfigError(\n `in-process executor: AgentProfile.harness ${JSON.stringify(harness)} is not a local harness; expected ${LOCAL_HARNESSES.join(', ')}`,\n )\n }\n if (opts?.backend?.type !== undefined && opts.backend.type !== harness) {\n throw new ConfigError(\n `in-process executor: backend.type ${JSON.stringify(opts.backend.type)} conflicts with AgentProfile.harness ${JSON.stringify(harness)}`,\n )\n }\n const localHarness = harness as LocalHarness\n const runId = randomUUID()\n\n const virtual: VirtualSandbox = {\n id: `in-process-${runId}`,\n __inProcess: { runId, harness: localHarness },\n async *streamPrompt(\n this: VirtualSandbox,\n message: string | unknown[],\n promptOpts?: { signal?: AbortSignal },\n ): AsyncGenerator<SandboxEvent> {\n const taskPrompt =\n typeof message === 'string'\n ? message\n : message\n .map((p) =>\n typeof p === 'object' && p && 'text' in p\n ? String((p as { text: unknown }).text)\n : '',\n )\n .join('\\n')\n\n // The shared worktree-harness core: worktree → profile-aware harness → diff → checks.\n // A throw cleans up inside the core; on success we own the teardown (the finally).\n const run = await runWorktreeHarness({\n repoRoot: options.repoRoot,\n profile,\n harness: localHarness,\n taskPrompt,\n runId,\n harnessTimeoutMs: options.harnessTimeoutMs ?? DEFAULT_HARNESS_TIMEOUT_MS,\n checkTimeoutMs: options.postCheckTimeoutMs ?? DEFAULT_POSTCHECK_TIMEOUT_MS,\n ...(options.testCmd !== undefined ? { testCmd: options.testCmd } : {}),\n ...(options.typecheckCmd !== undefined ? { typecheckCmd: options.typecheckCmd } : {}),\n ...(options.runGit ? { runGit: options.runGit } : {}),\n ...(options.runHarness ? { runHarness: options.runHarness } : {}),\n runCommand,\n ...(promptOpts?.signal ? { signal: promptOpts.signal } : {}),\n })\n this.__inProcess.worktree = run.worktree\n\n try {\n yield {\n type: 'in_process.harness.started',\n data: {\n runId,\n harness: localHarness,\n worktreePath: run.worktree.path,\n command: localHarness,\n },\n }\n const h = run.result.harness\n yield {\n type: 'in_process.harness.ended',\n data: {\n runId,\n exitCode: h.exitCode,\n durationMs: h.durationMs,\n killedBySignal: h.killedBySignal,\n timedOut: h.timedOut,\n stdoutBytes: h.stdout.length,\n stderrBytes: h.stderr.length,\n },\n }\n yield {\n type: 'result',\n data: {\n result: run.result,\n source: 'in-process-executor',\n harness: localHarness,\n runId,\n },\n }\n } finally {\n await run.cleanup()\n }\n },\n } as unknown as VirtualSandbox\n\n return virtual\n },\n describePlacement(box: SandboxInstance): InProcessExecutorDescribePlacement {\n const sandboxId = (box as unknown as { id?: string }).id\n const meta = (box as VirtualSandbox).__inProcess\n return {\n kind: 'sibling',\n sandboxId,\n worktreePath: meta?.worktree?.path,\n harness: meta?.harness,\n }\n },\n }\n\n return {\n client,\n placement: 'in-process',\n describe(): string {\n return `in-process (repoRoot=${options.repoRoot}, harness=profile-selected${\n options.testCmd ? `, testCmd=\"${options.testCmd}\"` : ''\n }${options.typecheckCmd ? `, typecheckCmd=\"${options.typecheckCmd}\"` : ''})`\n },\n }\n}\n\nasync function defaultRunPostCheck(\n cmd: string,\n cwd: string,\n signal?: AbortSignal,\n): Promise<{ exitCode: number; stdout: string; stderr: string }> {\n const { spawn } = await import('node:child_process')\n return new Promise((resolve, reject) => {\n const child = spawn('sh', ['-c', cmd], { cwd, stdio: 'pipe' })\n let stdout = ''\n let stderr = ''\n child.stdout?.on('data', (c) => {\n stdout += String(c)\n })\n child.stderr?.on('data', (c) => {\n stderr += String(c)\n })\n if (signal) {\n const onAbort = () => {\n if (!child.killed) child.kill('SIGTERM')\n }\n if (signal.aborted) onAbort()\n else signal.addEventListener('abort', onAbort, { once: true })\n }\n const killTimer = setTimeout(() => {\n if (!child.killed) child.kill('SIGTERM')\n }, DEFAULT_POSTCHECK_TIMEOUT_MS)\n if (typeof (killTimer as { unref?: () => void }).unref === 'function') {\n ;(killTimer as { unref: () => void }).unref()\n }\n child.on('error', (err) => {\n clearTimeout(killTimer)\n reject(err)\n })\n child.on('close', (code) => {\n clearTimeout(killTimer)\n resolve({ exitCode: code ?? -1, stdout, stderr })\n })\n })\n}\n","/**\n *\n * Helpers extracted from `bin.ts` so the env-detection + executor-selection\n * logic is unit-testable without spawning a subprocess. The bin imports from\n * here; tests import from here directly.\n *\n * @experimental\n */\n\nimport type { SandboxClient } from '../runtime'\nimport {\n createFleetWorkspaceExecutor,\n createSiblingSandboxExecutor,\n type DelegationExecutor,\n type FleetHandle,\n} from './executor'\nimport { createInProcessExecutor } from './in-process-executor'\n\n/** @experimental */\nexport interface DetectExecutorArgs {\n sandboxClient: SandboxClient\n /** Raw env (defaults to `process.env`). Pass an explicit map for tests. */\n env?: Record<string, string | undefined>\n /**\n * Override how a fleet handle is resolved from the client + fleet id. The\n * default reads `client.fleets.get(fleetId)` and validates the returned\n * shape against the structural `FleetHandle` contract.\n */\n resolveFleet?: (client: SandboxClient, fleetId: string) => Promise<FleetHandle>\n}\n\n/**\n * Pick the right executor for an MCP server invocation based on env vars.\n *\n * - `TANGLE_FLEET_ID` set → fleet-workspace placement; resolves the handle\n * via `sandboxClient.fleets.get(...)`.\n * - Otherwise → sibling-sandbox placement; each delegation creates a fresh\n * sandbox via `sandboxClient.create(...)`.\n *\n * Fails loud (throws) when fleet mode is requested but the SDK shape is\n * incompatible — the operator chose fleet semantics, silently degrading to\n * sibling mode would lie about workspace topology.\n *\n * @experimental\n */\nexport async function detectExecutor(args: DetectExecutorArgs): Promise<DelegationExecutor> {\n const env = args.env ?? process.env\n\n // In-process (Phase 2.8): parent harness sets AGENT_RUNTIME_IN_SANDBOX=1\n // and points us at the workspace root. Highest-priority — when this is\n // set, delegations spawn local harness CLIs on git worktrees in the\n // SAME filesystem instead of provisioning sibling sandboxes.\n if (env.AGENT_RUNTIME_IN_SANDBOX === '1') {\n const repoRoot = env.AGENT_RUNTIME_REPO_ROOT?.trim()\n if (!repoRoot) {\n throw new Error(\n 'agent-runtime-mcp: AGENT_RUNTIME_IN_SANDBOX=1 requires AGENT_RUNTIME_REPO_ROOT to point at the workspace root',\n )\n }\n return createInProcessExecutor({\n repoRoot,\n testCmd: env.AGENT_RUNTIME_TEST_CMD?.trim() || undefined,\n typecheckCmd: env.AGENT_RUNTIME_TYPECHECK_CMD?.trim() || undefined,\n })\n }\n\n const fleetId = parseFleetId(env.TANGLE_FLEET_ID)\n if (!fleetId) {\n return createSiblingSandboxExecutor({ client: args.sandboxClient })\n }\n const resolveFleet = args.resolveFleet ?? defaultResolveFleet\n const fleet = await resolveFleet(args.sandboxClient, fleetId)\n const excludeMachineIds = parseList(env.TANGLE_FLEET_EXCLUDE_MACHINES)\n return createFleetWorkspaceExecutor({\n fleet,\n excludeMachineIds,\n })\n}\n\ninterface FleetsApi {\n get(fleetId: string): Promise<unknown>\n}\n\nasync function defaultResolveFleet(\n sandboxClient: SandboxClient,\n fleetId: string,\n): Promise<FleetHandle> {\n const fleets = (sandboxClient as unknown as { fleets?: FleetsApi }).fleets\n if (!fleets || typeof fleets.get !== 'function') {\n throw new Error(\n '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.',\n )\n }\n const raw = await fleets.get(fleetId)\n if (!raw || typeof raw !== 'object') {\n throw new Error(`agent-runtime-mcp: fleets.get(${fleetId}) returned no handle`)\n }\n const handle = raw as Partial<FleetHandle>\n if (typeof handle.fleetId !== 'string' || !Array.isArray(handle.ids)) {\n throw new Error(\n `agent-runtime-mcp: fleet handle for ${fleetId} is missing fleetId/ids — incompatible sandbox SDK shape`,\n )\n }\n if (typeof handle.sandbox !== 'function') {\n throw new Error(\n `agent-runtime-mcp: fleet handle for ${fleetId} is missing sandbox(machineId) — incompatible sandbox SDK shape`,\n )\n }\n return handle as FleetHandle\n}\n\nfunction parseFleetId(raw: string | undefined): string | undefined {\n if (typeof raw !== 'string') return undefined\n const trimmed = raw.trim()\n return trimmed.length > 0 ? trimmed : undefined\n}\n\nfunction parseList(raw: string | undefined): string[] | undefined {\n if (!raw) return undefined\n const list = raw\n .split(',')\n .map((entry) => entry.trim())\n .filter(Boolean)\n return list.length > 0 ? list : undefined\n}\n","/**\n *\n * Sandbox-session coder decode layer. The sandbox-session delegate (`./delegates`) and the\n * cross-restart resume driver run the in-box harness over a `SandboxClient` and need to\n * (a) build an `AgentRunSpec` from the caller-authored exact worker\n * profile, (b) decode the harness event stream into a structured `CoderOutput`, and (c) gate it with\n * the shared mechanical checks. This sandbox-session path is kept separate from the generic recursive\n * path: `worktreeFanout` instead settles the raw `WorktreePatchArtifact` and gates via\n * `patchDelivered`. Prefer `worktreeFanout` / `worktreeLoopRunner` for NEW local-repo coding.\n *\n * The decode tolerates two `result`-event shapes:\n * 1. the in-process executor's raw worktree-harness result (`{ branch, patch, stats, checks }`),\n * projected onto `CoderOutput`; and\n * 2. an LLM-emitted JSON block (`{ branch, patch, testResult, typecheckResult, diffStats }`),\n * lifted onto `data.result` or scanned out of the assistant transcript (any harness shape).\n *\n * @experimental\n */\n\nimport { type AgentProfile, agentProfileSchema } from '@tangle-network/agent-interface'\nimport type { SandboxEvent } from '@tangle-network/sandbox'\nimport { ConfigError } from '../errors'\nimport { type CoderTask, coderTaskToPrompt } from '../profiles/coder'\nimport { assertExecutableAgentProfile } from '../runtime/supervise/model-policy'\nimport { type CoderCheckConstraints, runCoderChecks } from '../runtime/supervise/patch-checks'\nimport type { AgentRunSpec, Driver, OutputAdapter, Validator } from '../runtime/types'\n\nconst DEFAULT_MAX_DIFF_LINES = 400\n\n/** @experimental The structured coder result the sandbox-session path decodes + gates. */\nexport interface CoderOutput {\n /** Branch the agent wrote the patch on. */\n branch: string\n /** Unified diff (`git diff <base>..HEAD`). */\n patch: string\n testResult: { passed: boolean; output: string }\n typecheckResult: { passed: boolean; output: string }\n diffStats: { filesChanged: number; insertions: number; deletions: number }\n /** Optional reviewer commentary surfaced by the agent. */\n reviewerNotes?: string\n}\n\n/** @experimental Inputs for one authored coder run on the sandbox-session path. */\nexport interface CoderRunSpecOptions {\n /** Caller-authored exact worker identity. It is the sole harness/provider/model authority. */\n profile: AgentProfile\n /** Stable name for `AgentRunSpec.name`. Default = `profile.name`. */\n name?: string\n}\n\n/** @experimental Build the `AgentRunSpec<CoderTask>` the sandbox-session `runAgentRounds` path drives. */\nexport function coderRunSpec(options: CoderRunSpecOptions): AgentRunSpec<CoderTask> {\n const profile = agentProfileSchema.parse(options.profile) as AgentProfile\n assertExecutableAgentProfile(profile, 'coderRunSpec')\n return {\n name: options.name ?? profile.name,\n profile,\n taskToPrompt: coderTaskToPrompt,\n }\n}\n\n/** @experimental The output adapter the sandbox-session path decodes the harness stream with. */\nexport const coderOutputAdapter: OutputAdapter<CoderOutput> = { parse: parseCoderEvents }\n\n/** @experimental */\nexport interface MultiHarnessCoderFanoutOptions {\n /** Exact worker identities, one per parallel agent. Must contain at least one profile. */\n profiles: ReadonlyArray<AgentProfile>\n}\n\n/**\n * The multi-harness coder fanout driving the sandbox-session delegate's `variants>1` path.\n * (`worktreeFanout` is the local-repo generic counterpart for new code.)\n *\n * @experimental\n */\nexport function multiHarnessCoderFanout(options: MultiHarnessCoderFanoutOptions): {\n agentRuns: AgentRunSpec<CoderTask>[]\n output: OutputAdapter<CoderOutput>\n validator: Validator<CoderOutput>\n driver: Driver<CoderTask, CoderOutput, 'pick-winner' | 'fail'>\n} {\n if (!options.profiles || options.profiles.length === 0) {\n throw new ConfigError('multiHarnessCoderFanout: at least one exact profile is required')\n }\n const agentRuns = options.profiles.map((profile) => coderRunSpec({ profile }))\n const driver: Driver<CoderTask, CoderOutput, 'pick-winner' | 'fail'> = {\n name: 'fanout',\n plan: async (task, history) => (history.length === 0 ? agentRuns.map(() => task) : []),\n decide: (history) => (history.some((i) => i.verdict?.valid === true) ? 'pick-winner' : 'fail'),\n }\n return { agentRuns, output: coderOutputAdapter, validator: defaultCoderValidator(), driver }\n}\n\n/**\n * The sandbox `CoderOutput` validator. A thin shim over the shared {@link runCoderChecks} gate,\n * adapting the parsed `CoderOutput` into the gate inputs.\n *\n * @experimental\n */\nexport function createCoderValidator(task: CoderTask): Validator<CoderOutput> {\n const constraints: CoderCheckConstraints = {\n maxDiffLines: task.maxDiffLines ?? DEFAULT_MAX_DIFF_LINES,\n forbiddenPaths: task.forbiddenPaths ?? [],\n }\n return {\n async validate(output) {\n return runCoderChecks(\n {\n patch: output.patch,\n testsPassed: output.testResult.passed,\n typecheckPassed: output.typecheckResult.passed,\n },\n constraints,\n )\n },\n }\n}\n\nfunction defaultCoderValidator(): Validator<CoderOutput> {\n return createCoderValidator({\n goal: '',\n repoRoot: '',\n forbiddenPaths: [],\n maxDiffLines: DEFAULT_MAX_DIFF_LINES,\n })\n}\n\n/**\n * Walk the event stream and return the structured coder payload.\n *\n * A `result` / `final` event lifts the structured payload onto `data.result`. That payload is\n * either the in-process executor's raw worktree-harness result (projected onto `CoderOutput`) or an\n * LLM-emitted `CoderOutput`-shaped JSON. When neither is present, the scan accumulates ALL assistant\n * text in stream order (any harness shape) and takes the last fenced JSON block that coerces —\n * claude-code lifts whole text onto `data.text`/`data.delta`; opencode streams `message.part.updated`\n * fragments, so the final block is split across many events and never whole in one.\n */\nfunction parseCoderEvents(events: SandboxEvent[]): CoderOutput {\n for (let i = events.length - 1; i >= 0; i -= 1) {\n const event = events[i]\n if (!event) continue\n const type = String(event.type ?? '')\n const data = isRecord(event.data) ? event.data : {}\n if (type === 'result' || type === 'final' || type === 'coder.result') {\n const payload = data.result ?? data.output ?? data\n const projected = projectWorktreeArtifact(payload)\n if (projected) return projected\n const direct = coerceCoderOutput(payload)\n if (direct) return direct\n }\n }\n const transcript = collectAssistantText(events)\n for (const candidate of fencedJsonBlocks(transcript)) {\n const coerced = coerceCoderOutput(candidate)\n if (coerced) return coerced\n }\n return {\n branch: '',\n patch: '',\n testResult: { passed: false, output: '' },\n typecheckResult: { passed: false, output: '' },\n diffStats: { filesChanged: 0, insertions: 0, deletions: 0 },\n }\n}\n\n/** Project the in-process executor's raw worktree-harness result (`{ branch, patch, stats, checks,\n * harness }`) onto `CoderOutput`. A check that did not run is treated as passing (the executor\n * simply didn't run that command). Returns undefined when the payload is not a worktree artifact. */\nfunction projectWorktreeArtifact(value: unknown): CoderOutput | undefined {\n if (!isRecord(value)) return undefined\n const stats = value.stats\n if (!isRecord(stats)) return undefined // not the raw artifact shape\n const branch = pickString(value.branch) ?? ''\n const patch = pickString(value.patch) ?? ''\n const checks = isRecord(value.checks) ? value.checks : {}\n const tests = isRecord(checks.tests) ? checks.tests : undefined\n const typecheck = isRecord(checks.typecheck) ? checks.typecheck : undefined\n const harness = isRecord(value.harness) ? value.harness : undefined\n const exitCode = harness ? toFiniteInt(harness.exitCode) : 0\n const timedOut = harness?.timedOut === true\n const harnessName = harness ? (pickString(harness.name) ?? 'harness') : 'harness'\n return {\n branch,\n patch,\n testResult: {\n passed: tests ? tests.passed === true : true,\n output: tail(pickString(tests?.output) ?? '', 4000),\n },\n typecheckResult: {\n passed: typecheck ? typecheck.passed === true : true,\n output: tail(pickString(typecheck?.output) ?? '', 4000),\n },\n diffStats: {\n filesChanged: toFiniteInt(stats.filesChanged),\n insertions: toFiniteInt(stats.insertions),\n deletions: toFiniteInt(stats.deletions),\n },\n ...(exitCode !== 0\n ? {\n reviewerNotes: `harness ${harnessName} exited ${exitCode}${timedOut ? ' (timed out)' : ''}`,\n }\n : {}),\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\n/** Keep the last `max` chars of a diagnostic string — harness stdout can be large; the gate reads\n * `passed`, not this text, so only the tail is retained for traces/logs. */\nfunction tail(text: string, max: number): string {\n return text.length <= max ? text : text.slice(text.length - max)\n}\n\nfunction pickString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\n/**\n * Concatenate assistant text across the event stream in arrival order, tolerating every harness\n * shape: claude-code lifts text onto `data.text`/`data.delta`; opencode streams\n * `message.part.updated` with `data.part.type === 'text'` carrying `data.delta`/`data.part.text`.\n * Reasoning/thinking parts are excluded — only the final answer text carries the result JSON.\n */\nfunction collectAssistantText(events: SandboxEvent[]): string {\n const chunks: string[] = []\n for (const event of events) {\n if (!event) continue\n const data = isRecord(event.data) ? event.data : {}\n if (String(event.type ?? '') === 'message.part.updated') {\n const part = isRecord(data.part) ? data.part : {}\n const partType = String(part.type ?? '')\n if (partType !== 'text' && partType !== '') continue\n const text = pickString(data.delta) ?? pickString(part.text)\n if (text) chunks.push(text)\n continue\n }\n const text = pickString(data.text) ?? pickString(data.delta)\n if (text) chunks.push(text)\n }\n return chunks.join('')\n}\n\n/** All parseable fenced JSON blocks in `text`, last-first (the final result block the agent emits\n * is the one we want). */\nfunction fencedJsonBlocks(text: string): unknown[] {\n const out: unknown[] = []\n const matches = [...text.matchAll(/```(?:json)?\\s*([\\s\\S]*?)```/gi)]\n for (let i = matches.length - 1; i >= 0; i -= 1) {\n const body = (matches[i]?.[1] ?? '').trim()\n if (!body) continue\n try {\n out.push(JSON.parse(body))\n } catch {\n // not JSON — keep scanning earlier blocks\n }\n }\n return out\n}\n\nfunction coerceCoderOutput(value: unknown): CoderOutput | undefined {\n if (!isRecord(value)) return undefined\n const branch = pickString(value.branch)\n const patch = pickString(value.patch) ?? ''\n if (branch === undefined) return undefined\n return {\n branch,\n patch,\n testResult: coerceCmdResult(value.testResult),\n typecheckResult: coerceCmdResult(value.typecheckResult),\n diffStats: coerceDiffStats(value.diffStats),\n reviewerNotes: pickString(value.reviewerNotes),\n }\n}\n\nfunction coerceCmdResult(value: unknown): { passed: boolean; output: string } {\n if (!isRecord(value)) return { passed: false, output: '' }\n return { passed: value.passed === true, output: pickString(value.output) ?? '' }\n}\n\nfunction coerceDiffStats(value: unknown): {\n filesChanged: number\n insertions: number\n deletions: number\n} {\n if (!isRecord(value)) return { filesChanged: 0, insertions: 0, deletions: 0 }\n return {\n filesChanged: toFiniteInt(value.filesChanged),\n insertions: toFiniteInt(value.insertions),\n deletions: toFiniteInt(value.deletions),\n }\n}\n\nfunction toFiniteInt(value: unknown): number {\n if (typeof value !== 'number') return 0\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.trunc(value))\n}\n","/**\n *\n * Detached delegation turns over the sandbox SDK's `driveTurn` primitive.\n *\n * Two halves of one story:\n *\n * - {@link runDetachedTurn} — the dispatch side. A single-session delegate\n * (single-variant coder / researcher) acquires a box, binds the sandbox id\n * into the record's `detachedSessionRef`, then advances the turn with\n * repeated `driveTurn` ticks instead of holding a live SSE stream. The\n * session id is deterministic and supplied at submit time, so a process\n * crash between ticks loses nothing — the turn keeps running in the box.\n *\n * - {@link createDetachedTurnResumeDriver} — the resume side. A\n * `DelegationResumeDriver` that re-attaches restored in-flight records to\n * their detached runs: parse the record's ref, resolve the box, advance the\n * turn one `driveTurn` pass per `tick()`, and map the SDK's three states\n * (`completed | running | failed`) onto `DelegationResumeTick`.\n *\n * Both sides type the box structurally ({@link DriveTurnCapableBox}) so tests\n * inject fakes and the module never requires the sandbox SDK at runtime — the\n * SDK stays an optional peer, exactly like the executors' `SandboxClient` seam.\n *\n * Tradeoffs of detached mode (why it is opt-in, not the default): a detached\n * turn yields one terminal payload instead of a live event stream, so kernel\n * token/cost aggregation is not produced for that turn. The trace sinks still\n * observe detached work — `runDetachedTurn` synthesizes a single-iteration\n * loop event stream (see `RunDetachedTurnOptions.traceEmitter`) so the span\n * topology joins the inherited trace context, with zero observed subtotals\n * explicitly marked incomplete under the `'detached-turn'` driver tag. Multi-variant fanout stays on the\n * streaming `runAgentRounds` path — N concurrent sessions cannot be expressed as one\n * resume key, and winner selection needs every candidate.\n *\n * @experimental\n */\n\nimport type { SandboxEvent } from '@tangle-network/sandbox'\nimport { ValidationError } from '../errors'\nimport type { AgentRunSpec, LoopTraceEmitter, LoopTraceEvent, SandboxClient } from '../runtime'\nimport { createSandboxForSpec } from '../runtime/run-loop'\nimport { deleteBoxSafe, sleep, throwAbort, throwIfAborted } from '../runtime/util'\nimport type { DelegationRecord, DelegationResumeDriver, DelegationResumeTick } from './task-queue'\nimport type { DelegationProgress, DelegationResultPayload } from './types'\n\nconst DEFAULT_TICK_INTERVAL_MS = 5000\n\n/**\n * Structural mirror of the sandbox SDK's `TurnDriveResult` (>= 0.6).\n * Discriminated on `state`; `failed` is terminal and deterministic per the\n * SDK contract — re-invoking with the same ids returns the same outcome.\n *\n * @experimental\n */\nexport type DriveTurnTick =\n | { state: 'completed'; text: string; result: Record<string, unknown> }\n | { state: 'running'; startedAt?: Date; elapsedMs?: number }\n | { state: 'failed'; error: string }\n\n/**\n * The box surface detached turns need. `SandboxInstance`\n * (`@tangle-network/sandbox` >= 0.6) satisfies it structurally; tests pass\n * in-memory fakes. `_sessionCancel` is the SDK's remote-cancellation surface —\n * optional here because older SDKs / fakes may not expose it; when present it\n * is invoked on abort so the remote run actually stops.\n *\n * @experimental\n */\nexport interface DriveTurnCapableBox {\n driveTurn(\n message: string,\n opts: { sessionId: string; turnId?: string; wallCapMs?: number },\n ): Promise<DriveTurnTick>\n _sessionCancel?(id: string): Promise<void>\n}\n\n/**\n * Decoded `DelegationRecord.detachedSessionRef`. `sandboxId` is absent between\n * submit and box acquisition — a record restored in that window is not\n * resumable (there is no box to resume on) and the resume driver fails it\n * loud rather than dispatching onto a guessed box.\n *\n * @experimental\n */\nexport interface DetachedSessionRefParts {\n sessionId: string\n sandboxId?: string\n}\n\n/**\n * Encode ref parts into the JSON-safe string stored on the record:\n * `session=<id>` before the box exists, `sandbox=<id>;session=<id>` once\n * bound. Ids must not contain the `;`/`=` delimiters.\n *\n * @experimental\n */\nexport function formatDetachedSessionRef(parts: DetachedSessionRefParts): string {\n assertRefComponent('sessionId', parts.sessionId)\n if (parts.sandboxId === undefined) return `session=${parts.sessionId}`\n assertRefComponent('sandboxId', parts.sandboxId)\n return `sandbox=${parts.sandboxId};session=${parts.sessionId}`\n}\n\n/** Parse a `detachedSessionRef` string back to parts; throws `ValidationError` on malformed input. @experimental */\nexport function parseDetachedSessionRef(raw: string): DetachedSessionRefParts {\n const fields = new Map<string, string>()\n for (const pair of raw.split(';')) {\n const eq = pair.indexOf('=')\n const key = eq === -1 ? '' : pair.slice(0, eq)\n const value = eq === -1 ? '' : pair.slice(eq + 1)\n if ((key !== 'session' && key !== 'sandbox') || value.length === 0 || fields.has(key)) {\n throw new ValidationError(\n `parseDetachedSessionRef: malformed detachedSessionRef ${JSON.stringify(raw)} — expected \"session=<id>\" or \"sandbox=<id>;session=<id>\"`,\n )\n }\n fields.set(key, value)\n }\n const sessionId = fields.get('session')\n if (!sessionId) {\n throw new ValidationError(\n `parseDetachedSessionRef: detachedSessionRef ${JSON.stringify(raw)} carries no session id`,\n )\n }\n const sandboxId = fields.get('sandbox')\n return { sessionId, ...(sandboxId !== undefined ? { sandboxId } : {}) }\n}\n\nfunction assertRefComponent(name: string, value: string): void {\n if (value.length === 0 || value.includes(';') || value.includes('=')) {\n throw new ValidationError(\n `formatDetachedSessionRef: ${name} ${JSON.stringify(value)} must be non-empty and free of \";\" / \"=\"`,\n )\n }\n}\n\n/** @experimental The terminal payload of a finished detached turn. */\nexport interface DetachedTurn {\n /** Final assistant text. */\n text: string\n /** The SDK's cached AgentExecutionResult-shape record for the turn. */\n result: Record<string, unknown>\n}\n\n/**\n * Synthesize the terminal event array a detached turn settles through. Shaped\n * so the existing event-stream output adapters (coder, researcher) parse it:\n * `data.result` for adapters that read a structured terminal record, `data.text`\n * for adapters that scan assistant text for the fenced result block.\n *\n * @experimental\n */\nexport function detachedTurnEvents(sessionId: string, turn: DetachedTurn): SandboxEvent[] {\n return [\n {\n type: 'result',\n id: sessionId,\n data: {\n text: turn.text,\n finalText: turn.text,\n success: true,\n result: turn.result,\n },\n } as SandboxEvent,\n ]\n}\n\n/** @experimental */\nexport interface RunDetachedTurnOptions {\n /** Sandbox client used to acquire the box (the delegate's executor client). */\n client: SandboxClient\n /** Profile + overrides for box acquisition — same spec the streaming path uses. */\n spec: AgentRunSpec<unknown>\n /** The full turn prompt; consumed by `driveTurn`'s dispatch leg. */\n prompt: string\n /** Deterministic resume key, minted at submit time (`parseDetachedSessionRef(ref).sessionId`). */\n sessionId: string\n /**\n * Called once the box exists, with its sandbox id. Callers persist\n * `formatDetachedSessionRef({ sandboxId, sessionId })` onto the record here so\n * a restart can resolve the box again.\n */\n bindSandbox(sandboxId: string): void\n signal: AbortSignal\n report(progress: DelegationProgress): void\n /** Delay between `running` ticks (ms). Default 5000. */\n tickIntervalMs?: number\n /** Wall-clock cap forwarded to `driveTurn` — the SDK cancels and fails a session past it. */\n wallCapMs?: number\n /**\n * Loop-trace sink. When set, the detached turn synthesizes a\n * single-iteration loop span tree (`runId` = `sessionId`, driver\n * `'detached-turn'`) so trace-context inheritance survives the detached\n * path — the same events the streaming `runAgentRounds` path would emit, minus\n * per-token telemetry: `driveTurn` yields one terminal payload, so token\n * and cost figures are structurally unavailable; zero observed subtotals are\n * marked incomplete under this driver tag.\n */\n traceEmitter?: LoopTraceEmitter\n /** Physical placement stamped on the synthesized dispatch event. Default `'sibling'`. */\n placement?: 'sibling' | 'fleet'\n}\n\n/**\n * Dispatch one detached turn and advance it to a terminal state with\n * `driveTurn` ticks. The first tick dispatches (idempotent on `sessionId`);\n * subsequent ticks poll. On abort the remote session is cancelled via\n * `_sessionCancel` when the box exposes it. The box is torn down on every\n * in-process exit path (success, failure, abort) — only a process death skips\n * teardown, which is exactly the case the resume driver re-attaches to.\n *\n * @experimental\n */\nexport async function runDetachedTurn(options: RunDetachedTurnOptions): Promise<DetachedTurn> {\n const intervalMs = options.tickIntervalMs ?? DEFAULT_TICK_INTERVAL_MS\n const trace = createDetachedTurnTrace(options)\n trace.started()\n const box = await createSandboxForSpec(options.client, options.spec, options.signal).catch(\n (err) => {\n trace.ended(err instanceof Error ? err.message : String(err))\n throw err\n },\n )\n const drive = box as Partial<DriveTurnCapableBox>\n const onAbort = () => {\n void drive._sessionCancel?.(options.sessionId).catch(() => {})\n }\n try {\n if (typeof drive.driveTurn !== 'function') {\n throw new ValidationError(\n 'runDetachedTurn: the acquired sandbox exposes no driveTurn(message, { sessionId }) — ' +\n 'detached dispatch requires @tangle-network/sandbox >= 0.6 and a session-backed ' +\n 'placement (sibling/fleet); disable detached dispatch for this executor.',\n )\n }\n const sandboxId = (box as { id?: unknown }).id\n if (typeof sandboxId !== 'string' || sandboxId.length === 0) {\n throw new ValidationError(\n 'runDetachedTurn: the acquired sandbox carries no id — without it the detached run ' +\n 'cannot be resumed after a restart, so refusing to dispatch detached.',\n )\n }\n options.bindSandbox(sandboxId)\n trace.dispatched(sandboxId)\n options.signal.addEventListener('abort', onAbort, { once: true })\n for (;;) {\n throwIfAborted(options.signal)\n const tick = await drive.driveTurn(options.prompt, {\n sessionId: options.sessionId,\n turnId: options.sessionId,\n ...(options.wallCapMs !== undefined ? { wallCapMs: options.wallCapMs } : {}),\n })\n throwIfAborted(options.signal)\n if (tick.state === 'completed') {\n trace.ended()\n return { text: tick.text, result: tick.result }\n }\n if (tick.state === 'failed') {\n throw new Error(`detached turn ${options.sessionId} failed: ${tick.error}`)\n }\n options.report({ iteration: 0, phase: detachedRunningPhase(tick.elapsedMs) })\n await sleep(intervalMs, options.signal)\n }\n } catch (err) {\n trace.ended(err instanceof Error ? err.message : String(err))\n throw err\n } finally {\n options.signal.removeEventListener('abort', onAbort)\n if (options.signal.aborted) onAbort()\n await deleteBoxSafe(box)\n }\n}\n\n/**\n * Synthesize the single-iteration loop event stream for one detached turn so\n * the trace sinks (OTEL exporter, delegation journal) observe detached work\n * exactly like a streamed `runAgentRounds` run. `runId` = the deterministic session\n * id; cost/token figures are structurally unavailable on the `driveTurn`\n * surface, so zero observed subtotals carry explicit unknown flags.\n */\nfunction createDetachedTurnTrace(options: RunDetachedTurnOptions): {\n started(): void\n dispatched(sandboxId: string): void\n ended(error?: string): void\n} {\n const emitter = options.traceEmitter\n if (!emitter) {\n return { started() {}, dispatched() {}, ended() {} }\n }\n const runId = options.sessionId\n const agentRunName = options.spec.name ?? options.spec.profile.name ?? 'detached-turn'\n const startMs = Date.now()\n let done = false\n const emit = (event: LoopTraceEvent): void => {\n void emitter.emit(event)\n }\n return {\n started(): void {\n emit({\n kind: 'loop.started',\n runId,\n timestamp: startMs,\n payload: {\n driver: 'detached-turn',\n agentRunNames: [agentRunName],\n maxIterations: 1,\n maxConcurrency: 1,\n },\n })\n emit({\n kind: 'loop.iteration.started',\n runId,\n timestamp: startMs,\n payload: { iterationIndex: 0, agentRunName, taskHash: options.sessionId },\n })\n },\n dispatched(sandboxId: string): void {\n emit({\n kind: 'loop.iteration.dispatch',\n runId,\n timestamp: Date.now(),\n payload: {\n iterationIndex: 0,\n agentRunName,\n placement: options.placement ?? 'sibling',\n sandboxId,\n },\n })\n },\n ended(error?: string): void {\n if (done) return\n done = true\n const endMs = Date.now()\n emit({\n kind: 'loop.iteration.ended',\n runId,\n timestamp: endMs,\n payload: {\n iterationIndex: 0,\n agentRunName,\n costUsd: 0,\n costUsdKnown: false,\n durationMs: endMs - startMs,\n tokenUsage: { input: 0, output: 0, tokensKnown: false },\n ...(error !== undefined ? { error } : {}),\n },\n })\n emit({\n kind: 'loop.ended',\n runId,\n timestamp: endMs,\n payload: {\n ...(error === undefined ? { winnerIterationIndex: 0 } : {}),\n totalCostUsd: 0,\n costUsdKnown: false,\n durationMs: endMs - startMs,\n iterations: 1,\n },\n })\n },\n }\n}\n\nfunction detachedRunningPhase(elapsedMs: number | undefined): string {\n return elapsedMs === undefined\n ? 'detached-running'\n : `detached-running ${Math.round(elapsedMs / 1000)}s`\n}\n\n/** @experimental */\nexport interface DetachedTurnResumeDriverOptions {\n /**\n * Resolve the live box owning a detached session. The bin wires this to the\n * sandbox client's `get(sandboxId)`; throw when the box no longer exists —\n * a thrown tick settles the record as failed, which is the truth.\n */\n resolveSandbox(sandboxId: string): Promise<DriveTurnCapableBox>\n /**\n * Rebuild the turn prompt from the persisted record. Only consumed by\n * `driveTurn`'s dispatch leg — i.e. when the previous process died after\n * binding the box but before the session was dispatched. Must reproduce the\n * prompt the delegate would have sent.\n */\n buildMessage(record: DelegationRecord): string\n /**\n * Map a completed turn onto the delegation's typed output payload (parse +\n * validate per profile). Throw when the resumed result does not pass the\n * profile's gate — the queue settles the record as failed with that error.\n */\n settleOutput(\n turn: DetachedTurn,\n record: DelegationRecord,\n ctx: { signal: AbortSignal },\n ): Promise<DelegationResultPayload['output']> | DelegationResultPayload['output']\n /** Delay between `running` ticks (ms). Default 5000. */\n intervalMs?: number\n /** Wall-clock cap forwarded to `driveTurn` on every tick. */\n wallCapMs?: number\n}\n\n/**\n * Build the `driveTurn`-backed {@link DelegationResumeDriver}. Each `tick()`\n * is one settle/poll/dispatch pass:\n *\n * - ref without a sandbox binding → `failed` (`DetachedSessionUnboundError`):\n * the previous process died before a box existed; there is nothing to resume.\n * - `driveTurn` `completed` → `settleOutput` → `completed` tick.\n * - `running` → progress via `ctx.report`, `running` tick (queue re-ticks\n * after `intervalMs`).\n * - `failed` → `failed` tick (`DetachedTurnFailedError`) — terminal per the\n * SDK's deterministic-failure contract.\n *\n * Abort: the queue stops ticking once `cancel()` flips the record, so remote\n * cancellation is hooked onto `ctx.signal` (once per task) and fires\n * `_sessionCancel` when the SDK surface exposes it. The driver never deletes\n * boxes — it cannot know whether `sandboxId` is a disposable sibling or a\n * fleet machine, and destroying a fleet machine would be unrecoverable.\n *\n * @experimental\n */\nexport function createDetachedTurnResumeDriver(\n options: DetachedTurnResumeDriverOptions,\n): DelegationResumeDriver {\n const cancelHooked = new Set<string>()\n return {\n intervalMs: options.intervalMs ?? DEFAULT_TICK_INTERVAL_MS,\n async tick({ record, detachedSessionRef }, ctx): Promise<DelegationResumeTick> {\n const ref = parseDetachedSessionRef(detachedSessionRef)\n if (ref.sandboxId === undefined) {\n return {\n state: 'failed',\n error: {\n message:\n `detached session \"${ref.sessionId}\" was never bound to a sandbox — the previous ` +\n 'process died before the box was acquired, so the turn was never dispatched and ' +\n 'cannot be resumed',\n kind: 'DetachedSessionUnboundError',\n },\n }\n }\n const box = await options.resolveSandbox(ref.sandboxId)\n if (!cancelHooked.has(record.taskId)) {\n cancelHooked.add(record.taskId)\n ctx.signal.addEventListener(\n 'abort',\n () => {\n void box._sessionCancel?.(ref.sessionId).catch(() => {})\n },\n { once: true },\n )\n }\n if (ctx.signal.aborted) throwAbort()\n const tick = await box.driveTurn(options.buildMessage(record), {\n sessionId: ref.sessionId,\n turnId: ref.sessionId,\n ...(options.wallCapMs !== undefined ? { wallCapMs: options.wallCapMs } : {}),\n })\n if (tick.state === 'completed') {\n const output = await options.settleOutput(\n { text: tick.text, result: tick.result },\n record,\n {\n signal: ctx.signal,\n },\n )\n return { state: 'completed', output }\n }\n if (tick.state === 'failed') {\n return {\n state: 'failed',\n error: {\n message: `detached turn ${ref.sessionId} failed: ${tick.error}`,\n kind: 'DetachedTurnFailedError',\n },\n }\n }\n ctx.report({ iteration: 0, phase: detachedRunningPhase(tick.elapsedMs) })\n return { state: 'running' }\n },\n }\n}\n","/**\n *\n * `detachedSessionDelegate` — the sandbox-session coder delegate: a closure that drives `runAgentRounds`\n * against a `SandboxClient` + a caller-supplied exact worker profile, to a\n * mechanically-validated `CoderOutput`. The caller invokes the returned delegate directly with its\n * coder args; when wired into a durable queue it also settles cross-restart-resumed records.\n *\n * Delegation vs COORDINATION (`../runtime/supervise/coordination-mcp.ts`): this delegate runs a\n * coding task INSIDE the agent's OWN sandbox environment — a sibling box on its own `SandboxClient`,\n * fresh branch on its repo. It is NOT backend-pluggable. To instead SPAWN + live-drive workers in a\n * CHOSEN backend (sandbox OR cli-bridge, via `createExecutor({ backend })`) with observe/steer/resume\n * + recursion, use `delegate()` / the coordination MCP.\n *\n * The worker profile is a parameter the caller supplies (§1.5: the system authors profiles).\n * For NEW local-repo coding use `worktreeFanout` / `worktreeLoopRunner`\n * (author one `AgentProfile` per harness → `createWorktreeCliExecutor` leaves → `gateOnDeliverable`).\n *\n * @experimental\n */\n\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport { ConfigError } from '../errors'\nimport type { CoderTask } from '../profiles/coder'\nimport type {\n AgentRunSpec,\n Iteration,\n LoopTraceEmitter,\n Outcome,\n SandboxClient,\n WinnerStrategy,\n} from '../runtime'\nimport { runAgentRounds, selectValidWinner } from '../runtime'\nimport { composeLoopTraceEmitters } from './delegation-trace'\nimport {\n type CoderOutput,\n coderOutputAdapter,\n coderRunSpec,\n createCoderValidator,\n multiHarnessCoderFanout,\n} from './detached-coder'\nimport {\n type DetachedTurn,\n detachedTurnEvents,\n formatDetachedSessionRef,\n parseDetachedSessionRef,\n runDetachedTurn,\n} from './detached-turn'\nimport { createSiblingSandboxExecutor, type DelegationExecutor } from './executor'\nimport type {\n DelegateCodeArgs,\n DelegateUiAuditArgs,\n DelegationProgress,\n UiAuditorDelegationOutput,\n} from './types'\n\n/** @experimental */\nexport interface DelegateRunCtx {\n signal: AbortSignal\n report(progress: DelegationProgress): void\n /**\n * Detached-run resume key recorded on the queue record at submit time\n * (`formatDetachedSessionRef`). Present only when the submit path requested\n * detached dispatch — its presence is what routes a session-backed delegate\n * onto the `driveTurn` tick path instead of holding a stream.\n */\n detachedSessionRef?: string\n /** Rebind the record's resume key (e.g. once the sandbox id is known). */\n updateDetachedSessionRef?(ref: string): void\n /**\n * Per-delegation trace sink supplied by the queue — loop events emitted\n * here land on the delegation record as a compact span tree. Delegates\n * compose it with their configured OTEL emitter so both sinks observe\n * the same stream.\n */\n traceEmitter?: LoopTraceEmitter\n}\n\n/** @experimental The coder delegate closure — given the coder args + run context, drives the\n * sandbox-session coder path to a validated `CoderOutput`. `detachedSessionDelegate` is the\n * built-in implementation; the queue invokes one of these per coder delegation. */\nexport type CoderDelegate = (args: DelegateCodeArgs, ctx: DelegateRunCtx) => Promise<CoderOutput>\n\n/**\n * UI-auditor delegate — fully consumer-injected. agent-runtime ships no\n * default factory because execution belongs to a caller-supplied exact\n * agent profile and Runtime executor.\n *\n * @experimental\n */\nexport type UiAuditorDelegate = (\n args: DelegateUiAuditArgs,\n ctx: DelegateRunCtx,\n) => Promise<UiAuditorDelegationOutput>\n\n/** @experimental Structured review verdict over a coder candidate. */\nexport interface CoderReview {\n /** Gate: only approved candidates are eligible to win. */\n approved: boolean\n /** Reviewer's recommendation — surfaced in traces. */\n recommendation: 'ship' | 'approve-with-nits' | 'changes-requested' | 'reject'\n /** Readiness 0..1, used by the `highest-readiness` winner-selection strategy. */\n readiness: number\n notes?: string\n}\n\n/**\n *\n * Optional adversarial reviewer over a coder candidate that already passed\n * mechanical validation (tests/typecheck/forbidden/diff/no-op/secrets). Folded\n * from the ai-trading-blueprint delegation MCP: a candidate is only eligible to\n * win if the reviewer approves it. The reviewer is the consumer's seam — an LLM\n * judge, a `pnpm review` command, anything returning a `CoderReview`.\n *\n * @experimental\n */\nexport type CoderReviewer = (\n output: CoderOutput,\n task: CoderTask,\n ctx: { signal: AbortSignal },\n) => Promise<CoderReview> | CoderReview\n\n/**\n * @experimental Winner-selection strategy among validated (+ reviewed) candidates on the\n * sandbox-session path. The base strategies (`highest-score` / `smallest-diff` /\n * `first-approved`) delegate to the shared `selectValidWinner`; `highest-readiness` is the\n * reviewer-only strategy this path keeps that the generic selector does not express. Default\n * `highest-score`.\n */\nexport type DetachedWinnerSelection =\n | 'highest-score'\n | 'smallest-diff'\n | 'highest-readiness'\n | 'first-approved'\n\n/** @experimental */\nexport interface DetachedSessionDelegateOptions {\n /**\n * Execution placement. Pass a {@link DelegationExecutor} (sibling or fleet)\n * to control where worker iterations land. `sandboxClient` is a\n * convenience shorthand that wraps the client in a sibling executor — pass\n * one or the other, not both.\n */\n executor?: DelegationExecutor\n /**\n * Convenience shorthand for sibling placement. Equivalent to\n * `executor: createSiblingSandboxExecutor({ client: sandboxClient })`.\n */\n sandboxClient?: SandboxClient\n /**\n * The worker's exact authored `AgentProfile` (§1.5: the system authors profiles). It is the sole\n * harness/provider/model/prompt authority for the single-coder path and the default identity for\n * repeated fanout shots.\n */\n workerProfile: AgentProfile\n /** Optional exact identities for heterogeneous fanout. Omit to repeat `workerProfile`. */\n fanoutProfiles?: ReadonlyArray<AgentProfile>\n /** Hard cap on the kernel's per-batch concurrency. Default 4. */\n maxConcurrency?: number\n /**\n * Optional adversarial reviewer. When set, a candidate must pass mechanical\n * validation AND `reviewer.approved` to be eligible to win — empty/secret/\n * test-failing patches are already gone; this catches the \"compiles + passes\n * but wrong/unsafe\" class the deterministic validator can't see.\n */\n reviewer?: CoderReviewer\n /** Winner-selection strategy among eligible candidates. Default `highest-score`. */\n winnerSelection?: DetachedWinnerSelection\n /**\n * Loop trace emitter forwarded into every delegated `runAgentRounds`. Wire\n * `createPropagatingTraceEmitter(readTraceContextFromEnv())` here (the bin\n * does) so delegated build-loops export their topology spans to the OTLP /\n * Tangle Intelligence sink when `OTEL_EXPORTER_OTLP_ENDPOINT` is set — and\n * are a cheap no-op when it isn't. Configurable by construction.\n *\n * Detached single-variant turns (taken when `ctx.detachedSessionRef` is set)\n * bypass `runAgentRounds`; `runDetachedTurn` synthesizes a single-iteration loop\n * event stream for them so this emitter observes detached work too.\n */\n traceEmitter?: LoopTraceEmitter\n /** Tick cadence (ms) for the detached single-variant path. Default 5000. */\n detachedTickIntervalMs?: number\n /** Wall-clock cap (ms) forwarded to `driveTurn` for detached turns. */\n detachedWallCapMs?: number\n}\n\n/**\n * Build the sandbox-session coder delegate. It drives `runAgentRounds` against the project's\n * sandbox client + coder profile; when `args.variants > 1` it switches to the multi-harness fanout\n * topology.\n *\n * This is the SANDBOX-SESSION coder path: workers run the in-box harness via the\n * `SandboxClient`'s `streamPrompt`, and single-variant turns can dispatch DETACHED\n * (driveTurn ticks) so a durable queue resumes them across an MCP restart — a substrate\n * the recursive worktree-CLI leaf does not yet have a journal-replay equivalent for.\n *\n * For NEW local-repo coding use `worktreeFanout` / `worktreeLoopRunner` (author an `AgentProfile`\n * per harness → `createWorktreeCliExecutor` leaves → `gateOnDeliverable`). This delegate runs\n * held-stream by default and only its OPTIONAL cross-restart resume (the `driveTurn` tick) is opt-in\n * behind `MCP_ENABLE_DETACHED_RESUME`.\n *\n * @experimental\n */\nexport function detachedSessionDelegate(options: DetachedSessionDelegateOptions): CoderDelegate {\n if (!options.workerProfile) {\n throw new ConfigError('detachedSessionDelegate: workerProfile is required')\n }\n const workerProfile = coderRunSpec({ profile: options.workerProfile }).profile\n const fanoutProfiles = options.fanoutProfiles?.map((profile) => coderRunSpec({ profile }).profile)\n if (fanoutProfiles?.length === 0) {\n throw new ConfigError('detachedSessionDelegate: fanoutProfiles must not be empty')\n }\n const executor = resolveExecutor(options)\n const sandboxClient = executor.client\n const maxConcurrency = options.maxConcurrency ?? 4\n const traceEmitter = options.traceEmitter\n return async (args, ctx) => {\n const task = coderTaskFromArgs(args)\n const variants = Math.max(1, Math.trunc(args.variants ?? 1))\n const selectedFanoutProfiles =\n variants <= 1\n ? undefined\n : (fanoutProfiles ?? Array.from({ length: variants }, () => workerProfile))\n if (selectedFanoutProfiles && selectedFanoutProfiles.length < variants) {\n throw new ConfigError(\n `detachedSessionDelegate: ${variants} variants requested but only ${selectedFanoutProfiles.length} exact fanout profiles were configured`,\n )\n }\n const loopEmitter = composeLoopTraceEmitters(traceEmitter, ctx.traceEmitter)\n ctx.report({ iteration: 0, phase: 'starting' })\n if (variants <= 1) {\n const agentRunSpec = coderRunSpec({ profile: workerProfile })\n const output = coderOutputAdapter\n const validator = createCoderValidator(task)\n // Detached dispatch: one session on one box, driven by `driveTurn` ticks\n // instead of a held stream, so the run survives an MCP-process restart\n // (the resume driver re-attaches via the persisted ref). Only the\n // single-variant path detaches — fanout needs N sessions + winner\n // selection over every candidate, which one resume key cannot express.\n if (ctx.detachedSessionRef !== undefined && ctx.updateDetachedSessionRef) {\n const { sessionId } = parseDetachedSessionRef(ctx.detachedSessionRef)\n const rebind = ctx.updateDetachedSessionRef\n const turn = await runDetachedTurn({\n client: sandboxClient,\n spec: agentRunSpec as AgentRunSpec<unknown>,\n prompt: agentRunSpec.taskToPrompt(task),\n sessionId,\n bindSandbox: (sandboxId) => rebind(formatDetachedSessionRef({ sandboxId, sessionId })),\n signal: ctx.signal,\n report: ctx.report,\n ...(loopEmitter ? { traceEmitter: loopEmitter } : {}),\n ...(executor.placement === 'fleet' ? { placement: 'fleet' as const } : {}),\n ...(options.detachedTickIntervalMs !== undefined\n ? { tickIntervalMs: options.detachedTickIntervalMs }\n : {}),\n ...(options.detachedWallCapMs !== undefined\n ? { wallCapMs: options.detachedWallCapMs }\n : {}),\n })\n const chosen = await settleDetachedCoderTurn(turn, {\n task,\n sessionId,\n signal: ctx.signal,\n ...(options.reviewer ? { reviewer: options.reviewer } : {}),\n })\n ctx.report({ iteration: 1, phase: 'completed' })\n return chosen\n }\n const result = await runAgentRounds({\n driver: singleShotDriver,\n agentRun: agentRunSpec,\n output,\n validator,\n task,\n ctx: {\n sandboxClient,\n signal: ctx.signal,\n ...(loopEmitter ? { traceEmitter: loopEmitter } : {}),\n },\n maxIterations: 1,\n maxConcurrency,\n })\n const chosen = await pickCoderWinner({\n iterations: result.iterations,\n reviewer: options.reviewer,\n selection: options.winnerSelection ?? 'highest-score',\n task,\n signal: ctx.signal,\n })\n if (!chosen) throw new Error(noWinnerMessage(options.reviewer))\n ctx.report({ iteration: 1, phase: 'completed' })\n return chosen\n }\n const fanout = multiHarnessCoderFanout({\n profiles: selectedFanoutProfiles!.slice(0, variants),\n })\n const agentRuns = fanout.agentRuns.slice(0, variants)\n const result = await runAgentRounds({\n driver: fanout.driver,\n agentRuns,\n output: fanout.output,\n validator: fanout.validator,\n task,\n ctx: {\n sandboxClient,\n signal: ctx.signal,\n ...(loopEmitter ? { traceEmitter: loopEmitter } : {}),\n },\n maxIterations: variants,\n maxConcurrency: Math.min(maxConcurrency, variants),\n })\n const chosen = await pickCoderWinner({\n iterations: result.iterations,\n reviewer: options.reviewer,\n selection: options.winnerSelection ?? 'highest-score',\n task,\n signal: ctx.signal,\n })\n if (!chosen) throw new Error(noWinnerMessage(options.reviewer))\n ctx.report({ iteration: agentRuns.length, phase: 'completed' })\n return chosen\n }\n}\n\ninterface PickCoderWinnerArgs {\n iterations: ReadonlyArray<Iteration<CoderTask, CoderOutput>>\n reviewer: CoderReviewer | undefined\n selection: DetachedWinnerSelection\n task: CoderTask\n signal: AbortSignal\n}\n\n/** A valid (and, when a reviewer is wired, approved) candidate kept for selection. */\ninterface EligibleCandidate {\n iter: Iteration<CoderTask, CoderOutput>\n /** Reviewer readiness (defaults to the verdict score when no reviewer ran). */\n readiness: number\n}\n\n/**\n * Pick the winning coder candidate from a finished loop's iterations:\n * 1. keep only mechanically-VALID candidates (the validator already gated\n * tests/typecheck/forbidden/diff/no-op/secrets),\n * 2. if a `reviewer` is wired, keep only those it APPROVES,\n * 3. select among survivors via the shared `selectValidWinner` (base strategies) or, for the\n * reviewer-only `highest-readiness`, a readiness sort (the one strategy the generic selector\n * does not express — a documented capability of this sandbox-session path).\n * Returns `undefined` when nothing survives — the delegate fails loud.\n */\nasync function pickCoderWinner(args: PickCoderWinnerArgs): Promise<CoderOutput | undefined> {\n const eligible: EligibleCandidate[] = []\n for (const iter of args.iterations) {\n if (iter.output === undefined || iter.error || iter.verdict?.valid !== true) continue\n const readiness = iter.verdict.score ?? 0\n if (args.reviewer) {\n const review = await args.reviewer(iter.output, args.task, { signal: args.signal })\n if (!review.approved) continue\n eligible.push({ iter, readiness: review.readiness })\n } else {\n eligible.push({ iter, readiness })\n }\n }\n if (eligible.length === 0) return undefined\n\n // `highest-readiness` ranks on the reviewer's readiness — a reviewer-only metric the generic\n // valid-only selector does not carry. Ties → earliest iteration.\n if (args.selection === 'highest-readiness') {\n const sorted = [...eligible].sort(\n (a, b) => b.readiness - a.readiness || a.iter.index - b.iter.index,\n )\n return sorted[0]!.iter.output\n }\n\n // Base strategies route through the SHARED valid-only selector. Wrap each survivor's raw\n // `CoderOutput` in the `Outcome<D>` shape `selectValidWinner` reads, preserving verdict/index.\n const wrapped: Iteration<unknown, Outcome<CoderOutput>>[] = eligible.map(({ iter }) => ({\n ...iter,\n output: { kind: 'done', deliverable: iter.output as CoderOutput },\n }))\n const winner = selectValidWinner<CoderOutput>({\n strategy: baseStrategy(args.selection),\n sizeOf: (o) => o.diffStats.insertions + o.diffStats.deletions,\n })(wrapped)\n const out = winner?.output\n if (out?.kind !== 'done') return undefined\n return out.deliverable\n}\n\n/** Map the detached-session selection enum onto the shared `WinnerStrategy`. `first-approved`\n * reduces to `first-valid` over the already-approved set; `smallest-diff` to `smallest-artifact`. */\nfunction baseStrategy(\n selection: Exclude<DetachedWinnerSelection, 'highest-readiness'>,\n): WinnerStrategy {\n switch (selection) {\n case 'smallest-diff':\n return 'smallest-artifact'\n case 'first-approved':\n return 'first-valid'\n default:\n return 'highest-score'\n }\n}\n\nfunction noWinnerMessage(reviewer: CoderReviewer | undefined): string {\n return reviewer\n ? 'coder delegate: no candidate passed validation + review'\n : 'coder delegate: no candidate passed validation'\n}\n\n/**\n * Canonical `DelegateCodeArgs` → `CoderTask` mapping — the single source for\n * the delegate's live dispatch AND the resume driver's settle/message\n * rebuilding, so a resumed record reproduces exactly the task the original\n * process dispatched.\n *\n * @experimental\n */\nexport function coderTaskFromArgs(args: DelegateCodeArgs): CoderTask {\n return {\n goal: buildCoderGoal(args),\n repoRoot: args.repoRoot,\n testCmd: args.config?.testCmd,\n typecheckCmd: args.config?.typecheckCmd,\n forbiddenPaths: args.config?.forbiddenPaths,\n maxDiffLines: args.config?.maxDiffLines,\n }\n}\n\n/** @experimental */\nexport interface SettleDetachedCoderTurnOptions {\n task: CoderTask\n /** Session id of the detached turn — used as the synthesized event id. */\n sessionId: string\n signal: AbortSignal\n /** Same gate as the streaming path: an unapproved candidate cannot win. */\n reviewer?: CoderReviewer\n}\n\n/**\n * Settle a completed detached coder turn through the same gate the streaming\n * path applies: parse the terminal payload with the coder output adapter,\n * run the mechanical validator (tests/typecheck/forbidden/diff/no-op/secrets),\n * then the optional reviewer. Throws when nothing survives — a resumed or\n * detached run must not return an unvalidated patch.\n *\n * SCOPE NOTE (detached/resume): the detached `driveTurn`-tick + cross-restart resume path is\n * bound to the `runAgentRounds` + sandbox-session substrate. The recursive `Scope`/worktree-CLI leaf has\n * journal→replay but no driveTurn-over-a-detached-sandbox-session equivalent yet, so resume is NOT\n * advertised on the generic `worktreeFanout` path. This helper (with `coderTaskFromArgs` and\n * `createDetachedTurnResumeDriver`) stays as the resume seam `bin.ts` wires for in-flight records.\n *\n * @experimental\n */\nexport async function settleDetachedCoderTurn(\n turn: DetachedTurn,\n options: SettleDetachedCoderTurnOptions,\n): Promise<CoderOutput> {\n const parsed = coderOutputAdapter.parse(detachedTurnEvents(options.sessionId, turn))\n const validator = createCoderValidator(options.task)\n const verdict = await validator.validate(parsed, { iteration: 0, signal: options.signal })\n if (verdict.valid !== true) throw new Error(noWinnerMessage(options.reviewer))\n if (options.reviewer) {\n const review = await options.reviewer(parsed, options.task, { signal: options.signal })\n if (!review.approved) throw new Error(noWinnerMessage(options.reviewer))\n }\n return parsed\n}\n\nfunction buildCoderGoal(args: DelegateCodeArgs): string {\n if (!args.contextHint) return args.goal\n return [args.goal, '', '## Context', args.contextHint].join('\\n')\n}\n\nfunction resolveExecutor(options: DetachedSessionDelegateOptions): DelegationExecutor {\n if (options.executor && options.sandboxClient) {\n throw new Error('detachedSessionDelegate: pass exactly one of `executor` or `sandboxClient`')\n }\n if (options.executor) return options.executor\n if (options.sandboxClient) {\n return createSiblingSandboxExecutor({ client: options.sandboxClient })\n }\n throw new Error('detachedSessionDelegate: `executor` or `sandboxClient` is required')\n}\n\n/**\n * Single-shot driver — plan one task on iteration 0, stop after one\n * iteration. Used by the coder delegate when `variants <= 1`. Keeps the\n * runAgentRounds kernel-level accounting (timing, cost, trace emission) while\n * skipping fanout/refine topology overhead.\n */\nconst singleShotDriver = {\n name: 'mcp-single-shot',\n async plan<Task>(task: Task, history: ReadonlyArray<unknown>): Promise<Task[]> {\n return history.length === 0 ? [task] : []\n },\n decide(history: ReadonlyArray<unknown>): 'pick-winner' | 'fail' {\n return history.length > 0 ? 'pick-winner' : 'fail'\n },\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/mcp/executor.ts","../../src/mcp/in-process-executor.ts","../../src/mcp/bin-helpers.ts","../../src/mcp/detached-coder.ts","../../src/mcp/detached-turn.ts","../../src/mcp/delegates.ts"],"sourcesContent":["/**\n *\n * Delegation executors — the layer between MCP delegates and the sandbox\n * substrate. Each executor exposes a {@link SandboxClient} the kernel\n * consumes plus a placement tag so the trace pipeline can correlate workers\n * with their physical placement.\n *\n * Two implementations ship in-box:\n *\n * - {@link createSiblingSandboxExecutor} — every delegation spawns a fresh\n * sandbox sibling to the caller. Default when the MCP server runs as a\n * standalone CLI mounted outside a fleet.\n *\n * - {@link createFleetWorkspaceExecutor} — delegations dispatch onto machines\n * in the caller's existing fleet so worker diffs land directly on the\n * caller's filesystem (the fleet's shared workspace). Selected when the\n * parent sandbox passes `TANGLE_FLEET_ID` into the MCP server's env.\n *\n * @experimental\n */\n\nimport type { CreateSandboxOptions, SandboxInstance } from '@tangle-network/sandbox'\nimport type { LoopSandboxPlacement, SandboxClient } from '../runtime'\n\n/** @experimental */\nexport interface DelegationExecutor {\n /** Sandbox client the kernel calls. Returned with `describePlacement` set. */\n readonly client: SandboxClient\n /** Best-effort one-liner used in stderr boot logs and diagnostics. */\n describe(): string\n /**\n * Where delegated work physically runs. `sibling` and `fleet` placements are\n * session-backed (boxes expose `driveTurn`, so detached dispatch + resume\n * apply); `in-process` spawns local harness CLIs with no sandbox session to\n * detach. Optional so consumer-implemented executors stay source-compatible;\n * absent means \"unknown\" and detached dispatch is not enabled for it.\n */\n readonly placement?: 'sibling' | 'fleet' | 'in-process'\n}\n\n/** @experimental */\nexport interface SiblingSandboxExecutorOptions {\n client: SandboxClient\n}\n\n/**\n * Wrap a raw sandbox SDK client so the kernel emits\n * `loop.iteration.dispatch` events with `{ placement: 'sibling', sandboxId }`.\n *\n * The returned client `.create()` delegates to the underlying client; the\n * only added behavior is a `describePlacement` tag the kernel reads.\n *\n * @experimental\n */\nexport function createSiblingSandboxExecutor(\n options: SiblingSandboxExecutorOptions,\n): DelegationExecutor {\n const underlying = options.client\n const client: SandboxClient = {\n create(opts?: CreateSandboxOptions): Promise<SandboxInstance> {\n return underlying.create(opts)\n },\n describePlacement(box: SandboxInstance): LoopSandboxPlacement {\n return { kind: 'sibling', sandboxId: readId(box) }\n },\n }\n return {\n client,\n placement: 'sibling',\n describe(): string {\n return 'sibling-sandbox (each delegation = fresh sandbox via client.create)'\n },\n }\n}\n\n/**\n * Minimal `SandboxFleet` surface the fleet executor calls. Declared\n * structurally so tests can pass an in-memory stub without instantiating the\n * sandbox SDK.\n *\n * @experimental\n */\nexport interface FleetHandle {\n readonly fleetId: string\n /** Machine ids in dispatch-eligible order. The executor round-robins. */\n readonly ids: ReadonlyArray<string>\n /** Resolve a machine id to its `SandboxInstance` — that machine is mounted\n * on the fleet's shared workspace, so any diff the worker writes lands on\n * every other fleet machine's filesystem too. */\n sandbox(machineId: string): Promise<SandboxInstance>\n}\n\n/** @experimental */\nexport interface FleetWorkspaceExecutorOptions {\n fleet: FleetHandle\n /**\n * Override the machine-selection policy. Default = round-robin across\n * `fleet.ids`, skipping the optional `excludeMachineIds` set (typically the\n * coordinator machine the MCP server is running on).\n */\n selectMachine?: (call: { callIndex: number; ids: ReadonlyArray<string> }) => string\n /**\n * Machine ids to skip during default round-robin. Set to the caller's own\n * machineId so workers don't compete with the orchestrator on the same VM.\n */\n excludeMachineIds?: ReadonlyArray<string>\n}\n\n/**\n * Build an executor that resolves each delegated iteration to an existing\n * machine in `fleet`. The fleet's shared-workspace policy means the worker\n * machine sees the caller's filesystem — diffs land in-place with no\n * cross-sandbox copy step.\n *\n * @experimental\n */\nexport function createFleetWorkspaceExecutor(\n options: FleetWorkspaceExecutorOptions,\n): DelegationExecutor {\n const fleet = options.fleet\n const exclude = new Set(options.excludeMachineIds ?? [])\n let callIndex = 0\n // machineId-by-sandboxId, populated as we resolve machines so\n // `describePlacement` can recover the assignment from the SandboxInstance\n // the kernel hands back.\n const placementBySandboxId = new Map<string, { machineId: string }>()\n\n const client: SandboxClient = {\n async create(): Promise<SandboxInstance> {\n const ids = fleet.ids.filter((id) => !exclude.has(id))\n if (ids.length === 0) {\n throw new Error(\n `agent-runtime: fleet ${fleet.fleetId} has no eligible worker machines (ids=[${fleet.ids.join(',')}], excluded=[${[...exclude].join(',')}])`,\n )\n }\n const selector = options.selectMachine\n const machineId = selector ? selector({ callIndex, ids }) : ids[callIndex % ids.length]\n callIndex += 1\n if (typeof machineId !== 'string' || machineId.length === 0) {\n throw new Error('agent-runtime: fleet executor selectMachine returned an empty machine id')\n }\n const box = await fleet.sandbox(machineId)\n const sandboxId = readId(box)\n if (sandboxId) placementBySandboxId.set(sandboxId, { machineId })\n return box\n },\n describePlacement(box: SandboxInstance): LoopSandboxPlacement {\n const sandboxId = readId(box)\n const recorded = sandboxId ? placementBySandboxId.get(sandboxId) : undefined\n return {\n kind: 'fleet',\n sandboxId,\n fleetId: fleet.fleetId,\n machineId: recorded?.machineId,\n }\n },\n }\n\n return {\n client,\n placement: 'fleet',\n describe(): string {\n const excluded = exclude.size > 0 ? ` (excluded=[${[...exclude].join(',')}])` : ''\n return `fleet-workspace (fleetId=${fleet.fleetId}, machines=[${fleet.ids.join(',')}]${excluded})`\n },\n }\n}\n\nfunction readId(box: SandboxInstance): string | undefined {\n const raw = (box as unknown as { id?: unknown }).id\n return typeof raw === 'string' && raw.length > 0 ? raw : undefined\n}\n","/**\n *\n * In-process delegation executor — when `agent-runtime-mcp` runs inside a sandbox whose image\n * carries the local coding-harness CLIs (claude / codex / opencode), delegations spawn the harness\n * AS A SUBPROCESS against a git worktree on the SAME filesystem instead of provisioning a sibling\n * sandbox. Zero provisioning latency; worker diffs land in-place; multi-harness fanout = N parallel\n * subprocesses in N parallel worktrees. Each authored profile selects its own harness.\n *\n * This is a THIN adapter over `runWorktreeHarness` (`./worktree-harness`) — the SAME core the\n * `Scope` leaf `createWorktreeCliExecutor` uses. It only adapts the core to the `SandboxClient`\n * port: `create()` reads the authored profile from `CreateSandboxOptions.backend.profile`, and\n * `streamPrompt` runs the core then emits its raw `WorktreeHarnessResult` (the content-addressed\n * patch artifact) on the `result` event. The sandbox-session decode layer\n * (`./detached-coder`) projects that artifact onto `CoderOutput`; the generic `Scope` path settles\n * the artifact directly. The §1.5 payload (systemPrompt + model) reaches the harness inside the core.\n *\n * @experimental\n */\n\nimport { randomUUID } from 'node:crypto'\nimport { type AgentProfile, agentProfileSchema } from '@tangle-network/agent-interface'\nimport type { CreateSandboxOptions, SandboxEvent, SandboxInstance } from '@tangle-network/sandbox'\nimport { ConfigError } from '../errors'\nimport type { LoopSandboxPlacement, SandboxClient } from '../runtime'\nimport { assertExecutableAgentProfile } from '../runtime/supervise/model-policy'\nimport type { DelegationExecutor } from './executor'\nimport { LOCAL_HARNESSES, type LocalHarness } from './local-harness'\nimport type { GitRunner, WorktreeHandle } from './worktree'\nimport { runWorktreeHarness } from './worktree-harness'\n\n/** @experimental */\nexport interface InProcessExecutorOptions {\n /** Absolute path to the git repo (the workspace). Worktrees go under `<repoRoot>/.agent-worktrees/`. */\n repoRoot: string\n /** Optional per-delegation test command run in the worktree after the harness exits. */\n testCmd?: string\n /** Optional per-delegation typecheck command. Same shape as `testCmd`. */\n typecheckCmd?: string\n /** Wall-clock cap per harness subprocess (ms). Default 5min. */\n harnessTimeoutMs?: number\n /** Wall-clock cap per test/typecheck subprocess (ms). Default 2min. */\n postCheckTimeoutMs?: number\n /** Test seam — override the git runner used by the worktree helpers. */\n runGit?: GitRunner\n /** Test seam — override the harness runner (defaults to the real CLI via `runLocalHarness`). */\n runHarness?: typeof import('./local-harness').runLocalHarness\n /** Test seam — override the post-check runner (defaults to a `sh -c` spawn). A throw is folded\n * into a non-fatal `{exitCode:-1}` so a broken check command fails the signal, not the run. */\n runPostCheck?: (\n cmd: string,\n cwd: string,\n signal?: AbortSignal,\n ) => Promise<{ exitCode: number; stdout: string; stderr: string }>\n}\n\n/** @experimental */\nexport interface InProcessExecutorDescribePlacement extends LoopSandboxPlacement {\n /** Worktree path in the parent sandbox's filesystem (set so traces correlate to on-disk artifacts). */\n worktreePath?: string\n /** Which harness handled this delegation. */\n harness?: LocalHarness\n}\n\ninterface VirtualSandbox extends SandboxInstance {\n __inProcess: {\n runId: string\n harness: LocalHarness\n worktree?: WorktreeHandle\n }\n}\n\nconst DEFAULT_HARNESS_TIMEOUT_MS = 5 * 60 * 1000\nconst DEFAULT_POSTCHECK_TIMEOUT_MS = 2 * 60 * 1000\n\n/**\n * Build an in-process executor. Returns a {@link DelegationExecutor} whose `client.create()`\n * returns a minimal virtual `SandboxInstance`; the kernel calls `streamPrompt(msg)` on it, which\n * runs the shared worktree-harness core and emits one `result` event whose `data.result` is the\n * raw `WorktreeHarnessResult` (the content-addressed patch artifact). The authored profile\n * (`backend.profile`) threads its systemPrompt + model into the harness via the core.\n *\n * @experimental\n */\nexport function createInProcessExecutor(options: InProcessExecutorOptions): DelegationExecutor {\n const runPostCheck = options.runPostCheck ?? defaultRunPostCheck\n // The core speaks one `runCommand` seam ({exitCode, output}); adapt the post-check seam\n // ({exitCode, stdout, stderr}) onto it, folding a throw into a non-fatal failure signal so a\n // broken check command fails the signal rather than aborting the whole delegation.\n const runCommand = async ({\n command,\n cwd,\n signal,\n }: {\n command: string\n cwd: string\n timeoutMs: number\n signal?: AbortSignal\n }): Promise<{ exitCode: number | null; output: string }> => {\n try {\n const r = await runPostCheck(command, cwd, signal)\n return { exitCode: r.exitCode, output: r.stderr || r.stdout }\n } catch (err) {\n return { exitCode: -1, output: err instanceof Error ? err.message : String(err) }\n }\n }\n\n const client: SandboxClient = {\n async create(opts?: CreateSandboxOptions): Promise<SandboxInstance> {\n // The authored profile is the sole execution authority. Refuse before creating a run id or\n // worktree: ambient executor configuration must never choose a worker's harness or model.\n const rawProfile = (opts?.backend as { profile?: unknown } | undefined)?.profile\n if (rawProfile === undefined) {\n throw new ConfigError(\n 'in-process executor: backend.profile is required and must select the exact harness, provider, and model',\n )\n }\n const profile = agentProfileSchema.parse(rawProfile) as AgentProfile\n assertExecutableAgentProfile(profile, 'in-process executor')\n const harness = profile.harness\n if (!LOCAL_HARNESSES.includes(harness as LocalHarness)) {\n throw new ConfigError(\n `in-process executor: AgentProfile.harness ${JSON.stringify(harness)} is not a local harness; expected ${LOCAL_HARNESSES.join(', ')}`,\n )\n }\n if (opts?.backend?.type !== undefined && opts.backend.type !== harness) {\n throw new ConfigError(\n `in-process executor: backend.type ${JSON.stringify(opts.backend.type)} conflicts with AgentProfile.harness ${JSON.stringify(harness)}`,\n )\n }\n const localHarness = harness as LocalHarness\n const runId = randomUUID()\n\n const virtual: VirtualSandbox = {\n id: `in-process-${runId}`,\n __inProcess: { runId, harness: localHarness },\n async *streamPrompt(\n this: VirtualSandbox,\n message: string | unknown[],\n promptOpts?: { signal?: AbortSignal },\n ): AsyncGenerator<SandboxEvent> {\n const taskPrompt =\n typeof message === 'string'\n ? message\n : message\n .map((p) =>\n typeof p === 'object' && p && 'text' in p\n ? String((p as { text: unknown }).text)\n : '',\n )\n .join('\\n')\n\n // The shared worktree-harness core: worktree → profile-aware harness → diff → checks.\n // A throw cleans up inside the core; on success we own the teardown (the finally).\n const run = await runWorktreeHarness({\n repoRoot: options.repoRoot,\n profile,\n harness: localHarness,\n taskPrompt,\n runId,\n harnessTimeoutMs: options.harnessTimeoutMs ?? DEFAULT_HARNESS_TIMEOUT_MS,\n checkTimeoutMs: options.postCheckTimeoutMs ?? DEFAULT_POSTCHECK_TIMEOUT_MS,\n ...(options.testCmd !== undefined ? { testCmd: options.testCmd } : {}),\n ...(options.typecheckCmd !== undefined ? { typecheckCmd: options.typecheckCmd } : {}),\n ...(options.runGit ? { runGit: options.runGit } : {}),\n ...(options.runHarness ? { runHarness: options.runHarness } : {}),\n runCommand,\n ...(promptOpts?.signal ? { signal: promptOpts.signal } : {}),\n })\n this.__inProcess.worktree = run.worktree\n\n try {\n yield {\n type: 'in_process.harness.started',\n data: {\n runId,\n harness: localHarness,\n worktreePath: run.worktree.path,\n command: localHarness,\n },\n }\n const h = run.result.harness\n yield {\n type: 'in_process.harness.ended',\n data: {\n runId,\n exitCode: h.exitCode,\n durationMs: h.durationMs,\n killedBySignal: h.killedBySignal,\n timedOut: h.timedOut,\n stdoutBytes: h.stdout.length,\n stderrBytes: h.stderr.length,\n },\n }\n yield {\n type: 'result',\n data: {\n result: run.result,\n source: 'in-process-executor',\n harness: localHarness,\n runId,\n },\n }\n } finally {\n await run.cleanup()\n }\n },\n } as unknown as VirtualSandbox\n\n return virtual\n },\n describePlacement(box: SandboxInstance): InProcessExecutorDescribePlacement {\n const sandboxId = (box as unknown as { id?: string }).id\n const meta = (box as VirtualSandbox).__inProcess\n return {\n kind: 'in-process',\n sandboxId,\n worktreePath: meta?.worktree?.path,\n harness: meta?.harness,\n }\n },\n }\n\n return {\n client,\n placement: 'in-process',\n describe(): string {\n return `in-process (repoRoot=${options.repoRoot}, harness=profile-selected${\n options.testCmd ? `, testCmd=\"${options.testCmd}\"` : ''\n }${options.typecheckCmd ? `, typecheckCmd=\"${options.typecheckCmd}\"` : ''})`\n },\n }\n}\n\nasync function defaultRunPostCheck(\n cmd: string,\n cwd: string,\n signal?: AbortSignal,\n): Promise<{ exitCode: number; stdout: string; stderr: string }> {\n const { spawn } = await import('node:child_process')\n return new Promise((resolve, reject) => {\n const child = spawn('sh', ['-c', cmd], { cwd, stdio: 'pipe' })\n let stdout = ''\n let stderr = ''\n child.stdout?.on('data', (c) => {\n stdout += String(c)\n })\n child.stderr?.on('data', (c) => {\n stderr += String(c)\n })\n if (signal) {\n const onAbort = () => {\n if (!child.killed) child.kill('SIGTERM')\n }\n if (signal.aborted) onAbort()\n else signal.addEventListener('abort', onAbort, { once: true })\n }\n const killTimer = setTimeout(() => {\n if (!child.killed) child.kill('SIGTERM')\n }, DEFAULT_POSTCHECK_TIMEOUT_MS)\n if (typeof (killTimer as { unref?: () => void }).unref === 'function') {\n ;(killTimer as { unref: () => void }).unref()\n }\n child.on('error', (err) => {\n clearTimeout(killTimer)\n reject(err)\n })\n child.on('close', (code) => {\n clearTimeout(killTimer)\n resolve({ exitCode: code ?? -1, stdout, stderr })\n })\n })\n}\n","/**\n *\n * Helpers extracted from `bin.ts` so the env-detection + executor-selection\n * logic is unit-testable without spawning a subprocess. The bin imports from\n * here; tests import from here directly.\n *\n * @experimental\n */\n\nimport type { SandboxClient } from '../runtime'\nimport {\n createFleetWorkspaceExecutor,\n createSiblingSandboxExecutor,\n type DelegationExecutor,\n type FleetHandle,\n} from './executor'\nimport { createInProcessExecutor } from './in-process-executor'\n\n/** @experimental */\nexport interface DetectExecutorArgs {\n sandboxClient: SandboxClient\n /** Raw env (defaults to `process.env`). Pass an explicit map for tests. */\n env?: Record<string, string | undefined>\n /**\n * Override how a fleet handle is resolved from the client + fleet id. The\n * default reads `client.fleets.get(fleetId)` and validates the returned\n * shape against the structural `FleetHandle` contract.\n */\n resolveFleet?: (client: SandboxClient, fleetId: string) => Promise<FleetHandle>\n}\n\n/**\n * Pick the right executor for an MCP server invocation based on env vars.\n *\n * - `TANGLE_FLEET_ID` set → fleet-workspace placement; resolves the handle\n * via `sandboxClient.fleets.get(...)`.\n * - Otherwise → sibling-sandbox placement; each delegation creates a fresh\n * sandbox via `sandboxClient.create(...)`.\n *\n * Fails loud (throws) when fleet mode is requested but the SDK shape is\n * incompatible — the operator chose fleet semantics, silently degrading to\n * sibling mode would lie about workspace topology.\n *\n * @experimental\n */\nexport async function detectExecutor(args: DetectExecutorArgs): Promise<DelegationExecutor> {\n const env = args.env ?? process.env\n\n // In-process (Phase 2.8): parent harness sets AGENT_RUNTIME_IN_SANDBOX=1\n // and points us at the workspace root. Highest-priority — when this is\n // set, delegations spawn local harness CLIs on git worktrees in the\n // SAME filesystem instead of provisioning sibling sandboxes.\n if (env.AGENT_RUNTIME_IN_SANDBOX === '1') {\n const repoRoot = env.AGENT_RUNTIME_REPO_ROOT?.trim()\n if (!repoRoot) {\n throw new Error(\n 'agent-runtime-mcp: AGENT_RUNTIME_IN_SANDBOX=1 requires AGENT_RUNTIME_REPO_ROOT to point at the workspace root',\n )\n }\n return createInProcessExecutor({\n repoRoot,\n testCmd: env.AGENT_RUNTIME_TEST_CMD?.trim() || undefined,\n typecheckCmd: env.AGENT_RUNTIME_TYPECHECK_CMD?.trim() || undefined,\n })\n }\n\n const fleetId = parseFleetId(env.TANGLE_FLEET_ID)\n if (!fleetId) {\n return createSiblingSandboxExecutor({ client: args.sandboxClient })\n }\n const resolveFleet = args.resolveFleet ?? defaultResolveFleet\n const fleet = await resolveFleet(args.sandboxClient, fleetId)\n const excludeMachineIds = parseList(env.TANGLE_FLEET_EXCLUDE_MACHINES)\n return createFleetWorkspaceExecutor({\n fleet,\n excludeMachineIds,\n })\n}\n\ninterface FleetsApi {\n get(fleetId: string): Promise<unknown>\n}\n\nasync function defaultResolveFleet(\n sandboxClient: SandboxClient,\n fleetId: string,\n): Promise<FleetHandle> {\n const fleets = (sandboxClient as unknown as { fleets?: FleetsApi }).fleets\n if (!fleets || typeof fleets.get !== 'function') {\n throw new Error(\n '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.',\n )\n }\n const raw = await fleets.get(fleetId)\n if (!raw || typeof raw !== 'object') {\n throw new Error(`agent-runtime-mcp: fleets.get(${fleetId}) returned no handle`)\n }\n const handle = raw as Partial<FleetHandle>\n if (typeof handle.fleetId !== 'string' || !Array.isArray(handle.ids)) {\n throw new Error(\n `agent-runtime-mcp: fleet handle for ${fleetId} is missing fleetId/ids — incompatible sandbox SDK shape`,\n )\n }\n if (typeof handle.sandbox !== 'function') {\n throw new Error(\n `agent-runtime-mcp: fleet handle for ${fleetId} is missing sandbox(machineId) — incompatible sandbox SDK shape`,\n )\n }\n return handle as FleetHandle\n}\n\nfunction parseFleetId(raw: string | undefined): string | undefined {\n if (typeof raw !== 'string') return undefined\n const trimmed = raw.trim()\n return trimmed.length > 0 ? trimmed : undefined\n}\n\nfunction parseList(raw: string | undefined): string[] | undefined {\n if (!raw) return undefined\n const list = raw\n .split(',')\n .map((entry) => entry.trim())\n .filter(Boolean)\n return list.length > 0 ? list : undefined\n}\n","/**\n *\n * Sandbox-session coder decode layer. The sandbox-session delegate (`./delegates`) and the\n * cross-restart resume driver run the in-box harness over a `SandboxClient` and need to\n * (a) build an `AgentRunSpec` from the caller-authored exact worker\n * profile, (b) decode the harness event stream into a structured `CoderOutput`, and (c) gate it with\n * the shared mechanical checks. This sandbox-session path is kept separate from the generic recursive\n * path: `worktreeFanout` instead settles the raw `WorktreePatchArtifact` and gates via\n * `patchDelivered`. Prefer `worktreeFanout` / `worktreeLoopRunner` for NEW local-repo coding.\n *\n * The decode tolerates two `result`-event shapes:\n * 1. the in-process executor's raw worktree-harness result (`{ branch, patch, stats, checks }`),\n * projected onto `CoderOutput`; and\n * 2. an LLM-emitted JSON block (`{ branch, patch, testResult, typecheckResult, diffStats }`),\n * lifted onto `data.result` or scanned out of the assistant transcript (any harness shape).\n *\n * @experimental\n */\n\nimport { type AgentProfile, agentProfileSchema } from '@tangle-network/agent-interface'\nimport type { SandboxEvent } from '@tangle-network/sandbox'\nimport { ConfigError } from '../errors'\nimport { type CoderTask, coderTaskToPrompt } from '../profiles/coder'\nimport { assertExecutableAgentProfile } from '../runtime/supervise/model-policy'\nimport { type CoderCheckConstraints, runCoderChecks } from '../runtime/supervise/patch-checks'\nimport type { AgentRunSpec, Driver, OutputAdapter, Validator } from '../runtime/types'\n\nconst DEFAULT_MAX_DIFF_LINES = 400\n\n/** @experimental The structured coder result the sandbox-session path decodes + gates. */\nexport interface CoderOutput {\n /** Branch the agent wrote the patch on. */\n branch: string\n /** Unified diff (`git diff <base>..HEAD`). */\n patch: string\n testResult: { passed: boolean; output: string }\n typecheckResult: { passed: boolean; output: string }\n diffStats: { filesChanged: number; insertions: number; deletions: number }\n /** Optional reviewer commentary surfaced by the agent. */\n reviewerNotes?: string\n}\n\n/** @experimental Inputs for one authored coder run on the sandbox-session path. */\nexport interface CoderRunSpecOptions {\n /** Caller-authored exact worker identity. It is the sole harness/provider/model authority. */\n profile: AgentProfile\n /** Stable name for `AgentRunSpec.name`. Default = `profile.name`. */\n name?: string\n}\n\n/** @experimental Build the `AgentRunSpec<CoderTask>` the sandbox-session `runAgentRounds` path drives. */\nexport function coderRunSpec(options: CoderRunSpecOptions): AgentRunSpec<CoderTask> {\n const profile = agentProfileSchema.parse(options.profile) as AgentProfile\n assertExecutableAgentProfile(profile, 'coderRunSpec')\n return {\n name: options.name ?? profile.name,\n profile,\n taskToPrompt: coderTaskToPrompt,\n }\n}\n\n/** @experimental The output adapter the sandbox-session path decodes the harness stream with. */\nexport const coderOutputAdapter: OutputAdapter<CoderOutput> = { parse: parseCoderEvents }\n\n/** @experimental */\nexport interface MultiHarnessCoderFanoutOptions {\n /** Exact worker identities, one per parallel agent. Must contain at least one profile. */\n profiles: ReadonlyArray<AgentProfile>\n}\n\n/**\n * The multi-harness coder fanout driving the sandbox-session delegate's `variants>1` path.\n * (`worktreeFanout` is the local-repo generic counterpart for new code.)\n *\n * @experimental\n */\nexport function multiHarnessCoderFanout(options: MultiHarnessCoderFanoutOptions): {\n agentRuns: AgentRunSpec<CoderTask>[]\n output: OutputAdapter<CoderOutput>\n validator: Validator<CoderOutput>\n driver: Driver<CoderTask, CoderOutput, 'pick-winner' | 'fail'>\n} {\n if (!options.profiles || options.profiles.length === 0) {\n throw new ConfigError('multiHarnessCoderFanout: at least one exact profile is required')\n }\n const agentRuns = options.profiles.map((profile) => coderRunSpec({ profile }))\n const driver: Driver<CoderTask, CoderOutput, 'pick-winner' | 'fail'> = {\n name: 'fanout',\n plan: async (task, history) => (history.length === 0 ? agentRuns.map(() => task) : []),\n decide: (history) => (history.some((i) => i.verdict?.valid === true) ? 'pick-winner' : 'fail'),\n }\n return { agentRuns, output: coderOutputAdapter, validator: defaultCoderValidator(), driver }\n}\n\n/**\n * The sandbox `CoderOutput` validator. A thin shim over the shared {@link runCoderChecks} gate,\n * adapting the parsed `CoderOutput` into the gate inputs.\n *\n * @experimental\n */\nexport function createCoderValidator(task: CoderTask): Validator<CoderOutput> {\n const constraints: CoderCheckConstraints = {\n maxDiffLines: task.maxDiffLines ?? DEFAULT_MAX_DIFF_LINES,\n forbiddenPaths: task.forbiddenPaths ?? [],\n }\n return {\n async validate(output) {\n return runCoderChecks(\n {\n patch: output.patch,\n testsPassed: output.testResult.passed,\n typecheckPassed: output.typecheckResult.passed,\n },\n constraints,\n )\n },\n }\n}\n\nfunction defaultCoderValidator(): Validator<CoderOutput> {\n return createCoderValidator({\n goal: '',\n repoRoot: '',\n forbiddenPaths: [],\n maxDiffLines: DEFAULT_MAX_DIFF_LINES,\n })\n}\n\n/**\n * Walk the event stream and return the structured coder payload.\n *\n * A `result` / `final` event lifts the structured payload onto `data.result`. That payload is\n * either the in-process executor's raw worktree-harness result (projected onto `CoderOutput`) or an\n * LLM-emitted `CoderOutput`-shaped JSON. When neither is present, the scan accumulates ALL assistant\n * text in stream order (any harness shape) and takes the last fenced JSON block that coerces —\n * claude-code lifts whole text onto `data.text`/`data.delta`; opencode streams `message.part.updated`\n * fragments, so the final block is split across many events and never whole in one.\n */\nfunction parseCoderEvents(events: SandboxEvent[]): CoderOutput {\n for (let i = events.length - 1; i >= 0; i -= 1) {\n const event = events[i]\n if (!event) continue\n const type = String(event.type ?? '')\n const data = isRecord(event.data) ? event.data : {}\n if (type === 'result' || type === 'final' || type === 'coder.result') {\n const payload = data.result ?? data.output ?? data\n const projected = projectWorktreeArtifact(payload)\n if (projected) return projected\n const direct = coerceCoderOutput(payload)\n if (direct) return direct\n }\n }\n const transcript = collectAssistantText(events)\n for (const candidate of fencedJsonBlocks(transcript)) {\n const coerced = coerceCoderOutput(candidate)\n if (coerced) return coerced\n }\n return {\n branch: '',\n patch: '',\n testResult: { passed: false, output: '' },\n typecheckResult: { passed: false, output: '' },\n diffStats: { filesChanged: 0, insertions: 0, deletions: 0 },\n }\n}\n\n/** Project the in-process executor's raw worktree-harness result (`{ branch, patch, stats, checks,\n * harness }`) onto `CoderOutput`. A check that did not run is treated as passing (the executor\n * simply didn't run that command). Returns undefined when the payload is not a worktree artifact. */\nfunction projectWorktreeArtifact(value: unknown): CoderOutput | undefined {\n if (!isRecord(value)) return undefined\n const stats = value.stats\n if (!isRecord(stats)) return undefined // not the raw artifact shape\n const branch = pickString(value.branch) ?? ''\n const patch = pickString(value.patch) ?? ''\n const checks = isRecord(value.checks) ? value.checks : {}\n const tests = isRecord(checks.tests) ? checks.tests : undefined\n const typecheck = isRecord(checks.typecheck) ? checks.typecheck : undefined\n const harness = isRecord(value.harness) ? value.harness : undefined\n const exitCode = harness ? toFiniteInt(harness.exitCode) : 0\n const timedOut = harness?.timedOut === true\n const harnessName = harness ? (pickString(harness.name) ?? 'harness') : 'harness'\n return {\n branch,\n patch,\n testResult: {\n passed: tests ? tests.passed === true : true,\n output: tail(pickString(tests?.output) ?? '', 4000),\n },\n typecheckResult: {\n passed: typecheck ? typecheck.passed === true : true,\n output: tail(pickString(typecheck?.output) ?? '', 4000),\n },\n diffStats: {\n filesChanged: toFiniteInt(stats.filesChanged),\n insertions: toFiniteInt(stats.insertions),\n deletions: toFiniteInt(stats.deletions),\n },\n ...(exitCode !== 0\n ? {\n reviewerNotes: `harness ${harnessName} exited ${exitCode}${timedOut ? ' (timed out)' : ''}`,\n }\n : {}),\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\n/** Keep the last `max` chars of a diagnostic string — harness stdout can be large; the gate reads\n * `passed`, not this text, so only the tail is retained for traces/logs. */\nfunction tail(text: string, max: number): string {\n return text.length <= max ? text : text.slice(text.length - max)\n}\n\nfunction pickString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\n/**\n * Concatenate assistant text across the event stream in arrival order, tolerating every harness\n * shape: claude-code lifts text onto `data.text`/`data.delta`; opencode streams\n * `message.part.updated` with `data.part.type === 'text'` carrying `data.delta`/`data.part.text`.\n * Reasoning/thinking parts are excluded — only the final answer text carries the result JSON.\n */\nfunction collectAssistantText(events: SandboxEvent[]): string {\n const chunks: string[] = []\n for (const event of events) {\n if (!event) continue\n const data = isRecord(event.data) ? event.data : {}\n if (String(event.type ?? '') === 'message.part.updated') {\n const part = isRecord(data.part) ? data.part : {}\n const partType = String(part.type ?? '')\n if (partType !== 'text' && partType !== '') continue\n const text = pickString(data.delta) ?? pickString(part.text)\n if (text) chunks.push(text)\n continue\n }\n const text = pickString(data.text) ?? pickString(data.delta)\n if (text) chunks.push(text)\n }\n return chunks.join('')\n}\n\n/** All parseable fenced JSON blocks in `text`, last-first (the final result block the agent emits\n * is the one we want). */\nfunction fencedJsonBlocks(text: string): unknown[] {\n const out: unknown[] = []\n const matches = [...text.matchAll(/```(?:json)?\\s*([\\s\\S]*?)```/gi)]\n for (let i = matches.length - 1; i >= 0; i -= 1) {\n const body = (matches[i]?.[1] ?? '').trim()\n if (!body) continue\n try {\n out.push(JSON.parse(body))\n } catch {\n // not JSON — keep scanning earlier blocks\n }\n }\n return out\n}\n\nfunction coerceCoderOutput(value: unknown): CoderOutput | undefined {\n if (!isRecord(value)) return undefined\n const branch = pickString(value.branch)\n const patch = pickString(value.patch) ?? ''\n if (branch === undefined) return undefined\n return {\n branch,\n patch,\n testResult: coerceCmdResult(value.testResult),\n typecheckResult: coerceCmdResult(value.typecheckResult),\n diffStats: coerceDiffStats(value.diffStats),\n reviewerNotes: pickString(value.reviewerNotes),\n }\n}\n\nfunction coerceCmdResult(value: unknown): { passed: boolean; output: string } {\n if (!isRecord(value)) return { passed: false, output: '' }\n return { passed: value.passed === true, output: pickString(value.output) ?? '' }\n}\n\nfunction coerceDiffStats(value: unknown): {\n filesChanged: number\n insertions: number\n deletions: number\n} {\n if (!isRecord(value)) return { filesChanged: 0, insertions: 0, deletions: 0 }\n return {\n filesChanged: toFiniteInt(value.filesChanged),\n insertions: toFiniteInt(value.insertions),\n deletions: toFiniteInt(value.deletions),\n }\n}\n\nfunction toFiniteInt(value: unknown): number {\n if (typeof value !== 'number') return 0\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.trunc(value))\n}\n","/**\n *\n * Detached delegation turns over the sandbox SDK's `driveTurn` primitive.\n *\n * Two halves of one story:\n *\n * - {@link runDetachedTurn} — the dispatch side. A single-session delegate\n * (single-variant coder / researcher) acquires a box, binds the sandbox id\n * into the record's `detachedSessionRef`, then advances the turn with\n * repeated `driveTurn` ticks instead of holding a live SSE stream. The\n * session id is deterministic and supplied at submit time, so a process\n * crash between ticks loses nothing — the turn keeps running in the box.\n *\n * - {@link createDetachedTurnResumeDriver} — the resume side. A\n * `DelegationResumeDriver` that re-attaches restored in-flight records to\n * their detached runs: parse the record's ref, resolve the box, advance the\n * turn one `driveTurn` pass per `tick()`, and map the SDK's three states\n * (`completed | running | failed`) onto `DelegationResumeTick`.\n *\n * Both sides type the box structurally ({@link DriveTurnCapableBox}) so tests\n * inject fakes and the module never requires the sandbox SDK at runtime — the\n * SDK stays an optional peer, exactly like the executors' `SandboxClient` seam.\n *\n * Tradeoffs of detached mode (why it is opt-in, not the default): a detached\n * turn yields one terminal payload instead of a live event stream, so kernel\n * token/cost aggregation is not produced for that turn. The trace sinks still\n * observe detached work — `runDetachedTurn` synthesizes a single-iteration\n * loop event stream (see `RunDetachedTurnOptions.traceEmitter`) so the span\n * topology joins the inherited trace context, with zero observed subtotals\n * explicitly marked incomplete under the `'detached-turn'` driver tag. Multi-variant fanout stays on the\n * streaming `runAgentRounds` path — N concurrent sessions cannot be expressed as one\n * resume key, and winner selection needs every candidate.\n *\n * @experimental\n */\n\nimport type { SandboxEvent } from '@tangle-network/sandbox'\nimport { ValidationError } from '../errors'\nimport type { AgentRunSpec, LoopTraceEmitter, LoopTraceEvent, SandboxClient } from '../runtime'\nimport { createSandboxForSpec } from '../runtime/run-loop'\nimport { deleteBoxSafe, sleep, throwAbort, throwIfAborted } from '../runtime/util'\nimport type { DelegationRecord, DelegationResumeDriver, DelegationResumeTick } from './task-queue'\nimport type { DelegationProgress, DelegationResultPayload } from './types'\n\nconst DEFAULT_TICK_INTERVAL_MS = 5000\n\n/**\n * Structural mirror of the sandbox SDK's `TurnDriveResult` (>= 0.6).\n * Discriminated on `state`; `failed` is terminal and deterministic per the\n * SDK contract — re-invoking with the same ids returns the same outcome.\n *\n * @experimental\n */\nexport type DriveTurnTick =\n | { state: 'completed'; text: string; result: Record<string, unknown> }\n | { state: 'running'; startedAt?: Date; elapsedMs?: number }\n | { state: 'failed'; error: string }\n\n/**\n * The box surface detached turns need. `SandboxInstance`\n * (`@tangle-network/sandbox` >= 0.6) satisfies it structurally; tests pass\n * in-memory fakes. `_sessionCancel` is the SDK's remote-cancellation surface —\n * optional here because older SDKs / fakes may not expose it; when present it\n * is invoked on abort so the remote run actually stops.\n *\n * @experimental\n */\nexport interface DriveTurnCapableBox {\n driveTurn(\n message: string,\n opts: { sessionId: string; turnId?: string; wallCapMs?: number },\n ): Promise<DriveTurnTick>\n _sessionCancel?(id: string): Promise<void>\n}\n\n/**\n * Decoded `DelegationRecord.detachedSessionRef`. `sandboxId` is absent between\n * submit and box acquisition — a record restored in that window is not\n * resumable (there is no box to resume on) and the resume driver fails it\n * loud rather than dispatching onto a guessed box.\n *\n * @experimental\n */\nexport interface DetachedSessionRefParts {\n sessionId: string\n sandboxId?: string\n}\n\n/**\n * Encode ref parts into the JSON-safe string stored on the record:\n * `session=<id>` before the box exists, `sandbox=<id>;session=<id>` once\n * bound. Ids must not contain the `;`/`=` delimiters.\n *\n * @experimental\n */\nexport function formatDetachedSessionRef(parts: DetachedSessionRefParts): string {\n assertRefComponent('sessionId', parts.sessionId)\n if (parts.sandboxId === undefined) return `session=${parts.sessionId}`\n assertRefComponent('sandboxId', parts.sandboxId)\n return `sandbox=${parts.sandboxId};session=${parts.sessionId}`\n}\n\n/** Parse a `detachedSessionRef` string back to parts; throws `ValidationError` on malformed input. @experimental */\nexport function parseDetachedSessionRef(raw: string): DetachedSessionRefParts {\n const fields = new Map<string, string>()\n for (const pair of raw.split(';')) {\n const eq = pair.indexOf('=')\n const key = eq === -1 ? '' : pair.slice(0, eq)\n const value = eq === -1 ? '' : pair.slice(eq + 1)\n if ((key !== 'session' && key !== 'sandbox') || value.length === 0 || fields.has(key)) {\n throw new ValidationError(\n `parseDetachedSessionRef: malformed detachedSessionRef ${JSON.stringify(raw)} — expected \"session=<id>\" or \"sandbox=<id>;session=<id>\"`,\n )\n }\n fields.set(key, value)\n }\n const sessionId = fields.get('session')\n if (!sessionId) {\n throw new ValidationError(\n `parseDetachedSessionRef: detachedSessionRef ${JSON.stringify(raw)} carries no session id`,\n )\n }\n const sandboxId = fields.get('sandbox')\n return { sessionId, ...(sandboxId !== undefined ? { sandboxId } : {}) }\n}\n\nfunction assertRefComponent(name: string, value: string): void {\n if (value.length === 0 || value.includes(';') || value.includes('=')) {\n throw new ValidationError(\n `formatDetachedSessionRef: ${name} ${JSON.stringify(value)} must be non-empty and free of \";\" / \"=\"`,\n )\n }\n}\n\n/** @experimental The terminal payload of a finished detached turn. */\nexport interface DetachedTurn {\n /** Final assistant text. */\n text: string\n /** The SDK's cached AgentExecutionResult-shape record for the turn. */\n result: Record<string, unknown>\n}\n\n/**\n * Synthesize the terminal event array a detached turn settles through. Shaped\n * so the existing event-stream output adapters (coder, researcher) parse it:\n * `data.result` for adapters that read a structured terminal record, `data.text`\n * for adapters that scan assistant text for the fenced result block.\n *\n * @experimental\n */\nexport function detachedTurnEvents(sessionId: string, turn: DetachedTurn): SandboxEvent[] {\n return [\n {\n type: 'result',\n id: sessionId,\n data: {\n text: turn.text,\n finalText: turn.text,\n success: true,\n result: turn.result,\n },\n } as SandboxEvent,\n ]\n}\n\n/** @experimental */\nexport interface RunDetachedTurnOptions {\n /** Sandbox client used to acquire the box (the delegate's executor client). */\n client: SandboxClient\n /** Profile + overrides for box acquisition — same spec the streaming path uses. */\n spec: AgentRunSpec<unknown>\n /** The full turn prompt; consumed by `driveTurn`'s dispatch leg. */\n prompt: string\n /** Deterministic resume key, minted at submit time (`parseDetachedSessionRef(ref).sessionId`). */\n sessionId: string\n /**\n * Called once the box exists, with its sandbox id. Callers persist\n * `formatDetachedSessionRef({ sandboxId, sessionId })` onto the record here so\n * a restart can resolve the box again.\n */\n bindSandbox(sandboxId: string): void\n signal: AbortSignal\n report(progress: DelegationProgress): void\n /** Delay between `running` ticks (ms). Default 5000. */\n tickIntervalMs?: number\n /** Wall-clock cap forwarded to `driveTurn` — the SDK cancels and fails a session past it. */\n wallCapMs?: number\n /**\n * Loop-trace sink. When set, the detached turn synthesizes a\n * single-iteration loop span tree (`runId` = `sessionId`, driver\n * `'detached-turn'`) so trace-context inheritance survives the detached\n * path — the same events the streaming `runAgentRounds` path would emit, minus\n * per-token telemetry: `driveTurn` yields one terminal payload, so token\n * and cost figures are structurally unavailable; zero observed subtotals are\n * marked incomplete under this driver tag.\n */\n traceEmitter?: LoopTraceEmitter\n /** Physical placement stamped on the synthesized dispatch event. Default `'sibling'`. */\n placement?: 'sibling' | 'fleet'\n}\n\n/**\n * Dispatch one detached turn and advance it to a terminal state with\n * `driveTurn` ticks. The first tick dispatches (idempotent on `sessionId`);\n * subsequent ticks poll. On abort the remote session is cancelled via\n * `_sessionCancel` when the box exposes it. The box is torn down on every\n * in-process exit path (success, failure, abort) — only a process death skips\n * teardown, which is exactly the case the resume driver re-attaches to.\n *\n * @experimental\n */\nexport async function runDetachedTurn(options: RunDetachedTurnOptions): Promise<DetachedTurn> {\n const intervalMs = options.tickIntervalMs ?? DEFAULT_TICK_INTERVAL_MS\n const trace = createDetachedTurnTrace(options)\n trace.started()\n const box = await createSandboxForSpec(options.client, options.spec, options.signal).catch(\n (err) => {\n trace.ended(err instanceof Error ? err.message : String(err))\n throw err\n },\n )\n const drive = box as Partial<DriveTurnCapableBox>\n const onAbort = () => {\n void drive._sessionCancel?.(options.sessionId).catch(() => {})\n }\n try {\n if (typeof drive.driveTurn !== 'function') {\n throw new ValidationError(\n 'runDetachedTurn: the acquired sandbox exposes no driveTurn(message, { sessionId }) — ' +\n 'detached dispatch requires @tangle-network/sandbox >= 0.6 and a session-backed ' +\n 'placement (sibling/fleet); disable detached dispatch for this executor.',\n )\n }\n const sandboxId = (box as { id?: unknown }).id\n if (typeof sandboxId !== 'string' || sandboxId.length === 0) {\n throw new ValidationError(\n 'runDetachedTurn: the acquired sandbox carries no id — without it the detached run ' +\n 'cannot be resumed after a restart, so refusing to dispatch detached.',\n )\n }\n options.bindSandbox(sandboxId)\n trace.dispatched(sandboxId)\n options.signal.addEventListener('abort', onAbort, { once: true })\n for (;;) {\n throwIfAborted(options.signal)\n const tick = await drive.driveTurn(options.prompt, {\n sessionId: options.sessionId,\n turnId: options.sessionId,\n ...(options.wallCapMs !== undefined ? { wallCapMs: options.wallCapMs } : {}),\n })\n throwIfAborted(options.signal)\n if (tick.state === 'completed') {\n trace.ended()\n return { text: tick.text, result: tick.result }\n }\n if (tick.state === 'failed') {\n throw new Error(`detached turn ${options.sessionId} failed: ${tick.error}`)\n }\n options.report({ iteration: 0, phase: detachedRunningPhase(tick.elapsedMs) })\n await sleep(intervalMs, options.signal)\n }\n } catch (err) {\n trace.ended(err instanceof Error ? err.message : String(err))\n throw err\n } finally {\n options.signal.removeEventListener('abort', onAbort)\n if (options.signal.aborted) onAbort()\n await deleteBoxSafe(box)\n }\n}\n\n/**\n * Synthesize the single-iteration loop event stream for one detached turn so\n * the trace sinks (OTEL exporter, delegation journal) observe detached work\n * exactly like a streamed `runAgentRounds` run. `runId` = the deterministic session\n * id; cost/token figures are structurally unavailable on the `driveTurn`\n * surface, so zero observed subtotals carry explicit unknown flags.\n */\nfunction createDetachedTurnTrace(options: RunDetachedTurnOptions): {\n started(): void\n dispatched(sandboxId: string): void\n ended(error?: string): void\n} {\n const emitter = options.traceEmitter\n if (!emitter) {\n return { started() {}, dispatched() {}, ended() {} }\n }\n const runId = options.sessionId\n const agentRunName = options.spec.name ?? options.spec.profile.name ?? 'detached-turn'\n const startMs = Date.now()\n let done = false\n const emit = (event: LoopTraceEvent): void => {\n void emitter.emit(event)\n }\n return {\n started(): void {\n emit({\n kind: 'loop.started',\n runId,\n timestamp: startMs,\n payload: {\n driver: 'detached-turn',\n agentRunNames: [agentRunName],\n maxIterations: 1,\n maxConcurrency: 1,\n },\n })\n emit({\n kind: 'loop.iteration.started',\n runId,\n timestamp: startMs,\n payload: { iterationIndex: 0, agentRunName, taskHash: options.sessionId },\n })\n },\n dispatched(sandboxId: string): void {\n emit({\n kind: 'loop.iteration.dispatch',\n runId,\n timestamp: Date.now(),\n payload: {\n iterationIndex: 0,\n agentRunName,\n placement: options.placement ?? 'sibling',\n sandboxId,\n },\n })\n },\n ended(error?: string): void {\n if (done) return\n done = true\n const endMs = Date.now()\n emit({\n kind: 'loop.iteration.ended',\n runId,\n timestamp: endMs,\n payload: {\n iterationIndex: 0,\n agentRunName,\n costUsd: 0,\n costUsdKnown: false,\n durationMs: endMs - startMs,\n tokenUsage: { input: 0, output: 0, tokensKnown: false },\n ...(error !== undefined ? { error } : {}),\n },\n })\n emit({\n kind: 'loop.ended',\n runId,\n timestamp: endMs,\n payload: {\n ...(error === undefined ? { winnerIterationIndex: 0 } : {}),\n totalCostUsd: 0,\n costUsdKnown: false,\n durationMs: endMs - startMs,\n iterations: 1,\n },\n })\n },\n }\n}\n\nfunction detachedRunningPhase(elapsedMs: number | undefined): string {\n return elapsedMs === undefined\n ? 'detached-running'\n : `detached-running ${Math.round(elapsedMs / 1000)}s`\n}\n\n/** @experimental */\nexport interface DetachedTurnResumeDriverOptions {\n /**\n * Resolve the live box owning a detached session. The bin wires this to the\n * sandbox client's `get(sandboxId)`; throw when the box no longer exists —\n * a thrown tick settles the record as failed, which is the truth.\n */\n resolveSandbox(sandboxId: string): Promise<DriveTurnCapableBox>\n /**\n * Rebuild the turn prompt from the persisted record. Only consumed by\n * `driveTurn`'s dispatch leg — i.e. when the previous process died after\n * binding the box but before the session was dispatched. Must reproduce the\n * prompt the delegate would have sent.\n */\n buildMessage(record: DelegationRecord): string\n /**\n * Map a completed turn onto the delegation's typed output payload (parse +\n * validate per profile). Throw when the resumed result does not pass the\n * profile's gate — the queue settles the record as failed with that error.\n */\n settleOutput(\n turn: DetachedTurn,\n record: DelegationRecord,\n ctx: { signal: AbortSignal },\n ): Promise<DelegationResultPayload['output']> | DelegationResultPayload['output']\n /** Delay between `running` ticks (ms). Default 5000. */\n intervalMs?: number\n /** Wall-clock cap forwarded to `driveTurn` on every tick. */\n wallCapMs?: number\n}\n\n/**\n * Build the `driveTurn`-backed {@link DelegationResumeDriver}. Each `tick()`\n * is one settle/poll/dispatch pass:\n *\n * - ref without a sandbox binding → `failed` (`DetachedSessionUnboundError`):\n * the previous process died before a box existed; there is nothing to resume.\n * - `driveTurn` `completed` → `settleOutput` → `completed` tick.\n * - `running` → progress via `ctx.report`, `running` tick (queue re-ticks\n * after `intervalMs`).\n * - `failed` → `failed` tick (`DetachedTurnFailedError`) — terminal per the\n * SDK's deterministic-failure contract.\n *\n * Abort: the queue stops ticking once `cancel()` flips the record, so remote\n * cancellation is hooked onto `ctx.signal` (once per task) and fires\n * `_sessionCancel` when the SDK surface exposes it. The driver never deletes\n * boxes — it cannot know whether `sandboxId` is a disposable sibling or a\n * fleet machine, and destroying a fleet machine would be unrecoverable.\n *\n * @experimental\n */\nexport function createDetachedTurnResumeDriver(\n options: DetachedTurnResumeDriverOptions,\n): DelegationResumeDriver {\n const cancelHooked = new Set<string>()\n return {\n intervalMs: options.intervalMs ?? DEFAULT_TICK_INTERVAL_MS,\n async tick({ record, detachedSessionRef }, ctx): Promise<DelegationResumeTick> {\n const ref = parseDetachedSessionRef(detachedSessionRef)\n if (ref.sandboxId === undefined) {\n return {\n state: 'failed',\n error: {\n message:\n `detached session \"${ref.sessionId}\" was never bound to a sandbox — the previous ` +\n 'process died before the box was acquired, so the turn was never dispatched and ' +\n 'cannot be resumed',\n kind: 'DetachedSessionUnboundError',\n },\n }\n }\n const box = await options.resolveSandbox(ref.sandboxId)\n if (!cancelHooked.has(record.taskId)) {\n cancelHooked.add(record.taskId)\n ctx.signal.addEventListener(\n 'abort',\n () => {\n void box._sessionCancel?.(ref.sessionId).catch(() => {})\n },\n { once: true },\n )\n }\n if (ctx.signal.aborted) throwAbort()\n const tick = await box.driveTurn(options.buildMessage(record), {\n sessionId: ref.sessionId,\n turnId: ref.sessionId,\n ...(options.wallCapMs !== undefined ? { wallCapMs: options.wallCapMs } : {}),\n })\n if (tick.state === 'completed') {\n const output = await options.settleOutput(\n { text: tick.text, result: tick.result },\n record,\n {\n signal: ctx.signal,\n },\n )\n return { state: 'completed', output }\n }\n if (tick.state === 'failed') {\n return {\n state: 'failed',\n error: {\n message: `detached turn ${ref.sessionId} failed: ${tick.error}`,\n kind: 'DetachedTurnFailedError',\n },\n }\n }\n ctx.report({ iteration: 0, phase: detachedRunningPhase(tick.elapsedMs) })\n return { state: 'running' }\n },\n }\n}\n","/**\n *\n * `detachedSessionDelegate` — the sandbox-session coder delegate: a closure that drives `runAgentRounds`\n * against a `SandboxClient` + a caller-supplied exact worker profile, to a\n * mechanically-validated `CoderOutput`. The caller invokes the returned delegate directly with its\n * coder args; when wired into a durable queue it also settles cross-restart-resumed records.\n *\n * Delegation vs COORDINATION (`../runtime/supervise/coordination-mcp.ts`): this delegate runs a\n * coding task INSIDE the agent's OWN sandbox environment — a sibling box on its own `SandboxClient`,\n * fresh branch on its repo. It is NOT backend-pluggable. To instead SPAWN + live-drive workers in a\n * CHOSEN backend (sandbox OR cli-bridge, via `createExecutor({ backend })`) with observe/steer/resume\n * + recursion, use `delegate()` / the coordination MCP.\n *\n * The worker profile is a parameter the caller supplies (§1.5: the system authors profiles).\n * For NEW local-repo coding use `worktreeFanout` / `worktreeLoopRunner`\n * (author one `AgentProfile` per harness → `createWorktreeCliExecutor` leaves → `gateOnDeliverable`).\n *\n * @experimental\n */\n\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport { ConfigError } from '../errors'\nimport type { CoderTask } from '../profiles/coder'\nimport type {\n AgentRunSpec,\n Iteration,\n LoopTraceEmitter,\n Outcome,\n SandboxClient,\n WinnerStrategy,\n} from '../runtime'\nimport { runAgentRounds, selectValidWinner } from '../runtime'\nimport { composeLoopTraceEmitters } from './delegation-trace'\nimport {\n type CoderOutput,\n coderOutputAdapter,\n coderRunSpec,\n createCoderValidator,\n multiHarnessCoderFanout,\n} from './detached-coder'\nimport {\n type DetachedTurn,\n detachedTurnEvents,\n formatDetachedSessionRef,\n parseDetachedSessionRef,\n runDetachedTurn,\n} from './detached-turn'\nimport { createSiblingSandboxExecutor, type DelegationExecutor } from './executor'\nimport type {\n DelegateCodeArgs,\n DelegateUiAuditArgs,\n DelegationProgress,\n UiAuditorDelegationOutput,\n} from './types'\n\n/** @experimental */\nexport interface DelegateRunCtx {\n signal: AbortSignal\n report(progress: DelegationProgress): void\n /**\n * Detached-run resume key recorded on the queue record at submit time\n * (`formatDetachedSessionRef`). Present only when the submit path requested\n * detached dispatch — its presence is what routes a session-backed delegate\n * onto the `driveTurn` tick path instead of holding a stream.\n */\n detachedSessionRef?: string\n /** Rebind the record's resume key (e.g. once the sandbox id is known). */\n updateDetachedSessionRef?(ref: string): void\n /**\n * Per-delegation trace sink supplied by the queue — loop events emitted\n * here land on the delegation record as a compact span tree. Delegates\n * compose it with their configured OTEL emitter so both sinks observe\n * the same stream.\n */\n traceEmitter?: LoopTraceEmitter\n}\n\n/** @experimental The coder delegate closure — given the coder args + run context, drives the\n * sandbox-session coder path to a validated `CoderOutput`. `detachedSessionDelegate` is the\n * built-in implementation; the queue invokes one of these per coder delegation. */\nexport type CoderDelegate = (args: DelegateCodeArgs, ctx: DelegateRunCtx) => Promise<CoderOutput>\n\n/**\n * UI-auditor delegate — fully consumer-injected. agent-runtime ships no\n * default factory because execution belongs to a caller-supplied exact\n * agent profile and Runtime executor.\n *\n * @experimental\n */\nexport type UiAuditorDelegate = (\n args: DelegateUiAuditArgs,\n ctx: DelegateRunCtx,\n) => Promise<UiAuditorDelegationOutput>\n\n/** @experimental Structured review verdict over a coder candidate. */\nexport interface CoderReview {\n /** Gate: only approved candidates are eligible to win. */\n approved: boolean\n /** Readiness 0..1, used by the `highest-readiness` winner-selection strategy. */\n readiness: number\n /** The reviewer's own words. Selection reads `approved` and `readiness`; anything a reviewer\n * wants a caller to READ belongs here, because nothing else on this type is surfaced. */\n notes?: string\n}\n\n/**\n *\n * Optional adversarial reviewer over a coder candidate that already passed\n * mechanical validation (tests/typecheck/forbidden/diff/no-op/secrets). Folded\n * from the ai-trading-blueprint delegation MCP: a candidate is only eligible to\n * win if the reviewer approves it. The reviewer is the consumer's seam — an LLM\n * judge, a `pnpm review` command, anything returning a `CoderReview`.\n *\n * @experimental\n */\nexport type CoderReviewer = (\n output: CoderOutput,\n task: CoderTask,\n ctx: { signal: AbortSignal },\n) => Promise<CoderReview> | CoderReview\n\n/**\n * @experimental Winner-selection strategy among validated (+ reviewed) candidates on the\n * sandbox-session path. The base strategies (`highest-score` / `smallest-diff` /\n * `first-approved`) delegate to the shared `selectValidWinner`; `highest-readiness` is the\n * reviewer-only strategy this path keeps that the generic selector does not express. Default\n * `highest-score`.\n */\nexport type DetachedWinnerSelection =\n | 'highest-score'\n | 'smallest-diff'\n | 'highest-readiness'\n | 'first-approved'\n\n/** @experimental */\nexport interface DetachedSessionDelegateOptions {\n /**\n * Execution placement. Pass a {@link DelegationExecutor} (sibling or fleet)\n * to control where worker iterations land. `sandboxClient` is a\n * convenience shorthand that wraps the client in a sibling executor — pass\n * one or the other, not both.\n */\n executor?: DelegationExecutor\n /**\n * Convenience shorthand for sibling placement. Equivalent to\n * `executor: createSiblingSandboxExecutor({ client: sandboxClient })`.\n */\n sandboxClient?: SandboxClient\n /**\n * The worker's exact authored `AgentProfile` (§1.5: the system authors profiles). It is the sole\n * harness/provider/model/prompt authority for the single-coder path and the default identity for\n * repeated fanout shots.\n */\n workerProfile: AgentProfile\n /** Optional exact identities for heterogeneous fanout. Omit to repeat `workerProfile`. */\n fanoutProfiles?: ReadonlyArray<AgentProfile>\n /** Hard cap on the kernel's per-batch concurrency. Default 4. */\n maxConcurrency?: number\n /**\n * Optional adversarial reviewer. When set, a candidate must pass mechanical\n * validation AND `reviewer.approved` to be eligible to win — empty/secret/\n * test-failing patches are already gone; this catches the \"compiles + passes\n * but wrong/unsafe\" class the deterministic validator can't see.\n */\n reviewer?: CoderReviewer\n /** Winner-selection strategy among eligible candidates. Default `highest-score`. */\n winnerSelection?: DetachedWinnerSelection\n /**\n * Loop trace emitter forwarded into every delegated `runAgentRounds`. Wire\n * `createPropagatingTraceEmitter(readTraceContextFromEnv())` here (the bin\n * does) so delegated build-loops export their topology spans to the OTLP /\n * Tangle Intelligence sink when `OTEL_EXPORTER_OTLP_ENDPOINT` is set — and\n * are a cheap no-op when it isn't. Configurable by construction.\n *\n * Detached single-variant turns (taken when `ctx.detachedSessionRef` is set)\n * bypass `runAgentRounds`; `runDetachedTurn` synthesizes a single-iteration loop\n * event stream for them so this emitter observes detached work too.\n */\n traceEmitter?: LoopTraceEmitter\n /** Tick cadence (ms) for the detached single-variant path. Default 5000. */\n detachedTickIntervalMs?: number\n /** Wall-clock cap (ms) forwarded to `driveTurn` for detached turns. */\n detachedWallCapMs?: number\n}\n\n/**\n * Build the sandbox-session coder delegate. It drives `runAgentRounds` against the project's\n * sandbox client + coder profile; when `args.variants > 1` it switches to the multi-harness fanout\n * topology.\n *\n * This is the SANDBOX-SESSION coder path: workers run the in-box harness via the\n * `SandboxClient`'s `streamPrompt`, and single-variant turns can dispatch DETACHED\n * (driveTurn ticks) so a durable queue resumes them across an MCP restart — a substrate\n * the recursive worktree-CLI leaf does not yet have a journal-replay equivalent for.\n *\n * For NEW local-repo coding use `worktreeFanout` / `worktreeLoopRunner` (author an `AgentProfile`\n * per harness → `createWorktreeCliExecutor` leaves → `gateOnDeliverable`). This delegate runs\n * held-stream by default and only its OPTIONAL cross-restart resume (the `driveTurn` tick) is opt-in\n * behind `MCP_ENABLE_DETACHED_RESUME`.\n *\n * @experimental\n */\nexport function detachedSessionDelegate(options: DetachedSessionDelegateOptions): CoderDelegate {\n if (!options.workerProfile) {\n throw new ConfigError('detachedSessionDelegate: workerProfile is required')\n }\n const workerProfile = coderRunSpec({ profile: options.workerProfile }).profile\n const fanoutProfiles = options.fanoutProfiles?.map((profile) => coderRunSpec({ profile }).profile)\n if (fanoutProfiles?.length === 0) {\n throw new ConfigError('detachedSessionDelegate: fanoutProfiles must not be empty')\n }\n const executor = resolveExecutor(options)\n const sandboxClient = executor.client\n const maxConcurrency = options.maxConcurrency ?? 4\n const traceEmitter = options.traceEmitter\n return async (args, ctx) => {\n const task = coderTaskFromArgs(args)\n const variants = Math.max(1, Math.trunc(args.variants ?? 1))\n const selectedFanoutProfiles =\n variants <= 1\n ? undefined\n : (fanoutProfiles ?? Array.from({ length: variants }, () => workerProfile))\n if (selectedFanoutProfiles && selectedFanoutProfiles.length < variants) {\n throw new ConfigError(\n `detachedSessionDelegate: ${variants} variants requested but only ${selectedFanoutProfiles.length} exact fanout profiles were configured`,\n )\n }\n const loopEmitter = composeLoopTraceEmitters(traceEmitter, ctx.traceEmitter)\n ctx.report({ iteration: 0, phase: 'starting' })\n if (variants <= 1) {\n const agentRunSpec = coderRunSpec({ profile: workerProfile })\n const output = coderOutputAdapter\n const validator = createCoderValidator(task)\n // Detached dispatch: one session on one box, driven by `driveTurn` ticks\n // instead of a held stream, so the run survives an MCP-process restart\n // (the resume driver re-attaches via the persisted ref). Only the\n // single-variant path detaches — fanout needs N sessions + winner\n // selection over every candidate, which one resume key cannot express.\n if (ctx.detachedSessionRef !== undefined && ctx.updateDetachedSessionRef) {\n const { sessionId } = parseDetachedSessionRef(ctx.detachedSessionRef)\n const rebind = ctx.updateDetachedSessionRef\n const turn = await runDetachedTurn({\n client: sandboxClient,\n spec: agentRunSpec as AgentRunSpec<unknown>,\n prompt: agentRunSpec.taskToPrompt(task),\n sessionId,\n bindSandbox: (sandboxId) => rebind(formatDetachedSessionRef({ sandboxId, sessionId })),\n signal: ctx.signal,\n report: ctx.report,\n ...(loopEmitter ? { traceEmitter: loopEmitter } : {}),\n ...(executor.placement === 'fleet' ? { placement: 'fleet' as const } : {}),\n ...(options.detachedTickIntervalMs !== undefined\n ? { tickIntervalMs: options.detachedTickIntervalMs }\n : {}),\n ...(options.detachedWallCapMs !== undefined\n ? { wallCapMs: options.detachedWallCapMs }\n : {}),\n })\n const chosen = await settleDetachedCoderTurn(turn, {\n task,\n sessionId,\n signal: ctx.signal,\n ...(options.reviewer ? { reviewer: options.reviewer } : {}),\n })\n ctx.report({ iteration: 1, phase: 'completed' })\n return chosen\n }\n const result = await runAgentRounds({\n driver: singleShotDriver,\n agentRun: agentRunSpec,\n output,\n validator,\n task,\n ctx: {\n sandboxClient,\n signal: ctx.signal,\n ...(loopEmitter ? { traceEmitter: loopEmitter } : {}),\n },\n maxIterations: 1,\n maxConcurrency,\n })\n const chosen = await pickCoderWinner({\n iterations: result.iterations,\n reviewer: options.reviewer,\n selection: options.winnerSelection ?? 'highest-score',\n task,\n signal: ctx.signal,\n })\n if (!chosen) throw new Error(noWinnerMessage(options.reviewer))\n ctx.report({ iteration: 1, phase: 'completed' })\n return chosen\n }\n const fanout = multiHarnessCoderFanout({\n profiles: selectedFanoutProfiles!.slice(0, variants),\n })\n const agentRuns = fanout.agentRuns.slice(0, variants)\n const result = await runAgentRounds({\n driver: fanout.driver,\n agentRuns,\n output: fanout.output,\n validator: fanout.validator,\n task,\n ctx: {\n sandboxClient,\n signal: ctx.signal,\n ...(loopEmitter ? { traceEmitter: loopEmitter } : {}),\n },\n maxIterations: variants,\n maxConcurrency: Math.min(maxConcurrency, variants),\n })\n const chosen = await pickCoderWinner({\n iterations: result.iterations,\n reviewer: options.reviewer,\n selection: options.winnerSelection ?? 'highest-score',\n task,\n signal: ctx.signal,\n })\n if (!chosen) throw new Error(noWinnerMessage(options.reviewer))\n ctx.report({ iteration: agentRuns.length, phase: 'completed' })\n return chosen\n }\n}\n\ninterface PickCoderWinnerArgs {\n iterations: ReadonlyArray<Iteration<CoderTask, CoderOutput>>\n reviewer: CoderReviewer | undefined\n selection: DetachedWinnerSelection\n task: CoderTask\n signal: AbortSignal\n}\n\n/** A valid (and, when a reviewer is wired, approved) candidate kept for selection. */\ninterface EligibleCandidate {\n iter: Iteration<CoderTask, CoderOutput>\n /** Reviewer readiness (defaults to the verdict score when no reviewer ran). */\n readiness: number\n}\n\n/**\n * Pick the winning coder candidate from a finished loop's iterations:\n * 1. keep only mechanically-VALID candidates (the validator already gated\n * tests/typecheck/forbidden/diff/no-op/secrets),\n * 2. if a `reviewer` is wired, keep only those it APPROVES,\n * 3. select among survivors via the shared `selectValidWinner` (base strategies) or, for the\n * reviewer-only `highest-readiness`, a readiness sort (the one strategy the generic selector\n * does not express — a documented capability of this sandbox-session path).\n * Returns `undefined` when nothing survives — the delegate fails loud.\n */\nasync function pickCoderWinner(args: PickCoderWinnerArgs): Promise<CoderOutput | undefined> {\n const eligible: EligibleCandidate[] = []\n for (const iter of args.iterations) {\n if (iter.output === undefined || iter.error || iter.verdict?.valid !== true) continue\n const readiness = iter.verdict.score ?? 0\n if (args.reviewer) {\n const review = await args.reviewer(iter.output, args.task, { signal: args.signal })\n if (!review.approved) continue\n eligible.push({ iter, readiness: review.readiness })\n } else {\n eligible.push({ iter, readiness })\n }\n }\n if (eligible.length === 0) return undefined\n\n // `highest-readiness` ranks on the reviewer's readiness — a reviewer-only metric the generic\n // valid-only selector does not carry. Ties → earliest iteration.\n if (args.selection === 'highest-readiness') {\n const sorted = [...eligible].sort(\n (a, b) => b.readiness - a.readiness || a.iter.index - b.iter.index,\n )\n return sorted[0]!.iter.output\n }\n\n // Base strategies route through the SHARED valid-only selector. Wrap each survivor's raw\n // `CoderOutput` in the `Outcome<D>` shape `selectValidWinner` reads, preserving verdict/index.\n const wrapped: Iteration<unknown, Outcome<CoderOutput>>[] = eligible.map(({ iter }) => ({\n ...iter,\n output: { kind: 'done', deliverable: iter.output as CoderOutput },\n }))\n const winner = selectValidWinner<CoderOutput>({\n strategy: baseStrategy(args.selection),\n sizeOf: (o) => o.diffStats.insertions + o.diffStats.deletions,\n })(wrapped)\n const out = winner?.output\n if (out?.kind !== 'done') return undefined\n return out.deliverable\n}\n\n/** Map the detached-session selection enum onto the shared `WinnerStrategy`. `first-approved`\n * reduces to `first-valid` over the already-approved set; `smallest-diff` to `smallest-artifact`. */\nfunction baseStrategy(\n selection: Exclude<DetachedWinnerSelection, 'highest-readiness'>,\n): WinnerStrategy {\n switch (selection) {\n case 'smallest-diff':\n return 'smallest-artifact'\n case 'first-approved':\n return 'first-valid'\n default:\n return 'highest-score'\n }\n}\n\nfunction noWinnerMessage(reviewer: CoderReviewer | undefined): string {\n return reviewer\n ? 'coder delegate: no candidate passed validation + review'\n : 'coder delegate: no candidate passed validation'\n}\n\n/**\n * Canonical `DelegateCodeArgs` → `CoderTask` mapping — the single source for\n * the delegate's live dispatch AND the resume driver's settle/message\n * rebuilding, so a resumed record reproduces exactly the task the original\n * process dispatched.\n *\n * @experimental\n */\nexport function coderTaskFromArgs(args: DelegateCodeArgs): CoderTask {\n return {\n goal: buildCoderGoal(args),\n repoRoot: args.repoRoot,\n testCmd: args.config?.testCmd,\n typecheckCmd: args.config?.typecheckCmd,\n forbiddenPaths: args.config?.forbiddenPaths,\n maxDiffLines: args.config?.maxDiffLines,\n }\n}\n\n/** @experimental */\nexport interface SettleDetachedCoderTurnOptions {\n task: CoderTask\n /** Session id of the detached turn — used as the synthesized event id. */\n sessionId: string\n signal: AbortSignal\n /** Same gate as the streaming path: an unapproved candidate cannot win. */\n reviewer?: CoderReviewer\n}\n\n/**\n * Settle a completed detached coder turn through the same gate the streaming\n * path applies: parse the terminal payload with the coder output adapter,\n * run the mechanical validator (tests/typecheck/forbidden/diff/no-op/secrets),\n * then the optional reviewer. Throws when nothing survives — a resumed or\n * detached run must not return an unvalidated patch.\n *\n * SCOPE NOTE (detached/resume): the detached `driveTurn`-tick + cross-restart resume path is\n * bound to the `runAgentRounds` + sandbox-session substrate. The recursive `Scope`/worktree-CLI leaf has\n * journal→replay but no driveTurn-over-a-detached-sandbox-session equivalent yet, so resume is NOT\n * advertised on the generic `worktreeFanout` path. This helper (with `coderTaskFromArgs` and\n * `createDetachedTurnResumeDriver`) stays as the resume seam `bin.ts` wires for in-flight records.\n *\n * @experimental\n */\nexport async function settleDetachedCoderTurn(\n turn: DetachedTurn,\n options: SettleDetachedCoderTurnOptions,\n): Promise<CoderOutput> {\n const parsed = coderOutputAdapter.parse(detachedTurnEvents(options.sessionId, turn))\n const validator = createCoderValidator(options.task)\n const verdict = await validator.validate(parsed, { iteration: 0, signal: options.signal })\n if (verdict.valid !== true) throw new Error(noWinnerMessage(options.reviewer))\n if (options.reviewer) {\n const review = await options.reviewer(parsed, options.task, { signal: options.signal })\n if (!review.approved) throw new Error(noWinnerMessage(options.reviewer))\n }\n return parsed\n}\n\nfunction buildCoderGoal(args: DelegateCodeArgs): string {\n if (!args.contextHint) return args.goal\n return [args.goal, '', '## Context', args.contextHint].join('\\n')\n}\n\nfunction resolveExecutor(options: DetachedSessionDelegateOptions): DelegationExecutor {\n if (options.executor && options.sandboxClient) {\n throw new Error('detachedSessionDelegate: pass exactly one of `executor` or `sandboxClient`')\n }\n if (options.executor) return options.executor\n if (options.sandboxClient) {\n return createSiblingSandboxExecutor({ client: options.sandboxClient })\n }\n throw new Error('detachedSessionDelegate: `executor` or `sandboxClient` is required')\n}\n\n/**\n * Single-shot driver — plan one task on iteration 0, stop after one\n * iteration. Used by the coder delegate when `variants <= 1`. Keeps the\n * runAgentRounds kernel-level accounting (timing, cost, trace emission) while\n * skipping fanout/refine topology overhead.\n */\nconst singleShotDriver = {\n name: 'mcp-single-shot',\n async plan<Task>(task: Task, history: ReadonlyArray<unknown>): Promise<Task[]> {\n return history.length === 0 ? [task] : []\n },\n decide(history: ReadonlyArray<unknown>): 'pick-winner' | 'fail' {\n return history.length > 0 ? 'pick-winner' : 'fail'\n },\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { A as DELEGATION_HISTORY_INPUT_SCHEMA, B as DELEGATE_FEEDBACK_DESCRIPTION, E as DELEGATION_STATUS_TOOL_NAME, H as DELEGATE_FEEDBACK_TOOL_NAME, T as DELEGATION_STATUS_INPUT_SCHEMA, V as DELEGATE_FEEDBACK_INPUT_SCHEMA, j as DELEGATION_HISTORY_TOOL_NAME, k as DELEGATION_HISTORY_DESCRIPTION, w as DELEGATION_STATUS_DESCRIPTION } from "./supervise-BVE0XAJa.js";
1
+ import { A as DELEGATION_HISTORY_INPUT_SCHEMA, B as DELEGATE_FEEDBACK_DESCRIPTION, E as DELEGATION_STATUS_TOOL_NAME, H as DELEGATE_FEEDBACK_TOOL_NAME, T as DELEGATION_STATUS_INPUT_SCHEMA, V as DELEGATE_FEEDBACK_INPUT_SCHEMA, j as DELEGATION_HISTORY_TOOL_NAME, k as DELEGATION_HISTORY_DESCRIPTION, w as DELEGATION_STATUS_DESCRIPTION } from "./supervise-CqwjiXlX.js";
2
2
  //#region src/mcp/openai-tools.ts
3
3
  function buildTool(name, description, parameters) {
4
4
  return {
@@ -41,4 +41,4 @@ function mcpToolsForRuntimeMcpSubset(names) {
41
41
  //#endregion
42
42
  export { mcpToolsForRuntimeMcpSubset as n, mcpToolsForRuntimeMcp as t };
43
43
 
44
- //# sourceMappingURL=openai-tools-CkSQJppW.js.map
44
+ //# sourceMappingURL=openai-tools-D1VQ5e9p.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"openai-tools-CkSQJppW.js","names":[],"sources":["../src/mcp/openai-tools.ts"],"sourcesContent":["/**\n *\n * OpenAI Chat Completions `tools[]` projection of the queue-bound agent-runtime\n * MCP delegation tools.\n *\n * Use when a caller-owned OpenAI-compatible transport needs the model to call\n * `delegate_feedback`, `delegation_status`, and `delegation_history`. Execution\n * is the caller's responsibility (typically the parent sandbox runtime's MCP\n * mount); Runtime's profile-bound model path materializes profile tools through\n * its executor instead.\n *\n * Sandbox-SDK callers do NOT need this helper: the sandbox runtime mounts\n * MCP servers natively and the in-sandbox harness discovers tools via the\n * runtime, not via an OpenAI tools array.\n *\n * Tool name + description + JSON-schema are pulled from the canonical\n * `DELEGATE_*` constants exported by `./tools/*` so the projection cannot\n * drift from the server's own validators.\n *\n * @experimental\n */\n\nimport type { OpenAIChatTool } from '../types'\nimport {\n DELEGATE_FEEDBACK_DESCRIPTION,\n DELEGATE_FEEDBACK_INPUT_SCHEMA,\n DELEGATE_FEEDBACK_TOOL_NAME,\n} from './tools/delegate-feedback'\nimport {\n DELEGATION_HISTORY_DESCRIPTION,\n DELEGATION_HISTORY_INPUT_SCHEMA,\n DELEGATION_HISTORY_TOOL_NAME,\n} from './tools/delegation-history'\nimport {\n DELEGATION_STATUS_DESCRIPTION,\n DELEGATION_STATUS_INPUT_SCHEMA,\n DELEGATION_STATUS_TOOL_NAME,\n} from './tools/delegation-status'\n\nfunction buildTool(\n name: string,\n description: string,\n parameters: Readonly<Record<string, unknown>>,\n): OpenAIChatTool {\n // `parameters` arrives as a deeply-readonly `as const` literal. The\n // OpenAI-compatible transports JSON-serialize the body, so a shallow copy\n // into a plain object is sufficient and shields callers that mutate\n // the returned descriptor from corrupting the source constant.\n return {\n type: 'function',\n function: { name, description, parameters: { ...parameters } },\n }\n}\n\n/**\n *\n * Returns the queue-bound delegation tools projected into OpenAI Chat\n * Completions `tools[]` shape. The order is stable: `delegate_feedback`,\n * `delegation_status`, `delegation_history`.\n *\n * @experimental\n */\nexport function mcpToolsForRuntimeMcp(): OpenAIChatTool[] {\n return [\n buildTool(\n DELEGATE_FEEDBACK_TOOL_NAME,\n DELEGATE_FEEDBACK_DESCRIPTION,\n DELEGATE_FEEDBACK_INPUT_SCHEMA as Readonly<Record<string, unknown>>,\n ),\n buildTool(\n DELEGATION_STATUS_TOOL_NAME,\n DELEGATION_STATUS_DESCRIPTION,\n DELEGATION_STATUS_INPUT_SCHEMA as Readonly<Record<string, unknown>>,\n ),\n buildTool(\n DELEGATION_HISTORY_TOOL_NAME,\n DELEGATION_HISTORY_DESCRIPTION,\n DELEGATION_HISTORY_INPUT_SCHEMA as Readonly<Record<string, unknown>>,\n ),\n ]\n}\n\n/**\n *\n * Subset filter — return only the projected tools whose `function.name`\n * appears in `names`. Useful for curated mounts (e.g. only the queue-bound\n * delegation tools, omitting `delegate_feedback`). Unknown names are\n * silently ignored; pass an empty array to get an empty result.\n *\n * @experimental\n */\nexport function mcpToolsForRuntimeMcpSubset(names: ReadonlyArray<string>): OpenAIChatTool[] {\n const allowed = new Set(names)\n return mcpToolsForRuntimeMcp().filter((tool) => allowed.has(tool.function.name))\n}\n"],"mappings":";;AAuCA,SAAS,UACP,MACA,aACA,YACgB;CAKhB,OAAO;EACL,MAAM;EACN,UAAU;GAAE;GAAM;GAAa,YAAY,EAAE,GAAG,WAAW;EAAE;CAC/D;AACF;;;;;;;;;AAUA,SAAgB,wBAA0C;CACxD,OAAO;EACL,UACE,6BACA,+BACA,8BACF;EACA,UACE,6BACA,+BACA,8BACF;EACA,UACE,8BACA,gCACA,+BACF;CACF;AACF;;;;;;;;;;AAWA,SAAgB,4BAA4B,OAAgD;CAC1F,MAAM,UAAU,IAAI,IAAI,KAAK;CAC7B,OAAO,sBAAsB,CAAC,CAAC,QAAQ,SAAS,QAAQ,IAAI,KAAK,SAAS,IAAI,CAAC;AACjF"}
1
+ {"version":3,"file":"openai-tools-D1VQ5e9p.js","names":[],"sources":["../src/mcp/openai-tools.ts"],"sourcesContent":["/**\n *\n * OpenAI Chat Completions `tools[]` projection of the queue-bound agent-runtime\n * MCP delegation tools.\n *\n * Use when a caller-owned OpenAI-compatible transport needs the model to call\n * `delegate_feedback`, `delegation_status`, and `delegation_history`. Execution\n * is the caller's responsibility (typically the parent sandbox runtime's MCP\n * mount); Runtime's profile-bound model path materializes profile tools through\n * its executor instead.\n *\n * Sandbox-SDK callers do NOT need this helper: the sandbox runtime mounts\n * MCP servers natively and the in-sandbox harness discovers tools via the\n * runtime, not via an OpenAI tools array.\n *\n * Tool name + description + JSON-schema are pulled from the canonical\n * `DELEGATE_*` constants exported by `./tools/*` so the projection cannot\n * drift from the server's own validators.\n *\n * @experimental\n */\n\nimport type { OpenAIChatTool } from '../types'\nimport {\n DELEGATE_FEEDBACK_DESCRIPTION,\n DELEGATE_FEEDBACK_INPUT_SCHEMA,\n DELEGATE_FEEDBACK_TOOL_NAME,\n} from './tools/delegate-feedback'\nimport {\n DELEGATION_HISTORY_DESCRIPTION,\n DELEGATION_HISTORY_INPUT_SCHEMA,\n DELEGATION_HISTORY_TOOL_NAME,\n} from './tools/delegation-history'\nimport {\n DELEGATION_STATUS_DESCRIPTION,\n DELEGATION_STATUS_INPUT_SCHEMA,\n DELEGATION_STATUS_TOOL_NAME,\n} from './tools/delegation-status'\n\nfunction buildTool(\n name: string,\n description: string,\n parameters: Readonly<Record<string, unknown>>,\n): OpenAIChatTool {\n // `parameters` arrives as a deeply-readonly `as const` literal. The\n // OpenAI-compatible transports JSON-serialize the body, so a shallow copy\n // into a plain object is sufficient and shields callers that mutate\n // the returned descriptor from corrupting the source constant.\n return {\n type: 'function',\n function: { name, description, parameters: { ...parameters } },\n }\n}\n\n/**\n *\n * Returns the queue-bound delegation tools projected into OpenAI Chat\n * Completions `tools[]` shape. The order is stable: `delegate_feedback`,\n * `delegation_status`, `delegation_history`.\n *\n * @experimental\n */\nexport function mcpToolsForRuntimeMcp(): OpenAIChatTool[] {\n return [\n buildTool(\n DELEGATE_FEEDBACK_TOOL_NAME,\n DELEGATE_FEEDBACK_DESCRIPTION,\n DELEGATE_FEEDBACK_INPUT_SCHEMA as Readonly<Record<string, unknown>>,\n ),\n buildTool(\n DELEGATION_STATUS_TOOL_NAME,\n DELEGATION_STATUS_DESCRIPTION,\n DELEGATION_STATUS_INPUT_SCHEMA as Readonly<Record<string, unknown>>,\n ),\n buildTool(\n DELEGATION_HISTORY_TOOL_NAME,\n DELEGATION_HISTORY_DESCRIPTION,\n DELEGATION_HISTORY_INPUT_SCHEMA as Readonly<Record<string, unknown>>,\n ),\n ]\n}\n\n/**\n *\n * Subset filter — return only the projected tools whose `function.name`\n * appears in `names`. Useful for curated mounts (e.g. only the queue-bound\n * delegation tools, omitting `delegate_feedback`). Unknown names are\n * silently ignored; pass an empty array to get an empty result.\n *\n * @experimental\n */\nexport function mcpToolsForRuntimeMcpSubset(names: ReadonlyArray<string>): OpenAIChatTool[] {\n const allowed = new Set(names)\n return mcpToolsForRuntimeMcp().filter((tool) => allowed.has(tool.function.name))\n}\n"],"mappings":";;AAuCA,SAAS,UACP,MACA,aACA,YACgB;CAKhB,OAAO;EACL,MAAM;EACN,UAAU;GAAE;GAAM;GAAa,YAAY,EAAE,GAAG,WAAW;EAAE;CAC/D;AACF;;;;;;;;;AAUA,SAAgB,wBAA0C;CACxD,OAAO;EACL,UACE,6BACA,+BACA,8BACF;EACA,UACE,6BACA,+BACA,8BACF;EACA,UACE,8BACA,gCACA,+BACF;CACF;AACF;;;;;;;;;;AAWA,SAAgB,4BAA4B,OAAgD;CAC1F,MAAM,UAAU,IAAI,IAAI,KAAK;CAC7B,OAAO,sBAAsB,CAAC,CAAC,QAAQ,SAAS,QAAQ,IAAI,KAAK,SAAS,IAAI,CAAC;AACjF"}
@@ -1,4 +1,4 @@
1
- import { Q as OpenAIChatTool } from "./types-DeX8ibLc.js";
1
+ import { Q as OpenAIChatTool } from "./types-DpdfZoQ3.js";
2
2
  //#region src/mcp/openai-tools.d.ts
3
3
  /**
4
4
  *
@@ -21,4 +21,4 @@ declare function mcpToolsForRuntimeMcp(): OpenAIChatTool[];
21
21
  declare function mcpToolsForRuntimeMcpSubset(names: ReadonlyArray<string>): OpenAIChatTool[];
22
22
  //#endregion
23
23
  export { mcpToolsForRuntimeMcpSubset as n, mcpToolsForRuntimeMcp as t };
24
- //# sourceMappingURL=openai-tools-z-whdYNC.d.ts.map
24
+ //# sourceMappingURL=openai-tools-wkxQ2aEw.d.ts.map
@@ -1,4 +1,4 @@
1
- import { x as contentAddress } from "./spawn-journal-duo0EkOp.js";
1
+ import { x as contentAddress } from "./spawn-journal-oewq1g2h.js";
2
2
  import { i as redactProtectedValue, n as createProtectedRecordRedactor, r as redactProtectedReason, t as assertNoProtectedBytes } from "./protected-redaction--F3v1oo8.js";
3
3
  import { agentCandidateArtifactRefSchema, agentCandidateBenchmarkResultEvidenceSchema, agentCandidateBenchmarkSuiteSchema, agentCandidateBenchmarkTaskSchema, agentCandidateBundleSchema, agentCandidateContainerSchema, agentCandidateExecutionLimitsSchema, agentCandidateExecutionPlanEvidenceSchema, agentCandidateExecutionPlanMaterialSchema, agentCandidateMaterializationReceiptSchema, agentCandidateModelAccessNetworkSchema, agentCandidateModelSettlementEvidenceSchema, agentCandidateProfileActivationSchema, agentCandidateProfilePlanEvidenceSchema, agentCandidateProfileSchema, agentCandidateResolvedModelSchema, agentCandidateRunCellSchema, agentCandidateRunReceiptSchema, agentCandidateTaskOutcomeEvidenceSchema, agentCandidateTaskOutcomeSpecSchema, agentCandidateTerminationSchema, agentCandidateWorkspaceManifestMaterialSchema, agentCandidateWorkspaceSnapshotEvidenceSchema, agentProfileDiffSchema, agentProfileSchema, applyAgentProfileDiff, sha256DigestSchema } from "@tangle-network/agent-interface";
4
4
  import { REDACTION_VERSION, canonicalJson, isLlmSpan } from "@tangle-network/agent-eval";
@@ -4484,4 +4484,4 @@ function errorMessage(error) {
4484
4484
  //#endregion
4485
4485
  export { parseAgentCandidateProfileActivation as $, verifyMaterializedWorkspace as A, rejectedStage as B, assertNoGitIndirection as C, captureMaterializedWorkspace as D, candidateWorkspaceManifest as E, assertTerminalAllowedInPhase as F, isWellFormedUnicode as G, sealTerminalDigest as H, assertTerminalMatchesClaim as I, assertCandidateProfileBinding as J, agentCandidateProfileAsAgentProfile as K, assertTerminalMatchesStaged as L, candidateCleanupTimeout as M, withinCandidateCleanupDeadline as N, readVerifiedArtifact as O, assertRecoveryMatchesStaged as P, omitUndefinedObjectFields as Q, recoveredTerminalRecord as R, CANDIDATE_TRACE_TAGS as S, runCandidateGit as T, terminalRecord as U, requireStagedTerminal as V, assertExactObjectKeys as W, freezeGenericAgentCandidateProfile as X, createAgentCandidateProfileActivation as Y, materializeAgentCandidateProfilePlan as Z, candidateExecutionClaim as _, persistCandidateOutputArtifact as a, canonicalCandidateDocument as at, consumePreparedCandidateExecution as b, CANDIDATE_KNOWLEDGE_ROOT_ENV as c, immutableCandidateValue as ct, verifiedResourceTextByDigest as d, verifyCanonicalCandidateDocument as dt, parseExactAgentProfile as et, verifyAgentCandidateBundle as f, candidateClaimFileInternals as g, InMemoryAgentCandidateExecutionClaimStore as h, persistCandidateModelSettlementEvidence as i, canonicalCandidateDigest$1 as it, candidateCleanupDeadline as j, verifyBytes as k, candidateKnowledgeExecutionPaths as l, omitTopLevelDigest as lt, usdToNanos as m, executePreparedAgentCandidate as n, parseExactCandidateProfile as nt, sealAgentCandidateExecutorStopAcknowledgement as o, deepFreezeCandidate as ot, sealAgentCandidateModelSettlement as p, applyExactAgentProfileDiff as q, RecoveryAgentCandidateTraceStore as r, canonicalCandidateBytes as rt, CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG_ENV as s, embeddedCandidateArtifact as st, prepareAgentCandidateExecution as t, parseExactAgentProfileDiff as tt, AGENT_CANDIDATE_EXECUTION_SUPPORT as u, sha256Bytes as ut, assertPreparedCandidateIntegrity as v, readCandidateGitTreeFiles as w, CANDIDATE_TRACE_ENV as x, beginPreparedCandidateDisposal as y, rejectedFinish as z };
4486
4486
 
4487
- //# sourceMappingURL=prepare-DcMjMdj-.js.map
4487
+ //# sourceMappingURL=prepare-VLGnSyav.js.map